KB-68C3

IU Core 500x — 03 DOT one-command operator surface

5 min read Revision 1
dieu44iu-core-mvp500xoperator-surfacemigration-017dot-commandsv0.62026-05-22

03 — DOT one-command operator surface

1. The problem

The 240x/480x composer gave every operation a single SQL function, and composer.COMPOSER_COMMANDS mapped a dot_iu_* name to it. But an operator still had to (a) remember each function's raw signature, and (b) know the multi-step sequences — and the third piece-disposal verb, soft-delete with rollback, had no governed function at all.

2. migration 017 — governed soft-delete / restore

017_dot_operator_surface.sql adds the missing governed primitive — and its inverse, so soft-delete is reversible by one command:

  • fn_iu_piece_soft_delete(uuid, text) — stamps deleted_at. Gated by the composer gate. Fail-closed: refuses an unknown piece, no-ops on an already-deleted piece, refuses an enacted piece (an enacted IU retires through the 'retired' lifecycle, never soft-delete), and refuses a piece still active in any collection — the operator must dot_iu_remove_piece it first. This keeps the three disposal verbs crisply ordered and stops a soft-delete silently breaking a composition.
  • fn_iu_piece_restore(uuid, text) — clears deleted_at; the exact inverse.

Both write information_unit the governed way: they set the IU Gateway canonical-writer marker GUC (key discovered from dot_config, never hardcoded) to the allow-listed 'fn_iu_structure_op' token, exactly as fn_iu_structure_op_apply does. DOT: function 36 → 38 / total → 106. Reversible via rollback/017.

3. The three-way piece-disposal distinction

verb command mechanism effect reverse
remove from collection dot_iu_remove_piece fn_iu_collection_remove_piece (015) membership ends; piece lives, keeps other memberships dot_iu_add_piece
retire globally dot_iu_retire_piece deprecate_piece structure op (012) lifecycle_status='deprecated' everywhere fn_iu_structure_op_rollback
soft-delete dot_iu_delete_piece_soft fn_iu_piece_soft_delete (017) deleted_at stamped; vanishes from every render/validate/compose path dot_iu_restore_piece

4. cutter_agent/iu_core/dot_commands.py — the operator surface

A pure module (no IO, no DB — the composer.py precedent). 17 dot_iu_* commands across 5 categories (collection / piece / lifecycle / read / health). Each resolves to a DotCommandPlan — an ordered tuple of ready-to-run governed SQL + description + reversal note. build() is fail-closed (rejects a missing required / unknown parameter). dot_iu_retire_piece resolves to a self-contained DO block that runs the deprecate_piece plan+apply and RAISE NOTICEs the op id for rollback — so even a multi-step lifecycle op is still one statement for the operator. sql_literal doubles every embedded quote (injection-inert). CLI: list / help <cmd> / explain <cmd> k=v…explain prints the SQL, never executes. composer.COMPOSER_COMMANDS extended 12 → 17 with the lifecycle verbs.

5. sandbox/120 — proof on the production schema

120_dot_operator_surface_probe.sql — one BEGIN…ROLLBACK, zero durable rows, 8/8 probes pass (SANDBOX_120_VERDICT all_pass=t):

  • O1 both functions installed;
  • O2 soft-delete stamps deleted_at (ok=true);
  • O3 restore clears it (ok=true);
  • O4 soft-delete refuses an active collection member;
  • O5 soft-delete gated — composer gate shut ⇒ refused;
  • O6 remove-from-collection leaves the piece alive, then soft-delete succeeds — the verbs compose in the documented order;
  • O7 restore of a live piece is a safe no-op (ok=false);
  • O8 soft-delete refuses an unknown piece.

6. Tests

test_iu_core_500x_operator_surface.py — 36 tests: migration 017 shape + gating + governed marker, sandbox/120 coverage, runtime/110 at 106, the delayed-lane fix, the 17-command registry, the three-way distinction, the sql_literal quoting/injection contract, every command resolving to a DOT-visible target, the CLI. Suite 843 → 879.

Back to Knowledge Hub knowledge/dev/laws/dieu44-trien-khai/v0.6-iu-core-500x-dot-one-command-composer-production-closeout-open-goal/03-operator-surface.md