Resolves #11976
Tests were reading gitignored, operator-mutable config.mjs overlays. This made the same commit behave differently across checkouts and allowed a direct template import plus a transitive overlay import to register the same Neo config class twice. The corrected test harness now resolves one committed template graph, keeps imported reactive Providers read-only, and uses fresh disposable Provider instances for config permutations.
Evidence: L2 (resolver runtime probes, one-worker shared-state topology, config-authority lint, and unified integration) → L2 required (all runtime ACs are test-harness-local). No residuals.
Deltas from ticket
- Adds one Playwright preload boundary that redirects only checkout-local
ai/**/config.mjs imports with a committed sibling template. Relative, absolute, file-URL, and neo.mjs/ specifiers are covered; outside-checkout paths, tracked configs without a template, and disposable child repositories pass through.
- Loads that boundary before every Playwright mode and inherits it into descendant Node processes. Direct executable test imports were migrated for source honesty; the resolver closes transitive production-import gaps.
- Migrates the 112 AST-visible overlay imports plus the executed child-source import identified by the ticket. Three remaining overlay imports execute only inside disposable deployment repositories and intentionally test generated-overlay runtime behavior.
- Deletes the former Tier-1 and Knowledge Base defaults fixtures. They materialized reactive Provider proxies into frozen plain objects, violating ADR-0019 B1 and losing hierarchical/inherited state. Canonical assertions now read the committed template Provider directly; permutations create and destroy isolated
ConfigProvider instances.
- Extends the target-zero config SSOT lint to reject test-side Provider-derived exports and direct Provider re-exports while allowing invocation-time direct reads. No snapshot or Provider-export baseline escape hatch exists.
- Corrects the source-path absence tests: the old
delete operations were ineffective because the hierarchical proxy has no delete trap. Missing keys and a missing sourcePaths namespace are now constructed honestly on disposable Providers.
- Routes template-derived Chroma, SQLite telemetry, WAL, handoff, route-ledger, recovery, and log writes into disposable per-runner/per-worker storage.
- Repairs shared-worker isolation defects exposed by the unified template graph: bounded graph cleanup, restored singleton seams, exact fixture removal, and an explicit canonical-frontier prerequisite for the public archive-recall spec.
Config-template impact
ai/config.template.mjs: adds engines.chroma.useUnitTestDatabase and engines.chroma.useTestHarness; engines.chroma.useTestDatabase becomes their computed effective selector. Existing host, port, and dataDir consumers remain unchanged.
- Memory Core: adds
storagePaths.useUnitTestDatabase and storagePaths.useTestHarness; graph, collection, WAL, handoff, and route-ledger formulas use the effective test boundary.
- Knowledge Base and Neural Link: split
memoryCoreDbPath into production/test leaves plus unit/Playwright selectors, while preserving memoryCoreDbPath as the computed consumer surface.
- Existing ignored operator overlays are not copied, overwritten, or migrated by this PR. Runtime production values therefore do not change. A future explicit config migration receives the new template shape; no MCP or harness restart is required for this test-only boundary.
Test Evidence
- Exact rebased head
d14006865d: focused Provider/config/lint/RecoveryActuator/SourcePaths cluster, one worker — 126/126 passed.
- Exact rebased head
d14006865d: node ai/scripts/lint/lint-config-template-ssot.mjs — pass; zero test overlay imports and zero test config-authority violations.
- Exact rebased head
d14006865d: node buildScripts/util/check-aiconfig-test-mutation.mjs — pass; 801 files scanned, zero new violations.
- Exact rebased head
d14006865d: npm run agent-preflight -- --no-fix <changed files> and git diff origin/dev...HEAD --check — pass.
- Earlier pre-correction head
82a46ae542: resolver/lint/config and spawned-process cluster — 104 passed; shared-state regression clusters — 209/209, 56/56, and the exact GraphService → MailboxService → PublicRecall one-worker chain 149/149.
- Earlier pre-correction head
82a46ae542: full unit normal topology — 7,164 passed; exact CI topology — 7,032 passed with four local sandbox-denied lifecycle writes subsequently isolated green 26/26; unified integration — 5 runnable passed, 45 deployment-gated skipped. Fresh GitHub CI will revalidate the rebased correction head.
- Whitebox E2E and local-model-only coverage: None found; this PR changes Node/Playwright test resolution and config isolation, not an app or model-execution surface.
Post-Merge Validation
Evolution
The first implementation replaced hand-copied defaults with frozen snapshots of Provider.data. That preserved the wrong abstraction: Provider.data is a hierarchical reactive proxy, not a flat object, and snapshotting it created another authority while omitting inherited state. The correction removes the fixtures entirely, moves mutations to disposable Providers, and adds a narrow mechanical guard for the exact exported-snapshot/re-export recurrence.
Authored by Euclid (GPT-5.6 Sol Ultra, Codex Desktop). Session 837ad74b-c2d2-413d-9aab-b7165a93a82a.
Resolves #11976
Tests were reading gitignored, operator-mutable
config.mjsoverlays. This made the same commit behave differently across checkouts and allowed a direct template import plus a transitive overlay import to register the same Neo config class twice. The corrected test harness now resolves one committed template graph, keeps imported reactive Providers read-only, and uses fresh disposable Provider instances for config permutations.Evidence: L2 (resolver runtime probes, one-worker shared-state topology, config-authority lint, and unified integration) → L2 required (all runtime ACs are test-harness-local). No residuals.
Deltas from ticket
ai/**/config.mjsimports with a committed sibling template. Relative, absolute, file-URL, andneo.mjs/specifiers are covered; outside-checkout paths, tracked configs without a template, and disposable child repositories pass through.ConfigProviderinstances.deleteoperations were ineffective because the hierarchical proxy has no delete trap. Missing keys and a missingsourcePathsnamespace are now constructed honestly on disposable Providers.Config-template impact
ai/config.template.mjs: addsengines.chroma.useUnitTestDatabaseandengines.chroma.useTestHarness;engines.chroma.useTestDatabasebecomes their computed effective selector. Existinghost,port, anddataDirconsumers remain unchanged.storagePaths.useUnitTestDatabaseandstoragePaths.useTestHarness; graph, collection, WAL, handoff, and route-ledger formulas use the effective test boundary.memoryCoreDbPathinto production/test leaves plus unit/Playwright selectors, while preservingmemoryCoreDbPathas the computed consumer surface.Test Evidence
d14006865d: focused Provider/config/lint/RecoveryActuator/SourcePaths cluster, one worker — 126/126 passed.d14006865d:node ai/scripts/lint/lint-config-template-ssot.mjs— pass; zero test overlay imports and zero test config-authority violations.d14006865d:node buildScripts/util/check-aiconfig-test-mutation.mjs— pass; 801 files scanned, zero new violations.d14006865d:npm run agent-preflight -- --no-fix <changed files>andgit diff origin/dev...HEAD --check— pass.82a46ae542: resolver/lint/config and spawned-process cluster — 104 passed; shared-state regression clusters — 209/209, 56/56, and the exactGraphService → MailboxService → PublicRecallone-worker chain 149/149.82a46ae542: full unit normal topology — 7,164 passed; exact CI topology — 7,032 passed with four local sandbox-denied lifecycle writes subsequently isolated green 26/26; unified integration — 5 runnable passed, 45 deployment-gated skipped. Fresh GitHub CI will revalidate the rebased correction head.Post-Merge Validation
unit,integration-unified, CodeQL, and config-template SSOT checks are green on the merge candidate.Evolution
The first implementation replaced hand-copied defaults with frozen snapshots of
Provider.data. That preserved the wrong abstraction:Provider.datais a hierarchical reactive proxy, not a flat object, and snapshotting it created another authority while omitting inherited state. The correction removes the fixtures entirely, moves mutations to disposable Providers, and adds a narrow mechanical guard for the exact exported-snapshot/re-export recurrence.Authored by Euclid (GPT-5.6 Sol Ultra, Codex Desktop). Session 837ad74b-c2d2-413d-9aab-b7165a93a82a.