KB-2395

01 — P-pub Birth-Gate Promotion Authority Pack (2026-05-28)

9 min read Revision 1
iuppubbirth-gatepublication-authorityauthority-packdieu38dieu39dieu32fn-iu-createstaged-enforcement2026-05-28

Doc 01 — Branch B: P-pub Birth-Gate Promotion Authority Pack

Verdict: DEFER — warn→block promotion is UNSAFE today. Full authority pack below. IU birth must not break.


1. Live evidence (read-only, 2026-05-28)

1.1 Birth-gate trigger wiring on information_unit

Trigger Timing Function Note
trg_aa_iu_gateway_write_guard BEFORE INSERT OR UPDATE fn_iu_gateway_write_guard canonical-writer allowlist
trg_iu_birth_gate_layer1 BEFORE INSERT only fn_iu_birth_gate_layer1 identity/vocab/P-id/P-pub checks
trg_iu_birth_gate_layer2 CONSTRAINT, AFTER INS/UPD, DEFERRABLE INITIALLY DEFERRED fn_iu_birth_gate_layer2 U5/U6 anchors at commit
trg_birth_information_unit AFTER INSERT fn_birth_registry_auto Đ0-G birth registry
trg_iu_enacted_immut BEFORE DELETE OR UPDATE fn_iu_enacted_immut enacted immutability

1.2 P-pub checks inside fn_iu_birth_gate_layer1 (BEFORE INSERT)

v_val := NEW.identity_profile->>'publication_authority_ref';
IF v_val IS NULL OR v_val = '' THEN
  RAISE WARNING 'Birth gate L1 PILOT-ONLY: P-pub1 missing — production sẽ BLOCK';   -- WARN ONLY
END IF;

v_val := NEW.identity_profile->>'publication_type_ref';
IF v_val IS NULL OR v_val = '' THEN
  RAISE WARNING 'Birth gate L1 PILOT-ONLY: P-pub2 missing — production sẽ BLOCK';   -- WARN ONLY
ELSE
  IF NOT EXISTS (SELECT 1 FROM dot_config WHERE key='vocab.publication_type.'||v_val)
  THEN RAISE EXCEPTION 'publication_type "%" not in vocab', v_val;  -- HARD if present-but-invalid
  END IF;
END IF;
  • P-pub1 (publication_authority_ref): warn-only, no vocab validation even when present.
  • P-pub2 (publication_type_ref): warn-only when absent; hard-block when present but not in vocab.publication_type.*.

1.3 fn_iu_create signature & body (the root cause)

Signature: (p_canonical_address, p_title, p_body, p_actor, p_unit_kind, p_section_type, p_owner_ref, p_publication_type, p_parent_ref).

  • Builds identity_profile = {title, owner_lookup_ref, primary_section_type_ref}.
  • Adds publication_type_ref only if p_publication_type passed (validated against vocab.publication_type.*).
  • Never sets publication_authority_ref. → Every IU born via fn_iu_create is missing P-pub1.

1.4 Live data profile (219 IUs)

Field Set Missing
publication_authority_ref 86 (all = incomex_council) 133
publication_type_ref 146 (all = law) 73

1.5 Vocabulary present

Key namespace Keys Values
vocab.publication_authority.* 1 incomex_council
vocab.publication_type.* 2 law, design_doc

2. Why promotion is unsafe NOW

  1. fn_iu_create writes no publication_authority_ref. Promote P-pub1 warn→block and every new IU birth fails immediately — including every split child created during compose/split/merge. This is a total birth outage.
  2. Vocabulary too thin for honest assignment. Only incomex_council exists as an authority. The 133 authority-less IUs are not all council-published (some are design docs). Blind-assigning incomex_council to all would be a false governance claim, violating Đ31 integrity.
  3. Blast radius is bounded but real. trg_iu_birth_gate_layer1 is BEFORE INSERT only → existing 133/73 rows do not break on UPDATE/retire/supersede. The break is confined to new INSERTs (births + split/merge children). This is what makes a staged path feasible, but does not make an immediate flip safe.
  4. P-pub2 present-but-invalid already hard-blocks. Only the absent case is warn. So a type-vocab expansion must precede any type backfill.

3. Authority pack — required changes (in dependency order)

3.1 fn_iu_create signature change (PREREQUISITE)

Add a publication-authority parameter and write it into identity_profile:

fn_iu_create(..., p_publication_type text, p_publication_authority text DEFAULT NULL, p_parent_ref uuid)
-- validate p_publication_authority against vocab.publication_authority.* when block-stage active
-- v_identity := v_identity || jsonb_build_object('publication_authority_ref', btrim(p_publication_authority))

Plus the split/merge child constructors (fn_iu_piece_split, fn_iu_piece_merge) must propagate publication_authority_ref from the source IU or accept it explicitly.

3.2 Publication-authority vocabulary expansion

vocab.publication_authority.* currently has only incomex_council. Before block, register the full lawful set via APR/Đ32. Candidate set (illustrative, ratify via Council):

  • incomex_council (exists), incomex_super_admin, department_lead, external_regulator, system_generated, pilot_provisional. Authorities are governance objects — registration must go through Đ32 high, not auto-seed.

3.3 216→219-row backfill plan (now 133 authority-less, 73 type-less)

  • Do NOT auto-assign. Build a classification worksheet: for each of the 133 authority-less IUs, derive the lawful authority from its unit_kind / owner_ref / source provenance.
  • Likely mapping: unit_kind=law_unit + existing publication_type_ref=lawincomex_council; design docs → a design_doc/internal authority.
  • Backfill is a governed UPDATE batch under a manifest + review_decision (production builder from Branch C), audited, reversible (snapshot prior identity_profile).
  • The 73 type-less rows similarly need publication_type_ref set from the (expanded) vocab.publication_type.* before P-pub2 blocks.

3.4 Đ38/Đ39/Đ32 sign-off path

  • Đ38 (IU law): P-pub fields are identity attributes of an IU → enforcement change is an Đ38 birth-contract amendment.
  • Đ39 (KG): publication_authority feeds provenance of every IU edge (A8) → consistency required.
  • Đ32 (approval): vocab expansion + backfill + warn→block flip each require an approval at high risk class with sovereign cross-sign.

Introduce a dot_config staged enforcement key, e.g. iu_create.ppub.enforcement_mode ∈ {warn, block_new, block_all}:

  • warn (today): RAISE WARNING only.
  • block_new: hard-block new INSERTs once §3.1 (fn writes authority) + §3.2 (vocab) ship; existing rows untouched (matches BEFORE-INSERT-only trigger).
  • block_all: only after §3.3 backfill completes; add a BEFORE UPDATE guard if full enforcement on mutation is desired. The L1 trigger reads this key and chooses WARN vs EXCEPTION per check. This makes the flip a config flip (reversible) rather than a code redeploy.

3.6 Rollback plan

  • Code: keep prior fn_iu_birth_gate_layer1 + fn_iu_create bodies; revert is CREATE OR REPLACE back to baseline (md5-pinned).
  • Config: set enforcement_mode=warn to instantly disable blocking.
  • Backfill: per-row prior identity_profile snapshotted → restorable via governed UPDATE.

3.7 Test plan

  1. In BEGIN..ROLLBACK: set enforcement_mode=block_new; attempt fn_iu_create without authority → must RAISE; with valid authority → must succeed; with invalid authority → must RAISE (vocab).
  2. Prove existing-row UPDATE still succeeds under block_new (BEFORE INSERT only).
  3. Split/merge child creation carries authority → succeeds.
  4. Negative: unknown authority value blocked; empty string blocked.
  5. Verify fn_iu_gate_verify_closed unaffected; commit nothing in test; separate committed apply only after sign-off.

3.8 Exact condition when warn→block becomes safe

block_new is safe when ALL hold:

  1. fn_iu_create + split/merge constructors write a valid publication_authority_ref.
  2. vocab.publication_authority.* covers every authority the pilot can emit (ratified Đ32).
  3. iu_create.ppub.enforcement_mode key exists and L1 honors it.
  4. Test plan §3.7 passes in-transaction.

block_all is additionally safe only when: 5. All 133 authority-less + 73 type-less rows backfilled under governed manifest/review_decision. 6. Production review_decision builder (Branch C) is live (backfill needs a real Đ32 approval).

Branch B depends on Branch C for the backfill approval and on a vocab-expansion Council pass. Sequence: vocab expand → fn_iu_create patch → block_new → backfill → block_all.


4. Outcome

  • Applied this run: nothing (correctly — flip is unsafe).
  • Deliverable: this authority pack + staged enforcement design.
  • Next macro: IU_PPUB_BIRTH_GATE_SAFE_PROMOTION_OR_STAGED_AUTHORITY_*X (doc 06, macro 1).
Back to Knowledge Hub knowledge/dev/reports/architecture/iu-limited-production-promotion-kg-relationship-and-4mothers-gate-authority-2026-05-28/01-ppub-birth-gate-promotion-authority.md