KB-49E6

IU Core 960x — 03 Text-as-code import to apply gate

5 min read Revision 1
iu-core960xdot-iu-cutter-v0.6text-as-codeapply-gatedieu44

03 — Text-as-code import → APPLY gate

1. The gap closed

The 480x/500x text-as-code layer parses, validates and proposes a composition import (propose_collection_import) but executes=False and IMPORT_IS_DESTRUCTIVE=False. This macro builds the controlled APPLY: a desired composition manifest reconciled to a live collection through the governed composer one-commands — bounded, gated, non-destructive, reversible.

2. text_as_code.py — the apply gate (pure, no IO)

New, additive:

  • APPLY_IS_DESTRUCTIVE = False — the apply path mints nothing and hard-deletes nothing.
  • ApplyOperation — one governed step: op_kind (add/remove/reorder), the dot_iu_* command, the iu_id, the resolve kwargs, a note.
  • CollectionApplyPlan — an ordered tuple of ApplyOperation + errors + destructive (always False); acceptable /is_noop / summary().
  • build_collection_apply_plan(manifest, current_pieces, *, collection_id, actor, known_iu_ids=None) — diffs the desired manifest against the collection's live piece list and emits governed one-commands:
    • a piece desired but absent → dot_iu_add_piece;
    • a piece present but undesired → dot_iu_remove_piece (DETACH only — the piece stays alive with every other membership);
    • a piece in both at a different order → dot_iu_reorder_piece. Emitted removes → adds → reorders.

Non-destructive by construction: only add/remove/reorder, no hard delete, no lifecycle mutation. Fail-closed: the manifest is validated first; a desired iu_id that is neither a current member nor in known_iu_ids is an ERROR ("does not mint IUs") — never an ungoverned birth. The plan is pure data; execution is one governed one-command at a time through OperatorRuntime, which re-checks the gates and the governance.

3. sandbox/160 — apply-gate probe, BEGIN … ROLLBACK — 8/8

Against the durable autocut collection iu_core.autocut.file-001 (3 pieces):

# probe result
T1 composer gate CLOSED → reconciliation refuses PASS
T2 gate open: REORDER reconciliation → new order PASS
T3 collection validates clean after reorder PASS
T4 REMOVE reconciliation → piece detached, count 3→2 PASS
T5 removed piece still alive globally (non-destructive) PASS
T6 ADD reconciliation → piece re-attached, count 2→3 PASS
T7 collection validates clean after add/remove PASS
T8 manifest_digest recomputes deterministically PASS

4. text_as_code_apply_operator_proof.py — durable apply, proven

The reproducible proof driver runs the FIRST durable text-as-code apply through OperatorRuntime against the live directus DB, on iu_core.autocut.file-001:

  1. read the live piece list (rows of v_iu_collection_manifest);
  2. build a DESIRED manifest = the same pieces in REVERSED order;
  3. build_collection_apply_plan → a 2-op reorder plan (destructive=False, acceptable=True);
  4. DRY-RUN — print the plan, execute nothing;
  5. GATED APPLY — enact both ops through OperatorRuntime.apply under the operator-runtime + composer gates → 2 applied ledger rows;
  6. VERIFYdot_iu_validate_collection verified; reorder_matches_desired = True;
  7. COMPENSATION — build the inverse plan (desired → original) and apply it → 2 more applied ledger rows;
  8. ROUNDTRIPorder_restored = True; manifest_digest 3d51e7593c3887dba501e9c40f622a60 before == after (the runtime/290 digest, byte-identical);
  9. fail-closed — operator-runtime gate shut → apply refused.

dot_iu_command_run 11 → 18 (+7: 4 reorder/applied, 2 validate/verified, 1 reorder/refused). The reorder is self-compensating, so the durable footprint nets to zero piece movement — only reversible ledger + composer-event history rows. Both gates closed in a finally.

5. Finding F-960x-1 — concurrency on the dot_config gates

During proof bring-up a first run of text_as_code_apply_operator_proof.py was still in flight (launched in background) when a second instance started. The two raced on the dot_config gate toggles: one instance's finally closed the gates mid-flight in the other, so a COMPENSATION step was refused and the collection was left reordered. Repaired in one governed transaction (fn_iu_collection_reorder_piece → original order, digest 3d51e759… confirmed). Lesson: the OperatorRuntime gate-window pattern is NOT concurrency-safe — the proof driver must run as a single instance. Recorded for the next macro; the final production state is clean.

6. Rollback / disable

The durable apply is self-compensating (step 7 ran the exact inverse). The 7 ledger rows are reversible by DELETE … WHERE actor='runtime_960x_textcode _apply'. Disable: close the composer gate (every reconciliation step refuses) or the operator-runtime gate (every apply refuses).

Back to Knowledge Hub knowledge/dev/laws/dieu44-trien-khai/v0.6-iu-core-960x-delivery-textcode-import-surface-sync-acceptance-open-goal/03-text-as-code-apply-gate.md