seisin (n.) — the legal possession of a piece of land. Not who owns it on paper: who holds it now.
OS-enforced permissions and ownership for AI agents.
Run multiple coding agents without letting them overwrite each other’s work.
Each role gets its own files, keys and network access. The OS enforces the boundary. When one agent needs another role’s territory, seisin tells you who owns it — turning a dead end into a handoff.
What you see
Other permission layers answer yes or no, and the good ones say which rule it was. Answering “no, and it belongs to backend” is the part an operating system cannot know.
frontend reaches into src/api/. The kernel denies it; seisin names the owner and leaves a request behind.The agent can ask before it reaches, too — seisin whose src/api/orders.ts answers from inside the sandbox.
The loop
Nothing is granted by an agent, and nothing is granted through the MCP server. Granting happens in a terminal or in the console, by a person.
Measured in real use
In one six-day deployment with four teams of agents, the boundary did more than deny writes. It showed what the policy was costing and where the noise came from.
Every denied read and write recorded during the window.
Were .git/index.lock. The fix was not a wider grant; it was removing an unnecessary write with GIT_OPTIONAL_LOCKS=0.
Deduplication collapsed 1,445 recorded asks into one relevant item waiting for a person.
One deployment, not a benchmark. The full method and the numbers that did not reproduce are in the field notes.
Policy review
seisin review turns runtime history into questions you can act on: where a role keeps being denied, which grants were never used, and which paths nobody owns.
Trimmed: each section also says why it matters, and an unowned path says what kind of thing it is — territory (ownable), or git's, temporary, build output, a credential — because only the first one wants an owner. This is not automatic policy mutation. It is evidence for a person deciding whether to narrow, transfer or add ownership.
How you use it
npm install -g seisinOn Linux, three system packages first — the README lists them.seisin initProposes a policy from what your repo already says: .claude/agents/, then CODEOWNERS, then one role per top-level folder that holds code. It proposes — a generated policy you did not read is not a policy.seisin checkThe map first, then one line for each way it does not hold — --verbose says why each matters. Read it before you trust it.seisin wireLets the agent record what it does, so a denial can be explained afterwards.seisin run <role> -- claude -p "…"Runs the agent as one of the roles seisin check lists, inside its own territory. Anything not listed is denied — there is no permissive default.The policy
[keys]
dir = ".secrets"
[network]
allow = ["github.com", "*.github.com"]
[roles.frontend]
writes = ["src/web/**", "public/**"]
keys = ["netlify-token.txt"]
[roles.backend]
writes = ["src/api/**", "migrations/**"]
keys = ["database-url.txt"]
network = ["api.stripe.com"]
[roles.ops]
writes = ["deploy/**"]
control_files = ["ide"] # its own .vscode/
scheme:// reference a provider resolves outside the sandbox — the role gets the value, never the file.[network] is reachable by every role, including the ones whose job is to reach nothing..claude/ and .mcp.json are closed to every role. Editor settings (.vscode/, .cursor/, .windsurf/) are protected too, unless a role is handed "ide"; instruction files (CLAUDE.md, AGENTS.md…) only when [protect] instructions = true.ProxyCommand the runtime wires up cannot send any. On Linux the runtime routes git’s SSH through an authenticated proxy instead (read from its source, not measured here). Use an HTTPS remote for git, and on macOS run SSH deploys outside the confined run.
Three ways in
A change to what any of them says lands in all three. That is a rule of the repo, and a test holds one half of it.
And what every agent runs under. run, check, whose, walls, grant, decline.
seisin ui — opens on what is waiting on a person. A grant needs a reason, says what it covers before the click, and shows the line it wrote.
An agent asking about its own situation. Read-only by design — granting is never a tool call.
The honest parts
.claude/, .mcp.json — is denied to every role, and so are editor settings unless the policy hands them to one.seisin log verify says when either was changed.@anthropic-ai/sandbox-runtime by default, tartaros, or one you declare; the OS does the enforcing.read = "all" that includes ~/.ssh, ~/.aws and ~/.npmrc; read = "territory" closes those homes. seisin scan helps find the rest.