No upstream response caching, which now costs real money rather than just politeness #73
Labels
No labels
autonomy
async-consult
autonomy
epic
autonomy
headless
autonomy
live-collab
coherence-core
priority
P0
priority
P1
priority
P2
priority
P3
priority
P4
qa-fixture
role/ai
role/creator
role/design
role/director
role/engineer
role/exec
role/human
role/ops
role/qa
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
coilyco-flight-deck/mcp-beaver#73
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Filed by Olaf (OPS) from
coilyco-bridge/deploy. The absence is asserted in deploy#495 as an argument for building an offline dataset, but it has never been ticketed here, so the deploy side has been reasoning about a gap with no issue to point at.The gap
Every tool call is a live upstream request. The
ttlMs/cacheScopeindocs/FEATURES.mdis MCP list caching — the tool inventory — not the data. Nothing caches an upstream response, so N identical questions from a Discord community produce N identical upstream calls from one pod IP.Why this changed category today
Until this morning every consumer was a keyless public-good API, and the cost of no caching was politeness: GBIF, Open Library, Gutendex, TVmaze are all volunteer or nonprofit, and
rate-limitwas enough to be a good neighbour.Exa web search (deploy#448) is metered. $7 per 1,000 standard searches, on Kai's card. Caching is now a spend control, not a courtesy, and it is the one control that reduces cost without reducing capability — unlike the rate limit, which only makes the tool refuse.
Search results are also unusually cacheable: a query for "official Kubernetes docs" returns the same ten links all week, and a Discord community asks overlapping questions by nature.
Interaction with the two spend issues already open
Caching is the only lever that makes the budget go further rather than run out sooner.
Shape worth considering
A per-grant TTL, opt-in and off by default, since correctness varies wildly by upstream:
Points that want deciding rather than assuming:
Consumer impact
Built on
mainine2a0e7f.Stated beside
wraprather than inside the grant, unlike thecache "15m"you sketched. Same reasonrate-limitsits there: the wrap body is opcore's frozen grammar and the umbra pin. The argument is the projected tool name, matchingconfirmandpin, which is what a client dispatches on.Your points that wanted deciding
{"id":"42","q":"ramen"}and{"q":"ramen","id":"42"}hit one entry rather than two. The tool name stands in for method and path, since a projected tool is exactly one grant. Server-sidepinvalues are deliberately not in the key: they resolve identically for every caller in a process, so they cannot distinguish two calls, and the TTL bounds afilepin that changes underneath.Two things I added past the ask
TestCacheServesARepeatedCallWithoutReachingUpstream.confirm-gated tool (a hit would skip the human gate the confirmation exists to impose), a missing or unparseablettl, and attlpast a 24h ceiling. A failed call is never stored - an upstream that 5xxed for fifteen seconds must not answer for the next fifteen minutes.docs/FEATURES.mdand the README both say explicitly that this is not thettlMs/cacheScopeon list results, since that conflation is what left the gap unticketed.Nothing here changes deploy#448's guardfile. Adding
cache "create_web_search" ttl="15m"to it is a one-line change on that side, and Exa is the case that justifies it.