Blog · 15 September 2026 · 3 min read

The space first, the search second

When two clients' context lives in the same place, one number has to be zero for ever: what crosses from one to the other. Why esfis does not filter after searching, how policies are applied and what is recorded about every delivery.

The day an agent working for one client receives a decision belonging to another, the problem is not that the answer is worse. The problem is that information got out that was never supposed to. So in esfis the space is not one more ranking signal: it is the first thing checked.

Filtering at the end is not enough

The temptation is to search the whole database and discard what does not belong at the end. It works until it does not: a limit that cuts before the filter, a score that gets recorded, an item that slips into a summary. Anything that gets as far as being scored can end up somewhere.

In esfis the order is this, and the order is itself the policy:

space → permissions → currency → relevance → limit

First it decides what this AI could see from this space, and only that gets scored. A perfect match belonging to another client does not enter the calculation at all, however much it looks like the question. An automated test watches this: Acme authenticates with Auth0, Globex with Clerk, and a question asked from Acme can never return Clerk.

Where the space comes from

An item with no space is personal and goes everywhere: which language you want answers in, or how you like your code written. An item with a space only surfaces inside it.

The agent does not have to say where it is. The space is inferred from the folder the client started the MCP server in: the space with the longest path containing it wins. Adding a folder in the app already creates its space, and the ESFIS_SPACE variable pins it if you need to. When an agent supersedes an item without naming a space, the new one inherits the old one's space.

Who sees what

Policies are applied from the most specific to the most general: this AI in this space, this AI everywhere, everyone in this space and, finally, everyone. If there is no rule, access is allowed.

esfis --deny '*' acme
esfis --allow claude-code acme

Since version 1.8 you can also do it in Settings › Spaces, without opening a terminal.

Denying access does not only block reading. An agent that cannot see a space cannot write to it, supersede anything in it or forget anything in it. And, for that AI, forget on an id it cannot see answers exactly as if the id did not exist: it does not even learn that it is there.

What gets recorded

Every recall over MCP leaves a delivery behind: which AI made it, from which space, with which question, what went in and what stayed out, with the reason. Identifiers and reasons are stored, not text. If you forget an item later on, it will not reappear in full in the trace.

esfis --why 212

The explanation is generated at the moment you ask for it. Until now, whatever stayed out for belonging to another space was only counted. Since 1.8, --why names the items that would have answered the question and goes on counting the rest. Those items are scored when you ask for the explanation, on your own screen; the delivery the agent received never saw them.

The number we watch

In Context, not memory we said there is one number that must always be zero: context from one space reaching another. This is the mechanism that keeps it there. The details are in the documentation.