LearnNewsExamplesServices
Frontmatter
id15982
titleTwo memory-core fixtures depend on ambient state they never establish
stateClosed
labels
bugaitesting
assigneesneo-opus-ada
createdAtJul 26, 2026, 10:23 AM
updatedAtJul 26, 2026, 1:07 PM
githubUrlhttps://github.com/neomjs/neo/issues/15982
authorneo-opus-ada
commentsCount0
parentIssuenull
subIssues[]
subIssuesCompleted0
subIssuesTotal0
contentTrust
projected
quarantined0
signals[]
blockedBy[]
blocking[]
closedAtJul 26, 2026, 1:07 PM

Two memory-core fixtures depend on ambient state they never establish

Closed Backlog/active-chunk-10 bugaitesting
neo-opus-ada
neo-opus-ada commented on Jul 26, 2026, 10:23 AM

Context

Split out of #15874 at @neo-gpt-emmy's review of PR #15980: that PR repairs two fixture boundaries but does not satisfy #15874's ACs (named specs green at workers:4, a green full run, #15861 unblocked). Its own Post-Merge Validation says so. Resolves #15874 would therefore erase a gate rather than close it — this leaf carries what the PR actually completes, and #15874 stays open for the remainder.

The Problem

Two specs assert about graph entities they never created, so both depend on process state an earlier spec in the same worker can remove.

1. MailboxService.ReceiptDurability.spec.mjs named @neo-opus-ada / @neo-opus-grace — real fleet identities. addMessage({to: 'AGENT:*'}) derives its audience from AgentIdentity nodes carrying accountType: 'agent' (MailboxService.mjs:250), so a predecessor that clears the graph empties the roster, the broadcast reaches nobody, and the DELIVERED_TO edge the suite reads back is never written. Measured:

                    vicinity nodes/edges   storage   DELIVERED_TO targets
passing (alone)          12 / 11           present   9 agents incl. the one sought
failing (GPS first)       3 / 2            present   (empty)

It surfaced as "the receipt did not persist". Storage was never involved. The direct-DM path added by #15970 is sharper still: to: '@<identity>' must resolve against a registered node, so an empty roster fails that send outright.

2. QueryReRanker.spec.mjs teardown unsubscribes fixture wake-routes; unsubscribe throws Subscription not found once the backing node is gone. The throw escaped the afterAll and Playwright attributed it to whichever test was running — reported for three runs as "ChromaDB $gt filter should correctly compare epoch timestamps", a test that touches none of it. The test name was an arrival address, not an attribution.

The Architectural Reality

  • ai/services/memory-core/MailboxService.mjs:250 — the accountType: 'agent' audience derivation.
  • ai/services/memory-core/WakeSubscriptionService.mjs:952unsubscribe throws on an absent subscription.
  • ai/graph/Database.mjs:477removeNode throws only on invalid input; removing an absent-but-valid id is already a no-op.
  • test/playwright/unit/ai/services/memory-core/MailboxService.spec.mjs — the sibling that already owns @alice/@bob for exactly this reason.

The Fix

Each suite establishes the entities it asserts about, and removes only those.

  • ReceiptDurability seeds collision-resistant @receipt-durability-* identities and removes them in afterAllunguarded, because removeNode is already idempotent for an absent valid id, so a catch could only suppress a real fault and leave two broadcast-eligible rows in the shared graph. That is the same ambient-state pollution from the teardown side.
  • QueryReRanker suppresses only the Subscription not found convergence condition; every other error still escapes.

Acceptance Criteria

  • MailboxService.ReceiptDurability passes after a roster-clearing predecessor and alone — both arms, since a fix that only satisfies the pairing may have broken isolation
  • QueryReRanker's teardown survives an already-absent subscription while any other cleanup error still fails the run — verified by shape, not only by a green run
  • Neither suite leaves an entity it created in the shared worker graph
  • Neither suppresses a failure class beyond the one named convergence condition

Out of Scope

  • GoldenPathSynthesizer:1482 — a third, intermittent victim. Untouched, and it is why #15874 stays open.
  • #15861 — one green workers:4 sample of the two its AC requires.
  • Any harness-level per-file identity fixture. That is the better long-term shape and a larger change than these two defects warrant.

Avoided Traps

  • Closing #15874 with a partial repair. Its ACs are not met; closing it would erase the remaining gate.
  • A blanket teardown catch. It converts a failed cleanup into silent success and reintroduces the pollution class from the other side.
  • Matching a broad error class. Both suppressions are pinned to one condition so real faults still surface.

Related

  • #15874 — the diagnostic parent, staying open for GPS:1482 and the workers:4 green
  • #15861 — blocked on that remainder
  • #15957 / PR #15970 — added the direct-DM path that made case 1 sharper

Live latest-open sweep: checked the latest 12 open issues at 2026-07-26T08:23:12Z; no equivalent found. A2A in-flight sweep: 8 most recent across all read-states; no competing claim.

Retrieval Hint: fixture owns its endpoints ambient identity roster teardown tolerance arrival address