Skip to content

Harden bind-text-block: deterministic element resolution + library-immutable item_type guard #900

Description

@jfrench9

Summary

Two hardening items in the new bind-text-block path
(robosystems/operations/roboledger/commands/text_blocks.py). Neither is a
security hole — both paths are tenant-scoped and write-gated — but both are
data-integrity / robustness looseness worth closing before the disclosure
authoring surface goes live in prod.

(a) Non-deterministic element resolution, no structure-membership check

_resolve_element resolves a qname via Element.qname == ... .limit(1) with no
ordering, then bind_text_block stamps the fact with structure_id = body.structure_id + element_id = element.id. Nothing verifies the element is
actually an arc member of that structure, and a qname duplicated across
taxonomies in the tenant schema resolves arbitrarily.

Result: a narrative can be attached to the wrong structure.

Fix: make the qname lookup deterministic/unique, and validate the element
participates in body.structure_id (via associations).

(b) item_type stamp can trip the library-immutability trigger

bind_text_block sets element.item_type = "text_block" on first bind
(text_blocks.py:145-149). If the target element is ever library-owned
(created_by = 'library-seeder'), the UPDATE elements on flush hits the
raise_library_immutable_elements trigger (migration 0002) → P0001, which
surfaces as an uncategorized InternalError → 500 (MCP: generic
command_failed).

Unreachable today: the only library text-block-CAP disclosure structures are
abstract (rejected by the is_abstract guard first), and the only concrete
library concepts are the 5 rs-metric ratios (not text-block). It becomes a live
crash the moment the library ships a concrete text-block concept.

Fix: only stamp item_type when created_by != 'library-seeder', drive the
write through the sanctioned library_resync path, or set item_type at
authoring time in create-taxonomy-block instead of lazily on bind.

Test gap

The bind_text_block command itself has no direct unit test (only the
envelope/dispatch and serialization paths are covered), so the item_type path is
untested.

Found during the v1.6.6 pre-release review.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions