5000x · final report · lessons · next macro
07 — 5000x final report · lessons · next macro
1. Status
IU_CORE_5000X_NUXT_FACTORY_PILOT_MONITORING_RETENTION_PASS.
- 24 / 26 product-readiness rows DONE (doc 06).
- 1 row DONE_WITH_EXTERNAL_BLOCKER — Nuxt UI factory authored (see doc 02). Deploy = frontend / DevOps slice over the existing factory output.
- 1 deferred-by-design row — durable retention enablement (see doc 05).
- Zero unsafe state at exit. All write gates inert. All audit rows scoped under explicit actor strings for clean rollback.
2. Code change set on this commit (parent 3ae4c62 from 4000x)
New artefacts:
sql/iu-core/025_iu_core_retention_substrate.sql+ rollback — forward-looking retention substrate.sql/iu-core/runtime/350_three_axis_envelope_auto_refresh_trigger_5000x_pilot.sql+ rollback — multi-invariant production pilot.sql/iu-core/sandbox/240_iu_core_retention_substrate_probe.sql— 7-probe BEGIN/ROLLBACK.cutter_agent/iu_core/ui_factory.py— schema-driven Nuxt artifact factory.cutter_agent/iu_core/healthcheck.py— pure-Python 7-surface healthcheck.scripts/iu_core_healthcheck.sh— cron-ready wrapper.ui-package/nuxt-three-axis-factory/— README, 4 templates, 2 descriptors, 8 generated files undergenerated/(deterministic).tests/test_iu_core_5000x_nuxt_factory.py— 15 contract tests.tests/test_iu_core_5000x_healthcheck.py— 10 contract tests.knowledge/dev/laws/dieu44-trien-khai/v0.6-iu-core-5000x-…/{01..07}.md— 7 KB reports (this directory).
Updates:
sql/iu-core/runtime/110_iu_core_dot_conformance_scan.sql— registers the 4 new objects from migration 025; D9 expected counts bumped to 144 / 144 (23 / 23 / 52 / 5 / 10 / 15 / 16).- 14 existing tests get mechanical DOT-count bumps (
'table',22→'table',23, etc.).
Production durable changes:
- migration 025 applied to live
directusDB onvmi3080463/ containerpostgres. CREATE TABLE / CREATE VIEW / CREATE FUNCTION / INSERT 3 policy rows / INSERT 1 config row. Gateiu_core.retention_enabledstaysfalse. - runtime/350 ran: +2 audit rows under
actor='iu_5000x_pilot', outcome=skipped_in_sync; gate cycled true → false within the transaction.
Backup taken before any durable mutation:
/opt/incomex/backups/directus-pre-iucore-5000x-20260523T093747Z.dump- size 77 654 276 bytes
- sha256
8a0df45e0e7dec4db0d1d2a3d34c1ffa38adeafc67ba8e2987ca41fcf90452e2
3. Tests
tests/test_iu_core_5000x_nuxt_factory.py— 15 passed (7 TestCases).tests/test_iu_core_5000x_healthcheck.py— 10 passed (4 TestCases).- Full suite:
python3 -m pytest tests/ -q --ignore=tests/_orchestrator_o2_harness.py→ 1163 passed in 0.67s (1138 baseline + 25 new).
4. Lessons captured (memory follow-ups)
4.1 The 3000x "env didn't reach Nuxt" finding generalised
3000x discovered that the compiled .output bundle at
/opt/incomex/deploys/nuxt-output/ carries zero IU Core references.
4000x found the actual source repo at
/opt/incomex/docker/nuxt-repo/web. 5000x's read-only discovery
confirmed both still hold — and the right deliverable from an IU Core
macro is never to push files into the live Nuxt repo, but to ship
a deploy-ready artifact (4000x) or, even better, a generator that
emits one (5000x).
4.2 4000x ui-package was a one-off, not a factory
The 4000x ui-package shipped a Vue page + composable hand-tailored to
iu_three_axis_envelope. Each subsequent three-axis collection would
have needed another hand-authored set of files with the same field
names baked into different places. The 5000x constitution renamed
this anti-pattern and required the factory pattern instead.
4.3 The Directus _contains operator does not work on json columns
axis_b_tags is jsonb in PG but Directus reports it as json and
rejects _contains. More importantly, the value shape is a dict
({group: [tag, …]}), not a flat array — for (const tag of row.axis_b_tags)
on a plain object iterates zero times. Both 4000x's ui-package and the
first cut of the 5000x factory had this bug; 5000x found it during live
REST smoke and fixed the factory templates (no server-side axisBTag
filter; flattenAxisBTags(raw) helper accepts both shapes).
4.4 Statement-level AFTER triggers fire ONCE per statement
runtime/350.4 proved this durably for information_unit: 3-row bulk
UPDATE → 1 refresh_log row. The auto-refresh trigger function is
therefore safe against bulk lifecycle operations — no fan-out.
4.5 iu_metadata_tag has assigned_at, not updated_at
A schema discovery delivered mid-pilot. The cleanest no-op rewrite
for the tag-side trigger probe is SET assigned_at = assigned_at —
Postgres still writes a new tuple, the AFTER STATEMENT trigger still
fires. Same statement-level invariant holds.
4.6 D8 drift guard catches unregistered IU Core objects mechanically
When migration 025 added v_iu_core_retention_candidates, the very
first DOT scan flagged it as unregistered. This is the SSOT working
as designed: a new IU Core view must be registered in
_iu_core_expect AND in the D9 expected-counts VALUES list, in the
same change as its CREATE.
5. Recommended next macro
Option A (smallest, ops slice) — IU_CORE_5200X_NUXT_FACTORY_DEPLOY_PILOT
- Frontend dev (or controlled SSH window) reviews
ui-package/nuxt-three-axis-factory/generated/iu_three_axis_envelope/. cpthe Vue + composable into/opt/incomex/docker/nuxt-repo/web.- Merge
compose.snippet.yml+runtimeConfig.snippet.ts. cd /opt/incomex/docker && docker compose up -d --build nuxt.dot_iu_nuxt_config_verify+ smokehttp://incomex-nuxt:3000/admin/iu-three-axis.
This closes the lone DONE_WITH_EXTERNAL_BLOCKER from row 26.
Option B (ops automation) — IU_CORE_5300X_HEALTHCHECK_CRON_AND_RETENTION_ENABLE
- Add a host-level cron entry that runs
scripts/iu_core_healthcheck.shevery 5 minutes and posts JSON to uptime-kuma's incoming webhook. - Take a backup; flip
iu_core.retention_enabled='true'; runfn_iu_core_retention_cleanuponce manually; schedule it weekly. - Add a Slack notifier that fires on
overall_oktransitions only.
Option C (real-corpus pilot) — IU_CORE_5500X_REAL_CORPUS_PILOT
- Ingest one full external doc into the IU lifecycle through the
composer + auto-cut path with the auto-refresh gate
true. - Observe the envelope auto-refreshes, the Directus REST reflects the new rows, the Qdrant collection picks them up under the per-IU boundary.
- Render one composed file via
dot_iu_render_file; confirm the exported text round-trips through text-as-code.
6. Verification gate before the next macro
The next macro should start only after GPT / User verified via
AgentData list_documents + search_knowledge that the 7 reports in
this directory are present and searchable, AND production reports:
iu_three_axis_envelopecarries 163 rows withcache_healthy=t;iu_three_axis_envelope_refresh_logcarries 2 rows underactor='iu_5000x_pilot'(in addition to the 4000x runtime/340 row);iu_three_axis_envelope_trigger_error_logis empty;dot_config.iu_core.three_axis_auto_refresh_enabled = false;dot_config.iu_core.retention_enabled = false;iu_core_retention_policyhas 3 rows;- DOT scan returns 144 / 144;
- 1163 tests passing on the 5000x commit;
scripts/iu_core_healthcheck.shreturns exit 0 withoverall_ok=true.