LearnNewsExamplesServices
Frontmatter
id12974
titleMemory-core unit flakes: cross-test identity/graph state bleeds (markRead count + addMessage target validation)
stateClosed
labels
bugaitesting
assigneesneo-gpt
createdAtJun 12, 2026, 10:34 AM
updatedAtJun 12, 2026, 11:51 AM
githubUrlhttps://github.com/neomjs/neo/issues/12974
authorneo-fable
commentsCount0
parentIssuenull
subIssues[]
subIssuesCompleted0
subIssuesTotal0
blockedBy[]
blocking[]
closedAtJun 12, 2026, 11:51 AM

Memory-core unit flakes: cross-test identity/graph state bleeds (markRead count + addMessage target validation)

neo-fable
neo-fable commented on Jun 12, 2026, 10:34 AM

Context

Same CI run as #12973 (PR #12971's unit job): two memory-core specs flaked (failed, then passed on retry) — surfaced by the operator from the logs.

Release classification: post-release — flaky-not-broken; costs retry minutes and erodes suite trust.

The Problem

Two distinct flake sites, one shared class — mutable shared state (graph identities / mailbox receipts) bleeding across tests:

  1. MailboxService.spec.mjs:1155 ("#11029 broadcast markRead updates only the caller delivery receipt"): expected unread 1 for @gpt after the caller-scoped markRead, got 0 — a sibling test's receipt state (or identity binding) leaked into the assertion window (:1203).
  2. WriteSideInvariant.spec.mjs:114 ("addMessage succeeds with a bound agent identity"): addMessage REJECTED '@neo-test-receiver' — "Expected '@' … matching a REGISTERED AgentIdentity graph node" (MailboxService.mjs:108). The test's receiver identity wasn't registered in the graph state the test observed — a registration-ordering / fixture-isolation race: the validation hardened in #10174-family work now requires graph-registered identities, and the spec's setup either registers too late or a parallel spec's teardown removes it.

Both passing on retry = state-order dependent, not logic defects.

The Architectural Reality

  • The memory-core unit specs share a live test database/graph context within a worker; identity registration (AgentIdentity nodes) and delivery receipts are cross-test-visible mutable state.
  • validateMailboxTarget (MailboxService.mjs:108) is strict-by-design (the #10174 anti-spoof lineage) — the fix is test-side isolation, not validation loosening.

The Fix

  1. Both specs get deterministic setup: register the identities they assert against IN the test's own beforeEach (idempotent upsert), and scope receipt assertions to identities no sibling spec touches (unique per-spec identities, e.g. @neo-test-receiver-<specHash>).
  2. If the suite runs these files in parallel workers against one DB: serialize the memory-core project or namespace the test tenant per worker (whichever the existing harness supports cheapest).

Acceptance Criteria

  • 20× repeat-run of the two spec files green without retries (--repeat-each=20 or loop).
  • No validation-layer changes.

Out of Scope

  • #12973 (the deterministic content-fixture break, sibling).
  • Unit tests performing real GitHub API calls (rate/504 weather noise observed in the same logs — separate observation, ticket only if it recurs as a failure rather than noise).

Related

#12973 (same CI run), #10174 / #11029 (the contracts the flaking tests pin), PR #12971.

Sweep note: live latest-open sweep waived under the active GitHub API rate-limit exhaustion; defects born this hour, session-fresh knowledge confirms no duplicate.

Origin Session ID: e605ce21-3668-445c-bc00-45896aa9a092

Retrieval Hint: "memory-core unit flake markRead unread count addMessage registered identity isolation"

tobiu referenced in commit 6f7c86d - "fix(test): isolate memory-core unit identities (#12974) (#12977)" on Jun 12, 2026, 11:51 AM
tobiu closed this issue on Jun 12, 2026, 11:51 AM