dot-iu-cutter v0.5 — Lifecycle Implementation Authoring · Live Re-check + Scope Lock (G0+G1 PASS) (doc 1 of 6)
dot-iu-cutter v0.5 — Lifecycle Implementation Authoring · Live Re-check + Scope Lock
doc 1 of 6 · 2026-05-20 · READ-ONLY RE-CHECK + AUTHORING SCOPE LOCK
phase : G0 (SSOT re-confirm) + G1 (scope lock) outcome : PASS — all design facts still hold; scope locked production_mutation : NONE
0. Macro framing
This macro is the implementation-authoring follow-on to the design
package at [[dot-iu-cutter-v0-5-06-final-lifecycle-design-report-2026-05-20]].
Per the GPT ruling
(reviews/dot-iu-cutter-v0.5-lifecycle-enactment-design-ready-gpt-ruling-2026-05-20.md):
M3_lifecycle_design : PASS
selected_next_path : PATH_1_IMPLEMENTATION_AUTHORING_MACRO
OQ_defaults : ACCEPT_AGENT_RECOMMENDED_DEFAULTS
production_enactment : not_authorized_yet
new_review_decision_required_before_enactment : true
This macro authors DDL/function bodies + patches + the operator package. It does NOT execute DDL, mutate lifecycle state, deploy, merge, or push.
1. G0 — live state re-check (2026-05-20T07:09:51Z)
1.1 Authoritative inventory unchanged
SELECT COUNT(*) AS n_icx_const,
COUNT(*) FILTER (WHERE lifecycle_status='draft') AS n_draft,
array_agg(DISTINCT lifecycle_status) AS statuses
FROM public.information_unit
WHERE canonical_address LIKE 'ICX-CONST%';
n_icx_const : 60
n_draft : 60
statuses : ['draft']
SELECT (SELECT count(*) FROM public.information_unit) AS iu_total,
(SELECT count(*) FROM public.unit_version) AS uv_total,
(SELECT count(*) FROM public.unit_version WHERE enacted_at IS NOT NULL)
AS uv_enacted_at_nonnull;
iu_total : 158
uv_total : 165
uv_enacted_at_nonnull : 0
1.2 No new lifecycle infrastructure crept in
public.iu_lifecycle_vocab : DOES NOT EXIST
public.iu_lifecycle_log : DOES NOT EXIST
public.fn_iu_enact : DOES NOT EXIST
public.fn_iu_enacted_immut : DOES NOT EXIST
public.fn_uv_enacted_immut : DOES NOT EXIST
trg_iu_enacted_immut : NOT ATTACHED
trg_uv_enacted_immut : NOT ATTACHED
dot_config.iu_enact.* : ABSENT (0 keys)
1.3 Function body fingerprints unchanged from design
| function | body md5 (live now) | design finding |
|---|---|---|
public.fn_iu_create |
3017892a5ac605a6daeaa5348e2a6cdf |
match |
public.fn_iu_apply_edit_draft |
22875ce25b2e2d1751cc4f3d1757252e |
match (latent defect still present) |
public.fn_iu_gateway_write_guard |
6907fa4e5e46b5617d7dfecbd86326d7 |
match |
public.fn_iu_verify_invariants |
6d005323d15eb4802f22802470b2c966 |
(new pin; matches G1 doc 01 of design) |
⇒ fn_iu_apply_edit_draft body BYTE-IDENTICAL to the body the design package analyzed. The patch text in doc 03 of this package is directly applicable; no re-derivation needed.
1.4 Gateway policy unchanged
SELECT key, value FROM public.dot_config
WHERE key='iu_create.gateway.allowed_marker_values' OR key LIKE 'iu_enact.%';
iu_create.gateway.allowed_marker_values : 'fn_iu_create,fn_iu_apply_edit_draft' (1 row)
iu_enact.* : (0 rows)
1.5 Cross-schema privilege probe (critical for fn_iu_enact SECDEF body)
SELECT nspacl FROM pg_namespace WHERE nspname='cutter_governance';
-- {workflow_admin=UC/workflow_admin,
-- directus=U/workflow_admin,
-- cutter_ro=U/workflow_admin,
-- cutter_exec=U/workflow_admin,
-- cutter_verify=U/workflow_admin}
SELECT has_schema_privilege('directus','cutter_governance','USAGE') AS directus_usage;
-- true
SELECT relacl FROM pg_class c JOIN pg_namespace n ON c.relnamespace=n.oid
WHERE n.nspname='cutter_governance' AND c.relname IN ('review_decision','cut_change_set');
-- review_decision: directus=r/workflow_admin
-- cut_change_set : directus=r/workflow_admin
directus_schema_usage_cutter_governance : true
directus_table_select_review_decision : true
directus_table_select_cut_change_set : true
⇒ fn_iu_enact running SECURITY DEFINER as directus CAN execute PERFORM 1 FROM cutter_governance.review_decision WHERE review_decision_id = p_review_decision_id. No additional grant required for the design's step-6 governance-link probe.
1.6 Governance table PK column names (must match in function body)
SELECT c.relname AS tbl, a.attname
FROM pg_constraint co
JOIN pg_class c ON co.conrelid=c.oid
JOIN pg_namespace n ON c.relnamespace=n.oid
JOIN pg_attribute a ON a.attrelid=c.oid AND a.attnum=ANY(co.conkey)
WHERE n.nspname='cutter_governance'
AND c.relname IN ('review_decision','cut_change_set')
AND co.contype='p';
cutter_governance.review_decision : PK = review_decision_id (uuid)
cutter_governance.cut_change_set : PK = change_set_id (uuid)
⇒ Function body MUST reference review_decision_id (not id) when probing review_decision; MUST reference change_set_id (not id) when probing cut_change_set. Captured here so the DDL author does not silently use id.
2. G1 — implementation scope lock
2.1 Objects to CREATE / REPLACE (full list)
The macro authors but does NOT execute the following. Ordering matches the 7-phase implementation sequence from the design ( [[dot-iu-cutter-v0-5-05-grant-verification-rollback-plan-2026-05-20]] §2):
Bundle A — Vocab + Log tables (Phase 1 in execution macro):
A.1 CREATE TABLE public.iu_lifecycle_vocab
A.2 4-row INSERT … ON CONFLICT DO UPDATE (seed)
A.3 CREATE TABLE public.iu_lifecycle_log
A.4 5 indexes on iu_lifecycle_log
A.5 GRANT SELECT on vocab/log to read roles (PUBLIC for vocab;
cutter_exec/cutter_verify/context_pack_readonly/workflow_admin for log)
Bundle B — Immutability functions + triggers (Phase 2):
B.1 CREATE OR REPLACE FUNCTION public.fn_iu_enacted_immut() (non-SECDEF)
B.2 CREATE TRIGGER trg_iu_enacted_immut BEFORE UPDATE OR DELETE
ON public.information_unit FOR EACH ROW EXECUTE FUNCTION ...
B.3 CREATE OR REPLACE FUNCTION public.fn_uv_enacted_immut() (non-SECDEF)
B.4 CREATE TRIGGER trg_uv_enacted_immut BEFORE UPDATE OR DELETE
ON public.unit_version FOR EACH ROW EXECUTE FUNCTION ...
Bundle C — fn_iu_enact body (Phase 3):
C.1 CREATE OR REPLACE FUNCTION public.fn_iu_enact(
p_canonical_address text,
p_actor text,
p_review_decision_id uuid,
p_target_lifecycle text DEFAULT 'enacted',
p_change_set_id uuid DEFAULT NULL,
p_reason text DEFAULT NULL,
p_tool_revision text DEFAULT NULL,
p_dry_run boolean DEFAULT false
) RETURNS jsonb
LANGUAGE plpgsql
SECURITY DEFINER
SET search_path = pg_catalog, public;
Bundle D — Gateway policy + dot_config + grants (Phase 4):
D.1 UPDATE dot_config: allowed_marker_values append ',fn_iu_enact'
D.2 INSERT 8 keys iu_enact.* (ON CONFLICT DO UPDATE)
D.3 REVOKE EXECUTE ON FUNCTION public.fn_iu_enact(...) FROM PUBLIC
D.4 GRANT EXECUTE ON FUNCTION public.fn_iu_enact(...) TO cutter_exec
D.5 (optional, deferred to a separate step) GRANT EXECUTE TO workflow_admin
Bundle E — fn_iu_apply_edit_draft patch (Phase 5):
E.1 CREATE OR REPLACE FUNCTION public.fn_iu_apply_edit_draft(
p_draft_id uuid, p_actor text, p_review_note text
) RETURNS jsonb
LANGUAGE plpgsql
SECURITY DEFINER
SET search_path = pg_catalog, public;
-- replace global lifecycle_status block with per-anchor lookup;
-- add 'base_version_enacted' refusal
Bundle F — Caller / repo integration (Phase 6; authored here, repo work
in a follow-on commit gated on Bundle A..E execution):
F.1 cutter_agent/lifecycle_enact_adapter.py (module + tests)
F.2 cutprod_canonical.py 'enact' sub-command
F.3 knowledge/dev/laws/dieu44-trien-khai/readme/iu-lifecycle-enactment-readme.md
2.2 Objects EXPLICITLY NOT touched in any execution phase
production rows NOT touched:
- 158 information_unit rows (all lifecycle_status, all data)
- 165 unit_version rows (all lifecycle_status, all data, all enacted_at)
- all 60 ICX-CONST IUs remain lifecycle_status='draft' through the
full implementation execution; only Phase 7 (separate sovereign gate)
enacts them.
production functions NOT touched:
- public.fn_iu_create
- public.fn_iu_gateway_write_guard
- public.fn_iu_verify_invariants
- public.fn_iu_create_plan / fn_iu_create_preflight
- public.fn_iu_create_edit_draft / fn_iu_create_edit_draft_for_supersede
- public.fn_iu_save / fn_iu_edit / fn_iu_edit_plan
- public.fn_iu_comment / fn_iu_comment_edit_draft
- public.fn_iu_mark_read / fn_iu_unread / fn_iu_notification_board
- public.fn_iu_notif_* (3 functions)
- public.fn_iu_classify_existing / fn_iu_resolve_default
- public.fn_birth_registry_auto / fn_birth_auto_certify / fn_birth_change_flag_matrix
- public.fn_iu_birth_gate_layer1 / fn_iu_birth_gate_layer2 / fn_iu_updated_at
- public.fn_law_enacted_immutable / fn_law_enacted_must_have_enforcement
- public.fn_nrm_enacted_* (3 functions)
- public.fn_tac_enacted_immut / fn_tac_pm_enacted_lock / fn_tac_birth_gate_lu
- public.fn_transition_lifecycle / fn_bulk_transition / fn_backfill_lifecycle_log
- public.fn_enforce_apr_lifecycle / fn_iu_verify_invariants
- public.fn_content_hash
- all sandbox_tac.* functions
production tables/triggers NOT touched:
- public.lifecycle_log (the existing INTEGER-keyed log; left alone)
- public.birth_registry (data NOT touched; triggers attached NOT touched)
- public.dot_config (8 INSERTs in iu_enact.* namespace + 1 row UPDATE only;
no other rows changed)
- public.collection_registry (unchanged)
- public.tac_*_lifecycle_vocab (unchanged; we author iu_lifecycle_vocab,
not tac_*)
- public.tac_unit_version (unchanged)
- public.normative_registry (unchanged)
- public.approval_requests (unchanged)
- all triggers ALREADY on information_unit & unit_version are unchanged
(gateway, birth-gate L1, birth-gate L2, updated_at, notif-version)
- all cutter_governance.* tables (no write; only SELECT-probes from SECDEF)
- all sandbox_tac.* tables
roles NOT created/dropped:
- new GRANTs to existing roles only; no CREATE ROLE / DROP ROLE
- no role membership change
2.3 Idempotency contract (per OQ-1..OQ-7 defaults)
fn_iu_enact idempotency:
- same (canonical_address, target) re-call: returns status='already_<target>',
no new log row, no rows written
- same (canonical_address, target) re-call from a different actor:
still returns 'already_<target>' (the lifecycle_log row from the
ORIGINAL transition remains authoritative; we do NOT append a
duplicate transition row)
- re-call after a successful 'plan_ok' dry_run: full transition fires
(dry_run never wrote anything)
DDL idempotency (vocab/log/functions/triggers):
- CREATE TABLE … IF NOT EXISTS is intentionally NOT used because we
want CREATE-failures to surface and be diagnosed (rather than
silently skip a schema-drift). Instead the macro guards with a
preflight probe (PHASE 1 P0.4 in design doc 05 §2).
- CREATE OR REPLACE FUNCTION is used; safe by definition.
- CREATE TRIGGER does NOT support OR REPLACE; the execution macro
will use a guarded DROP TRIGGER IF EXISTS … followed by CREATE TRIGGER.
Same guard pattern as Pack 22-P3 rev7.
- INSERT … ON CONFLICT (key) DO UPDATE for vocab seed + dot_config
iu_enact.* keys (idempotent).
- UPDATE dot_config WHERE key=… (idempotent on the value; safe to
re-run with the same final value).
GRANT idempotency:
- GRANT is idempotent in PostgreSQL (re-running a grant does nothing).
2.4 Fail-closed guards in fn_iu_enact
G-IN-1 : input validation (canonical_address/actor/review_decision_id required)
else: status='invalid_input'
G-IN-2 : target_lifecycle must exist in iu_lifecycle_vocab
else: status='invalid_target_lifecycle'
G-IDM : idempotent no-op if from==to
status='already_<target>'
G-FSM : FSM transition matrix
else: status='fsm_denied'
G-INV : fn_iu_verify_invariants(canonical_address) all_pass
else: status='invariant_failed'
G-GOV : review_decision_id exists in cutter_governance.review_decision
else: status='review_decision_not_found'
G-GOV2 : if change_set_id provided, must exist in cutter_governance.cut_change_set
else: status='change_set_not_found'
G-LOCK : pg_advisory_xact_lock(hashtext('iu_enact:'||iu_id::text))
serializes per-IU; no failure mode
G-MARK : set_config('app.canonical_writer','fn_iu_enact',true)
no failure mode; transaction-local
G-POST : post-write re-check IU.lifecycle_status==target
else: RAISE EXCEPTION 'fn_iu_enact post-write mismatch' (txn rolls back)
If ANY guard trips, the function returns a failure-status JSON or
RAISEs an exception that aborts the transaction. No partial state.
2.5 Required p_review_decision_id contract
HARD REQUIRE (OQ-5 default):
NOT NULL : enforced at step 0 (input validation)
exists in cutter_governance.review_decision : enforced at step 6
semantic appropriateness : NOT enforced by function;
operational discipline checks that
the row's governance_event_kind and
review_scope are appropriate for
enactment (vs CUT or other events)
The function does NOT enforce "must differ from CUT review_decision
(29c88a7b-…)" because the row's contents — not its identity — determine
appropriateness. The operator obtaining the new review_decision via
leg-B style governed recording is responsible for ensuring the row's
content (decision_at, decided_by, verdict, review_scope) reflects an
ENACTMENT decision, not a CREATION decision.
Pre-Phase-7 prerequisite (NOT covered by this macro):
- record a NEW cutter_governance.review_decision row with
governance_event_kind suitable for enactment scope
- record (optionally) a NEW cutter_governance.cut_change_set row
linking to it
- sovereign ruling on the new review_decision before phase 7 fires
2.6 Concurrency posture
single-IU concurrency:
pg_advisory_xact_lock(hashtext('iu_enact:'||iu_id::text))
- two concurrent enactments on the SAME IU: second waits for first
- first finishes → second sees lifecycle_status=already_<target> →
returns idempotent 'already_<target>'
cross-IU concurrency:
- independent advisory locks per IU
- two concurrent enactments on DIFFERENT IUs: both proceed in parallel
- gateway marker app.canonical_writer is transaction-local (set_config
with is_local=true) so no cross-session pollution
cross-with-other-canonical-writers:
- fn_iu_create on a new IU (different canonical_address):
no advisory-lock collision; both proceed
- fn_iu_apply_edit_draft on an existing IU (same target IU as enact):
no advisory-lock collision in design (apply_edit_draft uses FOR UPDATE
on the IU row at its step 'SELECT * INTO v_iu FROM ... FOR UPDATE');
advisory lock and row lock are different. If apply_edit_draft is
creating a new UV while fn_iu_enact is transitioning the current
UV anchor: serialized by FOR UPDATE on information_unit row.
2.7 What this macro produces — final deliverables list
KB artifacts (6 docs in v0.5-lifecycle-enactment-implementation-authoring/):
- 01-live-recheck-and-scope-lock (this doc)
- 02-fn-iu-enact-ddl-package (Bundles A+B+C+D)
- 03-fn-iu-apply-edit-draft-patch-package (Bundle E)
- 04-verification-rollback-compensation-plan
- 05-command-review-package
- 06-final-implementation-authoring-report
repo artifacts (NOT committed in this macro; surfaced as backlog with
exact body sketches in doc 02 §13 and doc 03 §5):
- cutter_agent/lifecycle_enact_adapter.py (module body sketched)
- cutter_agent/tests/test_lifecycle_enact_adapter.py (tests sketched)
- cutprod_canonical.py (enact sub-command sketched)
operator README (authored but not yet placed):
- knowledge/dev/laws/dieu44-trien-khai/readme/iu-lifecycle-enactment-readme.md
(full body in doc 05 §7)
NOT included in this macro:
- any SQL execution against production
- any commit / push / tag / merge
- any test invocation against live DB
- any leg-B governed recording of a NEW review_decision
- any phase-7 enactment
3. G0+G1 disposition
G0_live_state_re_check : PASS — all design fingerprints unchanged
G1_scope_lock : PASS — bundles A..F locked; non-touched
objects enumerated; idempotency contract
defined; concurrency posture defined
production_mutation : NONE
next : G2 — DDL/function authoring
[[dot-iu-cutter-v0-5-02-fn-iu-enact-ddl-package-2026-05-20]]
Related KB documents in this package:
- [[dot-iu-cutter-v0-5-02-fn-iu-enact-ddl-package-2026-05-20]]
- [[dot-iu-cutter-v0-5-03-fn-iu-apply-edit-draft-patch-package-2026-05-20]]
- [[dot-iu-cutter-v0-5-04-verification-rollback-compensation-plan-2026-05-20]]
- [[dot-iu-cutter-v0-5-05-command-review-package-2026-05-20]]
- [[dot-iu-cutter-v0-5-06-final-implementation-authoring-report-2026-05-20]]
Predecessors:
v0.5-lifecycle-enactment-design/(6 docs; OPT-E1 + OQ-1..OQ-7 defaults)reviews/dot-iu-cutter-v0.5-lifecycle-enactment-design-ready-gpt-ruling-2026-05-20.md(GPT ruling)