LearnNewsExamplesServices
Frontmatter
id16060
titleadd_memory reports success without disclosing that visibility is deferred, so a read-back reads as data loss
stateClosed
labels
enhancementai
assigneesneo-opus-vega
createdAtJul 27, 2026, 9:38 PM
updatedAtJul 28, 2026, 1:09 PM
githubUrlhttps://github.com/neomjs/neo/issues/16060
authorneo-opus-vega
commentsCount1
parentIssuenull
subIssues[]
subIssuesCompleted0
subIssuesTotal0
contentTrust
projected
quarantined0
signals[]
blockedBy[]
blocking[]
closedAtJul 28, 2026, 1:09 PM

add_memory reports success without disclosing that visibility is deferred, so a read-back reads as data loss

Closed Backlog/active-chunk-10 enhancementai
neo-opus-vega
neo-opus-vega commented on Jul 27, 2026, 9:38 PM

Context

Observed on a live deployment, where it cost a team three sessions and produced a wrong recorded diagnosis of their own infrastructure.

add_memory returns:

{ "id": "…", "sessionId": "…", "timestamp": "…", "message": "Memory successfully added", "mailbox": {} }

The write is durable at that point, but the memory is not yet queryable — the write-ahead log drains asynchronously. Nothing in the response says so.

The Problem

A user wrote a memory, immediately read back, saw nothing, and concluded the write had silently no-opped. They retried twice more over 50 minutes, each time reaching the same conclusion. Their own session summaries now record that reasoning verbatim:

  • "Smoke testing memory core write path after embedding failure"
  • "Investigating embedding provider false-success through smoke-test retry"
  • "Smoke Test Verification of Memory Write/Read Stability"

All three writes had landed. All three sessions were summarized correctly. Semantic search over them returns real distances, so embeddings were computed throughout. The infrastructure was healthy for the entire episode; the API's silence about drain latency manufactured a phantom outage — and the phantom is now the durable record of what happened.

That is the expensive part: a false diagnosis persisted into the corpus, where the next reader will find "embedding provider false-success" as recorded history.

This is not a regression. add_memory has never disclosed deferred visibility.

The Architectural Reality

"Memory successfully added" is true and, in context, misleading. It answers "was it accepted?" while the caller is asking "can I rely on it?" — and an immediate read-back is the natural way to check the latter. Async drain is the correct design; the response contract simply does not model the gap the design creates.

The failure direction matters: a caller who assumes immediate visibility concludes data loss, which is the most alarming possible wrong conclusion and the one most likely to trigger a redeploy — which, per #16055, destroys the corpus for real.

Note also that the deployment exposes no read-side signal a caller could use instead: there is no drain-status tool, so even a caller who knew about the lag has nothing to poll.

The Fix (one PR)

  • Have the add_memory response state that queryability is deferred, and expose the signal a caller can act on — pending drain depth, an expected-visible-by hint, or both.
  • The tool description should say plainly that an immediate read-back may not return the write, and what to do instead.
  • Expose drain state as something observable, so "is my write visible yet?" is answerable rather than inferable.

Acceptance Criteria

  • The add_memory response distinguishes accepted from queryable, so a success cannot be read as immediate visibility.
  • The response carries an actionable signal — pending depth and/or expected-visible-by — not merely a prose caveat.
  • Drain state is observable through a tool, so a caller can confirm visibility rather than guess. Without this, the disclosure just relocates the uncertainty.
  • The tool description states the read-back caveat, since the affected caller was reading the description, not the source.
  • A fixture asserts the accepted-vs-queryable distinction survives, so a future refactor cannot silently collapse them back into one boolean.
  • The wording must not imply failure or partial success — the write is durable, and over-correcting into an alarming response trades one wrong conclusion for another.

Out of Scope

  • Changing drain latency or making writes synchronous — async drain is correct.
  • Session summarization, which behaved correctly throughout.

Related

  • #16055 (redeploy data survivability) — the escalation path this misdiagnosis leads to
  • #16056 (failures must record their cause) — sibling: both are cases where the system knows something the operator cannot see