KB-5C20

Lifecycle DDL Ratification · 03 Runbook Artefact Summary

9 min read Revision 1
dot-iu-cutterv0.5lifecycle-ddl-ratificationrunbook-artifactsg3-passdieu442026-05-20

dot-iu-cutter v0.5 — Lifecycle DDL Ratification · Runbook Artefact Summary

doc 3 of 6 · 2026-05-20

phase    : G3 — authored artefacts
outcome  : 11 files committed under sql/lifecycle/
commit   : 1cd286e039357018c40a1281599e17961b848749  (feature branch only)

1. File inventory

# Path (under repo root) Bytes Role
1 sql/lifecycle/README.md 5,431 Operator intro + warnings + apply order
2 sql/lifecycle/bundle_a_vocab_and_log.sql 4,855 TXN-1: vocab + log tables, indexes, grants
3 sql/lifecycle/bundle_b_immutability.sql 6,867 TXN-2: 2 trigger fns + 2 triggers
4 sql/lifecycle/bundle_c_fn_iu_enact.sql 11,571 TXN-3: SECDEF lifecycle writer (8-arg)
5 sql/lifecycle/bundle_d_gateway_and_grants.sql 3,535 TXN-4: dot_config + EXECUTE grants
6 sql/lifecycle/bundle_e_fn_iu_apply_edit_draft_patch.sql 7,104 TXN-5: narrow per-anchor patch
7 sql/lifecycle/verify_preflight.sql 3,016 Pre-apply absence probes
8 sql/lifecycle/verify_postapply.sql 7,376 Post-apply presence + md5 probes
9 sql/lifecycle/verify_behavioral_probes.sql 3,900 B-1..B-8 ROLLBACK-only behavioral
10 sql/lifecycle/rollback_runbook.sql 7,642 Per-bundle rollback + safety constraints
11 sql/lifecycle/fingerprints.yaml 5,856 md5 / count / role pin manifest
TOTAL 67,153 11 files, 1,335 inserted lines

2. Apply-order encoded in filenames

bundle_a → bundle_b → bundle_c → bundle_d → bundle_e

The letter encodes both the M3a-retry TXN sequence AND the dependency graph:

dependencies:
  bundle_a : depends on   {public.information_unit table, roles}
  bundle_b : depends on   {public.information_unit, public.unit_version}
  bundle_c : depends on   {bundle_a (vocab/log), bundle_b (triggers),
                           public.fn_iu_verify_invariants,
                           cutter_governance.review_decision + cut_change_set}
  bundle_d : depends on   {bundle_c (function must exist before GRANT)}
  bundle_e : depends on   {public.unit_edit_draft + unit_edit_comment +
                           public.fn_content_hash + public.fn_iu_verify_invariants}
            independent of bundle_a..d, BUT must be applied BEFORE Phase 7
            (the global-coupling defect activates the moment any UV becomes
             non-'draft').

3. Function bodies — byte-equality assertion

Every CREATE OR REPLACE FUNCTION block in bundles B / C / E uses a unique dollar-quote tag ($iuim$ / $uvim$ / $enact$ / $apply$) so the body between the dollar markers is byte-identical to live pg_proc.prosrc. Verification:

function                       len   md5(repo body)                    md5(live prosrc)
-----------------------------+------+----------------------------------+--------------------------------
fn_iu_enacted_immut          1631   aeb3fa4fdb225f6ba6b7073582caa454  aeb3fa4fdb225f6ba6b7073582caa454
fn_uv_enacted_immut          2415   03f035a23cbc79a9e811a6da6f5266ba  03f035a23cbc79a9e811a6da6f5266ba
fn_iu_enact                  8674   6ca9bc39e2d2be93dd8a71739fa80dc4  6ca9bc39e2d2be93dd8a71739fa80dc4
fn_iu_apply_edit_draft       4826   42e96b6c9e81a2d0a28b30644d178a26  42e96b6c9e81a2d0a28b30644d178a26

This is the load-bearing guarantee of this ratification. A future fresh-PG apply that produces a different md5 means the SQL has drifted from the live substrate — which the operator should treat as a STOP condition, not silently edit fingerprints.yaml to match.

4. Header conventions

Every SQL file begins with a fixed-format header:

-- =============================================================
-- Bundle X — <short title> (TXN-N)
-- =============================================================
-- SOURCE       : <KB document path>
-- APPLIED      : <date> (<macro>, <txn>, PASS)
-- LIVE STATE   : <one-line live-state summary>
-- WARNING      : DO NOT re-apply blindly. <consequences>
-- FINGERPRINT  : <md5 + length pin where applicable>
-- DEPENDS ON   : <prerequisites>
-- =============================================================

This makes the "this is already applied; do not re-run blindly" warning unavoidable for any operator opening any of the files.

5. Pre-flight / post-apply / behavioral probes

verify_preflight.sql       (P0.1..P0.6)
  - gateway value at pre-state ('fn_iu_create,fn_iu_apply_edit_draft')
  - 60 ICX-CONST all draft / 0 enacted_at
  - lifecycle infrastructure absent
  - pre-patch md5(fn_iu_apply_edit_draft) = 22875ce25b2e2d1751cc4f3d1757252e
  - cutter_governance accessibility by directus
  - cutter_exec role exists

verify_postapply.sql       (A.V1..E.V3 + data invariants pre + post Phase 7)
  - vocab 4 rows / log empty pre-Phase-7
  - all 4 lifecycle fn md5(prosrc) byte-equal to pin
  - 2 triggers enabled
  - gateway includes fn_iu_enact
  - 8 iu_enact.* keys
  - cutter_exec has EXECUTE; PUBLIC does not
  - post-patch md5(fn_iu_apply_edit_draft) byte-equal to pin

verify_behavioral_probes.sql  (B-1..B-8; every probe BEGIN..ROLLBACK)
  - B-1 valid dry-run
  - B-2 invalid vocab target
  - B-3 nonexistent canonical_address
  - B-4 review_decision_not_found
  - B-5 raw UPDATE blocked by gateway
  - B-6 NULL review_decision_id
  - B-7 NULL actor
  - B-8 FSM behavior (varies pre/post Phase 7)

6. Rollback runbook (safety-constrained)

rollback_runbook.sql documents per-bundle rollback DDL AND the pre-conditions that must hold before a rollback is safe. Critical refusal rules surfaced:

bundle_A_rollback_refuses_if : iu_lifecycle_log > 0 rows
bundle_B_rollback_refuses_if : any IU or UV has lifecycle_status='enacted'
bundle_C_rollback_refuses_if : iu_lifecycle_log > 0 rows
bundle_E_rollback_refuses_if : any UV has lifecycle_status != 'draft'

live_state_post_Phase_7 : violates 3 of 4 refusal rules
runbook_disposition     : explicit DO-NOT-RUN warning at top of the file

7. Fingerprints.yaml manifest

Machine-readable; structured as:

apply_date_utc            : 2026-05-20
bundles_applied_in_order  : [A,B,C,D,E]
functions:
  fn_iu_enact             : md5_prosrc + secdef + search_path + identity_args
  fn_iu_enacted_immut     : md5_prosrc
  fn_uv_enacted_immut     : md5_prosrc
  fn_iu_apply_edit_draft  : pre-patch + post-patch md5 + lengths
  fn_iu_create            : (cross-check, NOT in M3a scope)
  fn_iu_gateway_write_guard : (cross-check, NOT in M3a scope)
triggers                  : tgname + table + function + tgenabled
tables                    : iu_lifecycle_vocab + iu_lifecycle_log shape + row counts
dot_config_keys           : 9 entries (1 updated + 8 new)
grants                    : EXECUTE / SELECT / explicit REVOKE map
data_invariants_pre_phase7  : 158/165/158/165/0/0/60/60/0
data_invariants_post_phase7 : 158/165/0/60/60/60/4 + Phase 7 metadata

8. Gate disposition

G3_files_authored               : PASS  (11/11)
G3_apply_order_encoded          : PASS  (letter prefix + README)
G3_post_applied_warning_present : PASS  (header on every .sql file)
G3_dependencies_documented      : PASS  (per-bundle in headers + README)
G3_fingerprints_pinned          : PASS  (4 functions byte-equal; manifest published)
G3_verification_queries_present : PASS  (preflight + postapply + behavioral)
G3_rollback_with_safety         : PASS  (per-bundle + cascading + refusal rules)
G3_no_duplication               : PASS  (no KB content mirrored verbatim)
G3_no_production_DDL_executed   : PASS
G3_no_lifecycle_mutation        : PASS

9. STOP

Artefact summary complete. Proceed to doc 04 (test + static-check result).

Back to Knowledge Hub knowledge/dev/laws/dieu44-trien-khai/v0.5-lifecycle-ddl-ratification-runbook/03-runbook-artifact-summary-2026-05-20.md