KB-3B70

dot-iu-cutter v0.4 — Schema-Binding Risk & Code-Change Plan (2026-05-17)

6 min read Revision 1
dot-iu-cutterv0.4schema-bindingriskcode-change-plandieu44design

dot-iu-cutter v0.4 — Schema-Binding Risk & Code-Change Plan

Date: 2026-05-17 · DESIGN ONLY (no code/commit/dry-run/provision). Defines the bounded code-change surface for the next GPT-gated cycle and the risk register. Nothing here is executed or committed.

1. Code-change surface (for the future "v0.4 LedgerWriter schema-binding CODE" cycle — NOT this phase)

Strictly scoped, additive-in-spirit (no behaviour/flow change, only row-payload binding):

File Change Notes
cutter_agent/ledger.py Rebind 9 row-builders: append_history, append_sweep_log, write_manifest_envelope, write_manifest_unit_block, write_review_decision, write_signature, write_cut_change_set, write_affected_row, write_verify_result Method signatures/callers unchanged where possible; only the emitted row dict maps to deployed columns per per-writer-mapping-design
cutter_agent/ledger.py (or new cutter_agent/schema_binding.py) Add binding constants/derivations (TOOL_REV, lane→signature_kind, sentinels SB-DEC-3/4, jsonb defaults) Prefer a small dedicated module so the mapping is reviewable in isolation
cutter_agent/phases.py Thread render_order enumerate index (SB-DEC-5) into write_manifest_unit_block; thread review_decision_id into CUT and manifest_id/review_decision_id into VERIFY (SB-DEC-6); replace InMemory _source_entry virtual filter with the real-schema source_doc_ref join (SB-DEC-1) Small, local; flow/guards/state-machine untouched
tests/ Add static schema-contract fixture + per-writer contract tests; update InMemory-fixture row-key assertions whose shape changed Per pg-backed-test-revision-plan
cutter_agent/db_adapter.py No change Adapter is correct; _EXEC/_VERIFY_INSERT_TABLES, routing, isolation, append-only guards all already align to deployed table names
state_machine.py, idempotency.py, canonicalization.py, signing.py, signal.py, cli.py No change Vocabulary/contracts already compatible

Not in scope (forbidden / unnecessary): any cutter_governance DDL/migration; any GRANT/role change; any new DELETE/TRUNCATE/DDL surface; any production connection; any change to phase order, principal routing, or isolation; ProductionDBAdapter refusal stays verbatim.

2. Schema migration assessment — NOT needed

Every deployed NOT-NULL-without-default column is fillable from a deterministic, semantically-correct in-process source (state vocabulary, principal/lane/tool constants, clock) or absorbed by an existing jsonb column. No runtime semantic is unrepresentable in the deployed schema (it is a strict superset). Constraint C honoured: migration only if a blocker proves the schema cannot represent required semantics — no such blocker found. (If, during the code cycle, a concrete value is found genuinely underivable, that is a new blocker → STOP + report, not a unilateral migration.)

3. Risk register

ID Risk Likelihood Impact Mitigation
R1 A deployed NN column's intended semantic is mis-guessed by a constant (e.g. operation_kind, governance_event_kind) Med Med Mappings are explicit & GPT-reviewed here before code; values are conservative/neutral; contract test asserts presence, GPT asserts correctness
R2 Rebinding silently changes a row count (breaks r3) Low High Design proves count-invariance (binding is column-level); per-writer-mapping + binding-plan §2; contract tests don't add writes; r3 re-verified by the dry-run itself
R3 FK ordering violation inside a phase Low High Intra-phase order pinned (binding-plan §1); FK graph captured from live catalog
R4 UNIQUE collision on cut_change_set.rollback_key/idempotency_key Low Med Deterministic keys derived from entry_id/change_set_id; single-entry canonical fixture ⇒ no collision; replay converges (23505→RESUME by design)
R5 Test false-negative (string DDL compare, grep -c, schema-qualified names) Med Med Contract test uses set-equality on column-name sets, integer counts via captured ints — explicitly the project's anti-FN discipline
R6 Scope creep into a schema redesign Low High Hard scope table §1; migration forbidden absent a proven representability blocker; GPT-gated cycle boundary
R7 Lineage join (SB-DEC-1) wrong on re-review (out-of-canonical) Low Low Canonical path has no prior (empty join, identical behaviour); re-review explicitly out of canonical scope; covered by a dedicated test
R8 _Secret/redaction or no-prod invariants disturbed by edits Low High Edits are row-payload only; db_adapter.py untouched; redaction/no-DSN/no-.env invariants unaffected; security-boundary tests retained

Residual risk class: STANDARD (bounded, column-level, no migration, GPT-gated, count-invariant, strong test net).

4. Code-authoring "r2"? — terminology

GPT asked "whether code authoring r2 is needed". The accepted code is r1 (56d3732, FINAL CODE PASS). The schema binding requires a new code-authoring cycle (call it the LedgerWriter schema-binding code cycle; "r2" of the cutter-agent code). Yes — a code-authoring cycle is required, scoped to §1, GPT-gated (design→code→evidence→GPT PASS), producing a new scoped commit. It is not authored in this design phase.

5. Verdict (this doc)

  • Code-authoring cycle: REQUIRED, surface = §1 (≈2 modules + tests; db_adapter.py untouched).
  • Schema migration: NOT required.
  • PG-backed dry-run: resumes after the code cycle PASSes, using command-review r1 + verification-plan r3 unchanged.
  • Residual risk: STANDARD. No production write, no migration, count-invariant.
Back to Knowledge Hub knowledge/dev/laws/dieu44-trien-khai/v0.4-schema-binding/dot-iu-cutter-v0.4-schema-binding-risk-and-code-change-plan-2026-05-17.md