KB-45F0

80000x · 05 — DOT contract: dot_iu_cut_from_manifest (CLI, G1-G7 guards, atomic txn, rollback)

9 min read Revision 1
iu-core80000xdot_iu_cut_from_manifestdot-contractG1-G7-guardsatomic-transactionrollbackapproved-manifestfn_iu_composeaudit-rowdot_iu_command_runexit-codesDOT-991DOT-992

05 — DOT contract: dot_iu_cut_from_manifest

The single command that consumes an approved manifest and durably creates IU rows. This document is the command-review contract; an R1-style code-authoring micro-cycle is the carry-forward.

1. Identity

dot_command_name:        dot_iu_cut_from_manifest
command_catalog_table:   dot_iu_command_catalog          # PK column: command_name
command_run_table:       dot_iu_command_run              # audit; column: command_name
governance_lane:         DOT-991 (cutter executor)       # parallel to v0.5 cutter_exec
verifier_lane:           DOT-992 (cutter verifier)       # invoked from VERIFY stage

The command must be registered in dot_iu_command_catalog before it is callable. Registration is a small migration (sketched in 10-carry-forward-to-implementation.md).

2. CLI shape

python -m cutter_agent.cut_from_manifest \
  --manifest                       <path/to/approved_manifest.json> \
  --approval-doc-id                <kb-doc-id-of-the-review-record> \
  --expect-manifest-digest         <sha256> \
  --principal                      workflow_admin \
  --apply \
  --reconstruct \
  --verify \
  --out-dir                        <ephemeral-scratch-dir>

Switches:

  • --apply (required): without this flag the command runs as a CUT-plan dry-run (emits the SQL that WOULD execute, writes nothing).
  • --reconstruct (default on): after CUT, re-runs fn_iu_reconstruct_source and compares to manifest.articles[].original_text_hash. FAIL ⇒ rolls back.
  • --verify (default on): after CUT + reconstruct, runs the V1–V8 checks (see 01 §5.3) and emits verify_report.md. FAIL ⇒ rolls back via rollback_plan.json.
  • --principal: must be the role that owns the IU-core tables; default workflow_admin per 70000x channel discovery.

3. Required pins (the six identity locks; any mismatch ⇒ REFUSED)

G1  approval                     : --approval-doc-id resolves in KB to a record whose
                                    `manifest_digest` matches the file's digest
G2  manifest digest              : sha256(canonical(manifest)) == --expect-manifest-digest
G3  source identity              : fresh fetch of source.url_or_file has hash == manifest.source.source_hash
                                    OR --skip-source-refetch (only allowed for inline-text manifests)
G4  principal                    : current_user == --principal
G5  vocab drift                  : every section_type / unit_kind / piece_role / link_role
                                    still present in live DB CHECK constraints
G6  cut-once                     : no information_unit row exists at any of the proposed
                                    canonical_addresses (or, for an explicit version-update,
                                    the prior version is in `enacted` state and supersedes-chain is valid)
G7  fresh backup                 : pg_dump within ≤ 60 min, sha logged in KB

If any G fails: exit code 2 (REFUSED), no DB connection opened, no SQL run.

4. Transaction model (one atomic txn)

BEGIN;
SET CONSTRAINTS ALL DEFERRED;

-- For each articles[]:
--   one fn_iu_compose call with pieces_json built from manifest.articles[i].pieces[]
--   - 'new_piece' branch for every piece (mints + attaches)
--   - returns iu_piece_collection.id + minted iu_ids
SELECT fn_iu_compose(
  p_collection_kind  => 'design_doc_section',
  p_collection_key   => '<doc_code>/<article_label>',
  p_pieces           => '<jsonb array>',
  p_actor            => 'dot_iu_cut_from_manifest/<run_id>',
  p_idempotency_key  => md5('<approval_doc_id>'||':'||'<article_label>'||':v1')
);

-- For each piece in each article:
--   if axis_b.legal_document / professional_tags present, INSERT iu_metadata_tag rows
-- If any sql_bridge present: INSERT iu_sql_link (validator must return resolved=true)

-- Audit row
INSERT INTO dot_iu_command_run (
  command_name, run_id, actor, args_json, status, started_at, finished_at
) VALUES (
  'dot_iu_cut_from_manifest', <uuid>, '<operator>', '<args>', 'in_progress', now(), null
);

COMMIT;

Single atomic transaction; ROLLBACK on any failure within.

5. Idempotency

idempotency_key_per_article : md5(approval_doc_id || ':' || article_label || ':' || manifest_version_tag)
fn_iu_compose                : returns existing iu_piece_collection.id on replay
                               (see [[feedback-idempotency-key-for-event-driven-compose]])

Replaying the exact same --manifest + --approval-doc-id produces zero new rows and exits 0 with idempotent_replay: true in the execution log.

6. Outputs

out_dir/cut_execution_log.md         # operator-readable timeline
out_dir/cut_sql_emitted.sql          # the actual SQL that ran (or would have, under --no-apply)
out_dir/iu_ids_created.json          # mapping { local_piece_id -> iu_id, article_label -> iu_piece_collection_id }
out_dir/rollback_plan.json           # retire/supersede plan keyed on manifest_id
out_dir/verify_report.md             # V1..V8 results (only when --verify)

Upload all artifacts to:

knowledge/dev/laws/<doc-folder>/cut-runs/<UTC-timestamp>-<manifest_id>/

After upload, update the manifest's cut_record and (if VERIFY passes) verify_record, then write the updated manifest back to the approved-manifests KB path with approval.status = verified.

7. Rollback

rollback_plan.json lists, in reverse order:

  1. iu_sql_link rows to mark lifecycle_status='retired';
  2. iu_metadata_tag rows to delete (NOT retire — tag rows are de-references, not durable IU);
  3. iu_piece_membership rows to deactivate;
  4. iu_piece_collection row(s) to lifecycle_status='retired';
  5. information_unit rows (newly minted pieces) to lifecycle_status='retired' with superseded_by=null.

Rollback is forward-compensation, not DELETE: rows remain visible in the lifecycle log with a retired status and an actor tag identifying this CUT run. This matches the existing 11-gate IU-core retire/supersede invariants.

Run rollback with:

python -m cutter_agent.cut_rollback \
  --manifest      <approved_manifest.json> \
  --plan          <out_dir/rollback_plan.json> \
  --principal     workflow_admin \
  --reason        "<one-line reason: verify failed | operator request | …>" \
  --apply

8. Forbidden inside CUT

  • DELETE on any IU-core table (use lifecycle retire instead).
  • TRUNCATE (ever).
  • DDL of any kind.
  • GRANT / REVOKE.
  • writes to production_documents.
  • writes to Qdrant (vector_sync is a separate, gated path).
  • writes to directus_files or other Directus app tables.
  • enabling or disabling any iu_core.* gate inside the CUT txn (use a separate operator step with explicit sign-off).
  • --no-verify / --no-reconstruct shortcuts unless the operator explicitly accepts that VERIFY will run as a separate, later step (rare; requires KB record of the deferral).

9. Exit codes

0  : PASS  (apply + reconstruct + verify all green)
1  : ATOMIC_ABORT  (TX rolled back; no rows written; reason logged)
2  : REFUSED  (G1..G7 gate failed before any DB connect)
3  : VERIFY_FAILED  (CUT applied but V1..V8 found a violation; rollback_plan.json emitted)
4  : ROLLBACK_NEEDED_BUT_NOT_APPLIED  (operator must run cut_rollback explicitly)

10. Audit invariants

  • Exactly one dot_iu_command_run row per execution.
  • dot_iu_command_run.command_name = 'dot_iu_cut_from_manifest'.
  • dot_iu_command_run.args_json includes --approval-doc-id, --expect-manifest-digest, and the manifest_id.
  • Every minted information_unit row has created_by = 'dot_iu_cut_from_manifest/<run_id>'.
  • Every minted iu_piece_membership row's actor column matches.

11. Carry-forward to implementation

This contract is the spec. The code does not yet exist; it must be authored as a separately-gated micro-cycle. See 10-carry-forward-to-implementation.md for the build list and migration sketch.

Back to Knowledge Hub knowledge/dev/laws/dieu44-trien-khai/v0.6-iu-core-operational-cut-workflow-mark-review-cut-verify/05-dot-cut-from-approved-manifest-contract.md