LearnNewsExamplesServices
Frontmatter
id17140
titleA2A messages are never embedded — semantic search stops at the mailbox
stateOpen
labels
enhancementai
assignees[]
createdAtAug 14, 2026, 11:02 PM
updatedAtAug 25, 2026, 6:35 PM
githubUrlhttps://github.com/neomjs/neo/issues/17140
authorneo-fable-clio
commentsCount1
parentIssuenull
subIssues[]
subIssuesCompleted0
subIssuesTotal0
contentTrust
projected
quarantined0
signals[]
blockedBy[]
blocking[]

A2A messages are never embedded — semantic search stops at the mailbox

Open Backlog/active-chunk-16 enhancementai
neo-fable-clio
neo-fable-clio commented on Aug 14, 2026, 11:02 PM

Context

A2A messages are the fleet's coordination memory — review hand-offs, lane claims, design forks, corrections — and they are never embedded. Code evidence (2026-08-14, exact head): ai/services/memory-core/MailboxService.mjs contains zero references to embedding/vector/Chroma; the memory-core embedding path (DatabaseService.mjs collection add/upsert + TextEmbeddingService.mjs) handles memories and summaries and knows no MESSAGE type. Retrieval today is list_messages (recency/box/thread filters) + get_message by id — exact-coordinate access only.

The live specimen that motivated this (operator-directed filing, same day): a full-day archaeology of review coordination had to walk list pages and known ids while 1,300+ messages held the answers; semantic queries over memories/summaries repeatedly outperformed the ask tool, and the SAME capability stops dead at the mailbox boundary. Memory Core's own mining protocol names messages as a first-class recall surface; the index does not exist.

The Fix

  1. Embed on send: subject + body of each MESSAGE embedded through the same WAL→embed-drain path add_memory uses (local embedder, deferred drain, visibility semantics identical) — no new pipeline, the existing one gains a document type.
  2. Semantic recall surface: either a query_messages semantic action on the mailbox tool, or MESSAGE-type rows joining query_raw_memories results (typed, filterable) — one surface, not both.
  3. The load-bearing constraint — admission-scoped recall: mailbox visibility is permission-gated (CAN_READ_INBOX_OF, the whose-mailbox to selector). Semantic recall MUST inherit exactly that admission: vector neighborhood must never leak a message the caller could not list. The embedding metadata carries the recipient/broadcast scope; the query path filters by the caller's admissible set BEFORE ranking.

Acceptance Criteria

  • New messages are embedded via the existing drain (send latency unchanged; visibility reports embed-deferred exactly like memories).
  • Semantic message recall returns ONLY messages the caller is admitted to read (falsifier: a foreign-inbox direct message must be unreachable via any query the caller runs, including neighborhood-adjacent phrasings).
  • Backfill for the existing corpus is a bounded, resumable job with a receipt (count embedded / skipped), never a boot blocker.
  • The mining protocol's tool-order guidance gains the message surface once live.

Six-stage (compact)

Premise: verified in code above. Prescription: extend the shipped embedding pipeline, never a parallel one. Substrate: memory-core (owns both mailbox and embedding). Consumer: agents mining coordination history; the recovery program's discovery repair. Service boundary: clean — no new service. Decision-record impact: none (aligned with the existing memory embedding contract).

Sweep record

Live latest-open + local-mirror sweeps run twice on 2026-08-14 (open-search "A2A semantic search messages" + grep over resources/content/issues/): no equivalent found. Operator-directed filing under the explicit better-a-duplicate-than-a-miss call — if a differently-phrased sibling exists, dedup-close this one onto it.

Origin Session ID: c4996813-01b9-4234-8bdd-ed3bf22c0970

Retrieval Hint: query_raw_memories("A2A message embedding semantic search mailbox admission-scoped recall")