IU Test b–f Command Pack — 05 Test d Compose / Structure-Ops Plan
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; DOTdot_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; DOTdot_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=false→fn_iu_structure_op_applyrefuses (checked viafn_iu_structure_ops_enabled).iu_core.composer_enabled=false→ compose/cut refuses (checked viafn_iu_composer_enabled).iu_enact.allow_no_review_decision=false+iu_edit.policy.default_mode=require_review→ any enact/edit needs areview_decision_id.- Gateway
mode=enforced,direct_insert_policy=block_after_guard,allowed_marker_valuesincludesfn_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 itlifecycle=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
ordinalorder (hash match). - Reorder (d4): post-reorder render reflects new
ordinal;iu_structure_operationgains areorder/reparentrow; 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_setrow links parent→children; lineage + birth_registry supersede recorded. - Merge (d6): N IUs → 1; merged body == ordered concat of sources;
iu_merge_setrow; 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_rollbackfor each applied op; delete/retire theTEST-COMPOSE-<runid>collection and its clones; verifyiu_split_set/iu_merge_settest 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).