Cache poisoning is the whole problem
Semantic caching has an obvious failure mode nobody likes to talk about: one bad write, served forever to everyone nearby. This is how Crowkis decides what to trust.
Here is the uncomfortable math of semantic caching. A normal cache serves a bad entry to exactly the requests that match its key. A semantic cache serves a bad entry to every request that lands near it in embedding space. Poison doesn't sit in one cell — it radiates.
Semantic reach is the feature — and, untreated, the vulnerability.
And LLM systems produce bad writes constantly. Hallucinations. Prompt injections that smuggle instructions into what looks like an answer. A response computed for tenant A that would be a data leak if tenant B ever saw it. If your cache trusts every write, your cache is an amplifier for your worst outputs.
Five stages, every write
Weighted, not unanimous — but heavily tilted toward coherence and history.
The two heavyweights are coherence and source trust, and that's deliberate. Coherence catches injected content that doesn't actually answer the question. Source trust means a writer that produced garbage before has to earn its way back — every accept and refuse lands in an append-only ledger, so trust has memory.
Trust has memory
2026-04-29T14:02:11 writer=svc-support ACCEPT composite=0.91 2026-04-29T14:02:38 writer=svc-support ACCEPT composite=0.88 2026-04-29T14:03:02 writer=ext-webhook REFUSE stage=1 coherence=0.31 2026-04-29T14:03:05 writer=ext-webhook REFUSE stage=3 trust=0.22 # ext-webhook now faces a higher bar on every future write
A cache that can't say no isn't infrastructure. It's a liability with a hit rate.
Refusal is a feature you can see
Blocked writes show up in the dashboard's live feed with the stage that vetoed them, and the rejection counters break down by stage so you can see what kind of poison your system actually attracts. That visibility matters more than it sounds: the first question every operator asks about a safety system is 'what is it actually doing?' — and the answer should never be 'trust us.'
Tenant isolation deserves the last word. It isn't only an access-control rule at read time — it's a scored stage at write time. An entry that smells like it crossed a tenant boundary doesn't get a chance to be mis-served later, because it never enters the cache at all.