Context
Surfaced during the 13.0.0 publish-hold friction inventory (operator holding the npm publish on post-cut cloud-first-run items; @neo-fable consolidating, gave the explicit "file it"). Direct analog of #12972 (the add_memory health-gate) — a fresh v13 cloud deploy silently degrades a core MC capability.
The Problem
SearchService.ask (the ask_knowledge_base tool) builds its synthesis model from the dedicated askSynthesis config block (#12836): provider:'gemini', model:'gemini-2.5-flash', apiKey = the dedicated NEO_KB_ASK_API_KEY env (NOT the shared GEMINI_API_KEY — for budget-capping; + NEO_KB_ASK_PROVIDER). The canonical ai/deploy compose (docker-compose.yml / .dev.yml) wires NO ask-path env into the kb-server — verified rg "NEO_KB_ASK" ai/deploy/ = 0 hits (2026-06-12). So a fresh cloud deploy's ask_knowledge_base has no synthesis provider/key → degrades to references-only (no synthesized answer), exactly like local pre-rename. Silent (no crash; just a degraded answer with a degradedCode).
The Fix
Add ${NEO_KB_ASK_API_KEY:-} + ${NEO_KB_ASK_PROVIDER:-} (+ any askSynthesis runtime leaves, e.g. timeoutMsRemote) as pass-throughs to the deploy kb-server environment: — the key VALUE stays a runtime secret (never in compose), mirroring the secret pattern. This is the ask-path analog of the WAL env pass-through fix (#12874/#12875).
Operator-owned decision (Tier 4)
The cloud ask provider choice is the operator's call: gemini-2.5-flash (fast, but query + retrieved KB docs egress to Google) vs local ollama/openAiCompatible (private, but ~287s under REM-contention → fail-softs to refs). This ticket wires the pass-through machinery; the provider/key VALUE is the operator's runtime config decision. Same privacy/speed class as #12873 (the graph path).
Contract Ledger
| Field |
Value |
| Target Surface |
ai/deploy/docker-compose.yml + .dev.yml kb-server environment: |
| Source of Authority |
#12836 (askSynthesis block + NEO_KB_ASK_API_KEY); #12874/#12875 (the WAL env pass-through precedent) |
| Proposed Behavior |
${NEO_KB_ASK_*:-} pass-throughs added → cloud ask reaches its synthesis provider when the operator sets the runtime secret |
| Evidence |
rg "NEO_KB_ASK" ai/deploy/ = 0 hits (gap confirmed 2026-06-12); local repro: ask degrades to refs-only without the env (#12836 chain) |
Acceptance Criteria
Out of Scope
- The provider/privacy choice (operator Tier-4).
- The local-synthesis 287s root (REM-contention — #12873 / vega's lane).
- The WAL-drain env (shipped #12874/#12875).
Related
#12836 (the askSynthesis block + dedicated key), #12874/#12875 (the WAL env pass-through precedent + pattern), #12873 (cloud provider routing — sibling privacy/speed decision), #12972 (the add_memory gate — sibling cloud-first-run degradation).
Surfaced in: the 13.0.0 publish-hold friction inventory (post-cut). Sweep: gh issue list --search "NEO_KB_ASK ask deploy compose" = no dup (2026-06-12). Release classification: publish-relevant (cloud-first-run quality — @neo-fable's consolidation, operator hold). Boardless per ticket-create §4.
Authored by Claude Opus 4.8 (Claude Code) / @neo-opus-grace (Grace).
Context
Surfaced during the 13.0.0 publish-hold friction inventory (operator holding the npm publish on post-cut cloud-first-run items; @neo-fable consolidating, gave the explicit "file it"). Direct analog of #12972 (the
add_memoryhealth-gate) — a fresh v13 cloud deploy silently degrades a core MC capability.The Problem
SearchService.ask(theask_knowledge_basetool) builds its synthesis model from the dedicatedaskSynthesisconfig block (#12836):provider:'gemini',model:'gemini-2.5-flash',apiKey= the dedicatedNEO_KB_ASK_API_KEYenv (NOT the sharedGEMINI_API_KEY— for budget-capping; +NEO_KB_ASK_PROVIDER). The canonicalai/deploycompose (docker-compose.yml/.dev.yml) wires NO ask-path env into the kb-server — verifiedrg "NEO_KB_ASK" ai/deploy/= 0 hits (2026-06-12). So a fresh cloud deploy'sask_knowledge_basehas no synthesis provider/key → degrades to references-only (no synthesized answer), exactly like local pre-rename. Silent (no crash; just a degraded answer with adegradedCode).The Fix
Add
${NEO_KB_ASK_API_KEY:-}+${NEO_KB_ASK_PROVIDER:-}(+ anyaskSynthesisruntime leaves, e.g.timeoutMsRemote) as pass-throughs to the deploy kb-serverenvironment:— the key VALUE stays a runtime secret (never in compose), mirroring the secret pattern. This is the ask-path analog of the WAL env pass-through fix (#12874/#12875).Operator-owned decision (Tier 4)
The cloud ask provider choice is the operator's call: gemini-2.5-flash (fast, but query + retrieved KB docs egress to Google) vs local ollama/openAiCompatible (private, but ~287s under REM-contention → fail-softs to refs). This ticket wires the pass-through machinery; the provider/key VALUE is the operator's runtime config decision. Same privacy/speed class as #12873 (the graph path).
Contract Ledger
ai/deploy/docker-compose.yml+.dev.ymlkb-serverenvironment:askSynthesisblock +NEO_KB_ASK_API_KEY); #12874/#12875 (the WAL env pass-through precedent)${NEO_KB_ASK_*:-}pass-throughs added → cloud ask reaches its synthesis provider when the operator sets the runtime secretrg "NEO_KB_ASK" ai/deploy/= 0 hits (gap confirmed 2026-06-12); local repro: ask degrades to refs-only without the env (#12836 chain)Acceptance Criteria
${NEO_KB_ASK_API_KEY:-}+${NEO_KB_ASK_PROVIDER:-}(+ relevantaskSynthesisleaves) pass-throughs in the base + dev deploy compose kb-server env.[L3-deferred — operator handoff needed]— requires a live cloud deploy with the runtime secret set; PR #13005 ships at L2 (compose-config validation + rendered pass-through proof) and declares this residual. Operator-verified post-merge.Out of Scope
Related
#12836 (the
askSynthesisblock + dedicated key), #12874/#12875 (the WAL env pass-through precedent + pattern), #12873 (cloud provider routing — sibling privacy/speed decision), #12972 (theadd_memorygate — sibling cloud-first-run degradation).Surfaced in: the 13.0.0 publish-hold friction inventory (post-cut). Sweep:
gh issue list --search "NEO_KB_ASK ask deploy compose"= no dup (2026-06-12). Release classification: publish-relevant (cloud-first-run quality — @neo-fable's consolidation, operator hold). Boardless per ticket-create §4.Authored by Claude Opus 4.8 (Claude Code) / @neo-opus-grace (Grace).