KB-4AEB

IU Test b–f Command Pack — 05 Test d Compose / Structure-Ops Plan

8 min read Revision 1
iutest-dcomposestructure-opssplit-mergereview-decisioncommand-pack2026-05-28

05 — Test d: Compose / Structure-Ops Plan (MUTATING, GATED)

Goal: Assemble a document from scratch by composing IUs, then exercise add / remove / reorder / merge / split automatically, with render + reconstruct verification and full rollback. Mutating and gated — must NOT run before the bounded gate protocol (08) and review_decision wiring (U3).

Owner laws: Điều 38/39 (IU structure/body), Điều 32 (approval of mutating ops), Điều 35 (DOT mutation + audit), Điều 30/31 (reversibility/audit), Điều 0-G/36 (born outputs not orphaned). Mutation: YES. Readiness: MEDIUM.

1. Live substrate (verified)

  • Compose/assembly: fn_iu_compose, fn_iu_collection_create, fn_iu_collection_add_piece, fn_iu_collection_remove_piece, fn_iu_collection_reorder_piece, fn_iu_collection_render, fn_iu_render_file; DOT dot_iu_create_collection, dot_iu_add_piece, dot_iu_remove_piece, dot_iu_reorder_piece, dot_iu_create_file_from_pieces, dot_iu_render_file.
  • Structure ops: fn_iu_structure_op_plan/apply/verify/rollback, fn_iu_structure_op (gateway marker), fn_iu_piece_split, fn_iu_piece_merge; DOT dot_iu_split_piece, dot_iu_merge_piece, dot_iu_supersede_piece, dot_iu_clone_piece.
  • State: iu_piece_collection (45), iu_piece_membership (227), iu_structure_operation (72 = reparent 60 + deprecate 12), iu_split_set (0), iu_merge_set (0), iu_tree_change_log (56).
  • Reconstruct/verify: fn_iu_reconstruct_source, fn_iu_structure_op_verify.

2. Gating reality (why this is blocked today)

  • iu_core.structure_ops_enabled=falsefn_iu_structure_op_apply refuses (checked via fn_iu_structure_ops_enabled).
  • iu_core.composer_enabled=false → compose/cut refuses (checked via fn_iu_composer_enabled).
  • iu_enact.allow_no_review_decision=false + iu_edit.policy.default_mode=require_review → any enact/edit needs a review_decision_id.
  • Gateway mode=enforced, direct_insert_policy=block_after_guard, allowed_marker_values includes fn_iu_structure_op → ops MUST flow through the marked function path; direct INSERT blocked.

3. Safe test collection strategy

  • Create an isolated test collection (a fresh iu_piece_collection, clearly named e.g. TEST-COMPOSE-<runid>) so no production collection is mutated. Tag it lifecycle=testing.
  • Prefer clone-from-existing test pieces (dot_iu_clone_piece) over inventing content, so axis envelopes/birth records are well-formed and we avoid orphan creation.
  • Everything runs inside a single transaction per sub-step with BEGIN…ROLLBACK for the dry-run proof; a separate committed run (bounded gate open) produces the durable first-use of iu_split_set/iu_merge_set.

4. Existing-IU vs staging test-IU strategy

  • Read/assemble/reorder sub-tests use clones of existing enacted IUs (safe, real envelopes).
  • Split/merge sub-tests use dedicated test IUs created via the staging→cut path (No-Vector Staging Zone) so we never split/merge a production law IU on first exercise.

5. Sub-test sequence

Step Action Function / DOT First-use?
d1 assemble from scratch fn_iu_compose / dot_iu_create_file_from_pieces no
d2 add piece fn_iu_collection_add_piece / dot_iu_add_piece no
d3 remove piece fn_iu_collection_remove_piece / dot_iu_remove_piece no
d4 reorder piece fn_iu_collection_reorder_piece / dot_iu_reorder_piece reparent proven (60 rows)
d5 split piece fn_iu_piece_split / dot_iu_split_piece YES — iu_split_set first row
d6 merge pieces fn_iu_piece_merge / dot_iu_merge_piece YES — iu_merge_set first row
d7 render + reconstruct verify fn_iu_collection_render + fn_iu_reconstruct_source + fn_iu_structure_op_verify no

6. Expected output comparison

  • Assemble (d1): render of the composed collection equals the concatenation of member bodies in ordinal order (hash match).
  • Reorder (d4): post-reorder render reflects new ordinal; iu_structure_operation gains a reorder/reparent row; reconstruct still valid.
  • Split (d5): one IU → N child IUs; concatenation of children's bodies (source order) == original body hash (Axis A preserved); iu_split_set row links parent→children; lineage + birth_registry supersede recorded.
  • Merge (d6): N IUs → 1; merged body == ordered concat of sources; iu_merge_set row; supersede recorded.

7. review_decision_id dependency

  • Split/merge (d5/d6) require a non-null review_decision_id (iu_enact.allow_no_review_decision=false). The governed REVIEW sub-pipeline + row-builder were "never committed" (TD-P1 OPEN). Therefore d5/d6 are blocked until U3 lands. d1–d4 + d7 can run under the structure_ops/composer bounded gate without new review wiring only if they do not trigger an enact requiring a decision — verify per-function; if add/remove also require review, they too wait for U3.

8. Gate dependencies

  • structure_ops_enabled → bounded-open for d4–d6 (protocol 08).
  • composer_enabled → bounded-open for d1/d7.
  • Both opened together for the committed run, closed immediately after (mirrors mig-057 composer open→CUT→close pattern).

9. Rollback / cleanup

  • Dry-run sub-tests: ROLLBACK (no persistence).
  • Committed run: fn_iu_structure_op_rollback for each applied op; delete/retire the TEST-COMPOSE-<runid> collection and its clones; verify iu_split_set/iu_merge_set test rows are clearly marked test and either retained as first-use evidence or rolled back per Council choice.
  • Close all opened gates; verify closed (protocol 08).

10. First-use proof for iu_split_set / iu_merge_set

This test is the first ever population of these two tables. The proof must show: (a) a split produces a well-formed iu_split_set row with parent/children FKs; (b) Axis-A reconstruct of children == parent original hash; (c) rollback cleanly removes/supersedes; (d) no orphan child left unparented (Điều 0-G).

11. State-machine rollback dependency

cut_request can stick at mark_verified with cut_run_id=NULL (no mark_verified→mark_rejected edge). If d's split/merge route through the cut state machine, U5 (state-machine rollback edge) is a prerequisite for clean recovery on failure. Document as a hard dependency.

12. Exact PASS criteria

PASS iff: d1–d4 + d7 succeed with hash-verified render + valid reconstruct + audit rows + clean rollback; AND (after U3) d5/d6 produce first valid iu_split_set/iu_merge_set rows with Axis-A preservation and clean rollback; all under bounded gates that are verified closed afterward; zero orphan. Without U3, test d is PARTIAL (d1–d4/d7 only).

13. Failure modes

Mode Detection Handling
split breaks Axis-A order reconstruct hash mismatch FAIL; rollback; do not commit
orphan child after split orphan check (Điều 0-G) FAIL hard
gate left open post-check (protocol 08) incident; force-close
stuck mark_verified state-machine probe blocked on U5
missing review_decision enact refusal blocked on U3 (expected)

14. Why this must not run before gate/review protocol

Running split/merge without U3 either (a) is refused by the enact guard (best case) or (b) if forced, mutates IU bodies without an approval record — a direct Điều 32 violation and an orphan/đẻ-rơi risk at the exact layer the industrial-birth law (Điều 0-G/36) protects. The bounded gate protocol (08) is the only sanctioned way to open structure_ops_enabled/composer_enabled, and it requires Điều 32 approval to open. Test d therefore sits behind macros 3 (gate) and 4 (review wiring).

Back to Knowledge Hub knowledge/dev/reports/architecture/iu-test-b-to-f-readiness-command-pack-2026-05-28/05-test-d-compose-structure-ops-plan.md