dot-iu-cutter v0.4 — Real DB Adapter Design Master (design only)
dot-iu-cutter v0.4 — Real DB Adapter Design Master
document_path: knowledge/dev/laws/dieu44-trien-khai/v0.4-db-adapter-design/dot-iu-cutter-v0.4-real-db-adapter-design-master-2026-05-17.md
revision: r1
date: 2026-05-17
author: Agent (Claude Code CLI, Opus 4.7 1M)
verifier: GPT (review pending — this package is the design for it)
phase: v0.4 — REAL DB ADAPTER DESIGN (design only)
opened_by: GPT production-credential-execution review = PASS
+ explicit User "v0.4 real DB adapter DESIGN ONLY" prompt.
status: design_only_pending_gpt_review
⛔ DESIGN ONLY. No code modification, no DB connection, no secret read, no
.envedit, no dry-run execution, no production action, no CUT/VERIFY, no deploy. Every interface, env var, transaction boundary and SQLSTATE rule below is a target for a future, separately-authorized cycle — not an instruction to execute. Nothing here connects the accepted in-memory code (commit 689e53e) to PostgreSQL.
§1 — Purpose & Scope
Design how the accepted in-memory cutter-agent skeleton (/opt/incomex/dot/iu-cutter/
@ commit 689e53e, GPT code PASS 2026-05-16) will later connect to the
production cutter_governance schema through the already-live
least-privilege principals cutter_exec / cutter_verify (GPT credential
PASS 2026-05-17) — safely, without exposing secrets and without bypassing
the least-privilege model.
In-scope (design artefacts only):
- Connection construction & secret loading discipline —
dot-iu-cutter-v0.4-connection-and-secret-loading-design-2026-05-17.md - Phase→table→transaction mapping —
dot-iu-cutter-v0.4-transaction-mapping-design-2026-05-17.md - Phase→principal routing & separation of duty —
dot-iu-cutter-v0.4-principal-routing-design-2026-05-17.md - Error / SQLSTATE / rollback semantics —
dot-iu-cutter-v0.4-db-adapter-error-and-rollback-design-2026-05-17.md - PG-backed dry-run test plan (gated, not executed) —
dot-iu-cutter-v0.4-db-adapter-dry-run-test-plan-2026-05-17.md - Risk & review plan —
dot-iu-cutter-v0.4-db-adapter-risk-review-plan-2026-05-17.md - This master + the rollup report —
…-design-report-2026-05-17.md
Out-of-scope / explicitly NOT authorized by this phase: writing the adapter
code, reading any secret, opening a DB connection, editing .env, running a
PG-backed dry-run, CUT, VERIFY, deploy, runtime binding, Directus/RLS/Qdrant
change, canonicalization/signing productionization.
§2 — Ground Truth (carried from controlling files)
schema: cutter_governance @ prod (container postgres, postgres:16 / PG 16.13,
db directus, superuser workflow_admin, sysid 7611578671664259111)
base_tables: 12 observe_views: 12 total_rows: 0
in_schema_fk: 19 cross_schema_fk: 0
constraints: NO CHECK / NO trigger / NO DEFAULT / NO PG-enum on the governance
family — ALL invariants are app/agent-enforced (BATCH-1 model: text +
documented allowed values).
principals_live:
cutter_exec (DOT-991 lane): LOGIN, CONNECTION_LIMIT 2, NOSUPERUSER,
NOCREATEDB, NOCREATEROLE, NOREPLICATION, NOBYPASSRLS, memberless,
0 object ownership, SCRAM-SHA-256
cutter_verify (DOT-992 lane): same flags
matrix: 33 table-priv tuples (18 exec + 15 verify) + 3 column-UPDATE
tuples; grant_option 0; destructive 0; out-of-schema 0
column_update_tuples (the ONLY column-scoped grants):
- cutter_exec.decision_backlog_entry.status
- cutter_verify.decision_backlog_entry.status
- cutter_exec.review_decision.superseded_by_review_decision_id
cutter_ro: 13 grants, NOLOGIN, views-only — READ-ONLY, NEVER a writer
secrets_live (in /opt/incomex/docker/.env, 600 root:root):
DOT_CUTTER_EXEC_DB_USER, DOT_CUTTER_EXEC_DB_PASSWORD,
DOT_CUTTER_VERIFY_DB_USER, DOT_CUTTER_VERIFY_DB_PASSWORD
code_baseline: commit 689e53e — DBAdapter ABC; InMemoryDryRunAdapter;
ProductionDBAdapter.__init__ raises ProductionAccessNotAuthorized;
_assert_writer() rejects FORBIDDEN_WRITE_PRINCIPALS {cutter_ro,
workflow_admin, directus, postgres} and anything not in
{cutter_exec, cutter_verify}; transaction() = one atomic non-nested txn;
delete()/truncate() raise AppendOnlyViolation; runtime package imports
NO psycopg/asyncpg/sqlalchemy/socket/os.environ.
§3 — Design Stance (the eight load-bearing principles)
P-1 secrets-from-env-only: the adapter reads credentials ONLY from the
approved /opt/incomex/docker/.env-style environment, never hardcoded,
never argv, never logged, never committed, never to KB. Fail closed if
any required key is absent. (doc 2)
P-2 principal-as-construction-identity: an adapter instance is bound to
EXACTLY ONE principal (cutter_exec OR cutter_verify) at construction;
the principal cannot be switched on a live instance; phase→principal is
table-driven and a mismatch is refused before any SQL. (doc 4)
P-3 one-atomic-txn-per-phase: MARK/REVIEW/CUT/VERIFY each map to exactly
one BEGIN…COMMIT; no cross-phase txn; no nested txn (mirrors the PASSed
skeleton transaction() contract). (doc 3)
P-4 least-privilege-is-the-DB's-job-too: the adapter NEVER attempts a write
outside the granted matrix; if PG returns 42501 that is a STOP-class
defect, not something to retry or escalate around. The matrix is the
authority; the adapter mirrors it, it does not widen it. (doc 5)
P-5 append-only-preserved: NO DELETE / TRUNCATE / DDL / GRANT path exists
in the adapter surface (the skeleton already raises AppendOnlyViolation);
corrections are forward compensating INSERTs only. (doc 3, doc 5)
P-6 idempotent-resumable: every phase does read-before-write on a
deterministic key; 23505 unique collision resolves to dedup/resume, never
a duplicate or a double-apply. (doc 3, doc 5)
P-7 fail-closed-no-partial: a missing secret, a connection failure, or an
unauthorized SQLSTATE aborts the whole phase txn with zero partial state;
the agent never silently drops or half-writes work. (doc 5)
P-8 interface-not-implementation: this phase defines RealPostgresAdapter as
the typed REPLACEMENT contract for InMemoryDryRunAdapter; NO code is
written; ProductionDBAdapter stays refusing-to-construct until a future
authorized code cycle implements RealPostgresAdapter against this design
AND its dry-run test plan has been GPT-reviewed. (doc 2, doc 5, doc 6)
§4 — RealPostgresAdapter Contract (interface target, NOT code)
RealPostgresAdapter is the future drop-in replacement for
InMemoryDryRunAdapter, satisfying the same DBAdapter ABC the PASSed
skeleton already defines — so CutterRuntime is unchanged; only adapter
construction differs.
RealPostgresAdapter (target shape — narrative, not source)
construct(principal: {cutter_exec|cutter_verify}, conn_factory)
· principal validated against {cutter_exec, cutter_verify} ONLY
(reuses the skeleton _assert_writer allow-set; FORBIDDEN set still
rejects cutter_ro/workflow_admin/directus/postgres)
· conn_factory yields a connection authenticated AS that principal,
built from env per doc 2; NO DSN/host/password literal in code
transaction() · one BEGIN; COMMIT on clean exit; ROLLBACK on any
exception; nested txn → TransactionError (== skeleton)
insert(table,row) · _require_txn(); _assert_writer(); parameterised
INSERT; table ∈ that principal's granted INSERT set
cas_status(id,exp,nw)· _require_txn(); _assert_writer(); UPDATE … SET
status=nw WHERE entry_id=id AND status=exp
(column-scoped UPDATE(status) only)
stamp_superseded(…) · cutter_exec only; UPDATE review_decision SET
superseded_by_review_decision_id=… (write-once,
the single sanctioned non-status UPDATE column)
find(table, **eq) · read-before-write SELECT for idempotency/dedup
(the writer reads with ITS OWN principal — never
cutter_ro, never a separate read role)
delete()/truncate() · raise AppendOnlyViolation (unchanged from skeleton)
no other surface · no DDL, no GRANT, no COPY, no multi-statement
Invariant: RealPostgresAdapter adds no method the skeleton ABC does
not already expose. The security guarantees that earned the code PASS
(_assert_writer, append-only, one-txn) are inherited, not re-litigated.
§5 — Recommended Outcome (rolled up; details in companion docs)
recommended_adapter: RealPostgresAdapter, psycopg3 (sync), one
connection per phase txn from a small per-principal pool (≤ CONNECTION_LIMIT
2), server-side parameterised statements, autocommit OFF. [doc 2]
recommended_env_discipline: component env vars (host/port/db/sslmode shared,
user/password per principal); password ONLY from DOT_CUTTER_*_DB_PASSWORD;
no DSN-with-password env; fail closed on any missing key; never logged.
[doc 2]
recommended_txn_boundaries: TXN-MARK/REVIEW/CUT under cutter_exec;
TXN-VERIFY under cutter_verify; each exactly one atomic txn; isolation
READ COMMITTED default, SERIALIZABLE for TXN-CUT & TXN-VERIFY; row guard =
status CAS (UPDATE … WHERE status=expected) + advisory lock on entry_id.
[doc 3]
risk_class: STANDARD-HIGH (privileged credentials now real; the wrong design
could leak a secret or write outside the matrix — but the DB-side matrix
and append-only model are independent backstops). Not CRITICAL because
no code/connection happens in this phase and the matrix denies overreach
at the server. [doc 6]
blockers_before_code: B-A1..B-A5 (see report §)
blockers_before_dry_run: B-D1..B-D4 (see report §)
open_decisions_for_GPT: DA-1..DA-12 (see report §)
§6 — Hard Boundary Restatement
this_phase_performed:
- authored 8 design documents (this package)
this_phase_did_NOT:
- modify any code (689e53e untouched; ProductionDBAdapter still refuses)
- open any DB connection
- read/decrypt/print any secret
- edit /opt/incomex/docker/.env
- run any dry-run (in-memory or PG-backed)
- perform any production action / CUT / VERIFY / deploy / binding
- self-advance
next: GPT review of this design package.
agent_self_advance: PROHIBITED.
End of real DB adapter design master (design only; nothing built; next = GPT review).