Lifecycle DDL Ratification · 01 DDL Provenance Map
dot-iu-cutter v0.5 — Lifecycle DDL Ratification · Provenance Map
doc 1 of 6 · 2026-05-20 · ratification of M3a Bundles A..E into repo
phase : G1 — DDL provenance trace outcome : PASS (4/4 function md5(prosrc) byte-equal to live) production_mutation : NONE this phase (read-only PG + read KB)
1. Source-of-truth chain
The lifecycle substrate live in directus PG was applied during the M3a-retry
macro on 2026-05-20. The repo runbook just committed mirrors that substrate
exactly, with two source streams cross-checked:
authoring_KB:
- knowledge/dev/laws/dieu44-trien-khai/v0.5-lifecycle-enactment-implementation-authoring/
docs 01..06; bundles fully designed
execution_KB:
- knowledge/dev/laws/dieu44-trien-khai/v0.5-lifecycle-enactment-execution-m3a-retry/
docs 00..07; bundles applied; fingerprints recorded
live_pg:
- directus PG; pg_proc.prosrc / pg_trigger / pg_class read on 2026-05-20
- role: context_pack_readonly (read-only)
ground_truth_for_runbook_bodies:
- live pg_proc.prosrc (decoded from base64-utf8); md5 verified against
M3a-retry post-apply pins
2. Bundle inventory
bundle_A_vocab_and_log:
txn : 1
objects:
- public.iu_lifecycle_vocab (table + 4-row seed)
- public.iu_lifecycle_log (table + 5 indexes + FK + grants/revoke)
ddl_kind : CREATE TABLE / INSERT ON CONFLICT / CREATE INDEX / GRANT / REVOKE
source : authoring KB doc 02 (verbatim, no body normalization needed)
bundle_B_immutability:
txn : 2
objects:
- public.fn_iu_enacted_immut() (LANGUAGE plpgsql, trigger fn)
- public.fn_uv_enacted_immut() (LANGUAGE plpgsql, trigger fn)
- trg_iu_enacted_immut (BEFORE UPDATE OR DELETE)
- trg_uv_enacted_immut (BEFORE UPDATE OR DELETE)
ddl_kind : CREATE OR REPLACE FUNCTION / DROP+CREATE TRIGGER
source : live pg_proc.prosrc + authoring KB header
body_origin : LIVE PG (authoring SQL had decorative comments that PG
stripped; using LIVE body preserves md5 equality)
bundle_C_fn_iu_enact:
txn : 3
objects:
- public.fn_iu_enact(text,text,uuid,text,uuid,text,text,boolean) → jsonb
ddl_kind : CREATE OR REPLACE FUNCTION (SECURITY DEFINER, search_path pinned)
source : live pg_proc.prosrc + authoring KB signature + comment
body_origin : LIVE PG (same reason as Bundle B)
bundle_D_gateway_and_grants:
txn : 4
objects:
- UPDATE public.dot_config gateway allowed_marker_values
- INSERT 8 iu_enact.* keys (ON CONFLICT DO UPDATE)
- REVOKE EXECUTE on fn_iu_enact FROM PUBLIC
- GRANT EXECUTE on fn_iu_enact TO cutter_exec
ddl_kind : UPDATE / INSERT ON CONFLICT / REVOKE / GRANT
source : authoring KB doc 02 (verbatim)
bundle_E_fn_iu_apply_edit_draft_patch:
txn : 5
objects:
- public.fn_iu_apply_edit_draft(uuid,text,text DEFAULT NULL::text) → jsonb
ddl_kind : CREATE OR REPLACE FUNCTION (SECURITY DEFINER, search_path pinned)
source : live pg_proc.prosrc + M3a-retry doc 02 signature spec
body_origin : LIVE PG (narrow patch; preserves p_review_note default)
3. Fingerprint verification (md5(prosrc) byte-equality)
Verified by re-extracting bodies from the committed repo SQL files
(sql/lifecycle/bundle_*.sql) between $tag$…$tag$ markers and computing
md5 against the live PG md5(prosrc) values:
function len md5(extracted) md5(live) verdict
-----------------------------+------+----------------------------------+----------------------------------+--------
fn_iu_enacted_immut 1631 aeb3fa4fdb225f6ba6b7073582caa454 aeb3fa4fdb225f6ba6b7073582caa454 OK
fn_uv_enacted_immut 2415 03f035a23cbc79a9e811a6da6f5266ba 03f035a23cbc79a9e811a6da6f5266ba OK
fn_iu_enact 8674 6ca9bc39e2d2be93dd8a71739fa80dc4 6ca9bc39e2d2be93dd8a71739fa80dc4 OK
fn_iu_apply_edit_draft 4826 42e96b6c9e81a2d0a28b30644d178a26 42e96b6c9e81a2d0a28b30644d178a26 OK
All 4 lifecycle function bodies in the repo SQL files are byte-equal to the live function bodies stored in PG. Re-applying any of these bundles in a fresh PG environment will produce md5(prosrc) values that match these pins (assuming PG ≥ 16 stores prosrc unchanged from CREATE OR REPLACE source, which it does).
4. Body-extraction technique (audit trail)
extraction_query :
SELECT proname,
length(prosrc) AS body_len,
md5(prosrc) AS body_md5,
encode(convert_to(prosrc, 'UTF8'), 'base64') AS body_b64
FROM pg_proc
WHERE pronamespace = 'public'::regnamespace
AND proname IN ('fn_iu_enact','fn_iu_apply_edit_draft',
'fn_iu_enacted_immut','fn_uv_enacted_immut');
decode_step :
base64 → bytes → utf-8 decode → write to /tmp/live_bodies/<name>.txt
dollar_quote_check :
Verified no body contains literal '$$' before embedding;
used unique per-function dollar tags ($iuim$, $uvim$, $enact$, $apply$)
so the embedded body is never escaped or re-flowed.
5. Authoring vs live divergence — surfaced
discovery:
authoring_SQL_in_KB_doc_02 had inline `-- step N` comments and used
UTF-8 arrow characters (→) in RAISE EXCEPTION messages.
live_pg_storage:
PG stripped the inline `--` comments from prosrc and replaced the
UTF-8 arrows with ASCII '->' during M3a-retry apply (the actual
sidecar SQL applied was a stripped/normalized form, not the authoring
doc copy verbatim).
implication:
Authoring docs are NOT byte-for-byte the same as live prosrc.
The runbook commits the LIVE bodies to preserve fingerprint equality
for future re-apply / recovery scenarios.
KB_note:
This divergence is documented here, not as a defect — the authoring
docs remain readable for design intent, and the runbook SQL files
remain re-applicable for substrate reproduction.
6. Static dependencies surfaced (must exist before re-apply)
pre_existing_objects_required :
- public.information_unit (table)
- public.unit_version (table)
- public.unit_edit_draft (table) # Bundle E callers
- public.unit_edit_comment (table) # Bundle E callers
- public.dot_config (table) # Bundle D updates
- public.fn_iu_verify_invariants(text) → jsonb (used by Bundle C + E)
- public.fn_content_hash(text) → text (used by Bundle E)
- cutter_governance.review_decision (table) with SELECT visible to directus
- cutter_governance.cut_change_set (table) with SELECT visible to directus
- role cutter_exec (GRANT EXECUTE target)
- role context_pack_readonly, cutter_verify, workflow_admin (read grants)
- role directus (SECDEF principal at apply time)
7. Gate disposition
G1_KB_source_traced : PASS (authoring + execution KB read)
G1_live_PG_bodies_extracted : PASS (4 × base64 → utf-8)
G1_md5_byte_equality : PASS (4/4 byte-equal to live md5)
G1_dollar_quote_safety : PASS (no body contains $$, unique tags chosen)
G1_authoring_vs_live_divergence : SURFACED + documented (authoring comments
stripped; arrows normalized)
G1_dependencies_listed : PASS
G1_no_invention : PASS (no DDL fabricated from memory)
8. STOP
Provenance map complete. Proceed to doc 02 (repo placement decision).