KB-6E7C

40000x · 06 — Carry-forward (D / E / F / G)

8 min read Revision 1
iu-core40000xcarry-forwardauto-refreshscaleoutevent-boundaryops

40000x · 06 — Carry-forward (D / E / F / G)

The 40000x focused subset shipped B + C + H + I + J. The four phases below are explicit carry-forward, each with an executable package outline so a follow-up macro can start without re-discovery.

D — Envelope auto-refresh on auto-compose

Goal. When dot_iu_auto_instantiate_from_event composes an instance, the three-axis envelope cache should reflect the new collection's pieces without an operator manually running dot_iu_three_axis_envelope_refresh.

Substrate already live. Migration 024 ships fn_iu_three_axis_envelope_refresh_if_stale plus a trigger on information_unit lifecycle, gated by iu_core.three_axis_auto_refresh_enabled (currently false). Migration 033's orchestrator writes new rows into iu_collection_template_instance_lineage and (transitively, via fn_iu_compose) into iu_piece_membership — neither is a current trigger host for the envelope refresh.

Package outline (migration 036 candidate).

  1. Decide whether to fire on INSERT INTO iu_collection_template_instance_lineage (one fire per instance) or INSERT INTO iu_auto_instantiate_event_log (mirror the audit event) — the lineage table is the cleaner semantic anchor.
  2. Author an AFTER INSERT trigger on iu_collection_template_instance_lineage that, gated by iu_core.three_axis_auto_refresh_enabled, calls fn_iu_three_axis_envelope_refresh_if_stale('iu_auto_instantiate_trigger').
  3. Add a swallowed EXCEPTION block writing to iu_three_axis_envelope_trigger_error_log so a refresh fault never breaks the orchestrator.
  4. Bound a BEGIN/ROLLBACK probe: gate=true in TX, fire orchestrator dry_run, observe iu_three_axis_envelope_refresh_log row +1, ROLLBACK, both row and gate revert.
  5. Bump the 8-surface healthcheck to include the new trigger health line.
  6. D9 surface +1 trigger (29 → 30 triggers? — verify current count); pinning test bump per [[feedback-pinning-tests-bump-per-macro]].

Why not done now. Three reasons: (a) the refresh trigger needs a separate substrate decision (trigger vs. orchestrator-internal call vs. cron); (b) the DIEU envelope invariant (27/23/36) is currently held by the manual dot_iu_three_axis_envelope_refresh plus the lifecycle trigger from mig 024 — auto-instantiate composed collections have not surfaced through the envelope yet because they reuse existing pieces; (c) a partial implementation risks a refresh storm and a deferred decision is safer.

E — Larger durable scaleout 20–40 via orchestrator

Goal. Run a bounded durable batch of 20–40 product instances through dot_iu_auto_instantiate_from_event (workflow + file templates mixed, actor-tagged, rollback-addressable, digest-matched, lineage-clean).

Substrate already live. 25000x proved the path at N=12 (8 wf + 4 file) durably. The single-loop pattern fits any N as long as the BEGIN/COMMIT fits one TX.

Package outline.

  1. Author ops/40000x-followup/scaleout/run_bounded_scaleout.sql (PL/pgSQL loop, N parametrized, actor=iu-core-Nx-bulk, gate-toggle inside BEGIN/COMMIT per [[feedback-in-tx-gate-toggle-reversibility]]).
  2. Verify digest_matches_template=true for all N via v_iu_auto_instantiate_event_log.
  3. Verify text-as-code roundtrip on a sampled instance.
  4. Verify observability views show 0 orphan + 0 digest drift.
  5. Verify Qdrant unchanged (instance collections reuse template pieces).
  6. Actor-scoped rollback via dot_iu_auto_instantiate_rollback_by_actor (dry_run then live) to verify the addressable boundary.

Why not done now. A larger durable scaleout would change row counts on multiple tables which then changes the regression baseline for every future macro — a non-trivial decision the focused-subset boundary explicitly defers.

F — Internal event automation boundary hardening

Goal. Make the "internal-only" boundary on event_type='iu.template.instance_auto_composed' explicit and durably proven (today it is documentary).

Substrate already live. The event_type is registered (25000x mig 033) with no route attached; the delivery worker is gated by iu_core.delivery_live_routes (empty) and iu_core.delivery_enabled=false.

Package outline.

  1. Author ops/40000x-followup/event-boundary/internal_only_proof.sql that asserts: event_type_registry row exists, delivery_lane <> 'live', no route_registry row keys this event_type, delivery_enabled=false, delivery_live_routes=''.
  2. Bounded BEGIN/ROLLBACK proof: insert a row into event_outbox keyed to this event_type; observe event_outbox_delivery_log writes 0; ROLLBACK.
  3. Document the rollback path for accidental route registration.
  4. Add a healthcheck surface that asserts the internal-only invariant on every cron tick.

Why not done now. The boundary is already correct by construction (no route, gate closed); promoting it to a proof needs careful gate handling that risks a flapping false-positive without a dedicated session.

G — UI / Ops / retention live closeout

Goal. Close out the operator-facing edges:

  1. PR #669 — comment / close / merge decision (external authority required).
  2. Nuxt — redeploy decision (external authority required).
  3. Retention — enablement decision (explicit future authorization required).
  4. VPS systemd timer for the Mac cron healthcheck.
  5. Operator runbook addendum.

Substrate already live. Mac cron is green. Uptime-kuma exists on the VPS. incomex-claude-kb provides KB upload from the Mac. The retention substrate is fully present and the policy is registered (40000x mig 035).

Package outline.

  1. PR #669gh pr view 669 --json state,mergeable,reviewDecision; do NOT merge unless authority verified in the next macro.
  2. Nuxtdot_iu_nuxt_config_verify; redeploy is out-of-scope until authority + canary plan.
  3. Retention enablement — author ops/40000x-followup/retention-enable/enable.sql (UPDATE gate + cleanup live run + close gate), pgdump pre/post, in a dedicated macro with explicit authorization.
  4. VPS monitoring — author systemd unit + timer for dot_iu_healthcheck aggregate; ship under ops/40000x-followup/vps-systemd/. Do not start the timer in the same macro.
  5. Operator runbook — append a 40000x section: new DOT commands, retention policy, dry-run cookbook.

Why not done now. Each of these is a real ops decision with external dependencies (humans, authority, deploy windows). A single Claude response should not pre-empt those decisions. The carry-forward package above gives the next macro a deterministic starting point.

Cross-cutting carry-forward

  • actor_column extension for iu_core_retention_policy — to enable actor-scoped pruning through the central fn_iu_core_retention_cleanup for tables whose actor column is not literal actor (e.g. iu_auto_instantiate_event_log.triggered_by). Currently routed around via the dedicated fn_iu_auto_instantiate_rollback_by_actor.
  • Auto-instantiate Qdrant indexing — if/when productized instances need to be searchable, they must be onboarded via the 9000x driver pattern; not in scope for 40000x.
  • Bulk-instance retire DOT — currently each instance is retired individually; a dot_iu_collection_retire (bulk-by-actor) could be authored when use-cases appear.
  • Cross-template piece sharing — observability already shows shared pieces between v1 and v2 of a template; explicit operator surface could be authored if the use-case appears.
Back to Knowledge Hub knowledge/dev/laws/dieu44-trien-khai/v0.6-iu-core-40000x-orchestrator-dot-retention-readiness-open-goal/06-carry-forward.md