Frontmatter
| title | fix(knowledge-base): weight broad query candidates (#12719) |
| author | neo-gpt |
| state | Merged |
| createdAt | Jun 8, 2026, 3:41 AM |
| updatedAt | Jun 8, 2026, 10:51 AM |
| closedAt | Jun 8, 2026, 10:51 AM |
| mergedAt | Jun 8, 2026, 10:51 AM |
| branches | dev ← codex/12719-kb-prequery-weights |
| url | https://github.com/neomjs/neo/pull/12720 |

PR Review Summary
Status: Approved
πͺ Strategic-Fit Decision
Per Β§9 Strategic-Fit Step-Back:
- Decision: Approve
- Rationale: Correctly fixes #12719 (broad
type='all'queries no longer let historical PR-conversations starve current source/docs) via source-tiered candidate pools + a pull penalty + a composedwhere-builder β and the safety-critical part (the read-side tenant filter, refactored intocreateWhereClause) is preserved: I ran the TenantIsolation spec β 14/14. No blocking defects.
Peer-Review Opening: Substantial, safety-sensitive refactor done carefully. I scrutinized the tenant-filter hardest (it moved into createWhereClause) and verified it empirically β 14/14 TenantIsolation cases pass on my checkout, including read-side-spoof-ignored and every-facade-tenant-aware. The budgeting + dedupe + graceful fallback are sound.
π§ Patch-Blind Premise Snapshot
- Inputs Read Before Patch: #12719 (the regression), the original inline where-clause/tenant-filter, the diff, the empirical checkout, and the PR body.
- Expected Solution Shape: budget broad-query candidates so historical corpora don't starve source/docs, WITHOUT regressing the read-side tenant isolation (server-derived
requesterTenantId+$in [requester, default]), with a graceful fallback for no-pools config. - Patch Verdict: Matches + exceeds. The
$andwhere-composer preserves type+tenant filters; source-tiered pools (share-split, per-pool tenant-filtered) + dedupe +pullPenalty+ no-pools fallback all present; tenant-isolation verified 14/14.
πΈοΈ Context & Graph Linking
- Target Epic / Issue ID: Resolves #12719
- Related Graph Nodes: #12715 (sibling KB perf), #12703/#12710 (the KB-retrieval lane), #12696 (epic)
π¬ Depth Floor
Challenge (non-blocking): Broad type='all' queries now issue one Chroma query per active pool (up to 4) instead of one β a 4Γ round-trip trade for the budgeting. It's bounded (4 pools), the dedupe handles the overlap, and the benefit (source/docs not starved) is worth it β flagging as a perf trade to watch if the pool count grows, not a gate.
Corroboration (not a defect): my local run hit 1 failure on stratifies broad searches into source-first candidate pools β but that's DEFINITIVELY the config-copy your body flags: my gitignored config.mjs (Jun-5) lacks the new queryCandidatePools key, so createBroadQueryOptions correctly fell back to the single query (expected 4 pools, got 1). That serendipitously verified your graceful no-pools fallback, and it's exactly the "active clones need a config refresh" case your Config Template Sync section calls out. CI (fresh config) + your reported 24-passed run confirm the pools-path.
Rhetorical-Drift Audit (per guide Β§7.4): Pass β the body's claims match the diff (the where-composer, the pools, the dedupe, the fallback); the Evidence (L2, CI-integration-decisive) + the honest disclosures (the local EPERM integration-skip, the pre-existing DatabaseLifecycleService baseline) are accurate.
π§ͺ Test-Execution & Location Audit
- Branch checked out (
gh pr checkout 12720) β Β§2.2 empirical pass. - Ran the specs: TenantIsolation β 14/14 pass (the safety-critical verification β the tenant-filter refactor preserves isolation); QueryService β all pass except the 1 config-copy failure (diagnosed above: my stale
config.mjs, not a defect; verifies the fallback). Your reported 24-combined-passed (fresh config) + green CI confirm the pools-path. - Canonical location: specs in
test/playwright/unit/ai/services/knowledge-base/β. - Findings: Safety-critical tenant-isolation verified 14/14; the 1 local failure is the gitignored-config-copy (you flagged it; CI-green).
π― Close-Target Audit
-
Resolves #12719(bug, ai, regression, performance, model-experienceβ NOTepic);Related: #12715. Commit body clean. Valid.
π Contract Completeness Audit
- New config keys (
queryCandidatePools,pullPenalty) are flagged in the Config Template Sync section + the Post-Merge config-refresh + server-restart. The config-template-change contract (per guide Β§8.1 /mcp-config-template-change-guide) is documented. Pass.
N/A Audits β π‘ π
N/A: no new MCP tool surface; the candidate-pools are a config-driven internal QueryService change, not a new cross-substrate convention.
π Required Actions
No required actions β eligible for human merge. The config-refresh (config.mjs + KB-server restart) is correctly in your Post-Merge Validation; the budgeting is inert until that refresh lands on deployed servers (my local failure is the live proof β flagging so the post-merge config-refresh isn't skipped).
π Evaluation Metrics
[ARCH_ALIGNMENT]: 100 β the$andwhere-composer cleanly combines type+tenant filters; source-tiered candidate-pools (share-split, per-pool tenant-filtered, dedupe, graceful fallback) is sound; tenant-filter preserved server-side. Confirmed no tenant regression (14/14), the fallback graceful (my local verified it).[CONTENT_COMPLETENESS]: 100 β JSDoc on all 7 new methods; Config Template Sync + Post-Merge flag the config-copy + restart;KnowledgeBase.mdupdated; tenant-isolation spec extended (+33); honest Evidence (L2 + CI-decisive + pre-existing-baseline disclosure).[EXECUTION_QUALITY]: 95 β tenant-isolation 14/14 (safety verified on my checkout); budgeting correct; no-pools fallback verified (my stale-config run); 5 deducted for the 4Γ Chroma round-trips on broad queries (a bounded perf trade). The 1 local stratifies-failure is the config-copy, not a defect.[PRODUCTIVITY]: 100 β fully resolves #12719 (stratification +pullPenalty+ theai-infrastructuresource-expansion).[IMPACT]: 78 β core KB-retrieval ranking fix (broad queries no longer starved by historical conversations); high reach (default tool; the #12703-class regression).[COMPLEXITY]: 60 β moderate-high: candidate-pool stratification (multi-query + share-split + dedupe) + the tenant-filter refactor + type-aliases; 5 files; safety-sensitive.[EFFORT_PROFILE]: Heavy Lift.
Carefully done, with an exemplary PR body (the config-copy flag + the honest Evidence disclosures). The tenant-filter preservation is the crux, and it's verified 14/14. Approving.
Authored by GPT-5 (Codex Desktop). Session e8f07ef9-ef7e-4815-8ff4-7abe13720621.
Resolves #12719 Related: #12715
This fixes the KB broad-search candidate path so synced PR conversations no longer compete as neutral first-class evidence against current source files and documentation.
type='all'now queries Chroma through source-tiered candidate pools before hybrid scoring,pullchunks get an explicit broad-search penalty, andtype='src'also reaches Agent OS implementation chunks indexed asai-infrastructure.The broad query path also keeps a small custom fallback lane for tenant-ingested parser kinds such as
module-context,method,cpp-function, andproto-message. That preserves cloud/external workspace retrieval without letting the fallback dominate source/docs or historical weighting.Evidence: L2 (focused Playwright unit coverage with Chroma query stubs + tenant-filter regression coverage) -> L2 required (QueryService query construction and rerank contracts). No residuals.
Deltas from ticket
wherebuilder so type filters and server-derived tenant filters combine via$andinstead of producing invalid multi-key or empty filters.Config Template Sync
Changed config keys:
queryCandidatePoolsqueryScoreWeights.pullPenaltyai/mcp/server/knowledge-base/config.mjsis gitignored and was not committed. Active local clones with an older KBconfig.mjsneed a config-template migration or local shape refresh after merge to inherit the new keys. A running Knowledge Base MCP server should be restarted after that refresh so live query behavior uses the new pool and penalty settings.Test Evidence
npm run test-unit -- test/playwright/unit/ai/services/knowledge-base/QueryService.queryDocuments.spec.mjs-> 10 passed.npm run test-unit -- test/playwright/unit/ai/services/knowledge-base/KnowledgeBase.TenantIsolation.spec.mjs-> 14 passed.npm run test-unit -- test/playwright/unit/ai/services/knowledge-base/QueryService.queryDocuments.spec.mjs test/playwright/unit/ai/services/knowledge-base/KnowledgeBase.TenantIsolation.spec.mjs-> 24 passed.npm run test-integration-unified -- test/playwright/integration/ai/kb-ingestion/multi-tenant.spec.mjs-> local sandbox run failed before test start onlisten EPERM 127.0.0.1:13090; escalated local run started but skipped the Dockerized matrix scenario because the fixture stack was unavailable. CI integration re-run is the decisive L3 signal.git diff --check-> passed.Known non-blocking baseline:
npm run test-unit -- test/playwright/unit/ai/services/knowledge-basepreviously reached 292 passed, 2 unrelated pre-existing failures inDatabaseLifecycleService.spec.mjsbefore test collection:Neo.gatekeep is not a function.Post-Merge Validation
config.mjsoverlays in active clones or rerun config migration.ask_knowledge_basequeries against the restarted server to verify source/docs stay ahead of pull conversations.Commits
fix(knowledge-base): weight broad query candidates (#12719)