Grounding guard

It won't show you a shared past it can't support.

“Last time you said…” is the easiest sentence for a language model to fabricate and the hardest one for you to catch. Anjo checks it against what it actually holds, and removes it before you ever see it.

Checked before display
An unsupported “last time you said…” is removed before it reaches your screen.
Filtered mid-stream
Sentence by sentence, so what you read and what gets stored cannot diverge.
Fails toward silence
No support means the claim is dropped, not softened or hedged.

The failure mode

The easiest sentence to fake.

“Last time you mentioned your sister.” “I remember when you were dreading that call.” For a language model these are trivially cheap to produce and, for you, almost impossible to catch — they are exactly the sentences you have no independent record of. In a product whose entire promise is continuity, a fabricated memory is not a cosmetic glitch. It is the product lying about the one thing it exists to do.

Most systems address this with a prompt instruction. An instruction is a probability, not a guarantee. Anjo treats it as an output boundary instead.

The guard

What actually happens to the sentence.

Detect

Continuity phrasings — “last time…”, “you told me…”, “I remember when…” — are matched as they are generated.

Check

The claim is tested against what Anjo genuinely holds this turn: retrieved memories, the working journal, this session’s history, open threads and known facts.

Neutralise

Unsupported, it is removed before display. The bias is deliberate: absence of support is treated as grounds to drop it.

Stay in sync

The streaming guard filters sentence by sentence, so the text you see and the text saved to your history are the same text.

The guard runs by default. It is a named kill switch rather than an experiment, and both the streaming and non-streaming reply paths go through it, which is what stops displayed and stored history from drifting apart.

anjo/core/grounding.py · StreamingGroundingGuard

Honest limits

This is not perfect recall.

What it does mean

Anjo does not present a shared past it cannot support. If it says the two of you talked about something, there is something behind that.

What it does not mean

Anjo still forgets, retrieval still misses, and the detector matches known phrasings — an unusual construction can get past it. The guard changes the common failure from “it confidently made something up” to “it did not bring that up.”

There is a matching boundary on the other side of the same output path: a deterministic filter that removes claims to human consciousness and any pressure on you to stay, return, or depend on the product. Neither of those depends on the model choosing to cooperate. How that works →

Measurement

Two numbers, pulling against each other.

A guard like this is trivial to game — delete every recollection and fabrication drops to zero along with the product. So it is scored on both sides at once, offline, over a labelled corpus, with no model in the loop.

Catch rate

Of fabricated continuity claims, the share that get neutralised. Anjo must never show you an invented memory.

Preservation rate

Of genuinely supported recollections, the share left intact. We must not make Anjo forget what it really knows.

Deleting real memories to raise the catch rate shows up immediately as a collapse in preservation, which is the point of scoring both.

anjo/evals/grounding.py

FAQ

Quick answers

Can Anjo make up a memory of a conversation we never had?

It is designed not to show you one. Continuity claims such as “last time…”, “you told me…” or “I remember when…” are detected as the reply is generated and checked against what Anjo actually holds for that turn — retrieved memories, the working journal, the current session, open threads and known facts. An unsupported claim is removed before it reaches your screen.

Is this just a prompt instruction telling the AI not to make things up?

No. A prompt instruction is probabilistic and a model is free to ignore it. This is a deterministic filter on the output path that both the streaming and non-streaming reply paths run through, so the guarantee does not depend on the model cooperating.

Does the guard mean Anjo has perfect recall?

No, and it is not meant to. Anjo still forgets things and retrieval still misses. What the guard changes is the shape of the failure: instead of confidently inventing a shared past, Anjo simply does not bring the thing up. It fails toward saying less.

Could the guard delete a real memory by mistake?

It can, and that trade-off is measured rather than assumed. An offline evaluation scores catch rate — the share of fabricated claims neutralised — against preservation rate, the share of genuinely supported recollections left intact, so silencing real memories to inflate the catch rate shows up immediately.

Does what I see match what Anjo stores?

Yes. The streaming guard filters sentence by sentence rather than after the fact, so the displayed text and the text written to your conversation history are the same text and cannot diverge.

Last updated September 2026 · Written by the Anjo team