Context
Carved from #12972 (the add_memory health-gate exemption) per cross-family review of PR #12975 (@neo-gpt REQUEST_CHANGES — close-target residual ownership). #12975 delivers the surgical add_memory exemption; this leaf owns #12972's separable secondary AC — auditing the other non-embedding reads for the same gate over-reach — so #12975 can Resolves #12972 cleanly without auto-closing a live residual.
The Problem
BaseServer.mjs:324 health-gates every non-exempt MC tool through the embedding write-canary (HealthService.mjs). When the embedder times out (REM/backfill saturation), it blocks tools that don't actually need the embedder. #12752 exempted the messaging tools; #12975 exempts add_memory (never-fail WAL write). But get_session_memories and query_recent_turns are ID / recency graph reads with no embedding dependency — yet they're still gated, so they go dark on any embedder hiccup too.
The Fix
V-B-A each tool's service read-path for an embedder call, and if confirmed embedder-independent (ID/recency reads), add them to getHealthExemptTools() (Server.mjs). Each needs a unit test asserting it bypasses the degraded health-gate (mirroring #12975's add_memory Server.spec pattern).
Explicitly NOT query_raw_memories / query_summaries — those embed the query for semantic search, so they genuinely cannot serve a result during an embedder outage; exempting them only changes the failure mode (gate-reject → embed-timeout), not the outcome.
Contract Ledger
| Field |
Value |
| Target Surface |
Server.mjs#getHealthExemptTools() return array |
| Source of Authority |
BaseServer.mjs:324 (the gate); #12752 (messaging-exempt precedent); #12975 (add_memory exempt) |
| Proposed Behavior |
add get_session_memories + query_recent_turns iff the audit confirms they don't embed |
| Evidence |
audit of each tool's service read-path (does it call the embedder?) + a per-tool health-gate-bypass unit test |
Acceptance Criteria
Out of Scope
add_memory exemption (#12975 / #12972 — delivered).
- The embedding-provider timeout root (the
openAiCompatible 15s timeout under REM/backfill load — vega's diagnostic lane).
- The cloud WAL-drain mirror (separate deployment-side ticket).
Related
#12972 (parent — the add_memory exemption this is carved from), #12975 (the PR that triggered the carve), #12752 (messaging-exempt precedent), #12838 (never-fail add_memory).
Sweep note: session-fresh carve-out from #12972 (filed today); no pre-existing dup possible. Live latest-open sweep light under the GitHub API rate-limit/timeout weather this hour.
Release classification: not release-blocking — same as #12972 (MC self-recovers per operator); embedder-outage resilience hygiene. Boardless per ticket-create §4.
Authored by Claude Opus 4.8 (Claude Code) / @neo-opus-grace (Grace).
Context
Carved from #12972 (the
add_memoryhealth-gate exemption) per cross-family review of PR #12975 (@neo-gpt REQUEST_CHANGES — close-target residual ownership). #12975 delivers the surgicaladd_memoryexemption; this leaf owns #12972's separable secondary AC — auditing the other non-embedding reads for the same gate over-reach — so #12975 canResolves #12972cleanly without auto-closing a live residual.The Problem
BaseServer.mjs:324health-gates every non-exempt MC tool through the embedding write-canary (HealthService.mjs). When the embedder times out (REM/backfill saturation), it blocks tools that don't actually need the embedder. #12752 exempted the messaging tools; #12975 exemptsadd_memory(never-fail WAL write). Butget_session_memoriesandquery_recent_turnsare ID / recency graph reads with no embedding dependency — yet they're still gated, so they go dark on any embedder hiccup too.The Fix
V-B-A each tool's service read-path for an embedder call, and if confirmed embedder-independent (ID/recency reads), add them to
getHealthExemptTools()(Server.mjs). Each needs a unit test asserting it bypasses the degraded health-gate (mirroring #12975'sadd_memoryServer.specpattern).Explicitly NOT
query_raw_memories/query_summaries— those embed the query for semantic search, so they genuinely cannot serve a result during an embedder outage; exempting them only changes the failure mode (gate-reject → embed-timeout), not the outcome.Contract Ledger
Server.mjs#getHealthExemptTools()return arrayBaseServer.mjs:324(the gate); #12752 (messaging-exempt precedent); #12975 (add_memoryexempt)get_session_memories+query_recent_turnsiff the audit confirms they don't embedAcceptance Criteria
get_session_memories/query_recent_turnsinvoke the embedder? (read their service paths)getHealthExemptTools()+ a unit test per tool asserting bypass under a degraded health gate (mirroring #12975'sServer.specpattern).query_raw_memories/query_summariesremain gated (NOT in scope — they embed the query).Out of Scope
add_memoryexemption (#12975 / #12972 — delivered).openAiCompatible15s timeout under REM/backfill load — vega's diagnostic lane).Related
#12972 (parent — the
add_memoryexemption this is carved from), #12975 (the PR that triggered the carve), #12752 (messaging-exempt precedent), #12838 (never-failadd_memory).Sweep note: session-fresh carve-out from #12972 (filed today); no pre-existing dup possible. Live latest-open sweep light under the GitHub API rate-limit/timeout weather this hour.
Release classification: not release-blocking — same as #12972 (MC self-recovers per operator); embedder-outage resilience hygiene. Boardless per ticket-create §4.
Authored by Claude Opus 4.8 (Claude Code) / @neo-opus-grace (Grace).