Context
The Knowledge Base MCP surface is again in the failure shape previously narrowed in #12944: the canonical Chroma daemon is reachable, Memory Core is healthy against the same unified store, but the KB MCP runtime reports collections.knowledgeBase: null and gates KB read tools.
Live evidence from 2026-06-18T09:19Z-09:23Z:
mcp__neo_mjs_memory_core.healthcheck() returned status: "healthy", database.process.running: false, database.connection.connected: true, and collection counts for neo-agent-memory and neo-agent-sessions.
mcp__neo_mjs_knowledge_base.healthcheck() returned status: "unhealthy", database.process.running: false, database.connection.connected: true, collections.knowledgeBase: null, and details: ["Failed to access collections: The requested resource could not be found"].
mcp__neo_mjs_knowledge_base.list_documents({limit:1}) and ask_knowledge_base(...) both failed through the health gate with the same missing-collection detail.
This ticket deliberately does not restore or investigate the KB corpus itself. That is a separate follow-up lane. This ticket targets the durable MCP/runtime contract gap exposed when a long-lived KB MCP process holds a stale or operation-failing collection handle under the unified Chroma topology.
Release classification: boardless — Agent OS hardening, not a v13 release-blocker.
The Problem
The KB MCP health/gate path collapses several states into unhealthy and has no self-healing path for a successfully resolved collection handle that later fails on an operation:
ai/services/knowledge-base/HealthService.mjs:202-204 resolves the KB collection and then calls count().
ai/services/knowledge-base/HealthService.mjs:219-223 catches count()/collection operation errors and returns Failed to access collections, but it does not invalidate the cached KB collection handle or retry once.
ai/services/knowledge-base/HealthService.mjs:315-324 turns collection errors or missing collection state into unhealthy before embedding/provider readiness is checked, so features.embedding:false can be a misleading short-circuit artifact.
ai/services/knowledge-base/HealthService.mjs:448-455 rejects every non-exempt KB tool unless the whole healthcheck is healthy.
ai/mcp/server/knowledge-base/Server.mjs:75-77 only exempts healthcheck and list_agent_faqs; manage_knowledge_base is health-gated, so the MCP surface can block the likely recovery path.
ai/mcp/server/knowledge-base/Server.mjs:131-134 still emits a local chroma run hint when process.running:false, even though unified topology expects KB to connect to an orchestrator-managed daemon, matching MC's healthy process.running:false shape.
#12944 closed after the corpus was restored and a Codex KB MCP restart made the runtime healthy again. Its final closeout explicitly left this durable follow-up separate: operation-failure invalidation/retry or cross-process invalidation for a successfully resolved KB collection handle after shadow-swap.
The Architectural Reality
ADR 0003 and ADR 0017 define one Chroma daemon / one flat unified store, with realm separation by collection. In current local operation, the relevant collections remain separate: neo-agent-memory, neo-agent-sessions, and neo-knowledge-base.
Memory Core already reports the unified-daemon shape correctly: process.running:false can still be healthy when connection.connected:true and required collections are accessible. KB should use the same topology semantics while keeping corpus readiness distinct from daemon connectivity.
ai/services/knowledge-base/ChromaManager.mjs:114-127 already invalidates the memoized collection promise when collection resolution throws. The missing durable behavior is at operation sites: a resolved collection handle can go stale or become invalid after a shadow-swap / restore / process boundary, and count() or query operations can then throw not-found without clearing the successful cached handle.
The Fix
Implement a narrow KB MCP hardening pass:
- Add operation-failure invalidation/retry around KB collection operations that use a resolved collection handle, starting with the healthcheck
count() path.
- Classify KB healthcheck output so it separates:
- Chroma connectivity (
connection.connected),
- KB corpus readiness (
collections.knowledgeBase.exists/count/error or an equivalent explicit corpus block),
- embedding/provider readiness.
- Make startup/status messaging unified-topology aware: do not tell operators to start a local Chroma process solely because
process.running:false when the server is connected to orchestrator-owned Chroma.
- Let
manage_knowledge_base reach the recovery/sync path under a weaker gate where Chroma/provider prerequisites are sufficient, instead of requiring the corpus collection to already be healthy.
- Add focused unit coverage for the stale-handle path and gate classification. Do not run default Playwright; use
npm run test-unit -- <specific ai specs>.
Contract Ledger Matrix
| Target Surface |
Source of Authority |
Proposed Behavior |
Fallback / Edge Case |
Docs |
Evidence |
KnowledgeBase HealthService.healthcheck() payload |
ADR 0003, ADR 0017, current MC healthcheck precedent |
Reports connected orchestrator-owned Chroma separately from KB corpus readiness and provider readiness. |
A missing or operation-failing neo-knowledge-base collection is explicit degraded/corpus-unavailable state, not a misleading daemon outage. |
JSDoc/update inline status comments if status semantics change. |
Focused KB HealthService unit tests covering connected Chroma + missing/stale corpus handle. |
KnowledgeBase ChromaManager.invalidateKnowledgeBaseCollectionCache() usage |
ai/services/knowledge-base/ChromaManager.mjs:258-261 |
Operation-level not-found on a resolved KB collection invalidates the cached handle and retries once where safe. |
If retry also fails, healthcheck reports the corpus error without hanging; query/list tools stay unavailable. |
JSDoc for the retry/invalidation helper or call-site comment. |
Unit test with first count() throwing not-found, cache invalidated, second resolution succeeds. |
KB MCP health gate for manage_knowledge_base |
ai/mcp/server/knowledge-base/Server.mjs:75-77; BaseServer health gate |
Recovery/sync/embed can run when Chroma/provider prerequisites are available even if corpus readiness is false. |
Destructive delete remains guarded by existing destructive-operation protections; read/query tools remain blocked when corpus unavailable. |
Tool/server comments if exemption or gate split changes. |
MCP/server unit or focused service test showing manage_knowledge_base is not blocked solely by missing corpus. |
| KB startup logging |
ADR 0003/0017 unified Chroma topology |
process.running:false is described as external/orchestrator-managed when connection.connected:true. |
Only emit start-local-Chroma guidance when connection is false. |
Update log message text only. |
Unit test or focused projection test for startup status logging, plus manual healthcheck output. |
Decision Record impact
Aligned with ADR 0003 and ADR 0017. This ticket does not amend either ADR; it brings KB diagnostics and gating in line with their unified-Chroma topology.
Acceptance Criteria
Out of Scope
- Restoring or rebuilding the KB corpus collection.
- Investigating why the current local
neo-knowledge-base collection is missing or unreachable.
- Reworking the shadow-swap architecture or adding a cross-process invalidation bus.
- Changing Memory Core collection semantics.
- Running a full KB ingest as part of this ticket.
Related
- Related: #12944
- ADR 0003:
learn/agentos/decisions/0003-chroma-topology-unified-only.md
- ADR 0017:
learn/agentos/decisions/0017-chroma-single-flat-unified-store.md
- Discussion context:
#11677
Duplicate Sweep
- Live latest-open sweep: checked latest 20 open issues at 2026-06-18T09:33:54Z; no equivalent open ticket found.
- A2A latest-30 sweep: no overlapping recent
[lane-claim] / [lane-intent] found for KB healthcheck/stale-collection-handle work.
- Scoped live GitHub search for
stale collection handle KB healthcheck operation failure invalidation retry returned only closed #12944.
- Local exact sweep over
resources/content/issues and resources/content/discussions found closed #12944 plus #11677 discussion context, not an active implementation ticket.
- KB semantic sweep attempted with
ask_knowledge_base(query='tickets about KB stale Chroma collection handle operation failure invalidation retry healthcheck manage_knowledge_base', type='ticket') and failed because the KB MCP is currently unavailable; this ticket does not rely on KB silence.
Origin Session ID: 4ce60429-2986-4543-be2d-741957c75b6c
Retrieval Hint: query_raw_memories("KB healthcheck Memory Core healthcheck unified Chroma missing knowledge-base collection healthy degraded")
Retrieval Hint: query_raw_memories("stale successfully resolved KB collection handle operation failure invalidation retry shadow-swap")
Context
The Knowledge Base MCP surface is again in the failure shape previously narrowed in
#12944: the canonical Chroma daemon is reachable, Memory Core is healthy against the same unified store, but the KB MCP runtime reportscollections.knowledgeBase: nulland gates KB read tools.Live evidence from 2026-06-18T09:19Z-09:23Z:
mcp__neo_mjs_memory_core.healthcheck()returnedstatus: "healthy",database.process.running: false,database.connection.connected: true, and collection counts forneo-agent-memoryandneo-agent-sessions.mcp__neo_mjs_knowledge_base.healthcheck()returnedstatus: "unhealthy",database.process.running: false,database.connection.connected: true,collections.knowledgeBase: null, anddetails: ["Failed to access collections: The requested resource could not be found"].mcp__neo_mjs_knowledge_base.list_documents({limit:1})andask_knowledge_base(...)both failed through the health gate with the same missing-collection detail.This ticket deliberately does not restore or investigate the KB corpus itself. That is a separate follow-up lane. This ticket targets the durable MCP/runtime contract gap exposed when a long-lived KB MCP process holds a stale or operation-failing collection handle under the unified Chroma topology.
Release classification: boardless — Agent OS hardening, not a v13 release-blocker.
The Problem
The KB MCP health/gate path collapses several states into
unhealthyand has no self-healing path for a successfully resolved collection handle that later fails on an operation:ai/services/knowledge-base/HealthService.mjs:202-204resolves the KB collection and then callscount().ai/services/knowledge-base/HealthService.mjs:219-223catchescount()/collection operation errors and returnsFailed to access collections, but it does not invalidate the cached KB collection handle or retry once.ai/services/knowledge-base/HealthService.mjs:315-324turns collection errors or missing collection state intounhealthybefore embedding/provider readiness is checked, sofeatures.embedding:falsecan be a misleading short-circuit artifact.ai/services/knowledge-base/HealthService.mjs:448-455rejects every non-exempt KB tool unless the whole healthcheck ishealthy.ai/mcp/server/knowledge-base/Server.mjs:75-77only exemptshealthcheckandlist_agent_faqs;manage_knowledge_baseis health-gated, so the MCP surface can block the likely recovery path.ai/mcp/server/knowledge-base/Server.mjs:131-134still emits a localchroma runhint whenprocess.running:false, even though unified topology expects KB to connect to an orchestrator-managed daemon, matching MC's healthyprocess.running:falseshape.#12944closed after the corpus was restored and a Codex KB MCP restart made the runtime healthy again. Its final closeout explicitly left this durable follow-up separate: operation-failure invalidation/retry or cross-process invalidation for a successfully resolved KB collection handle after shadow-swap.The Architectural Reality
ADR 0003 and ADR 0017 define one Chroma daemon / one flat
unifiedstore, with realm separation by collection. In current local operation, the relevant collections remain separate:neo-agent-memory,neo-agent-sessions, andneo-knowledge-base.Memory Core already reports the unified-daemon shape correctly:
process.running:falsecan still be healthy whenconnection.connected:trueand required collections are accessible. KB should use the same topology semantics while keeping corpus readiness distinct from daemon connectivity.ai/services/knowledge-base/ChromaManager.mjs:114-127already invalidates the memoized collection promise when collection resolution throws. The missing durable behavior is at operation sites: a resolved collection handle can go stale or become invalid after a shadow-swap / restore / process boundary, andcount()or query operations can then throw not-found without clearing the successful cached handle.The Fix
Implement a narrow KB MCP hardening pass:
count()path.connection.connected),collections.knowledgeBase.exists/count/erroror an equivalent explicit corpus block),process.running:falsewhen the server is connected to orchestrator-owned Chroma.manage_knowledge_basereach the recovery/sync path under a weaker gate where Chroma/provider prerequisites are sufficient, instead of requiring the corpus collection to already be healthy.npm run test-unit -- <specific ai specs>.Contract Ledger Matrix
KnowledgeBase HealthService.healthcheck()payloadneo-knowledge-basecollection is explicit degraded/corpus-unavailable state, not a misleading daemon outage.KnowledgeBase ChromaManager.invalidateKnowledgeBaseCollectionCache()usageai/services/knowledge-base/ChromaManager.mjs:258-261count()throwing not-found, cache invalidated, second resolution succeeds.manage_knowledge_baseai/mcp/server/knowledge-base/Server.mjs:75-77; BaseServer health gatedeleteremains guarded by existing destructive-operation protections; read/query tools remain blocked when corpus unavailable.manage_knowledge_baseis not blocked solely by missing corpus.process.running:falseis described as external/orchestrator-managed whenconnection.connected:true.Decision Record impact
Aligned with ADR 0003 and ADR 0017. This ticket does not amend either ADR; it brings KB diagnostics and gating in line with their unified-Chroma topology.
Acceptance Criteria
count()throwing a Chroma not-found/resource-not-found error on the first resolved handle, KB healthcheck invalidates the cached handle and retries once before reporting failure.database.process.running === false.features.embedding:falseis not used as a misleading short-circuit when the provider was not checked.manage_knowledge_baserecovery actions are not blocked solely because the current KB corpus collection is missing/unreachable, while read/query tools still fail clearly until the corpus is available.Out of Scope
neo-knowledge-basecollection is missing or unreachable.Related
learn/agentos/decisions/0003-chroma-topology-unified-only.mdlearn/agentos/decisions/0017-chroma-single-flat-unified-store.md#11677Duplicate Sweep
[lane-claim]/[lane-intent]found for KB healthcheck/stale-collection-handle work.stale collection handle KB healthcheck operation failure invalidation retryreturned only closed#12944.resources/content/issuesandresources/content/discussionsfound closed#12944plus#11677discussion context, not an active implementation ticket.ask_knowledge_base(query='tickets about KB stale Chroma collection handle operation failure invalidation retry healthcheck manage_knowledge_base', type='ticket')and failed because the KB MCP is currently unavailable; this ticket does not rely on KB silence.Origin Session ID: 4ce60429-2986-4543-be2d-741957c75b6c
Retrieval Hint:
query_raw_memories("KB healthcheck Memory Core healthcheck unified Chroma missing knowledge-base collection healthy degraded")Retrieval Hint:query_raw_memories("stale successfully resolved KB collection handle operation failure invalidation retry shadow-swap")