KB-13D2

dot-iu-cutter v0.4 — LedgerWriter Per-Writer Mapping Design (2026-05-17)

14 min read Revision 1
dot-iu-cutterv0.4schema-bindingper-writer-mappingdieu44design

dot-iu-cutter v0.4 — LedgerWriter Per-Writer Mapping Design

Date: 2026-05-17 · DESIGN ONLY (no code/commit/dry-run/provision). Companion to gap-analysis; append_history/append_sweep_log/status detail is in state-history-and-sweep-mapping-design. Each writer: current code payload → deployed columns → required NOT NULLs → mismatch → exact target mapping → code-change? → SQL op → principal → txn/rollback implication.

0. Shared binding constants (proposed; one source module in the code cycle, NOT created here)

TOOL_REV = cutter_agent.__version__ ("0.4.0-dryrun-skeleton") · ACTOR_EXEC = cutter_exec · ACTOR_VERIFY = cutter_verify · CLOCK = phase clock (ISO8601 → timestamptz) · jsonb defaults {} where NN. SB-DEC-1 lineage carrier = manifest_envelope.source_doc_ref ← entry_id. SB-DEC-2 digest/address carriage: content_hashcut_change_set.payload_summary jsonb + dot_pair_signature.payload_hash; canonical_addressmanifest_unit_block.proposed_canonical_address. SB-DEC-3 cut_change_set.verifier_tool_revision sentinel "pending" at CUT (verifier not yet run). SB-DEC-4 dry-run affected_row.target_table/target_row_id = sentinel ("cutter_governance/none", entry_id) — CUT is logical in dry-run, no real row mutated (append-only invariant). SB-DEC-5 thread render_order (enumerate index) from phases.review loop. SB-DEC-6 thread review_decision_id into CUT and manifest_id/review_decision_id into VERIFY from the in-phase objects.

1. append_entrydecision_backlog_entry — MATCH

  • Code payload: entry_id, kind, status, payload, emitted_at, scenario_ref.
  • Deployed cols: same set exists; NN-no-default = kind (supplied). PK entry_id.
  • Mismatch: none. Target mapping: identity. Code change: NO. SQL: INSERT. Principal: cutter_exec (MARK; also cutter_verify for the escalation entry on verify-fail, allowed by _VERIFY_INSERT_TABLES). Txn: first write of MARK; rollback = whole-phase abort (atomic).

2. insert_manifest_envelopemanifest_envelope — MISMATCH

  • Code payload: envelope_id, canonical_address, content_hash, source_entry_id, canon_lib_version.
  • Deployed cols: envelope_id(pk), NN-no-default: operation_kind, status, source_doc_ref, created_by, created_at; nullable: escalation_ref, cut_change_set_ref, reviewer, reviewed_at, rationale, superseded_by_envelope_id.
  • Mismatch: code's canonical_address/content_hash/source_entry_id/canon_lib_version have no columns; deployed NN operation_kind/status/source_doc_ref/created_by/created_at unfilled.
  • Target mapping: envelope_id←envelope_id; operation_kind←"cut" (v0.4 single op); status←"proposed" (pre-review); source_doc_ref←source_entry_id (SB-DEC-1 lineage carrier); created_by←ACTOR_EXEC; created_at←CLOCK; canonical_address→carried on manifest_unit_block.proposed_canonical_address (SB-DEC-2); content_hash/canon_lib_versionrationale is text only, so carry on downstream jsonb (cut_change_set.payload_summary) — envelope itself does not need them.
  • Code change: YES (row-builder). SQL: INSERT. Principal: cutter_exec (REVIEW). Txn: inserted before review_decision (FK review_decision.manifest_id→manifest_envelope.envelope_id); same REVIEW atomic txn.

3. insert_manifest_unit_blockmanifest_unit_block — MISMATCH

  • Code payload: envelope_id, unit_local_id, descriptor.
  • Deployed cols: composite PK (envelope_id, unit_local_id), FK envelope_id→manifest_envelope; NN-no-default: block_role, source_span, render_order, created_at; nullable: target_unit_id, proposed_canonical_address, proposed_authority, payload_summary, candidate_edges, report_summary, decision_backlog_ref.
  • Mismatch: code's descriptor has no column; deployed NN block_role/source_span/render_order/created_at unfilled.
  • Target mapping: envelope_id←envelope_id; unit_local_id←unit_local_id; block_role←"unit" (single stub role); source_span←descriptor (jsonb); render_order←enumerate index (SB-DEC-5); created_at←CLOCK; proposed_canonical_address←plan.canonical_address (SB-DEC-2).
  • Code change: YES (row-builder + thread render_order). SQL: INSERT. Principal: cutter_exec (REVIEW). Txn: after envelope, same REVIEW txn. Composite-PK uniqueness holds (one u0 per envelope on the canonical single-unit fixture).

4. insert_review_decisionreview_decision — MISMATCH

  • Code payload: review_decision_id, manifest_id, manifest_unit_local_id, decision, reviewer, prior_review_decision_id, superseded_by_review_decision_id.
  • Deployed NN-no-default: review_decision_id, governance_event_kind, manifest_id, manifest_version, review_scope, status, verdict, findings, reviewer_class, reviewer_identity, risk_class_assessment, decision_at, decided_by, cross_signed_by_dot_verifier, version, created_at, updated_at. FK manifest_id→manifest_envelope.envelope_id; composite FK (manifest_id,manifest_unit_local_id)→manifest_unit_block (NULL manifest_unit_local_id ⇒ MATCH SIMPLE skips); self-FKs prior_*/superseded_by_*.
  • Mismatch: code's decision/reviewer have no columns; 13+ deployed NN unfilled.
  • Target mapping: review_decision_id←review_decision_id; governance_event_kind←"review_decision"; manifest_id←env.envelope_id; manifest_version←TOOL_REV; review_scope←"manifest" (unit-local NULL); manifest_unit_local_id←None; status←"decided"; verdict←decision (approve/reject/defer); findings←{}; reviewer_class←"automated_agent"; reviewer_identity←{"reviewer":reviewer}; risk_class_assessment←"standard"; decision_at←CLOCK; decided_by←reviewer; cross_signed_by_dot_verifier←false; version←TOOL_REV; created_at/updated_at←CLOCK; prior_review_decision_id←code (None on canonical); superseded_by_review_decision_id←None.
  • Code change: YES. SQL: INSERT. Principal: cutter_exec (REVIEW). Txn: after envelope+unit_block (FK order), same REVIEW txn. update_review_superseded_by_if_any later stamps superseded_by_review_decision_id (MATCH, unchanged) only on re-review (0× canonical).

5. insert_dot_pair_signaturedot_pair_signature — MISMATCH

  • Code payload: signature_id, lane, signer_identity, payload_digest, placeholder_signature, prior_signature_id, is_production.
  • Deployed: signature_id(pk/default); NN-no-default: signature_kind, signer_dot_id, signer_tool_revision, payload_hash, payload_envelope, signature_payload; signed_at default now(); validation_state default 'pending'; self-FK prior_signature_id; nullable cross_reference_*, scenario_ref.
  • Mismatch: code's lane/signer_identity/payload_digest/placeholder_signature/is_production have no columns.
  • Target mapping: signature_id←signature_id; signature_kind←{"DOT-991":"executor","DOT-992":"verifier"}[lane]; signer_dot_id←lane; signer_tool_revision←TOOL_REV; payload_hash←payload_digest; payload_envelope←{"lane":lane,"signer_identity":signer_identity,"is_production":False}; signature_payload←placeholder_signature; prior_signature_id←code; signed_at←CLOCK (or default).
  • Code change: YES. SQL: INSERT. Principal: cutter_exec (CUT executor sig) / cutter_verify (VERIFY verifier sig) — both in _*_INSERT_TABLES. Txn: first write of CUT / of VERIFY respectively (FK targets for cut_change_set/verify_result).

6. insert_cut_change_setcut_change_set — MISMATCH

  • Code payload: change_set_id, decision_backlog_entry_id, executor_signature_id, verifier_signature_id(None), manifest_id, content_hash.
  • Deployed: change_set_id(pk/default); NN-no-default: rollback_key, manifest_id, manifest_version, review_decision_id, executor_tool_revision, verifier_tool_revision, emitted_by; UNIQUE idempotency_key, UNIQUE rollback_key; FK executor_signature_id/verifier_signature_id→dot_pair_signature, decision_backlog_entry_id→decision_backlog_entry; defaults: state 'pending', cut_started_at now(), affected_unit_count 0, version '1.0.0', risk_class 'standard'; content_hash has NO column.
  • Target mapping: change_set_id←change_set_id; rollback_key←f"rbk:{entry_id}:{change_set_id}" (deterministic, UNIQUE-safe); manifest_id←code; manifest_version←TOOL_REV; review_decision_id←rd.review_decision_id (SB-DEC-6 thread from cut()); executor_tool_revision←TOOL_REV; verifier_tool_revision←"pending" (SB-DEC-3); emitted_by←ACTOR_EXEC; executor_signature_id←code; verifier_signature_id←None; decision_backlog_entry_id←code; idempotency_key←f"ick:{entry_id}" (supports 23505→RESUME convergence); payload_summary←{"content_hash":content_hash} (SB-DEC-2); state←"applied" (optional; else default).
  • Code change: YES + thread review_decision_id from phases.cut. SQL: INSERT. Principal: cutter_exec (CUT). Txn: after executor signature (FK), same CUT atomic txn (SERIALIZABLE).

7. insert_cut_change_set_affected_rowcut_change_set_affected_row — MISMATCH

  • Code payload: affected_row_id, change_set_id, target_ref, effect.
  • Deployed: affected_row_id(pk/default); NN-no-default: change_set_id, target_table, target_row_id, operation_kind; FK change_set_id→cut_change_set; applied_at default now(); nullable before/after_state_snapshot.
  • Mismatch: code's target_ref/effect have no columns; deployed NN target_table/target_row_id/operation_kind unfilled.
  • Target mapping: affected_row_id←affected_row_id; change_set_id←code; target_table←"cutter_governance/none" (SB-DEC-4, dry-run logical CUT); target_row_id←entry_id (from target_ref "iu:{entry_id}"); operation_kind←"apply" (from effect={"applied":True}); after_state_snapshot←effect.
  • Code change: YES. SQL: INSERT. Principal: cutter_exec (CUT). Txn: after cut_change_set (FK), same CUT txn.

8. insert_verify_resultverify_result — MISMATCH

  • Code payload: verify_result_id, change_set_id, executor_signature_id, verifier_signature_id, outcome, rollback_change_set_id_triggered, escalation_ref, prior_verify_result_id.
  • Deployed: verify_result_id(pk/default); NN-no-default: change_set_id, manifest_id, manifest_version, review_decision_id, executor_tool_revision, verifier_tool_revision; many defaulted (verify_kind, axis_1_status, axis_1_drift_unit, axis_2_status, verdict 'pending', verified_at now(), state 'pending', rollback_triggered false, canonicalization_rule_used); FK change_set_id→cut_change_set, executor/verifier_signature_id→dot_pair_signature, rollback_change_set_id_triggered→cut_change_set, escalation_ref→decision_backlog_entry, self-FK prior_verify_result_id.
  • Mismatch: code's outcome has no column (deployed uses verdict/state/axis_1_status); deployed NN manifest_id/manifest_version/review_decision_id unfilled.
  • Target mapping: verify_result_id←verify_result_id; change_set_id←code; manifest_id←cs.manifest_id (SB-DEC-6 thread from verify()); manifest_version←TOOL_REV; review_decision_id←cs.review_decision_id (SB-DEC-6); executor_tool_revision←TOOL_REV; verifier_tool_revision←TOOL_REV; verdict←{"pass":"pass","fail":"fail"}[outcome]; state←"complete"; rollback_triggered←(outcome=="fail"); executor/verifier_signature_id←code; rollback_change_set_id_triggered←code; escalation_ref←code; prior_verify_result_id←code.
  • Code change: YES + thread manifest_id/review_decision_id. SQL: INSERT. Principal: cutter_verify (VERIFY). Txn: after verifier signature (FK), same VERIFY atomic txn (SERIALIZABLE).

9. update_entry_statusdecision_backlog_entry.status (CAS) — MATCH

  • adapter._do_cas_status: UPDATE …decision_backlog_entry SET status=%s WHERE entry_id=%s AND status=%s (or IS NULL). Deployed status text NOT NULL default 'open'. Free-text accepts state-machine vocabulary. rowcount!=1 ⇒ AppendOnlyViolation (CAS lost). Code change: NO. SQL: column-scoped UPDATE. Principal: cutter_exec (SWEEP/REVIEW/CUT) or cutter_verify (VERIFY) — both hold UPDATE(status) in the frozen matrix. Txn: the sole sanctioned in-place mutation; same atomic phase txn as its mandatory append_history.

10. update_review_superseded_by_if_anyreview_decision.superseded_by_review_decision_id (write-once stamp) — MATCH

  • adapter._do_stamp_superseded: cutter_exec-only, table/column pinned to review_decision.superseded_by_review_decision_id, UPDATE … SET superseded_by_review_decision_id=%s WHERE review_decision_id=%s AND superseded_by_review_decision_id IS NULL, rowcount!=1 ⇒ AppendOnlyViolation. Deployed column exists (uuid, nullable, self-FK). Code change: NO. SQL: write-once column UPDATE. Principal: cutter_exec. Txn: REVIEW re-review path only — invoked on the canonical happy path; compatible if used.

11. Out-of-canonical: append_dependencydecision_backlog_dependency

Not in GPT's 12; dependency final = 0 (r3). For completeness: code dependency_id, from_entry_id, to_entry_id; deployed adds NN dependency_kind, created_at, created_by. Would need the same rebinding pattern (dependency_kind←"blocks", created_at←CLOCK, created_by←ACTOR_EXEC) if/when dependency authoring is exercised — off the binding critical path; flagged for the code cycle's backlog, not gating dry-run resume.

12. Summary

9 INSERT row-builders rebind (no new columns vs deployed; all NN fillable from deterministic sources); 2 in-place ops (cas_status, stamp_superseded) and append_entry already schema-correct. No DELETE/TRUNCATE/DDL/GRANT introduced; only INSERT + the 2 pre-existing sanctioned column UPDATEs. Principal routing unchanged. No schema migration.

Back to Knowledge Hub knowledge/dev/laws/dieu44-trien-khai/v0.4-schema-binding/dot-iu-cutter-v0.4-ledgerwriter-per-writer-mapping-design-2026-05-17.md