KB-3D59
dot-iu-cutter v0.4 — Credential Dry-Run Plan
7 min read Revision 1
dot-iu-cutterv0.4credential-designdry-run-plandieu44
dot-iu-cutter v0.4 — Credential Dry-Run Plan
document_path: knowledge/dev/laws/dieu44-trien-khai/v0.4-credential-design/dot-iu-cutter-v0.4-credential-dry-run-plan-2026-05-16.md
revision: r1
date_authored: 2026-05-17
cycle_date_label: 2026-05-16
author: Agent (Claude Code CLI, Opus 4.7 1M)
phase: v0.4 — credential-cycle DESIGN (dry-run plan)
status: design_only_pending_gpt_review
⛔ DESIGN ONLY. This plan is NOT executed. NO isolated env is created here. NO role/secret made. The dry-run itself is a SEPARATE, GPT-gated cycle that runs AFTER this design PASSes.
§1 — Principle
- roles + grants are created ONLY in an EPHEMERAL ISOLATED environment
FIRST — never in production before an isolated dry-run PASS + GPT review
(mirrors every prior dieu44 cycle: v0.2 P0-2, v0.3 read-obs each ran a
throwaway postgres:16 env restored from a prod backup, then torn down).
- NO production role exists until: this design PASS → real-adapter design
PASS → isolated credential dry-run PASS → command-review PASS → sovereign
prompt. (blockers B-1..B-6, master §6.)
- the dry-run validates the PRIVILEGE MATRIX (matrix doc §2) by attempting
allowed AND denied operations as each principal and asserting the
expected allow/deny outcome — catalog AND behavioural.
§2 — Target Isolated Environment (spec; not built here)
shape: ephemeral container `pg-dry-run-v0.4-credential-<date>` (postgres
major matching prod — PG per project memory; prod is PostgreSQL, S115
migration), restored from a READ-ONLY prod-directus pg_dump (same backup
discipline as v0.2/v0.3; pg_dump needs workflow_admin/rolsuper, taken
read-only; prod sysid 7611578671664259111 recorded before/after to prove
prod untouched).
isolation: no network path from the dry-run container to prod; distinct
system identifier asserted ≠ prod (the v0.2/v0.3 DR_SYSID ≠ PROD gate).
credentials_in_dry_run: TEMPORARY THROWAWAY passwords generated inside the
ephemeral env ONLY (CD-6 = YES recommended); never the real future
secret; never written to any .env; destroyed with the env.
teardown: env destroyed after the run; prod + all protected dry-run envs
untouched; only KB result docs persist.
§3 — Dry-Run Steps (target sequence; each gated)
D-1 restore prod backup into the isolated env; assert sysid ≠ prod; assert
schema cutter_governance present with 12 tables / 12 views / cutter_ro
exactly as v0.3 inventory (baseline fidelity gate).
D-2 CREATE ROLE cutter_exec / cutter_verify with the §1-attributes
(LOGIN, NOSUPERUSER, NOCREATE*, NOBYPASSRLS, no membership) + throwaway
passwords — IN THE ISOLATED ENV ONLY.
D-3 apply the enumerated grant set EXACTLY per matrix doc §2 (USAGE +
per-table S/I + 2 column-scoped UPDATEs). No ALTER DEFAULT PRIVILEGES.
D-4 CATALOG verification: information_schema.role_table_grants &
column_privileges & role_usage_grants show EXACTLY the matrix — and
NOTHING else (0 DELETE, 0 TRUNCATE, 0 REFERENCES, 0 TRIGGER, 0 grant on
public / observe views / cutter_ro, 0 membership, NOSUPERUSER etc.).
NOTE: use schema-qualified / structural comparison, not bare string
match (carry the pg_get_constraintdef schema-qualifier lesson from the
P0-6/P0-5 false-negative — see feedback memory).
D-5 BEHAVIOURAL allow-probes (must SUCCEED): as cutter_exec — INSERT into
each exec-INSERT table, UPDATE(status) decision_backlog_entry,
UPDATE(superseded_by_review_decision_id) review_decision, SELECT its
read tables; as cutter_verify — INSERT verify_result / dot_pair_signature
/ compensating cut_change_set(+row) / escalation entry+history,
UPDATE(status), SELECT its read tables.
D-6 BEHAVIOURAL deny-probes (must be REFUSED by PG):
- any DELETE / TRUNCATE on any table → permission denied
- UPDATE of a non-granted column (e.g. payload, any signature id,
any pk) on decision_backlog_entry/review_decision → denied
- any UPDATE on cut_change_set (OD-6: verifier_signature_id stays NULL) → denied
- cutter_exec touching verify_result (any verb) → denied
- either writer on canonical_address_alias (any verb) → denied
- either writer on schema public / any v_*_observe view / a non-
cutter_governance object → denied
- any CREATE/ALTER/DROP/GRANT by either writer → denied
- connect as cutter_ro and attempt any write → denied (cutter_ro
unchanged, still SELECT-on-views-only)
D-7 rollback the dry-run inside the env (REVOKE all, DROP both roles —
they are memberless & own nothing by construction), assert catalog
returns to the v0.3 baseline (no cutter_exec/verify, cutter_ro intact).
D-8 tear down the env; assert prod sysid unchanged & prod read-only
throughout; write 3 result docs to v0.4-credential-dry-run/.
§4 — Pass Criteria
PASS iff: every D-5 allow-probe succeeds, every D-6 deny-probe is refused
by PG, D-4 catalog == matrix exactly (nothing extra), D-7 rollback clean,
prod provably untouched (sysid + read-only), env torn down.
any deny-probe that SUCCEEDS, or any allow-probe that FAILS, or any catalog
drift = FAIL → matrix/role spec revised → re-design → GPT re-review
(NO production credential until a clean PASS + GPT PASS).
harness_discipline: assertion strings must be schema-qualified / structural
(P0-6/P0-5 false-negative lesson) so a clean run is not mis-flagged.
§5 — Hard Boundaries
NO production role/secret before GPT PASS of this design AND a clean
isolated dry-run AND command-review AND sovereign prompt. NO production
writer USE before a PG-backed cutter dry-run (separate, later). This
document executes NOTHING.
§6 — Open Decisions
CD-6 dry-run uses temporary fake credentials (RECOMMEND YES — throwaway,
env-local, destroyed with the env).
CD-13 dry-run backup source: fresh read-only prod pg_dump (RECOMMEND, per
v0.2/v0.3 pattern) vs reuse of an existing protected dry-run env
(REJECT — protected envs must stay untouched).
End of credential dry-run plan (design only; nothing executed).