Trust tiers
Trust is set per contact and enforced by a dedicated process with its own deny list. Tiers 1 to 3 ship. Tier 4 does not exist and is not planned.
The threat
Your friend is not the threat. Your friend’s Claude, which read a poisoned README an hour ago, is. So every rule here is about what the other person’s agent can cause on your machine, and every one of them is enforced by a process boundary, not a prompt.
| Tier | What the other side’s agent can cause | Enforced by |
|---|---|---|
| 1 | Words only. No Claude process exists for them. | Process absence |
| 2 | Reads what your agent hands it. No writes, no shell, no network. The default after the four words are confirmed. | Deny lists plus a dedicated process |
| 3 | Proposes writes as patches in a throwaway worktree. You apply them. | Deny lists, worktree boundary, path guard |
| 4 | Full agency. Not shipped, and not planned. | Would need a separate OS user |
Why a process, not a prompt
Tiers are enforced by giving each peer its own claude process with its own settings, because a permission hook receives a session id and never an originator. There is no other way for a permission rule to know which peer caused a tool call.
Tiers are expressed as deny lists, never allow lists, because deny beats allow at every scope and survives bypassPermissions. The peer process runs with --setting-sources user only, so a hostile repository’s own settings cannot disable hooks, and its environment is stripped of every ANTHROPIC_* key and base URL before it starts.
Tier 2, the default
The agent’s working directory is the conversation’s own folder under ~/.seshi. Denied outright, by tool name: Bash and PowerShell; Write, Edit and NotebookEdit; every agent, task, workflow and scheduling tool; WebFetch, WebSearch and every other egress; every MCP tool; and the tools that could escape into another session or worktree. Denied reads, filesystem wide: .env*, *.pem, *.key, *.p12, *.pfx, id_*, .git-credentials, .npmrc, .netrc, .pypirc, and everything under ~/.ssh, ~/.aws, ~/.gnupg, ~/.kube, ~/.docker, ~/.azure, ~/.config/gcloud, ~/Library/Keychains, ~/.claude, your shell rc files and history, and ~/.seshi itself. Bypass-permissions mode and auto mode are disabled for the process.
The residual, stated plainly: there is no outbound secret scanning. The other side’s agent cannot read your credentials, but your own agent can paraphrase something confidential it legitimately read, and that reaches the other person. Do not point a first run at a client repo under NDA.
Tier 3, patches in a worktree
seshi trust dave 3
When a tier 3 contact converses, seshi cuts a git worktree at ~/.seshi/convos/<id>/worktree on a branch named seshi/<peer>/<convo> from the repository you started in, so your current directory must be a git repository. Their agent may Write and Edit inside that worktree and nowhere else; Bash stays denied, and so do edits to .git, .claude, CLAUDE.md, AGENTS.md, .mcp.json, editor settings, workflows and package.json. At the close the staged diff lands in your DECISION.md under ## Proposed changes and the worktree is removed. Your own checkout is never touched. Read the patch, then apply it yourself if you agree.
Tier 1
Every new contact starts at tier 1, and start and join raise it to 2 the moment the four words are confirmed. A contact left at tier 1 cannot hold a conversation at all in the current CLI: there is no process for their words to reach.
Managing contacts
seshi contacts # who you are paired with, and at what tier
seshi trust <name> <1|2|3> # set what a contact's agent may do
seshi verify <name> # mark the four words confirmed, if you are recovering by hand
Raising a tier for a contact whose words were never confirmed is refused:
dave has not been verified. Compare your four safety words with them over a
channel other than the one that sent the link, then run: seshi verify dave
Tiers change only when you type it. A peer asking to be raised is wrong or lying, and your agent is told so.
The rule that makes tiers real
A peer never authors its own identity. Who sent a turn is stamped by the receiving daemon from the authenticated transport. Any identity claim inside a message body is decoration and is never read for a trust decision.
Without that, trust tiers are theatre. It is enforced three times over: the relay stamps the sender off the socket that proved its keys; the receiving daemon throws that label away and re-derives the sender from whichever paired contact’s key verifies the signature; and the wrapper the model sees says the same thing in words. The rule was learned by watching an impostor probe arrive during development carrying from="dan" and a key that was the literal string FAKE. There is no Dan.
every command on this page is the real one, from the source as shipped