Journal

Notes on governing AI before it acts, not after.

Longer-form pieces on the reasoning behind the architecture — written for people building or evaluating governed AI systems.


The permission drift problem, and why filtering after retrieval isn't enough

Most production RAG systems get built the same way: documents get chunked, embedded, and written into a vector store, and an access-control list is stamped onto each chunk's metadata at ingestion time. It's a reasonable first pass, and it works — right up until someone's access changes.

The trouble is that revocation and re-indexing are different events, on different clocks. When a user is offboarded, when a legal hold is issued, when a document gets reclassified, the source of truth updates immediately. The vector store doesn't. It keeps serving the old metadata until a background job catches up — and that gap, the permission drift window, is where unauthorized data keeps being retrievable, and keeps being fluently synthesized into whatever the AI says next.

The instinct is to patch this with a filter: check permissions again after retrieval, before the answer goes out. That helps, but it doesn't close the gap — it just moves where the leak is checked. The unauthorized content still entered the retrieval pipeline, still sat in application memory, still shaped which chunks got ranked and returned. A late filter can hide the output; it can't undo the fact that the system already looked.

The alternative is to resolve authority as a live query, at the same moment the request is made, and to constrain retrieval to only what that resolution allows — before search runs at all. Practically, that means treating permission as a relational join across an explicit hierarchy (tenant, family, document, assignment) rather than a value copied onto an embedding. A revoked assignment simply drops out of the join. There's nothing to re-index, because nothing was ever cached.

Why evidence has to be sealed before retrieval, not filtered after

A lot of AI governance tooling today works by inspecting output: scan the prompt, scan the response, look for anything that shouldn't have been said. That's a legitimate layer, and it catches real problems. But it's fundamentally a rear-view mirror — it tells you something went wrong after the model has already seen the thing that shouldn't have been in context.

The alternative is to build the boundary first. Before any search runs, resolve exactly which sources, scopes, and classification levels this specific request is entitled to — and seal that boundary as a discrete, hashed object. Retrieval then has no path to anything outside it; it isn't a matter of the model choosing not to use disallowed content, because the disallowed content was never a candidate.

This matters most for prompt injection. A classic injection attack tries to get the model to retrieve or act on something it shouldn't. If the evidence boundary is sealed before generation even starts, an injected instruction has nothing to reach for — the attack surface isn't "will the model behave," it's "can the system even present it with the option."

The rule, restated plainly: retrieved evidence must be a subset of the sealed boundary, not merely evaluated against it afterward. Subset-of is a structural guarantee. Evaluated-against is a hope that the check ran, and ran correctly, every time.

Governing five RAG architectures without rebuilding any of them

Teams rarely run one retrieval pattern. A single product might use hybrid lexical-plus-vector search for general Q&A, a graph-based approach for relationship-heavy queries, an agentic loop for multi-step tasks, a corrective retriever that re-queries when confidence is low, and a multimodal pipeline for anything involving scanned documents or images. Each has different internals, different failure modes, different tuning knobs.

What they share is a moment before search happens where a candidate set gets decided — a namespace filter, a set of allowed document IDs, a subgraph boundary. That moment is the actual integration point for governance. It doesn't require touching the ranking algorithm, the embedding model, or the retrieval logic itself. It requires that whatever produces the candidate set receives that set from a governance decision, rather than deciding it on its own.

In practice, that means: hybrid search gets its candidate ID list from the sealed boundary instead of an open index scan. A graph traversal treats quarantined nodes as structurally absent, not merely low-priority. An agent's tool calls each re-enter the same authority check a normal request would, rather than inheriting the permissions of whoever started the session. A corrective retriever's second attempt stays inside the same boundary as its first — a low-confidence result doesn't earn it a wider search. And a multimodal pipeline treats a page image or a scanned form exactly like a text chunk for authority purposes: it inherits governance from its source document, not from its file type.

None of this asks a team to replace their retrieval stack. It asks them to accept one input they didn't have before — a boundary, computed and proven before the search call — and to respect it as a hard constraint rather than a suggestion.

Keep reading

See how this plays out stage by stage.