KB-1216

D36 NVSZ Macro A — 09 Carry-Forward

8 min read Revision 1
d36carry-forwardmacro-amacro-b-roadmap2026-05-25

D36 NVSZ Macro A — 09 Carry-Forward

Items that Macro A did not complete or only partially completed, packaged for the next macro / future work.

1. Birth Execution Plan as pre-flight artifact (process)

Gap. This macro did not produce a Birth Execution Plan before substrate apply. User invoked the Collection Birth Hard Gate mid-execution. Plan published retrospectively in 01-birth-execution-plan.md.

Next macro must. Produce the Birth Execution Plan as the first artifact, before any CREATE TABLE / VIEW / FUNCTION. Plan must be uploaded to KB and explicitly reviewed before substrate apply. The check is enforceable in CI if desired (see ops/d36-birth-gate-precheck/ — not yet authored).

2. Auto-birth triggers (per-row)

Gap. Design doc 05 specifies trg_iu_staging_record_birth and trg_iu_staging_payload_birth that auto-write a birth_registry row on each staging record/payload INSERT. These were NOT created in Macro A — birth_registry holds only the 3 collection/species rows, not per-staging-row entries.

Macro B authoring outline.

CREATE OR REPLACE FUNCTION iu_core.tfn_iu_staging_record_birth()
RETURNS trigger LANGUAGE plpgsql AS $$
BEGIN
  INSERT INTO birth_registry (
    entity_code, collection_name, species_code, composition_level, dot_origin,
    born_at, governance_role, certified, status, canonical_address, owner, jsonb_profile,
    date_created, date_updated
  ) VALUES (
    NEW.staging_record_id::text, 'iu_staging_record', 'SPE-NVS', '1',
    'D36-runtime', now(), 'governed', true, 'born',
    'iu_core.iu_staging_record/'||NEW.staging_record_id::text, NEW.owner_actor,
    jsonb_build_object('staging_kind',NEW.staging_kind,'lifecycle_status',NEW.lifecycle_status),
    now(), now()
  );
  RETURN NEW;
END$$;

CREATE TRIGGER trg_iu_staging_record_birth AFTER INSERT ON iu_core.iu_staging_record
  FOR EACH ROW EXECUTE FUNCTION iu_core.tfn_iu_staging_record_birth();

(Analogous for payload.) Verify trigger fires on fn_iu_staging_create path — proof: insert one test row, expect +1 staging_record + ≥1 birth_registry. Then bump D9 by +2 routines + +2 triggers; pin in tests.

3. fn_iu_staging_cleanup + DOT

Gap. Cleanup function and DOT not authored (Auto-Scope).

Macro B authoring outline. Honors iu_core.staging_cleanup_enabled gate; transitions (expired ∨ consumed ∨ rejected) → cleaned in batches; sets cleaned_at=now(). Returns {cleaned: N, errors: []}. DELETE strategy is soft (lifecycle_status='cleaned') — actual DELETE of payload bytes is a separate _purge step on retention TTL.

CREATE OR REPLACE FUNCTION iu_core.fn_iu_staging_cleanup(p_scope jsonb DEFAULT '{}'::jsonb)
RETURNS jsonb LANGUAGE plpgsql SECURITY DEFINER AS $$ … $$;
INSERT INTO dot_iu_command_catalog VALUES ('dot_iu_staging_cleanup','lifecycle',true,true,'{fn_iu_staging_cleanup}',now());

4. fn_iu_staging_unregister + DOT (REFUSED-guarded rollback)

Gap. Per-record rollback function deferred.

Macro B authoring outline. Hard delete (FK CASCADE handles payload). Only callable when lifecycle_status='cleaned' or lifecycle_status='rejected'. Returns refused for pending/approved/consumed.

5. fn_iu_staging_emit_event + event_outbox wiring

Gap. Event emission deferred. Event types are registered (5 of them, lane=delayed) but no INSERT into event_outbox happens on lifecycle transitions.

Macro B authoring outline. Add fn_iu_staging_emit_event(record_id, event_type) that inserts into event_outbox honoring event_type_registry validation. Wire calls inside fn_iu_staging_create/_approve/_consume/_reject. Pair with feedback-event-outbox-jsonb-column-is-safe-payload lesson.

6. SSOT / pinning test bumps (requires app repo)

Gap. App repo not reachable from this MCP channel.

Next macro from a clone must. Bump:

  • cutter_agent/iu_core/dot_commands.py _REGISTRY: 26 → 30
  • D9 pinning test (currently 183 from 70000x): bump to current value
  • Test for v_collection_vector_eligibility shape
  • Test for iu_core.fn_iu_staging_healthcheck() returning green=true
  • Test for dot_iu_staging_* resolvability (R280-style)

7. Birth Gate WARNING on COL-IUS-001 code format

Gap. Live Birth Gate trigger warned: Code format PREFIX-NNN: Code "COL-IUS-001" sai format. INSERT proceeded but warning logged.

Triage. Either (a) widen the live Birth Gate regex to allow two-segment prefixes (^[A-Z]+(-[A-Z]+)?-\d+$), or (b) rename to single-segment codes (e.g. COLIUS-001, COLIUS-002).

Recommendation. Option (a) — widen regex — preserves Q13 freeze. Author one-line UPDATE to the Birth Gate fn or its regex constant.

8. Q5 sidecar doc-02 alignment sweep

Gap. Doc 02-governance-compatibility-matrix.md row referencing collection_registry is semantically unchanged but worth a wording pass to mention the sidecar explicitly. Patches in docs 04 and 07 are done.

Next macro from KB. One-paragraph addendum in doc 02 §2 noting that the "vector_eligible" attribute is resolved via v_collection_vector_eligibility, not the parent table column.

9. V6 external Qdrant probe

Gap. Macro A channel has no Qdrant API key. V6 is structurally guaranteed (no SQL→Qdrant path from staging) but not empirically probed.

Next macro / ops Run the curl probe in report 05; assert zero points. Add to operator runbook as a periodic check.

10. Operator runbook addendum

Gap. Not authored.

Outline.

  • How to enable iu_core.staging_writes_enabled for a window
  • How to manually trigger healthcheck
  • How to inspect pending staging records
  • How to roll back per the plan in report 08

Macro B should bundle:

  1. Birth Execution Plan published BEFORE any apply
  2. Auto-birth triggers
  3. fn_iu_staging_cleanup + DOT + retention gate flip rehearsal
  4. fn_iu_staging_unregister + DOT
  5. fn_iu_staging_emit_event + event_outbox wiring
  6. Birth Gate regex widening
  7. SSOT/pinning test bumps in app repo (Macro B should run from a clone)

Macro C should be MARK workflow integration (doc 06).

12. Lessons feedback to record (auto-memory)

  • [[feedback-birth-execution-plan-hard-gate-precedes-apply]] — When the user invokes Collection Birth Hard Gate (mid- or pre-execution), produce a Birth Execution Plan BEFORE any CREATE TABLE/VIEW/FUNCTION. The plan must include 9 sections (live evidence, species, codes, registry plan, birth behavior, DOT plan, D9 delta, rollback, sidecar policy). Skipping → PARTIAL_WITH_EXACT_GAP minimum.
  • [[feedback-live-vocab-collection-registry-checks]]collection_registry has 5 CHECK-vocab columns: birth_code_strategy {column,synthetic_id,legacy_id_single_colon,subordinate,disabled,unclassified}, birth_identity_source {inferred_from_existing_trigger,manual,migration_seed,system_default,unclassified}, description_policy {required_detailed,structured_exempt,unclassified}, coverage_status {BIRTH_REQUIRED, BIRTH_EXEMPT_*, UNCLASSIFIED_NEW} (UPPERCASE), coverage_scope_status {IN_SCOPE,USER_EXCLUDED,FUTURE_SCOPE,ORPHAN_REGISTRY} (UPPERCASE). "group" FK to collection_groups(code) — 9 values (GRP-*).
  • [[feedback-tac-birth-gate-mode-vocab]]tac_birth_gate_config.mode CHECK in {block,warn} only. 'gate' invalid.
  • [[feedback-event-type-registry-vocab]] — PK is (event_domain, event_type) — 2 cols. delivery_lane in {immediate, delayed}. event_stream in {comment,review,update,birth,task,alert,health}. NO 'internal' or 'create'.
  • [[feedback-dot-iu-command-category-vocab]]category CHECK in {collection,piece,lifecycle,read,health} only.
  • [[feedback-iu-core-is-table-prefix-not-schema]] — Pre-macro-A: iu_core_* tables live in public. Macro A creates a real iu_core schema as additive. Confirm before assuming.
Back to Knowledge Hub knowledge/dev/laws/dieu44-trien-khai/v0.6-d36-no-vector-staging-zone-macro-a-substrate-birth-dot-healthcheck/09-carry-forward.md