KB-53BB

04 — +60 Birth Cascade Characterization (P-1 CLOSED)

8 min read Revision 1
g1birth-registrycascadep-1entity-labelsrollback-mapirreversible-risk2026-05-29

04 — Branch D: Birth Cascade Characterization (P-1 CLOSED)

The prior campaign observed "+52" but did not decompose it. Measured precisely this campaign in BEGIN..ROLLBACK (birth_registry grouped by collection_name, before vs after): the deterministic cascade for the production 3-registry birth (with per-registry birth triggers) is +60 birth_registry rows.

Cascade map — measured delta by collection_name (3 registries)

collection_name total Δ per registry mechanism
meta_catalog +3 1 direct INSERT → fn_birth_registry_auto
entity_species +3 1 direct INSERT → birth
species_collection_map +3 1 direct INSERT → birth (synthetic entity_code species_collection_map::<id>)
collection_registry +3 1 direct INSERT → birth
measurement_registry +3 1 auto via fn_auto_create_measurement (fires: identity_class='managed' + registry_collection set + table exists) → that row is itself born
entity_labels +42 14 auto via fn_auto_label_assignment + fn_auto_label_provenance (AFTER INSERT on meta_catalog & collection_registry); each label row is born
system_issues +3 1 a DDL-detection event trigger logs each CREATE TRIGGER trg_birth_<reg> as a system_issue, which is itself born
TOTAL +60 20

So 20 birth rows per registry × 3 = 60. entity_labels (the auto-label machinery) is the bulk (70%) and is exactly what the "+52" estimate had not pinned down.

Why +60 and not +52

The figure depends on two activation choices:

  • WITH per-registry birth triggers (recommended, production-correct so future registry rows are counted) → the 3 CREATE TRIGGERs trip the DDL-detection event trigger → system_issues +3. Total +60.
  • WITHOUT per-registry birth triggers → no DDL logs → +57.
  • The prior "+52" was a leaner/earlier path (no birth triggers + slightly fewer auto-labels for the stub column shapes). The number is now deterministic and reproducible for whichever path is chosen; the activation pack (doc 06) uses the +60 path and asserts that exact delta.

Physical-row footprint (snapshot delta, in-tx)

Table Δ birth-tracked?
meta_catalog +3 yes
collection_registry +3 yes
entity_species +3 yes
species_collection_map +3 yes
measurement_registry +3 yes
v_registry_counts +3 no (no birth trigger on v_registry_counts)
entity_labels +42 yes
system_issues +3 yes
birth_registry +60 (the audit ledger itself)
governance_registry 0 (tier-ownership is an UPDATE, no new row)

Note v_registry_counts +3 produces no birth row (consistent: it is absent from the birth-delta table), confirming fn_birth_registry_auto is not attached to it.

Determinism

  • fn_birth_registry_auto is idempotent: EXISTS-guard on (entity_code, collection_name) + ON CONFLICT (entity_code) DO NOTHING. The duplicate birth triggers on meta_catalog/collection_registry/entity_species (birth_trigger_* + trg_birth_*) therefore do not double-count. Verified by the exact +1-per-table figures.
  • The cascade is fully a function of: identity_class='managed', registry_collection set (drives measurement), governance_role='governed' (drives auto-labels), and the presence of the per-registry birth trigger (drives the system_issues DDL log). All are fixed by the activation script → fully deterministic.

Rollback map

A. In-transaction (rehearsal): ROLLBACK → byte-identical. All 60 birth rows, 42 entity_labels, 3 system_issues, 3 measurement, 3 v_registry_counts and the 3 tables vanish. Zero risk. (Proven, doc 05.)

B. Committed → SOFT RETIRE (recommended reversal, Điều 30/31):

UPDATE collection_registry SET status='retired' WHERE code IN ('FIELD-001','FORM-001','TIER-001');
UPDATE entity_species      SET status='retired' WHERE code IN ('SPC-FIELD-001','SPC-FORM-001','SPC-TIER-001');
UPDATE measurement_registry SET enabled=false WHERE measurement_id LIKE 'MSR-AUTO-CAT_101%';
UPDATE birth_registry      SET status='retired' WHERE collection_name IN ('field_registry','input_form_registry','tier_registry'); -- registry-row births
-- tier ownership revert:
UPDATE governance_registry SET capability=NULL, output_target=NULL, primary_collection=NULL WHERE code='GOV-COUNCIL';

Tables and registration rows are preserved but inert. Lawful, low-risk, no guard fights.

C. Committed → HARD ROLLBACK (heavier; human-only):

DROP TABLE IF EXISTS public.field_registry, public.input_form_registry, public.tier_registry;  -- drops their birth triggers too
-- meta_catalog deletes are GUARDED → must bypass:
SET LOCAL app.allow_meta_update='true';
DELETE FROM meta_catalog WHERE code IN ('CAT-1011','CAT-1012','CAT-1013');  -- fires fn_auto_cleanup_on_meta_delete (removes v_registry_counts rows, drops count triggers, refreshes CAT-ALL)
DELETE FROM collection_registry     WHERE code IN ('FIELD-001','FORM-001','TIER-001');
DELETE FROM entity_species          WHERE code IN ('SPC-FIELD-001','SPC-FORM-001','SPC-TIER-001');
DELETE FROM species_collection_map  WHERE collection_name IN ('field_registry','input_form_registry','tier_registry');
DELETE FROM measurement_registry    WHERE measurement_id IN ('MSR-AUTO-CAT_1011','MSR-AUTO-CAT_1012','MSR-AUTO-CAT_1013');
DELETE FROM birth_registry          WHERE collection_name IN ('field_registry','input_form_registry','tier_registry')
                                        OR entity_code IN ('CAT-1011','CAT-1012','CAT-1013','FIELD-001','FORM-001','TIER-001','SPC-FIELD-001','SPC-FORM-001','SPC-TIER-001');
DELETE FROM entity_labels           WHERE <labels created for the above CAT/COL codes>;  -- scope by entity ref captured at commit
DELETE FROM system_issues           WHERE <the 3 CREATE TRIGGER DDL logs>;
UPDATE governance_registry SET capability=NULL, output_target=NULL, primary_collection=NULL WHERE code='GOV-COUNCIL';

Use a born_at window captured at commit to scope the entity_labels/system_issues/birth_registry deletes precisely.

Irreversible-risk map

Element Reversible? Risk
3 CREATE TABLE Yes (DROP) none
60 birth_registry rows Yes (retire or scoped DELETE) low
42 entity_labels Yes (scoped DELETE) low — must scope by entity ref/born_at window
3 measurement_registry Yes (disable or DELETE) low
3 v_registry_counts Auto-removed by meta_catalog DELETE cleanup, or DELETE low
3 meta_catalog rows Yes, but DELETE-guarded → needs app.allow_meta_update='true'; DELETE triggers auto-cleanup side effects moderate (guard + cascade)
GOV-COUNCIL ownership write Yes (set fields NULL) low
Pre-existing rows untouched none — no data loss

No truly irreversible step exists (no enum drop, no destructive ALTER of existing tables, no loss of pre-existing data). The single elevated-caution item is the guarded meta_catalog DELETE — fully characterized and bypassable. Soft retire (path B) is strongly preferred over hard rollback.

Human activation warning

A committed birth writes to 9 tables (60 birth rows + 42 entity_labels + 3 system_issues + the core rows). This is the normal, lawful industrial-birth cascade — but it means a committed activation is not undone by a one-line DELETE. The human must accept the soft-retire reversal model (path B) as the default rollback, with hard-rollback (path C) reserved for emergencies and run under the same server-side-timeout discipline.

Back to Knowledge Hub knowledge/dev/reports/architecture/g1-candidate-registry-activation-closure-campaign-2026-05-29/04-birth-cascade-characterization.md