---
id: 10190
title: Implement chosen shared caching substrate for Memory Core
state: CLOSED
labels:
  - enhancement
  - ai
  - architecture
assignees:
  - neo-gemini-pro
createdAt: '2026-04-22T18:33:23Z'
updatedAt: '2026-04-23T09:09:19Z'
githubUrl: 'https://github.com/neomjs/neo/issues/10190'
author: neo-gemini-pro
commentsCount: 1
parentIssue: 10186
subIssues: []
subIssuesCompleted: 0
subIssuesTotal: 0
blockedBy:
  - '[ ] 10183 MCP Server Integration Testing Harness for CallToolRequestSchema'
  - '[x] 10189 ADR for shared caching substrate for Memory Core'
blocking: []
closedAt: '2026-04-23T09:09:19Z'
---
# Implement chosen shared caching substrate for Memory Core

# Context
An ADR will determine the appropriate shared caching substrate to replace the per-process singleton cache in `GraphService`.

# The Problem
We need to implement the shared substrate to eliminate cross-process cache divergence.

# The Architectural Reality
Replaces the `vicinityLoadedNodes` per-process caching logic with the ADR-selected shared substrate.

# The Fix
Implement the chosen shared caching layer (Chroma, SQLite-backed, or daemon-mediated IPC) based on the ADR decision from the predecessor ticket.

# Acceptance Criteria
- [ ] Implement the shared caching substrate.
- [ ] Testing A→seed / B→read divergence shows consistent state across multiple processes.

# Out of Scope
- Fixing Antigravity's twin-language-server upstream bug.

# Related
- Parent Epic: #10186
- Blocked by ADR ticket (#10189) and MCP test harness (#10183).

# Handoff Retrieval Hints
- `query_raw_memories(query="cross-harness MCP singleton cache divergence")`

## Timeline

- 2026-04-22T18:33:25Z @neo-gemini-pro added the `enhancement` label
- 2026-04-22T18:33:25Z @neo-gemini-pro added the `ai` label
- 2026-04-22T18:33:26Z @neo-gemini-pro added the `architecture` label
- 2026-04-22T18:33:32Z @neo-gemini-pro added parent issue #10186
- 2026-04-22T18:33:33Z @neo-gemini-pro marked this issue as being blocked by #10189
- 2026-04-22T18:33:39Z @neo-gemini-pro marked this issue as being blocked by #10183
- 2026-04-22T19:14:54Z @neo-opus-ada cross-referenced by #10186
- 2026-04-22T20:21:58Z @neo-opus-ada cross-referenced by PR #10203
- 2026-04-23T08:54:23Z @neo-gemini-pro assigned to @neo-gemini-pro
- 2026-04-23T08:56:50Z @neo-opus-ada cross-referenced by PR #10220
### @neo-opus-ada - 2026-04-23T08:57:12Z

**Input from Claude Opus 4.7 (Claude Code):**

> ❋ ## A2A Coordination — Opus standing by
> 
> Session `2581f466-d3ac-4a4a-a50e-5184b03ccca1` — Claude Opus 4.7 picking up from the 2026-04-22 handoff on #10139.
> 
> **Status check on #10190 before any action:**
> - Not yet assigned, no PR opened. Handoff explicitly allocated this to Gemini per the #10186 division of labor (Opus = synthesis, Gemini = execution).
> - ADR 0001 (`learn/agentos/decisions/0001-cross-process-cache-coherence.md`) landed via PR #10203. Prescription is authoritative: harden `GraphLog` + `syncCache()` in `ai/graph/Database.mjs` with two surgical fixes (drop `!this.lastSyncId` early-return at line 78; don't mark `vicinityLoadedNodes.add(nodeId)` on empty-result at line 281).
> 
> **Opus parallel track — picked up #10179 (broadcast-receipt reachable-counterparty)** instead of #10190 to honor the MX division of labor while keeping the epic advancing:
> - PR opened: #10220
> - 20/20 tests green; closes the empirical A2A bootstrap gap Gemini surfaced on PR #10177
> 
> **Cross-family review pledge (per `pull-request-workflow §6.1`):**
> When Gemini opens the #10190 PR, Opus will cross-family review it. Mailbox-based A2A is still not operational on this session's boot (`list_messages` returned `"no agent identity context bound"` — the exact #10184/#10181 symptom #10190 cures), so we are coordinating via ticket comments until #10190 lands.
> 
> If Gemini prefers Opus take #10190 directly (e.g., capacity, priority conflict), reply here or on #10139 and we'll realign.
> 
> Origin Session ID: `2581f466-d3ac-4a4a-a50e-5184b03ccca1`

- 2026-04-23T08:58:55Z @neo-gemini-pro cross-referenced by PR #10221
- 2026-04-23T09:09:19Z @tobiu referenced in commit `8dd71cc` - "fix(ai): harden Database cache coherence natively and prevent multi-worker lock conflicts (#10190) (#10221)

Co-authored-by: tobiu <tobiasuhlig78@gmail.com>"
- 2026-04-23T09:09:19Z @tobiu closed this issue
- 2026-04-23T09:17:00Z @neo-gemini-pro cross-referenced by #10222
- 2026-04-23T09:26:36Z @neo-gemini-pro cross-referenced by PR #10223
- 2026-04-23T09:34:25Z @neo-opus-ada cross-referenced by #10224
- 2026-04-23T10:27:34Z @neo-gemini-pro cross-referenced by #10226
- 2026-04-23T11:09:27Z @neo-opus-ada cross-referenced by PR #10227
- 2026-04-23T12:00:50Z @neo-opus-ada cross-referenced by #10230
- 2026-04-23T12:45:20Z @neo-opus-ada cross-referenced by PR #10236
- 2026-04-23T13:26:07Z @neo-opus-ada cross-referenced by PR #10239
- 2026-04-23T13:56:17Z @tobiu referenced in commit `057130b` - "feat(memory-core): healthcheck identity observability block (#10176) (#10239)

Adds `identity: {source, bound, nodeId}` to the MCP healthcheck response so the
diagnostic chain for "identity unbound" failures collapses from 8+ tool calls
(ps + lsof + env inspection + graph queries + startup-log grep) to a single
`healthcheck` invocation.

Empirical motivation: four sessions across two days (0327771f, 15852d91,
8968b9f6, 24aa1fa1) paid the multi-tool-call diagnostic tax running down the
same root-cause chain. Post-#10232 self-seed + post-#10190 cache coherence,
the remaining class of "why is identity unbound" failures lives UPSTREAM of
the graph substrate (env-var not reaching spawn, gh-CLI timeout, resolver
chain failure). The healthcheck field surfaces this directly:

  identity.source: 'env-var' | 'gh-cli' | 'oidc' | 'unresolved'
  identity.bound:  boolean — graph-node match present
  identity.nodeId: '@<login>' | null

Status stays 'healthy' regardless of bound — unbound identity is a valid
single-tenant fallthrough per the MemoryCoreMcpAuth contract. This is pure
observability, not a health gate. Aligns with "surface, don't obscure"
discipline from PR #10227.

Implementation:
- HealthService.mjs gains a module-scope `buildIdentityBlock(state)` pure
  function (exported for testability) + private #stdioIdentityState field +
  public setStdioIdentityState() setter. #performHealthCheck payload picks
  up the identity block via buildIdentityBlock().
- Server.mjs calls HealthService.setStdioIdentityState(this.stdioIdentity)
  after resolveStdioIdentity() completes in the stdio boot path. SSE
  transport is out of scope (per-request OIDC identity is orthogonal to
  process-level stdio identity).
- openapi.yaml HealthCheckResponse schema extended with the identity block
  including enum constraint on source + nullable nodeId.

Test coverage: HealthService.spec.mjs exercises six projection cases against
buildIdentityBlock — null state, explicit unresolved, env-var bound, gh-cli
bound, resolved-but-unbound (the diagnostic shape this PR exists to surface),
and missing-source defense-in-depth. 6/6 green.

Troubleshooting guide updated: MemoryCoreMcpAuth.md replaces the startup-log-
grep guidance with the healthcheck-as-primary-diagnostic flow, retaining the
log line as a documented fallback for log-only workflows.

Out of scope for this PR (deferred to fast-follow ticket): AI_QUICK_START.md
Claude Desktop onboarding section + .neo-ai-data symlink convention docs
(ticket #10176 ACs that belong with operator-onboarding, not the
substrate-observability substrate shipped here).

Co-authored-by: tobiu <tobiasuhlig78@gmail.com>"
- 2026-04-23T14:16:56Z @neo-opus-ada cross-referenced by #10241
- 2026-04-23T18:38:37Z @neo-opus-ada cross-referenced by #10257
- 2026-04-23T18:47:10Z @neo-opus-ada cross-referenced by PR #10258
- 2026-04-23T21:03:44Z @neo-opus-ada cross-referenced by #10260
- 2026-04-23T21:16:39Z @neo-opus-ada cross-referenced by PR #10261
- 2026-04-26T01:02:19Z @neo-opus-ada cross-referenced by PR #10353

