dot-iu-cutter v0.5 — Canonical Path Survey · GRANT State and Delta Recommendation (S4 — REVOKE direct + GRANT EXECUTE on fn_iu_create; NOT executed) (doc 4 of 7)
dot-iu-cutter v0.5 — Canonical Path Survey · GRANT State and Delta Recommendation
doc 4 of 7 · 2026-05-20
phase : S4 — GRANT state delta recommendation outcome : RECOMMENDATION_AUTHORED (NOT executed) production_mutation : NONE this phase
1. Current GRANT state (after the rerun macro's G5 — still in place)
cutter_exec :
SELECT on public.information_unit : YES
INSERT on public.information_unit : YES ← used by legacy direct path
UPDATE(version_anchor_ref, content_anchor_ref) on public.information_unit : YES ← used by legacy direct path
SELECT on public.unit_version : YES
INSERT on public.unit_version : YES ← used by legacy direct path
SELECT on public.dot_config : YES ← used by drift G5 vocab check
EXECUTE on fn_iu_create / fn_iu_create_plan / fn_iu_create_preflight /
fn_iu_classify_existing / fn_iu_resolve_default / fn_iu_verify_invariants :
NO (function_acl = '{directus=X/directus}')
cutter_verify :
SELECT on public.information_unit : YES
SELECT on public.unit_version : YES
EXECUTE on any fn_iu_* : NO
other (unchanged) :
context_pack_readonly : SELECT on public.* (read-only role)
directus : owns public.* and all fn_iu_*
workflow_admin : superuser ; owns cutter_governance.*
2. Why the legacy direct grants are NO LONGER NEEDED on the canonical path
The canonical path calls SELECT public.fn_iu_create(...). The function is
SECURITY DEFINER — it runs as its owner (directus), which already has all
needed privileges on public.{information_unit, unit_version, dot_config,
birth_registry, collection_registry}. The calling role (cutter_exec) does
NOT need direct INSERT/UPDATE on the tables; it only needs EXECUTE on the
function.
Furthermore: even if cutter_exec retained the legacy direct grants, the
gateway trigger BLOCKS those writes — the grants are inert under the
gateway policy (Pack 22-P3-P2 rev7).
3. Recommended GRANT delta — minimal, SoD-safe, append-allowlist
-- principal apply : directus (GD-1 — owns public.* ; same as the rerun macro's G5)
BEGIN;
-- (A) REVOKE the now-unused direct writer grants on the IU/UV tables
REVOKE INSERT ON public.information_unit FROM cutter_exec;
REVOKE UPDATE (version_anchor_ref, content_anchor_ref) ON public.information_unit FROM cutter_exec;
REVOKE INSERT ON public.unit_version FROM cutter_exec;
-- (B) GRANT the canonical function EXECUTE
GRANT EXECUTE ON FUNCTION
public.fn_iu_create(text,text,text,text,text,text,text,text,uuid)
TO cutter_exec;
COMMIT;
(EXECUTE on fn_iu_create_plan is OPTIONAL — the canonical adapter does not
call it; only useful as a defense-in-depth pre-CUT canary. Recommendation:
skip for the leg-A CUT, add later if a non-CUT use case needs it.)
4. Post-delta target state
cutter_exec :
SELECT on public.information_unit : YES (G6 G-CUT-ONCE pre-check)
SELECT on public.unit_version : YES (kept for symmetry; G6 reads UV
too in the L1 PILOT warning context)
SELECT on public.dot_config : YES (G5 drift vocab probe)
INSERT on public.information_unit : NO ← REVOKED
UPDATE(...) on public.information_unit : NO ← REVOKED
INSERT on public.unit_version : NO ← REVOKED
EXECUTE on public.fn_iu_create(...) : YES ← NEW
cutter_verify : unchanged
context_pack_readonly / directus / workflow_admin / cutter_ro : unchanged
5. Acceptance gate (post-delta verification)
-- 18-bool probe row equivalent to the v0.5 rerun §6.1 shape, plus
-- EXECUTE probe on fn_iu_create
SELECT
has_table_privilege ('cutter_exec', 'public.information_unit', 'SELECT') AS ce_iu_S, -- t
has_table_privilege ('cutter_exec', 'public.information_unit', 'INSERT') AS ce_iu_I, -- f (revoked)
has_table_privilege ('cutter_exec', 'public.information_unit', 'DELETE') AS ce_iu_D, -- f
has_column_privilege('cutter_exec', 'public.information_unit',
'version_anchor_ref', 'UPDATE') AS ce_iu_upd_van, -- f (revoked)
has_column_privilege('cutter_exec', 'public.information_unit',
'content_anchor_ref', 'UPDATE') AS ce_iu_upd_can, -- f (revoked)
has_table_privilege ('cutter_exec', 'public.unit_version', 'SELECT') AS ce_uv_S, -- t
has_table_privilege ('cutter_exec', 'public.unit_version', 'INSERT') AS ce_uv_I, -- f (revoked)
has_table_privilege ('cutter_exec', 'public.dot_config', 'SELECT') AS ce_dc_S, -- t
has_function_privilege('cutter_exec',
'public.fn_iu_create(text,text,text,text,text,text,text,text,uuid)',
'EXECUTE') AS ce_fn_exec, -- t (new)
has_table_privilege ('cutter_verify','public.information_unit', 'SELECT') AS cv_iu_S, -- t
has_table_privilege ('cutter_verify','public.unit_version', 'SELECT') AS cv_uv_S; -- t
Expected row (text "t"/"f") : t|f|f|f|f|t|f|t|t|t|t
6. Rollback (byte-inverse)
BEGIN;
REVOKE EXECUTE ON FUNCTION
public.fn_iu_create(text,text,text,text,text,text,text,text,uuid)
FROM cutter_exec;
GRANT INSERT ON public.information_unit TO cutter_exec;
GRANT UPDATE (version_anchor_ref, content_anchor_ref) ON public.information_unit TO cutter_exec;
GRANT INSERT ON public.unit_version TO cutter_exec;
COMMIT;
(Restores the post-rerun-G5 state byte-identically.)
7. Side-effect boundary
no_changes_to_other_relacl :
context_pack_readonly : unchanged
directus / workflow_admin : unchanged
cutter_ro : unchanged
cutter_governance.* : unchanged (v0.4 CD-1..CD-13 matrix)
no_DDL / DROP / TRUNCATE : NONE
no_role_or_membership_change : NONE
no_password_change : NONE
no_pg_hba_change : NONE
8. Disposition
S4 : RECOMMENDATION_AUTHORED — NOT executed
sovereign_gate : the GRANT delta must be sovereign-approved in
the new approval package (doc 6 of this set)
execution_principal : directus (GD-1, unchanged)
execution_channel : docker exec postgres psql -U directus -d directus
(Unix-socket trust auth, same channel as rerun G5)
production_mutation_this_phase : NONE
doc 4 of 7.