Context
Carved from #17596 rows 4–5, following that ticket's own pattern of moving a shared cause to its own leaf (#17598 precedent) so the fix carries an honest close target rather than waiting on the other fourteen rows.
#17596's body records these rows as "the specs are correct and are reporting a real product defect." That is wrong — my own sentence, corrected there (comment). The possession hand-off works. The witness is holding the wrong object.
The Problem
test/playwright/e2e/agentos/FleetMailboxTabNL.spec.mjs:75 resolves the pane by class alone and takes the first match:
const [mounted] = await app.queryComponent({className: 'AgentOS.view.fleet.mailbox.Container'}, ['record', 'snapshot', 'id']);
expect(mounted?.properties?.record?.agentId, 'the pane record follows the drill').toBe(expectedAgentId);Measured during the drill on dev at 2026-08-23T16:51Z, that query returns two instances:
id agentId mounted parentId
neo-fm-mailbox-pane-1 null false neo-fm-operator-mailbox-1
neo-fm-mailbox-pane-2 neo-opus-ada true neo-container-103
Neither is an orphan, which was checked before concluding — a leaked instance and two legitimate instances are different defects with opposite owners:
pane-1 belongs to the Operator Mailbox (neo-fm-operator-mailbox-1), a different feature surface, and is not mounted. It correctly holds no drilled record because it is not the AgentDetail tab.
pane-2 is the AgentDetail Mailbox tab, mounted, holding exactly the record the drill selected.
AgentOS.view.fleet.mailbox.Container is used by two surfaces. The spec assumes the class identifies one.
Row 5 (:202) is the same seam, not a second defect. After that query the spec injects its snapshot into mounted.properties.id — i.e. into pane-1, the unmounted Operator Mailbox pane. The rows therefore never render in the AgentDetail tab and toHaveCount(50) receives 0. #17596 predicted one seam for both rows and was right about that; only the owner was wrong.
The Architectural Reality
test/playwright/e2e/agentos/FleetMailboxTabNL.spec.mjs:75 — the className-only resolution, and :~90 — the injection that inherits it.
AgentOS.view.fleet.mailbox.Container — shared by the AgentDetail Mailbox tab and the Operator Mailbox.
- The query surface (
queryComponent) returns every match; ordering across two independently-created instances is not a contract the spec may lean on.
A className query is only an identity when the class is unique. This one stopped being unique and nothing told the spec, because a first-match query has no failure mode — it silently returns something.
The Fix
Resolve the AgentDetail tab's pane specifically rather than by bare class. Cheapest ordering:
- Filter on
mounted === true — the Operator Mailbox instance is unmounted during this journey.
- Or scope through the AgentDetail pane / its known parent, which states the intent rather than a property that happens to discriminate today.
Option 2 is preferred if the parent is reachable: mounted is a symptom of being the right pane, not a definition, and a future journey that mounts both would silently re-break option 1.
Acceptance Criteria
Out of Scope
- The other fifteen #17596 rows. Unclassified there on purpose; a confident guess is worse than the gap.
- The
DemoB* cluster — read against #17578 first.
- Visual-baseline (
toHaveScreenshot) failures — excluded by #17596.
- Adding e2e to CI — #17596 notes it as a separate decision, and this leaf does not change that argument.
- Renaming or splitting
mailbox.Container. Two surfaces sharing a component is legitimate; the spec's assumption is the defect.
Avoided Traps
- Calling it a product defect from the error text.
Received: undefined reads identically whether the product failed to populate an instance or the witness is holding the wrong one. Two readers (myself and @neo-gpt) classified it from failure text and both landed on the wrong owner — the instance census is what separated them.
- Assuming the second instance is a leak. It is a legitimately-mounted-elsewhere Operator Mailbox pane; "fixing" it by destroying it would break that surface.
- Fixing by
mounted alone without saying why. It discriminates today because one pane happens to be unmounted. That is a coincidence the spec would be relying on, so the AC asks for identity.
Related
#17596 (parent census, and the corrected classification) · #17598 / PR #17599 (the carve precedent) · #17593 (the selection PR that moved the surface after the census, changing the expected agent from neo-gemini-pro to neo-opus-ada while the failure shape held)
Live latest-open sweep: latest 12 open read at 2026-08-23T16:52:13Z plus a state:all search for mailbox/pane/instance-query scope — nearest are #17596 (the parent) and #17560 (CLOSED, unrelated folder topology). No equivalent. A2A in-flight claim sweep: 12 most recent messages, window 16:08–16:47Z; active claims are #17419 (@neo-gpt-emmy), #17377/#17621 (@neo-preview); none overlap.
Origin Session ID: eb671e6e-ca17-4a53-8069-64fd5885ce84
Retrieval Hint: FleetMailboxTabNL agentId undefined; two mailbox.Container instances neo-fm-mailbox-pane-1 unmounted Operator Mailbox vs pane-2 AgentDetail tab; className-only queryComponent first match; snapshot injected into wrong pane so toHaveCount 0
Context
Carved from #17596 rows 4–5, following that ticket's own pattern of moving a shared cause to its own leaf (#17598 precedent) so the fix carries an honest close target rather than waiting on the other fourteen rows.
#17596's body records these rows as "the specs are correct and are reporting a real product defect." That is wrong — my own sentence, corrected there (comment). The possession hand-off works. The witness is holding the wrong object.
The Problem
test/playwright/e2e/agentos/FleetMailboxTabNL.spec.mjs:75resolves the pane by class alone and takes the first match:const [mounted] = await app.queryComponent({className: 'AgentOS.view.fleet.mailbox.Container'}, ['record', 'snapshot', 'id']); expect(mounted?.properties?.record?.agentId, 'the pane record follows the drill').toBe(expectedAgentId);Measured during the drill on
devat 2026-08-23T16:51Z, that query returns two instances:Neither is an orphan, which was checked before concluding — a leaked instance and two legitimate instances are different defects with opposite owners:
pane-1belongs to the Operator Mailbox (neo-fm-operator-mailbox-1), a different feature surface, and is not mounted. It correctly holds no drilled record because it is not the AgentDetail tab.pane-2is the AgentDetail Mailbox tab, mounted, holding exactly the record the drill selected.AgentOS.view.fleet.mailbox.Containeris used by two surfaces. The spec assumes the class identifies one.Row 5 (
:202) is the same seam, not a second defect. After that query the spec injects its snapshot intomounted.properties.id— i.e. intopane-1, the unmounted Operator Mailbox pane. The rows therefore never render in the AgentDetail tab andtoHaveCount(50)receives0. #17596 predicted one seam for both rows and was right about that; only the owner was wrong.The Architectural Reality
test/playwright/e2e/agentos/FleetMailboxTabNL.spec.mjs:75— the className-only resolution, and:~90— the injection that inherits it.AgentOS.view.fleet.mailbox.Container— shared by the AgentDetail Mailbox tab and the Operator Mailbox.queryComponent) returns every match; ordering across two independently-created instances is not a contract the spec may lean on.A className query is only an identity when the class is unique. This one stopped being unique and nothing told the spec, because a first-match query has no failure mode — it silently returns something.
The Fix
Resolve the AgentDetail tab's pane specifically rather than by bare class. Cheapest ordering:
mounted === true— the Operator Mailbox instance is unmounted during this journey.Option 2 is preferred if the parent is reachable:
mountedis a symptom of being the right pane, not a definition, and a future journey that mounts both would silently re-break option 1.Acceptance Criteria
FleetMailboxTabNL:23and:202pass ondev, and the pane they assert against is the AgentDetail tab's instance, established by identity rather than by list position.parentId/identity is enough — without it the fix is indistinguishable from the ordering having changed in our favour.queryComponentordering, asserted by intent rather than by the value that happens to sort first.Out of Scope
DemoB*cluster — read against #17578 first.toHaveScreenshot) failures — excluded by #17596.mailbox.Container. Two surfaces sharing a component is legitimate; the spec's assumption is the defect.Avoided Traps
Received: undefinedreads identically whether the product failed to populate an instance or the witness is holding the wrong one. Two readers (myself and @neo-gpt) classified it from failure text and both landed on the wrong owner — the instance census is what separated them.mountedalone without saying why. It discriminates today because one pane happens to be unmounted. That is a coincidence the spec would be relying on, so the AC asks for identity.Related
#17596 (parent census, and the corrected classification) · #17598 / PR #17599 (the carve precedent) · #17593 (the selection PR that moved the surface after the census, changing the expected agent from
neo-gemini-protoneo-opus-adawhile the failure shape held)Live latest-open sweep: latest 12 open read at 2026-08-23T16:52:13Z plus a
state:allsearch for mailbox/pane/instance-query scope — nearest are #17596 (the parent) and #17560 (CLOSED, unrelated folder topology). No equivalent. A2A in-flight claim sweep: 12 most recent messages, window 16:08–16:47Z; active claims are #17419 (@neo-gpt-emmy), #17377/#17621 (@neo-preview); none overlap.Origin Session ID: eb671e6e-ca17-4a53-8069-64fd5885ce84
Retrieval Hint:
FleetMailboxTabNL agentId undefined; two mailbox.Container instances neo-fm-mailbox-pane-1 unmounted Operator Mailbox vs pane-2 AgentDetail tab; className-only queryComponent first match; snapshot injected into wrong pane so toHaveCount 0