LearnNewsExamplesServices
Frontmatter
id11181
titleRestore shared summary visibility for swarm identities
stateClosed
labels
bugairegressionarchitecturemodel-experience
assigneesneo-gpt
createdAtMay 11, 2026, 6:55 AM
updatedAtMay 12, 2026, 4:08 AM
githubUrlhttps://github.com/neomjs/neo/issues/11181
authorneo-gpt
commentsCount0
parentIssuenull
subIssues[]
subIssuesCompleted0
subIssuesTotal0
blockedBy[]
blocking[]
closedAtMay 11, 2026, 1:49 PM

Restore shared summary visibility for swarm identities

Closedbugairegressionarchitecturemodel-experience
neo-gpt
neo-gpt commented on May 11, 2026, 6:55 AM

Context

Operator input: the named GitHub accounts for the current swarm are relatively new. Most historical Memory Core items predate those IDs and were produced by older Gemini-era runs over roughly 1-1.5 years. The swarm decision was to store those historical records as shared, not as one current agent's private tenant data.

Current symptom: @neo-gpt has restored Memory Core substrate available, but get_all_summaries({limit: 5}) returns zero summaries even though Memory Core health reports hundreds of summaries.

Verify-Before-Assert Footprint

Empirical checks run before filing:

  • Memory Core healthcheck: memories.count = 10391, summaries.count = 980.
  • Graph SQLite count: Nodes = 24266, Edges = 19454, total node+edge artifacts = 43720.
  • get_all_summaries({limit: 1}): total = 0, summaries = [] for @neo-gpt.
  • Direct Chroma SQLite metadata inspection for neo-agent-sessions:
    • total = 980
    • with userId = 46
    • userId=shared = 0
    • userId=neo-gpt = 0
    • missing userId = 934
    • userId distribution: only neo-gemini-3-1-pro = 46
    • participatingAgents contains GPT in 33 summaries, but current @neo-gpt visibility filter sees 0.

Problem

Summary visibility is identity-filtered too narrowly after restore / historical migration:

  • SummaryService.listSummaries() filters identity-bound reads to userId = current OR userId = shared.
  • SummaryService.querySummaries() applies the same current OR shared tenant filter to Chroma queries.
  • The restored historical summary collection has no shared summary rows and no neo-gpt summary rows.
  • 934 restored summary rows lack userId entirely, which makes them invisible to any read path that adds a userId where-clause.
  • 24 GPT-participating sample summaries are tagged neo-gemini-3-1-pro, which points at summarizer-owned metadata rather than participant-visible or swarm-shared semantics.

This creates a mismatch: the system reports 980 restored summaries, but the @neo-gpt read path returns zero, even for summaries where participatingAgents includes GPT.

Code Anchors

  • ai/services/memory-core/SummaryService.mjs
    • listSummaries() adds userId=current OR shared when a request identity exists.
    • querySummaries() builds the same tenant filter for Chroma summary queries.
  • ai/services/memory-core/SessionService.mjs
    • summarizeSession() tags generated summary metadata with RequestContextService.getUserId() when present. This records the summarizer identity, not necessarily summary visibility semantics.
  • ai/mcp/server/shared/services/RequestContextService.mjs
    • SHARED_USER_ID = 'shared' is the existing shared-commons sentinel.
  • ai/scripts/backfillChromaSharedUserId.mjs
    • Existing one-shot migration concept for legacy Chroma records missing userId, but the post-restore state shows the summary collection is still effectively unbackfilled from @neo-gpt's point of view.

Contract Ledger Matrix

Surface Current contract Broken case Target contract
get_all_summaries Return summaries visible to current identity or shared Restored legacy summaries missing userId are invisible Historical legacy summaries agreed as shared are visible to all three core swarm identities
query_summaries Chroma where filter uses current identity or shared No shared rows exist after restore, so GPT gets zero Same visibility semantics as get_all_summaries
Summary metadata writes Generated summary gets current request userId Multi-agent session summarized by Gemini becomes Gemini-only even if GPT participated Core-swarm shared summaries use shared/participant-safe visibility, not accidental summarizer ownership
Restore/backfill tooling Legacy Chroma records can be tagged shared by script Post-restore canonical data still has 934 summary rows without userId Restore or post-restore validation detects and repairs missing summary userId metadata

Acceptance Criteria

  1. Add a regression test or fixture that reproduces the current state: summary collection contains restored rows without userId; identity-bound @neo-gpt reads do not return zero after the fix.
  2. Ensure historical summary rows that predate current GitHub identities and lack userId are treated as shared by an idempotent migration/backfill or by a documented restore hook.
  3. Ensure get_all_summaries({limit: 5}) for @neo-gpt returns non-empty results after the migration/fix on the restored canonical data.
  4. Ensure query_summaries(...) follows the same visibility semantics as get_all_summaries.
  5. Add coverage for the summarizer-vs-participant ambiguity: a summary generated by one core swarm identity for a multi-agent session must not become private to only the summarizer if the intended contract is shared swarm context.
  6. Add a diagnostic surface to dry-run/healthcheck/restore validation that reports summary visibility counters: total, missing userId, shared, per-agent userId, and rows with participatingAgents that are not visible to that participant.
  7. Do not solve this by removing tenant filtering globally. The fix must preserve tenant isolation for non-shared records and only widen visibility through the existing shared contract or a documented core-swarm participant contract.

Out of Scope

  • A broad privacy model redesign for all Memory Core tenants.
  • Destructive re-restore of Chroma or graph data.
  • Raw-memory visibility changes unless the same diagnostic proves raw memories have the same restored historical userId mismatch.

Related

  • #10016 - Multi-Tenant Identity & Data Privacy epic.
  • #10556 / PR #10567 - original legacy Chroma userId backfill and additive tenant read filter.
  • #10813 - summary boot-context stale/empty follow-up.
  • #11151 - restore hardening context that made this restored-state regression observable.

Handoff Retrieval Hints

  • summary userId shared Chroma visibility get_all_summaries zero
  • participatingAgents neo-gpt hidden summaries
  • backfillChromaSharedUserId restored summaries missing userId

Origin session: 22713fa8-23d2-4b31-918b-6e2f48d69c06

tobiu referenced in commit 79416b6 - "fix(memory-core): share core swarm summaries (#11181) (#11200) on May 11, 2026, 1:49 PM
tobiu closed this issue on May 11, 2026, 1:49 PM