25000x · 11 — Lessons + Carry-forward (5 new lessons: sidecar-FK-matches-parent-PK, registry-schema-vary, no-truncated-UUIDs, vocab-enforcement, idempotency-key-composition)
25000x · 11 — Lessons + Carry-forward
New lessons
L1 — Sidecar PK column matches the parent's PK, not a synthetic id
The iu_collection_template_instance_lineage table (mig 031) has PK instance_collection_id (no id column). The 25000x sidecar iu_auto_instantiate_event_log initially used instance_lineage_id → migration failed on column "id" referenced in foreign key constraint does not exist. Pattern: always \d the parent table before writing the FK column — same shape as [[feedback-cutter-governance-pk-column-review-decision-id]].
L2 — Registry tables have schemas the migration template can't assume
event_type_registry lacks registered_by and uses (event_domain, event_type, event_stream, delivery_lane, default_severity, description, active, created_at). Many other "registry" tables have registered_by. Pattern: always \d the registry table before authoring INSERT.
L3 — Truncated UUIDs in display output are a footgun for follow-up SQL
The baseline-dump query showed iu8=09c8ee5f for piece IUs — only the first 8 hex chars. I made up the rest for the v2 file template apply script; fn_iu_collection_add_piece returned piece … not found / soft-deleted (because the full UUID was wrong). Pattern: fetch full UUIDs in a separate verification query before using them in apply SQL.
L4 — section_type + piece_role are enforced vocabularies
Both have CHECK constraints / RAISE checks. Discovered live during v2 file template apply: section_type='summary' and piece_role='executive_summary' both refused. Valid vocabularies:
section_type: appendix, article, changelog, checklist, definition, governance_process, heading, instruction_block, paragraph, principle, process, section, technical_specpiece_role: title, intro, body, step, clause, appendix, reference
L5 — Idempotency key composition for event-driven productization
idempotency_key = md5(event_id::text || ':' || template_id::text || ':' || instance_key_suffix) is the minimum quartet needed to make event replay safe. NOT just event_id (one event might legitimately spawn from multiple templates). NOT just template_id (different events targeting same template must produce different instances). Suffix gives caller control over multiple instances per (event, template) pair.
Refreshed lessons
- [[feedback-two-narrow-sidecars-over-one-wide-sidecar]] — third sidecar (mig 033) keyed on lineage PK rather than collection PK proves the pattern extends to different parent tables when concerns are orthogonal.
- [[feedback-in-tx-gate-toggle-reversibility]] — gate-toggle pattern now proven at n=12 in one TX (Phase E bulk scaleout).
- [[feedback-pinning-tests-bump-per-macro]] — 16 test files bumped in the same commit (up from 13 in 18000x).
- [[feedback-fn-iu-compose-is-the-bulk-instance-mechanism]] — fn_iu_compose plus fn_iu_auto_instantiate_from_event orchestrator together prove bulk-instance scales beyond direct compose looping.
Carry-forward to 30000x
High priority
- Auto-instantiate log retention policy — register
iu_auto_instantiate_event_loginiu_core_retention_policy. - DOT command registration — wrap fn_iu_auto_instantiate_from_event + rollback_by_actor (24 → 26 governed).
- Envelope refresh on auto-compose — wire
fn_iu_three_axis_envelope_refresh_if_staleinto orchestrator.
Medium priority
- External delivery policy — route + lane for
iu.template.instance_auto_composed? - Consolidated
v_iu_product_factory_dashboard— optional join view. - Linux systemd timer — Mac cron parity.
- Retention enablement audit + flip — separate macro.
Low priority
- PR #669 closeout — external authority.
- Nuxt deploy — external authority.
- Auto-instance Qdrant indexing — embedder credential gap, policy decision.
- Bulk-instance retire DOT — pair to rollback_by_actor that uses retire semantics.
Carried over
- Birth-gate PILOT noise (warnings on every compose) — cosmetic.
Why no DOT entries this macro
DOT registration requires: command name shape, input/output schemas, pre/post probes, catalog row + R280 governed-count bump. Genuinely additive non-blocking; carried forward.