CedarCopilot wants to merge 1 commit into staging from fix/chat-taxonomy-field-routing
Live on prod, 0 of 7 surfaces degraded
Strict CloudWatch fallback found 79 prod failure log lines for [executeExternalCrm] Failed to write snapshot on non-significant sync (Failed query: select \) in the last 24h while checking select, taxonomy-field-routing-eval, shared-chat-context, search, taxonomy, up from 3 in.
Verification reached its 130s outer budget before the verifier returned. Libra is keeping this intent verifying until the next check.
Verification reached its 130s outer budget before the verifier returned. Libra is keeping this intent verifying until the next check.
Verification reached its 120s wall-clock budget before a tied verdict. Libra is keeping this intent verifying until the next check.
Libra found 7 production surfaces on prod but could not judge any of them yet. 2 surfaces had under 20 requests, so Libra has not judged them; 3 surfaces had no requests at all. Libra checks hourly for 3 days after each deploy.
aopId (and other nullable fields) by name in include_attributes. A namespace where that attribute was only ever written null (e.g. a rep backfilled before AOP-classification ran) never gets a schema entry for it, so naming it explicitly 400s the entire query , vector and FTS alike. Switched to includeAttributes: true so search degrades gracefully instead of failing outright.taxonomy-fields tool, so cross-deal aggregate/topic questions ("which companies asked about X?") always went to the analyzer/semantic-search subagent , even though taxonomy-fields is reachable in chat and its own description says "CALL THIS FIRST" for this exact question shape. Added a <taxonomy_field_routing> block to the shared per-request chat context, gated on the same brainSkillsEnabled flag that gates the tool itself, so this is a no-op for orgs without brain access.Both bugs were found while debugging a real customer (Warp/Thiago) chat session from 2026-09-10, where a "what businesses asked for performance management" question hit the broken search index instead of the structured taxonomy field data that already had the answer.
attribute "aopId" not found in schema) before writing the fix.pnpm --filter @zero/server run types , no new errors in either changed file.apps/server/.claude/skills/playbook-instruction-eval/taxonomy-field-routing-eval.ts) that reproduces the real prompt/tool shapes and Thiago's exact question against claude-sonnet-4-6 (the model the affected surface actually runs), 8 trials/variant:
taxonomy-fields called first 0/8.taxonomy-fields called first 8/8 trials, analyzer never called.This PR changes conversation search to request all available Turbopuffer attributes and adds brain-gated instructions routing aggregate conversation questions through structured taxonomy data. The search change safely avoids failures when optional attributes are absent from a namespace schema, but the routing change advertises taxonomy-fields on the default granular chat surface where that tool is not registered.
includeAttributes: true for vector and full-text conversation searches.The PR is not yet safe to merge because the new routing instruction can direct the default granular chat agent to a tool it cannot call.
Brain access and family-tool selection are independent flags; the shared context enables taxonomy routing from the former, while taxonomy-fields is only proven available through the latter, leaving ordinary granular requests unable to execute the intended route.
Files Needing Attention: apps/server/src/mastra/workflows/chat/shared-chat-context.ts, apps/server/.claude/skills/playbook-instruction-eval/taxonomy-field-routing-eval.ts
| Filename | Overview |
|---|---|
| apps/server/src/mastra/workflows/chat/shared-chat-context.ts | Adds taxonomy-first routing, but gates it only on brain access rather than ensuring the selected chat surface exposes the named tool. |
| apps/server/src/services/turbopuffer/search.ts | Replaces brittle attribute projections with retrieval of available namespace attributes for both search modes. |
| apps/server/.claude/skills/playbook-instructio |
| Surface | Requests | Errors | p95 | Users | Verdict |
|---|---|---|---|---|---|
| POST /api/trpc/files.searchForLink | no baseline → 4 | no baseline → 0 (0%) | not measured → 3053 ms | 0 | Insufficient traffic 4 requests, under the 20 Libra needs |
| execute_tool search-live-emails | no baseline → 1 | no baseline → 0 (0%) | not measured → 350 ms | 0 | Insufficient traffic 1 request, under the 20 Libra needs |
| /api/trpc/crm.searchConversationsMinimal | no baseline → 0 | no baseline → 0 (0%) | not measured | not counted | Unavailable ClickHouse reads are unavailable, so Libra could not measure this surface. |
| POST /api/trpc/crm.searchConversationsMinimal | no baseline → 0 | no baseline → 0 (0%) | not measured | 0 | No traffic No requests recorded since this deploy. |
| /api/trpc/files.searchForLink | no baseline → 0 | no baseline → 0 (0%) | not measured | not counted | Unavailable ClickHouse reads are unavailable, so Libra could not measure this surface. |
| trpc.crm.searchConversationsMinimal | no baseline → 0 | no baseline → 0 (0%) | not measured | 0 | No traffic No requests recorded since this deploy. |
| crm.searchConversationsMinimal | no baseline → 0 | no baseline → 0 (0%) | not measured | 0 | No traffic No requests recorded since this deploy. |