KB-51C5
dot-iu-cutter v0.4 — DB Adapter Dry-Run Test Plan (design only, NOT executed)
8 min read Revision 1
dot-iu-cutterdieu44v0.4db-adapterdesign-onlydry-run-plangated
dot-iu-cutter v0.4 — DB Adapter Dry-Run Test Plan
document_path: knowledge/dev/laws/dieu44-trien-khai/v0.4-db-adapter-design/dot-iu-cutter-v0.4-db-adapter-dry-run-test-plan-2026-05-17.md
revision: r1
date: 2026-05-17
author: Agent (Claude Code CLI, Opus 4.7 1M)
phase: v0.4 — REAL DB ADAPTER DESIGN (companion to design-master)
status: design_only_pending_gpt_review — THIS PLAN IS NOT EXECUTED
⛔ DESIGN ONLY — A TEST PLAN, NOT A TEST RUN. No code exists yet; no connection; no dry-run executed; no production touch. Running ANY part of this plan requires: (1) RealPostgresAdapter code authored + GPT code PASS, (2) this plan GPT-reviewed, (3) an explicit separate execution prompt. All blockers in §6 are OPEN.
§1 — Environment (isolated; never production)
substrate: an ISOLATED, EPHEMERAL PostgreSQL restored from a READ-ONLY
production backup (pattern proven across v0.2/v0.3/v0.4-credential cycles:
pg_dump -Fc by a superuser, restore into a throwaway postgres:16 container
with a DIFFERENT system_identifier; torn down after; protected dry-run
envs untouched; production read-only only).
isolation_assertions (gate before any test write):
- restored env system_identifier ≠ production 7611578671664259111
- container/network not reachable from prod services
- no prod DSN/host in the test config
schema_state: the 12 cutter_governance tables + 19 FKs + 12 observe views,
0 rows (matches v0.2/v0.3 inventory) — restored, then tests populate it.
§2 — Roles & Secrets In Dry-Run (NEVER production secrets)
RULE: production secrets (the live DOT_CUTTER_*_DB_PASSWORD values) are
NEVER used in dry-run. The dry-run env gets a SEPARATE, FAKE role model:
- CREATE ROLE cutter_exec / cutter_verify / cutter_ro IN THE ISOLATED ENV
with FRESH throwaway passwords generated for the test only, and the
SAME least-privilege grant matrix as production (re-derived from the
credential-cycle artefacts) so privilege behaviour is faithful.
- test env vars (DOT_CUTTER_*_DB_*) point ONLY at the isolated env and
carry ONLY the fake passwords. Real .env is NOT read, NOT sourced,
NOT copied.
- if (and only if) GPT EXPLICITLY decides faithful behaviour requires the
real role model semantics beyond a re-derived copy, that is a separate
GPT decision recorded before the run. DEFAULT = fake roles + copied
matrix. Production secrets remain forbidden in dry-run unless GPT
explicitly approves in writing (not assumed here).
§3 — Test Matrix (allow paths + deny paths + rollback)
A. HAPPY PATH (allow) — dry-run env only, ONE full chain:
A-1 MARK (cutter_exec): entry+history(+dep)(+sweep) committed atomically
A-2 REVIEW (cutter_exec): manifest pair+review_decision+status+history;
re-review chains prior_/superseded_ correctly (write-once)
A-3 CUT (cutter_exec): sig(DOT-991)+change_set(verifier_sig NULL)+
affected_row+status+history; guards G-CUT-APPROVED/DEPS/ONCE
A-4 VERIFY pass (cutter_verify): verify_result+sig(DOT-992)+status
verified_complete
A-5 ONE end-to-end MARK→REVIEW→CUT→VERIFY happy path → verified_complete
(dry-run ONLY; mirrors the skeleton CLI demo but on real PG)
B. DENY PATHS (must be refused — privilege & routing):
B-1 cutter_verify attempts INSERT review_decision/manifest_* → 42501
B-2 cutter_exec attempts INSERT verify_result → 42501
B-3 any principal attempts DELETE/TRUNCATE/DDL/GRANT → refused
(AppendOnlyViolation client-side AND no grant server-side)
B-4 cutter_ro attempts any write → 42501
B-5 forbidden principal (workflow_admin/directus/postgres) construction
→ refused before connect (skeleton _assert_writer / ProductionDBAdapter
replacement guard)
B-6 phase-principal mismatch (e.g. routing forced to wrong lane) → refused
pre-SQL (PrincipalCapabilityError) AND, if bypassed, 42501 backstop
C. INDUCED PRIVILEGE FAILURE:
C-1 revoke one matrix grant in the isolated env → corresponding phase
write → 42501 → adapter STOPs (no retry, no escalation-around),
emits signal, ROLLBACK, zero rows persisted
D. IDEMPOTENCY REPLAY:
D-1 replay same MARK signal → no duplicate entry (dedup, existing returned)
D-2 23505 on idempotency key (simulate concurrent insert) → resume/dedup,
phase succeeds, exactly one row
D-3 re-review / re-verify replay → deterministic chaining, no double
supersede (write-once holds)
E. ROLLBACK / NO-PARTIAL-COMMIT:
E-1 inject exception mid-TXN-CUT (after sig insert, before status) →
ROLLBACK → zero rows from that phase persist (count == pre-state)
E-2 kill connection mid-txn → server aborts → no partial commit; retry
from last committed boundary converges
E-3 transient 40001/40P01 injected → bounded retry → eventual commit;
attempt_no recorded; no duplicate
E-4 retries exhausted → escalation entry created + status *_escalated +
history reason (NEEDS_HUMAN); work NOT silently dropped
F. SEMANTIC FAIL:
F-1 VERIFY outcome=fail → compensating change_set + escalation entry +
verify_failed_escalated; original change_set NOT physically deleted
G. NO-LEAK:
G-1 grep all test logs/console/signals/exception dumps → ZERO password
value, ZERO full DSN; only key names + SQLSTATE + entry_id present
G-2 28xxx (wrong password injected) → STOP, log names-only, no retry
§4 — Pass Criteria
- A-1..A-5 commit exactly the mapped rows, atomically, status terminal
verified_complete; row counts match transaction-mapping doc.
- B-1..B-6 ALL refused (client guard OR server 42501); zero unintended rows.
- C-1 STOPs cleanly, zero persisted rows, signal emitted, no retry loop.
- D-1..D-3 exactly-once convergence; no duplicate; lineage write-once.
- E-1..E-4 zero partial commits; bounded retry; exhaustion escalates.
- F-1 forward-compensation + escalation; append-only preserved.
- G-1..G-2 zero secret leakage anywhere.
- isolation assertions (§1) PASS before AND after; prod read-only/unchanged;
isolated env torn down; protected dry-run envs untouched.
§5 — What This Plan Forbids (even when later authorized to run)
- never run against production or any prod-reachable DB
- never use live production secrets (§2) unless GPT explicitly approves
- never leave the isolated env standing (tear down + confirm)
- never write to production cutter_governance / Directus / Qdrant
- a dry-run PASS does NOT authorize production CUT/VERIFY, deploy, or
runtime binding — those remain separate gated cycles
§6 — Blockers (ALL OPEN — nothing runnable now)
B-D1 .env connection keys (host/port/db/sslmode) not yet added (doc 2 §2)
B-D2 RealPostgresAdapter code NOT authored (still ProductionDBAdapter-refuses)
B-D3 RealPostgresAdapter code NOT GPT-PASSed
B-D4 this dry-run plan NOT GPT-reviewed
B-D5 isolated-env restore tooling/runbook for THIS plan not yet authored
gate: a PG-backed dry-run is BLOCKED until B-D1..B-D5 cleared AND an
explicit separate execution prompt is given. self-advance PROHIBITED.
End of DB adapter dry-run test plan (design only; NOT executed; all blockers open).