KB-77BC

dot-iu-cutter v0.4 — Cutter-Agent Write-Path Design (design only) (2026-05-16)

10 min read Revision 1
dot-iu-cutterdieu44v0.4tier2write-pathdesign-only

dot-iu-cutter v0.4 — Cutter-Agent Write-Path Design

document_path: knowledge/dev/laws/dieu44-trien-khai/v0.4-design/dot-iu-cutter-v0.4-cutter-agent-write-path-design-2026-05-16.md
revision: r1
date: 2026-05-16
author: Agent (Claude Code CLI, Opus 4.7 1M)
phase: v0.4 — Tier 2 write-path DESIGN (companion to design-master)
status: design_only_pending_gpt_review

⛔ DESIGN ONLY. No code, no SQL, no write, no GRANT. Every table-write, transaction, and privilege below is a target for a future authorized cycle, not an instruction to execute.


§1 — Single-Writer Principle

invariant W-1: the ONLY component permitted to INSERT/UPDATE any
  cutter_governance base table is the cutter-agent write path, running as a
  designated writer principal (cutter_exec / cutter_verify — doc 5).
invariant W-2: cutter_ro is READ-ONLY and MUST NOT appear on any write path.
invariant W-3: NO ad-hoc INSERT, no psql-by-hand, no Directus item-create,
  no ETL. First and every subsequent row enters via the planned writer.
invariant W-4: enforcement is the grant model (no write grant exists to any
  other principal) — but applying that grant model is a SEPARATE authorized
  credential cycle (doc 5), NOT this design.
invariant W-5: schema is frozen — the write path uses ONLY existing columns;
  any field the design "wants" but the schema lacks goes into an existing
  jsonb/text column, never a new column.

§2 — Tables Written Per Phase

Phase Table Op Notes
MARK decision_backlog_entry INSERT new work item, status='marked'
MARK decision_backlog_history INSERT birth record (transition ∅→marked)
MARK decision_backlog_dependency INSERT (0..N) only if entry depends on other entries
MARK decision_backlog_sweep_log INSERT sweep pass that picked/created the entry
REVIEW manifest_envelope INSERT the planned cut manifest (plan, no effect)
REVIEW manifest_unit_block INSERT (1..N) per-unit plan, composite PK
REVIEW review_decision INSERT approve/reject/defer bound to manifest pair
REVIEW decision_backlog_entry UPDATE status scalar only → reviewed_*
REVIEW decision_backlog_history INSERT transition record
CUT cut_change_set INSERT the applied change set header
CUT cut_change_set_affected_row INSERT (1..N) per affected row
CUT dot_pair_signature INSERT executor attestation (DOT-991 lane)
CUT decision_backlog_entry UPDATE status scalar only → cut_applied
CUT decision_backlog_history INSERT transition record
VERIFY verify_result INSERT independent verify outcome
VERIFY dot_pair_signature INSERT verifier attestation (DOT-992 lane)
VERIFY cut_change_set (+ affected_row) INSERT ONLY on fail: compensating rollback set
VERIFY decision_backlog_entry INSERT ONLY on fail: escalation entry
VERIFY decision_backlog_entry UPDATE status scalar → verified_complete | verify_failed_escalated
VERIFY decision_backlog_history INSERT transition record
mutation_policy:
  - the ONLY in-place UPDATE permitted anywhere is
    decision_backlog_entry.status (+ its history append). Everything else is
    INSERT-only (append-only lineage via prior_*/superseded_by_*).
  - canonical_address_alias: NOT written in v0.4 (OD-2, deferred).

§3 — Transaction Boundaries

TXN-MARK   : { decision_backlog_entry INSERT, history INSERT,
               dependency INSERT*, sweep_log INSERT } — one atomic txn.
             Either the entry + its audit + its edges all commit, or none.
TXN-REVIEW : { manifest_envelope INSERT, manifest_unit_block INSERT+,
               review_decision INSERT, entry.status UPDATE, history INSERT }
             — one atomic txn. The manifest pair and the decision that binds
             it MUST be co-committed (a review_decision must never reference
             a manifest that did not commit).
TXN-CUT    : { cut_change_set INSERT, cut_change_set_affected_row INSERT+,
               executor dot_pair_signature INSERT, entry.status UPDATE,
               history INSERT } — one atomic txn. A change set without its
             affected rows and its executor signature is forbidden to exist.
TXN-VERIFY : { verify_result INSERT, verifier dot_pair_signature INSERT,
               [fail: compensating cut_change_set+affected_row INSERT,
                escalation decision_backlog_entry INSERT], entry.status
               UPDATE, history INSERT } — one atomic txn.
isolation_target: READ COMMITTED minimum; SERIALIZABLE recommended for
  TXN-CUT/TXN-VERIFY to prevent two writers racing the same entry (final
  choice = OPEN, see risk doc). Belt-and-braces: a row-level guard (see §6).
no_cross_phase_txn: phases are NOT wrapped in one giant transaction; each
  phase commits independently and is resumable from its persisted state.

§4 — Idempotency Keys

IK-MARK: deterministic key = canonical_hash(signal_source_id, scenario_ref,
  payload_canonical_form). Stored at payload.idempotency_key (OD-1; schema
  frozen → lives in existing jsonb, not a new column). Before INSERT the
  writer SELECTs (via its own read, not cutter_ro) for an existing entry
  with the same key; if present → no-op return that entry (MARK is
  idempotent on replay of the same signal).
IK-REVIEW: natural key = (entry_id, manifest content hash). A second REVIEW
  on the same entry with identical manifest content is a no-op; a different
  manifest is a NEW review_decision with prior_review_decision_id set and
  the old one stamped superseded_by_review_decision_id.
IK-CUT: natural key = (decision_backlog_entry_id, approved review_decision_id,
  attempt_no in payload). Re-running CUT for an already-applied, non-rolled-
  back change set is a no-op (return existing change_set_id).
IK-VERIFY: natural key = (change_set_id). At most one non-superseded
  verify_result per change_set; a re-verify chains via prior_verify_result_id.
principle: idempotency is read-before-write keyed on a deterministic hash;
  replays converge, they never duplicate or double-apply.

§5 — Retry Behaviour

transient_failure (DB deadlock, conn drop, lock timeout):
  - safe to retry the SAME txn; idempotency keys (§4) guarantee convergence.
  - bounded exponential backoff; max attempts = config; attempt_no recorded
    in payload / change-set body (existing columns only).
semantic_retry (a phase produced a superseded result, e.g. re-review):
  - NEVER mutate the old row. INSERT a new artefact, set its prior_* self-FK
    to the old artefact, set the old artefact's superseded_by_* (the one
    sanctioned exception: superseded_by is a forward stamp, written once).
  - decision_backlog_entry.status moves back to the appropriate pending
    state and a history row records the reopen with reason.
exhausted_retries:
  - entry.status → a *_failed / escalated state (doc 4); history records
    terminal-for-now; manual escalation entry created (VERIFY-style) so a
    human/GPT loop can intervene. The agent does NOT silently drop work.
no_partial_commit_retry: because each phase is one txn (§3), a retry always
  restarts from a consistent committed boundary — there is no "half-written
  phase" to reconcile.

§6 — Rollback Behaviour

db_level: each phase txn either COMMITs whole or ROLLBACKs whole (PG txn).
  An aborted phase leaves zero trace (except possibly a sweep_log attempt
  row, which is intentionally allowed to persist as an audit of the try).
semantic_level (a committed CUT later found wrong by VERIFY):
  - NO physical DELETE / no UPDATE-away of cut_change_set or affected_row.
  - a COMPENSATING cut_change_set is INSERTed (a forward "undo" change set);
    verify_result.rollback_change_set_id_triggered points the failing verify
    at that compensating set; entry.status → rolled_back / escalated.
  - rationale: the governance schema is an append-only ledger; truth is
    "what happened", corrected by further recorded events, never erased.
escalation: verify_result.escalation_ref → a NEW decision_backlog_entry
  (kind='escalation') so the failure is itself a tracked, sweepable work
  item with its own history lineage.
guard_against_double_apply: a row-level guard (advisory lock on entry_id, or
  a status precondition in the UPDATE … WHERE status=expected) ensures two
  concurrent writers cannot both CUT the same entry; exact mechanism = OPEN
  (risk doc) but the *requirement* is fixed here.

§7 — No-Base-Table-Writes-Outside-Planned-Writer (restated, enforced design)

target_grant_model (DESIGN; applied later under doc 5's credential cycle):
  cutter_exec   : INSERT on { decision_backlog_entry, _history, _dependency,
                  _sweep_log, manifest_envelope, manifest_unit_block,
                  review_decision, cut_change_set, cut_change_set_affected_row,
                  dot_pair_signature }; UPDATE(status) on decision_backlog_entry
  cutter_verify : INSERT on { verify_result, dot_pair_signature,
                  cut_change_set, cut_change_set_affected_row,
                  decision_backlog_entry, decision_backlog_history };
                  UPDATE(status) on decision_backlog_entry
  everyone else : 0 write privilege (incl. cutter_ro, directus app role)
  DELETE/TRUNCATE/DDL/GRANT : granted to NO cutter principal
note: column-scoped UPDATE (status only) is not natively a PG table grant;
  enforcement is in the writer code + a CHECK-free, app-owned invariant
  (BATCH-1 model) + code review. PG grant gives table-level UPDATE;
  the status-only restriction is an agent invariant, audited via history.

End of v0.4 cutter-agent write-path design (design only; nothing built).

Back to Knowledge Hub knowledge/dev/laws/dieu44-trien-khai/v0.4-design/dot-iu-cutter-v0.4-cutter-agent-write-path-design-2026-05-16.md