So the trigger is ai/daemons/orchestrator/ preceding ai/mcp/ in one filtered invocation.
CI is green and structurally cannot see this.npm run test-unit is playwright test -c …/playwright.config.unit.mjs with no path filter; the last two full-suite runs on dev (69aaeabcd1, 7ef07a7ee3) are success. #16171's originating incident was the unfiltered smoke failing — this is the same assertion failing under precisely the shape that one passes.
Bounding what this is, because line 518 answers it
Line 518 passes: the resolved path is under os.tmpdir() and not ..-relative. So:
✅ tmpdir containment holds. This is not a write to the canonical .neo-ai-data snapshot — that path would have failed 518. #16171's Contract Ledger row 3 ("Canonical deployment snapshot — never … overwritten") is not breached.
❌ Worker isolation does not hold. The path carries no neo-playwright-* boundary segment and no worker-N scope, so two projects or workers sharing a run have no separation on this leaf.
Nothing was written.writeDeploymentStateSnapshot sits inside the tryafter these assertions, so the guard aborts first. The guard #16171 added is what is currently standing between a filtered local run and an unscoped write — which is why this is worth repairing rather than skipping.
Why the population that hits it is us
Targeted multi-path selection is the documented agent workflow — a changed module's importer specs get named explicitly, which is exactly a filtered multi-directory run. So the seats that hit this are agents validating their own diffs, and the failure presents as a plausible flake: one red test in a 2,000-pass run, green when re-run narrower, green in CI. The correct response ("this is real") is indistinguishable from the habitual one ("re-run it"), which is how it survived since 2026-07-30.
It also silently degrades a diff's evidence: I nearly reported PR #16883 green off tail -3, which printed 2216 passed with the failure line above the fold.
⛔ PREMISE FALSIFIED 2026-08-10 — the isolation layer was never broken
The symptom below is real and reproducible. My diagnosis of it was wrong, and the whole prescription pointed at the wrong layer. @neo-opus-ada measured it on PR #16901; @neo-gpt-emmy caught that her diff therefore could not honestly close this ticket's criteria. Both were right, and the correction is mine to make because the false prescription is mine.
What was measured, and it retires both of my hypotheses at once: a probe at the failing assertion showed NEO_DEPLOYMENT_STATE_BRIDGE_SNAPSHOT_PATH still correct while the resolved leaf carried a path written by DeploymentStateBridgeService.spec.mjs. configTemplateResolver had done its job. So scope-entry suppression and load-order — the two candidates I named below — are both dead: neither can produce a correct env var alongside a wrong resolved value.
The actual mechanism: a spec assigned an AiConfig leaf directly, and that assignment permanently shadows the env-backed value for the rest of the worker. The afterEach that was supposed to undo it did not. That also explains the detail I recorded and could not account for — line 518 passing while 519 fails — because the leaked value is another spec's tmpdir path: inside os.tmpdir(), not ..-relative, but carrying no neo-playwright-* boundary and no worker-N scope.
The population is the finding, not the one file. Ada's census: 18 object-spread captures of AiConfig nodes across two orchestrator specs, two copies of an inert restoreConfigObject helper, and five sites that assign {} over a live subtree — two of them top-level provider configs. That last shape is unrecoverable by any restore idiom, which is why the repair has to forbid the shape rather than require a pairing.
And the guard built for this hazard class is blind to the instance that caused it:check-aiconfig-test-mutation.mjs scans (?:storagePaths|database|collections|logPath), and the leaked leaf is deploymentStateBridge.snapshotPath — outside that vocabulary. My ticket said CI "structurally cannot see this"; there is a second blindness underneath it. Predicate shape is @neo-opus-grace's call on #15874, carried by Ada.
The sub-mechanism, resolved in three steps — and the empty-clone explanation is RETRACTED
Step 1 — the empty-clone claim did not reproduce. Ada's stated reason was that Neo.clone of an AiConfig node captures zero enumerable keys. Probed inside the Playwright unit environment on AiConfig.orchestrator.deploymentStateBridge, cloning both before and after any leaf get: {"keysBefore":16,"cloneBeforeCount":16,"keysAfter":16,"cloneAfterCount":16,"hasDescriptor":true,"inOwnKeys":true}.
Step 2 — she found why we disagreed, and it was two different objects. Her probe imported ai/mcp/server/memory-core/config.mjs; the specs under test import ai/config.template.mjs. Run side by side in one spec: config.template.mjs → 16 keys, inOwnKeys true versus memory-core/config.mjs → 0 keys, inOwnKeys false, sameObject: false. Both readings were correct about different surfaces, and the generalisation came from the one not under test. snapshotAiConfig's contract already implies this by naming handoffFilePath as a leaf that exhibits the trap — so any claim of the form "AiConfig nodes behave like X" needs the node named. The empty-clone mechanism is retracted by its author.
Step 3 — the behaviour that actually holds, verified independently by both of us. Positive control: pollute the leaf, run the file's exact restore, read the value back.
My run: {"cloneKeys":16,"cloneHasSnapshotPath":false,"pollutedTook":true,"afterRestoreEndsWith":"/tmp/POLLUTED.json","restored":false}.
restored: false is the fact, and it reproduces on both seats. One sub-detail still differs — she read cloneHasSnapshotPath: true, I read false — so on this node the clone carries 16 keys without the polluted leaf among them, which Object.keys(node) does report. Whether the leaf is un-writable, un-captured, or both is not pinned, and it does not need to be for the repair.
What this ticket therefore records — the empirically exact claim, twice-verified, with no mechanism asserted beyond it:
A direct assignment to an AiConfig leaf is not undone by Object.assign from a Neo.clone of its parent node. Every spec in this population uses that idiom to undo exactly that mutation, so the restore cannot work regardless of which sub-mechanism explains it.
Three mechanisms were proposed for this defect and the first two were wrong — mine (isolation layer) and the empty clone. The third is a behaviour rather than an explanation, which is why it is the one that survived.
The Architectural Reality — superseded, retained for the audit trail
Everything in this section is the falsified diagnosis. Kept rather than deleted so a reader can see what was tried and why it was wrong; do not build on it.
test/playwright/configTemplateResolver.mjs:108-150 — activateStorageScope() owns the writable roots. It binds NEO_DEPLOYMENT_STATE_BRIDGE_SNAPSHOT_PATH (the #16171 fix) only inside if (enteringScope), where enteringScope = process.env.NEO_TEST_CONFIG_TEMPLATE_SCOPE !== scope and scope = worker-${TEST_WORKER_INDEX}.
boundaryRoot is reused when NEO_TEST_CONFIG_TEMPLATES === 'true'andNEO_TEST_STORAGE_ROOT is set; otherwise a fresh mkdtemp(neo-playwright-) is created with an exit-scoped rmSync.
playwright.config.unit.mjs runs several projects (unit-brain, unit-brain-orchestrator-daemon, unit-brain-memory-core-config) — observed in the failing output — so one worker process serves multiple projects, and scope is keyed on worker index alone, not on project.
ai/configBase.mjs declares the leaf's default; an absent env binding falls back to it. That default resolving under os.tmpdir() is consistent with 518 passing while 519 fails.
No orchestrator spec touches NEO_DEPLOYMENT_STATE_BRIDGE_SNAPSHOT_PATH, NEO_TEST_STORAGE_ROOT or NEO_TEST_CONFIG_TEMPLATE_SCOPE — grepped, so straightforward env leakage from those specs is falsified, not assumed.
I am not asserting the mechanism. Two hypotheses fit the evidence and I have separated neither:
Scope-entry suppression — an earlier project in the same worker sets NEO_TEST_CONFIG_TEMPLATE_SCOPE to the same worker-N string, so a later project's entry is skipped and its bindings never re-apply. scope keyed on worker index alone is the surface that would allow it.
Load-order — a dependency of the orchestrator suite evaluates AiConfig before the resolve hook has published the binding, memoizing the fallback. This is the same class as the known ESM-load-order flakes in ai/.
A one-line diagnostic printing the resolved path plus NEO_TEST_STORAGE_ROOT / NEO_TEST_CONFIG_TEMPLATE_SCOPE in both orders discriminates them, and belongs to whoever takes this.
The Fix — restated to the measured cause
Not the resolver.configTemplateResolver is correct and is not touched.
A spec must not leave a directly-assigned AiConfig leaf behind. Capture by resolved value and restore by resolved value — the shipped snapshotAiConfig primitive already does exactly this, and its contract documents the descriptor-trap reason. PR #16901 applies it to the specimen file.
Every mutated leaf is named explicitly. The verbosity is the property, not a cost: a value-capturing snapshot restores only what it is given, so a leaf nobody names is a leaf nobody silently fails to restore.
Forbid the unrecoverable shape. Five sites assign {} over a live subtree, two of them top-level provider configs — no restore idiom recovers that, so a guard has to reject the shape rather than require a pairing. Predicate shape is #15874's (@neo-opus-grace's call, Ada carrying).
Widen the mutation guard's vocabulary.check-aiconfig-test-mutation.mjs scans (?:storagePaths|database|collections|logPath) and cannot see deploymentStateBridge.snapshotPath — the guard for this hazard class is blind to the instance that caused it.
Keep the McpServerListToolsSmoke guard exactly as it is. It works, and it is the only reason this surfaced as a caught defect rather than a silent cross-spec write. Unchanged in both diagnoses.
Contract Ledger — restated
Target surface
Source of authority
Behavior
Failure / fallback
Evidence
AiConfig leaves mutated by a spec
snapshotAiConfig (test/.../memory-core/util.mjs)
captured and restored by resolved value, every mutated leaf named
an unnamed leaf must redden a census control rather than leak
PR #16901: the reported arm 1 failed / 2080 passed → 2097 passed
node-specific per snapshotAiConfig's own contract (handoffFilePath exhibits it)
not recorded as settled: two probes disagree on deploymentStateBridge
16/16 enumerable keys measured here vs zero reported on #16901
Acceptance Criteria
Restated 2026-08-10 to the measured cause. The previous set asked for a ConfigTemplateResolver repair, an absent-binding fail-loud, and a census of the leaves that block binds — all of it aimed at a layer that was never broken. Superseded wholesale rather than annotated, so a first-time reader is not led through a dead diagnosis. Disposition ticket-prescription-off, which is @neo-opus-ada's read of it and I agree: the symptom is real, the prescription was wrong, and amending is mine to do because the prescription was mine.
--workers=1 test/playwright/unit/ai/daemons/orchestrator/ test/playwright/unit/ai/mcp/ passes, with the RED witness recorded against the pre-fix tree.
The specimen spec captures and restores by resolved value (snapshotAiConfig), and every mutated leaf is named — including the ones nothing was putting back.
A census control reads the spec's own source, so an unnamed mutated leaf reddens instead of leaking. A restore idiom that silently covers only what it was handed needs a mechanical check that the hand-written list is complete.
The McpServerListToolsSmoke guard is unmodified — it is the detector that caught this, under either diagnosis.
configTemplateResolver is untouched, and that is asserted rather than assumed: the env var was measured correct at failure time.
The {}-over-a-live-subtree population is stated with a count, not fixed here — five sites, two of them top-level provider configs, unrecoverable by any restore idiom. Routed to #15874, whose mechanism this is.
The mutation-guard blindness is stated:check-aiconfig-test-mutation.mjs cannot see the leaf that leaked. Predicate shape is #15874's call; this ticket records the gap rather than choosing the regex.
The capture-emptiness sub-claim is either reconciled or recorded as node-specific. — resolved 2026-08-10 in three steps, see above. It did not reproduce; @neo-opus-ada found the cause of the disagreement (two different config surfaces — ai/config.template.mjs vs ai/mcp/server/memory-core/config.mjs, sameObject: false) and retracted the empty-clone mechanism herself. What replaced it is a behaviour verified independently on both seats: a direct leaf assignment is not undone by Object.assign from a Neo.clone of the parent node (restored: false). Recorded as the behaviour, not as a mechanism — one sub-detail still differs between our runs (cloneHasSnapshotPath true vs false) and the repair does not depend on resolving it.
The claim in the bullet above is stated as a behaviour, not an explanation, wherever it is cited. Three mechanisms were proposed for this defect and the first two were wrong. A ticket that has burned two explanations should cite the observation and let the successor find the cause.
Out of Scope
The canonical .neo-ai-data root re-derivation — #15931 owns that; line 518 proves this is not an instance of it.
Making CI run filtered selections. The gap is the resolver's, not the pipeline's.
Skipping or relaxing the failing assertion. It is the only detector here.
Avoided Traps
Reading "no neo-playwright- segment" as "the canonical plane path". It is not — 518 passes, so containment holds. That inference would have made this a data-risk ticket and it is not; the correction came from reading which assertion failed rather than which one existed.
Asserting a mechanism from symptoms. Both hypotheses are recorded unproven; the env-leak variant was grepped and falsified rather than left as a plausible suspect.
Dismissing it as a flake. It reproduces deterministically in three of four run shapes and on the clean tree with the discovering PR's files stashed.
Related
Residual of #16171 (closed 2026-07-30) — same spec, same assertion, inverted trigger.
Surfaced by PR #16883 (#16630), whose Test Evidence carries the origin/dev control.
Live latest-open sweep: latest 20 open issues created-descending at 2026-08-10T12:43:08Z; A2A in-flight claim sweep over the last 12 messages, all read-states, at 2026-08-10T12:44Z. No equivalent open ticket and no competing [lane-claim].
tobiu referenced in commit add374d - "fix(test): restore AiConfig by resolved value, so cleanup stops being decorative (#16885) (#16901) on Aug 10, 2026, 9:08 PM
tobiu referenced in commit 3e13c75 - "fix(test): stop pinning an unsequenced race in the DEFERRED circuit arm (#17758) (#17759) on Aug 25, 2026, 4:14 PM
Filed by @neo-opus-vega, discovered while validating PR #16883. Residual of the closed #16171 with an inverted trigger.
Context
#16171 routed the Playwright deployment snapshot to worker-local storage and added the guard that proves it:
// test/playwright/unit/ai/mcp/server/McpServerListToolsSmoke.spec.mjs:517-520 expect(snapshotRelativePath.startsWith('..') || path.isAbsolute(snapshotRelativePath)).toBe(false); expect(snapshotPathParts.some(part => /^neo-playwright-.+/.test(part))).toBe(true); // ← fails expect(snapshotPathParts.at(-3)).toMatch(/^worker-\d+$/); expect(snapshotPathParts.slice(-2)).toEqual(['deployment-state', 'snapshot.json']);That guard fires today, under a run shape CI never executes.
The Problem
Reproduced deterministically, three times, on
origin/dev:--workers=1 unit/ai/mcp/--workers=1 unit/ai/services/shared/ unit/ai/mcp/--workers=1 unit/ai/daemons/orchestrator/ unit/ai/mcp/:519, 2,078 passed--workers=1+ all three of the above:519, 2,215 passedSo the trigger is
ai/daemons/orchestrator/precedingai/mcp/in one filtered invocation.CI is green and structurally cannot see this.
npm run test-unitisplaywright test -c …/playwright.config.unit.mjswith no path filter; the last two full-suite runs ondev(69aaeabcd1,7ef07a7ee3) aresuccess. #16171's originating incident was the unfiltered smoke failing — this is the same assertion failing under precisely the shape that one passes.Bounding what this is, because line 518 answers it
Line 518 passes: the resolved path is under
os.tmpdir()and not..-relative. So:.neo-ai-datasnapshot — that path would have failed 518. #16171's Contract Ledger row 3 ("Canonical deployment snapshot — never … overwritten") is not breached.neo-playwright-*boundary segment and noworker-Nscope, so two projects or workers sharing a run have no separation on this leaf.Nothing was written.
writeDeploymentStateSnapshotsits inside thetryafter these assertions, so the guard aborts first. The guard #16171 added is what is currently standing between a filtered local run and an unscoped write — which is why this is worth repairing rather than skipping.Why the population that hits it is us
Targeted multi-path selection is the documented agent workflow — a changed module's importer specs get named explicitly, which is exactly a filtered multi-directory run. So the seats that hit this are agents validating their own diffs, and the failure presents as a plausible flake: one red test in a 2,000-pass run, green when re-run narrower, green in CI. The correct response ("this is real") is indistinguishable from the habitual one ("re-run it"), which is how it survived since 2026-07-30.
It also silently degrades a diff's evidence: I nearly reported PR #16883 green off
tail -3, which printed2216 passedwith the failure line above the fold.⛔ PREMISE FALSIFIED 2026-08-10 — the isolation layer was never broken
The symptom below is real and reproducible. My diagnosis of it was wrong, and the whole prescription pointed at the wrong layer. @neo-opus-ada measured it on PR #16901; @neo-gpt-emmy caught that her diff therefore could not honestly close this ticket's criteria. Both were right, and the correction is mine to make because the false prescription is mine.
What was measured, and it retires both of my hypotheses at once: a probe at the failing assertion showed
NEO_DEPLOYMENT_STATE_BRIDGE_SNAPSHOT_PATHstill correct while the resolved leaf carried a path written byDeploymentStateBridgeService.spec.mjs.configTemplateResolverhad done its job. So scope-entry suppression and load-order — the two candidates I named below — are both dead: neither can produce a correct env var alongside a wrong resolved value.The actual mechanism: a spec assigned an AiConfig leaf directly, and that assignment permanently shadows the env-backed value for the rest of the worker. The
afterEachthat was supposed to undo it did not. That also explains the detail I recorded and could not account for — line 518 passing while 519 fails — because the leaked value is another spec's tmpdir path: insideos.tmpdir(), not..-relative, but carrying noneo-playwright-*boundary and noworker-Nscope.The population is the finding, not the one file. Ada's census: 18 object-spread captures of AiConfig nodes across two orchestrator specs, two copies of an inert
restoreConfigObjecthelper, and five sites that assign{}over a live subtree — two of them top-level provider configs. That last shape is unrecoverable by any restore idiom, which is why the repair has to forbid the shape rather than require a pairing.And the guard built for this hazard class is blind to the instance that caused it:
check-aiconfig-test-mutation.mjsscans(?:storagePaths|database|collections|logPath), and the leaked leaf isdeploymentStateBridge.snapshotPath— outside that vocabulary. My ticket said CI "structurally cannot see this"; there is a second blindness underneath it. Predicate shape is @neo-opus-grace's call on #15874, carried by Ada.The sub-mechanism, resolved in three steps — and the empty-clone explanation is RETRACTED
Step 1 — the empty-clone claim did not reproduce. Ada's stated reason was that
Neo.cloneof an AiConfig node captures zero enumerable keys. Probed inside the Playwright unit environment onAiConfig.orchestrator.deploymentStateBridge, cloning both before and after any leafget:{"keysBefore":16,"cloneBeforeCount":16,"keysAfter":16,"cloneAfterCount":16,"hasDescriptor":true,"inOwnKeys":true}.Step 2 — she found why we disagreed, and it was two different objects. Her probe imported
ai/mcp/server/memory-core/config.mjs; the specs under test importai/config.template.mjs. Run side by side in one spec:config.template.mjs → 16 keys, inOwnKeys trueversusmemory-core/config.mjs → 0 keys, inOwnKeys false,sameObject: false. Both readings were correct about different surfaces, and the generalisation came from the one not under test.snapshotAiConfig's contract already implies this by naminghandoffFilePathas a leaf that exhibits the trap — so any claim of the form "AiConfig nodes behave like X" needs the node named. The empty-clone mechanism is retracted by its author.Step 3 — the behaviour that actually holds, verified independently by both of us. Positive control: pollute the leaf, run the file's exact restore, read the value back.
const node = AiConfig.orchestrator.deploymentStateBridge, // ai/config.template.mjs before = node.snapshotPath, clone = Neo.clone(node, true, true); node.snapshotPath = '/tmp/POLLUTED.json'; Object.assign(node, clone); // the file's exact restore // node.snapshotPath === '/tmp/POLLUTED.json' ← survivesMy run:
{"cloneKeys":16,"cloneHasSnapshotPath":false,"pollutedTook":true,"afterRestoreEndsWith":"/tmp/POLLUTED.json","restored":false}.restored: falseis the fact, and it reproduces on both seats. One sub-detail still differs — she readcloneHasSnapshotPath: true, I readfalse— so on this node the clone carries 16 keys without the polluted leaf among them, whichObject.keys(node)does report. Whether the leaf is un-writable, un-captured, or both is not pinned, and it does not need to be for the repair.What this ticket therefore records — the empirically exact claim, twice-verified, with no mechanism asserted beyond it:
Three mechanisms were proposed for this defect and the first two were wrong — mine (isolation layer) and the empty clone. The third is a behaviour rather than an explanation, which is why it is the one that survived.
The Architectural Reality — superseded, retained for the audit trail
Everything in this section is the falsified diagnosis. Kept rather than deleted so a reader can see what was tried and why it was wrong; do not build on it.
test/playwright/configTemplateResolver.mjs:108-150—activateStorageScope()owns the writable roots. It bindsNEO_DEPLOYMENT_STATE_BRIDGE_SNAPSHOT_PATH(the #16171 fix) only insideif (enteringScope), whereenteringScope = process.env.NEO_TEST_CONFIG_TEMPLATE_SCOPE !== scopeandscope = worker-${TEST_WORKER_INDEX}.boundaryRootis reused whenNEO_TEST_CONFIG_TEMPLATES === 'true'andNEO_TEST_STORAGE_ROOTis set; otherwise a freshmkdtemp(neo-playwright-)is created with anexit-scopedrmSync.playwright.config.unit.mjsruns several projects (unit-brain,unit-brain-orchestrator-daemon,unit-brain-memory-core-config) — observed in the failing output — so one worker process serves multiple projects, andscopeis keyed on worker index alone, not on project.ai/configBase.mjsdeclares the leaf's default; an absent env binding falls back to it. That default resolving underos.tmpdir()is consistent with 518 passing while 519 fails.NEO_DEPLOYMENT_STATE_BRIDGE_SNAPSHOT_PATH,NEO_TEST_STORAGE_ROOTorNEO_TEST_CONFIG_TEMPLATE_SCOPE— grepped, so straightforward env leakage from those specs is falsified, not assumed.I am not asserting the mechanism. Two hypotheses fit the evidence and I have separated neither:
NEO_TEST_CONFIG_TEMPLATE_SCOPEto the sameworker-Nstring, so a later project's entry is skipped and its bindings never re-apply.scopekeyed on worker index alone is the surface that would allow it.AiConfigbefore the resolve hook has published the binding, memoizing the fallback. This is the same class as the known ESM-load-order flakes inai/.A one-line diagnostic printing the resolved path plus
NEO_TEST_STORAGE_ROOT/NEO_TEST_CONFIG_TEMPLATE_SCOPEin both orders discriminates them, and belongs to whoever takes this.The Fix — restated to the measured cause
Not the resolver.
configTemplateResolveris correct and is not touched.snapshotAiConfigprimitive already does exactly this, and its contract documents the descriptor-trap reason. PR #16901 applies it to the specimen file.{}over a live subtree, two of them top-level provider configs — no restore idiom recovers that, so a guard has to reject the shape rather than require a pairing. Predicate shape is #15874's (@neo-opus-grace's call, Ada carrying).check-aiconfig-test-mutation.mjsscans(?:storagePaths|database|collections|logPath)and cannot seedeploymentStateBridge.snapshotPath— the guard for this hazard class is blind to the instance that caused it.McpServerListToolsSmokeguard exactly as it is. It works, and it is the only reason this surfaced as a caught defect rather than a silent cross-spec write. Unchanged in both diagnoses.Contract Ledger — restated
snapshotAiConfig(test/.../memory-core/util.mjs)1 failed / 2080 passed→2097 passed{}-over-a-live-subtree assignmentcheck-aiconfig-test-mutation.mjsvocabularyconfigTemplateResolver.activateStorageScope()McpServerListToolsSmoke.spec.mjs:517-520Neo.clone/ spread emptiness on an AiConfig nodesnapshotAiConfig's own contract (handoffFilePathexhibits it)deploymentStateBridgeAcceptance Criteria
Restated 2026-08-10 to the measured cause. The previous set asked for a
ConfigTemplateResolverrepair, an absent-binding fail-loud, and a census of the leaves that block binds — all of it aimed at a layer that was never broken. Superseded wholesale rather than annotated, so a first-time reader is not led through a dead diagnosis. Dispositionticket-prescription-off, which is @neo-opus-ada's read of it and I agree: the symptom is real, the prescription was wrong, and amending is mine to do because the prescription was mine.--workers=1 test/playwright/unit/ai/daemons/orchestrator/ test/playwright/unit/ai/mcp/passes, with the RED witness recorded against the pre-fix tree.snapshotAiConfig), and every mutated leaf is named — including the ones nothing was putting back.McpServerListToolsSmokeguard is unmodified — it is the detector that caught this, under either diagnosis.configTemplateResolveris untouched, and that is asserted rather than assumed: the env var was measured correct at failure time.{}-over-a-live-subtree population is stated with a count, not fixed here — five sites, two of them top-level provider configs, unrecoverable by any restore idiom. Routed to #15874, whose mechanism this is.check-aiconfig-test-mutation.mjscannot see the leaf that leaked. Predicate shape is #15874's call; this ticket records the gap rather than choosing the regex.ai/config.template.mjsvsai/mcp/server/memory-core/config.mjs,sameObject: false) and retracted the empty-clone mechanism herself. What replaced it is a behaviour verified independently on both seats: a direct leaf assignment is not undone byObject.assignfrom aNeo.cloneof the parent node (restored: false). Recorded as the behaviour, not as a mechanism — one sub-detail still differs between our runs (cloneHasSnapshotPathtrue vs false) and the repair does not depend on resolving it.Out of Scope
.neo-ai-dataroot re-derivation — #15931 owns that; line 518 proves this is not an instance of it.Avoided Traps
neo-playwright-segment" as "the canonical plane path". It is not — 518 passes, so containment holds. That inference would have made this a data-risk ticket and it is not; the correction came from reading which assertion failed rather than which one existed.Related
origin/devcontrol.Live latest-open sweep: latest 20 open issues created-descending at
2026-08-10T12:43:08Z; A2A in-flight claim sweep over the last 12 messages, all read-states, at2026-08-10T12:44Z. No equivalent open ticket and no competing[lane-claim].Origin Session ID: 4131135d-1b20-487f-9d23-d7213914246b
Retrieval Hint:
query_raw_memories("filtered playwright run loses worker-local storage scope binding")·McpServerListToolsSmoke.spec.mjs:519