KB-6889
dot-iu-cutter v0.3 — Read-Observability Verification Plan (2026-05-16)
6 min read Revision 1
dot-iu-cutterdieu44v0.3ddl-authoringverification-plandesign-only
dot-iu-cutter v0.3 — Read-Observability Verification Plan
document_path: knowledge/dev/laws/dieu44-trien-khai/v0.3-ddl-authoring/dot-iu-cutter-v0.3-read-observability-verification-plan-2026-05-16.md
revision: r1
date: 2026-05-16
author: Agent (Claude Code CLI, Opus 4.7 1M)
phase: v0.3 — DDL AUTHORING (verification plan; authoring only — NOT run)
status: authored_for_gpt_review
The checks below are AUTHORED for the future dry-run / command-review chain. None is executed here. Structural assertions favour catalog queries over rendered-string matching (lesson from the P0-6 FK harness false-negative).
§1 — Preflight Gates (before the single txn; ABORT on any)
PG-G1 prod identity: system_identifier = 7611578671664259111 AND db=directus
PG-G2 role absent: NOT EXISTS (SELECT 1 FROM pg_roles WHERE rolname='cutter_ro')
PG-G3 views absent: 0 of the 12 v_*_observe relations exist in cutter_governance
PG-G4 base state intact: cutter_governance base-table count = 12, all 0 rows
PG-G5 no RLS pre-state: 0 cg tables with relrowsecurity (baseline preserved)
PG-G6 DDL artefact sha256 == canonical (pinned at command-review time)
on_any_gate: ABORT before BEGIN (nothing created)
§2 — Post-Execution Verification (must ALL pass)
V-01 role exists:
SELECT 1 FROM pg_roles WHERE rolname='cutter_ro' → 1
V-02 role is NOLOGIN / NOSUPERUSER / NOBYPASSRLS / NOCREATEROLE / NOCREATEDB / NOREPLICATION:
SELECT rolcanlogin,rolsuper,rolbypassrls,rolcreaterole,rolcreatedb,rolreplication
FROM pg_roles WHERE rolname='cutter_ro'
→ (f,f,f,f,f,f)
V-03 role has NO membership of workflow_admin / directus / any superuser role:
pg_auth_members check → cutter_ro is member of NOTHING
V-04 twelve views exist:
SELECT count(*) FROM information_schema.views
WHERE table_schema='cutter_governance' AND table_name LIKE 'v\_%\_observe'
→ 12 (and the exact 12 names match the spec)
V-05 cutter_ro has SELECT on EACH of the 12 views:
has_table_privilege('cutter_ro','cutter_governance.v_<t>_observe','SELECT') → true ×12
V-06 cutter_ro has NO SELECT on ANY of the 12 BASE tables:
has_table_privilege('cutter_ro','cutter_governance.<base>','SELECT') → false ×12
V-07 cutter_ro has NO write anywhere in cutter_governance:
has_table_privilege('cutter_ro', rel, 'INSERT'|'UPDATE'|'DELETE'|'TRUNCATE')
→ false for all 12 base tables AND all 12 views (96 assertions)
V-08 cutter_ro has USAGE on schema cutter_governance and NOT on public/sandbox_tac:
has_schema_privilege('cutter_ro','cutter_governance','USAGE') → true ;
has_schema_privilege('cutter_ro','public','USAGE') → (unchanged baseline; cutter_ro
was just created so expected false) ; 'sandbox_tac' → false ;
has_schema_privilege('cutter_ro','cutter_governance','CREATE') → false
V-09 redacted columns ABSENT from each view (catalog, per spec §2):
for each view: NOT EXISTS column in information_schema.columns matching its
REDACTED set (30 redacted-name assertions total)
V-10 visible columns PRESENT and count exact (spec §3 arithmetic):
count(view columns) == VISIBLE per table; 134 total view columns
V-11 no view re-exposes a redacted column via alias/expression:
pg_get_viewdef(view) contains none of the redacted base column names
(string scan as a SECONDARY check; primary is V-09 catalog)
V-12 Directus untouched:
directus_collections referencing cg = 0 (unchanged) ; directus_roles count,
directus_policies count, directus_permissions count, directus_access count
== pre-execution snapshot (9 / 8 / 1173 / 9)
V-13 no RLS enabled: 0 cg tables with relrowsecurity (== baseline)
V-14 no data rows written: every cg base table still 0 rows; every view 0 rows
V-15 base tables unchanged: 12 base tables present; column count per base table
== pre-snapshot; no ALTER (pg_get_… structural compare); PK/FK counts
unchanged (12 PK / 19 FK)
V-16 only-additive: exactly +1 role + 12 views + 13 privilege grants; nothing
dropped/altered on pre-existing objects
V-17 prod identity post: system_identifier unchanged 7611578671664259111
V-18 rollback rehearsed (in dry-run): applying the rollback draft returns the
environment to the pre-state (role gone, 12 views gone, grants gone, base
tables + Directus + RLS unchanged)
pass_condition: V-01..V-18 ALL green; any miss → ABORT / conditional rollback
per the rollback-draft (only on a TRUE failure; no string-prefix false-negative).
§3 — Method Notes
- privilege checks use has_table_privilege / has_schema_privilege /
pg_roles catalog booleans — not rendered text — to avoid the rendered-string
false-negative class.
- redaction proven structurally via information_schema.columns (V-09) with a
secondary pg_get_viewdef scan (V-11).
- counts of Directus authz objects snapshotted pre-exec and compared post.
- all checks are READ-ONLY (SELECT / catalog); they do not mutate.
§4 — Non-Scope
executed: NONE (plan only; no dry-run env provisioned). self_advance: PROHIBITED
End of v0.3 read-observability verification plan.