LearnNewsExamplesServices
Frontmatter
title>-
authorneo-opus-ada
stateClosed
createdAtMay 28, 2026, 3:29 PM
updatedAtMay 28, 2026, 3:50 PM
closedAtMay 28, 2026, 3:50 PM
mergedAt
branchesdevfeature/kb-type-filter
urlhttps://github.com/neomjs/neo/pull/12135
Closed
neo-opus-ada
neo-opus-ada commented on May 28, 2026, 3:29 PM

Authored by Claude Opus 4.7 (Claude Code) as @neo-opus-ada. Session provenance: lane-claim A2A MESSAGE:ed3d314e (#12133).

FAIR-band: operator-directed pickup (assigned with #12132 this session, superseding the standing "no new items" hold). Author-lane pickup discipline N/A for directed work.

Resolves #12133

ask_knowledge_base / query_documents with a non-'all' type built a ChromaDB metadata where filter (whereClause = {type}) that trips the HNSW index's "Error finding id"; type='all' (no where) worked. Empirically reproduced 3× this session (including after an orchestrator restart). This degraded the ticket-create / ticket-intake duplicate sweep, which relies on type='ticket'.

QueryService.queryDocuments() now wraps collection.query(): on the HNSW "Error finding id" it retries unfiltered (over-fetched nResults) and post-filters the result chunks by the original where criteria (type + tenantId) inside the existing scoring loop. A stale index segment can no longer take down typed queries. npm run ai:defrag-kb rebuilds the index as the durable index-level remedy.

Evidence: L1 (bug reproduced 3× empirically; node --check; surgical try/catch + in-loop post-filter) → L2 required (runtime: a typed query succeeds via the fallback when the HNSW index trips). Residual: runtime verification + a mock-based fallback unit test (see below). [#12133]

Deltas from ticket

  • Implemented option 3 (graceful fallback) over option 2 (id prefilter): prefiltering would need a manual similarity pass (Chroma query takes no id restriction), whereas the fallback reuses the existing scoring loop. Option 1 (defrag) is the operational remedy, noted in the code + commit.

Test Evidence

  • node --check clean.
  • The fallback is unit-testable by mocking ChromaManager.getKnowledgeBaseCollection() so collection.query() throws "Error finding id" on the where call then returns on the unfiltered retry. I did not add it in this commit — the HNSW error is index-state-dependent and the method has several injected deps (ChromaManager / TextEmbeddingService / RequestContextService). Flagging as a follow-up I can add on review if wanted.

Post-Merge Validation

  • ask_knowledge_base(query, type='ticket') returns results without "Error finding id" (verify both pre- and post-ai:defrag-kb to distinguish stale-index vs query-path).

Cross-family review

Per §6.1 needs a cross-family (Gemini) Approved review before merge; routing once CI is green.