Modes
/mode takes no argument and cycles read-only to approve-each to auto and back around.
Shift-Tab does the same without typing. There is no /mode auto form, and typing one is a
command error rather than a mode change. The current mode is shown in the session.
approve-each is the default, not read-only, and that was a measured decision rather than
a preference. A fresh session defaulting to read-only and given a write task was blocked
repeatedly and produced nothing: five denials, then a turn that ended with no tool call and no
file created. What keeps approve-each from being an every-call prompt is the remembered
approval below.
A task that needs to write in read-only reports the block rather than failing the run, and the
run still exits successfully. Cycle out of it and ask again.
What counts as a write
The classification is per tool, and it is deliberately asymmetric.
A name the gate does not recognise is treated as a write. That direction is the point. MCP
opens the tool set to third parties, so “absent from the write list” stops being evidence of
safety. An unfamiliar tool costs you an approval instead of being waved through in all three
modes.
Two names are exceptions, and neither writes.
dispatch_subagents hands the child the parent’s
own permission mode, so a subagent’s bash re-enters this same gate at the same mode rather than
escaping it. skill reads one file you put in .seri/skills/ yourself.
See Tools for what each one does.
Remembering an answer
An approval prompt can remember your answer. “Always” is narrower than it sounds, in two directions at once. It is scoped to that one tool, and to the project you granted it in. Grants live inpermissions.yaml in your profile root, in two tiers.
Answering “always” only ever writes the project tier. Nothing in seri promotes a grant to
global:, so an approval you gave in one repository does not follow you into the next one.
The project is keyed on the resolved worktree path, case-folded on Windows and macOS, where the
same directory routinely has two spellings.
Only three kinds of grant can persist at all, and the list is closed.
bash and powershell cannot be approved permanently at all. A grant keyed on a tool name
says nothing about what a shell command will do, so an entry reading bash would hand over the
shell for good. seri refuses such an entry on read as well as on write, so hand-editing one into
the file does not work either.
An MCP grant is stored as mcp_<server>_<tool>@<digest>. The digest fingerprints that tool’s
name, description and input schema at the moment you approved it, because a server is a third
party and those three together are the whole contract you were shown. Change the tool on the
server’s end and the digest stops matching, so seri asks again rather than trusting your old
answer about a tool you never actually saw.
Reviewing what you granted
/permissions lists the write_file and edit grants in effect for the project you are in, and
labels each one by the tier it came from.
A tool with no grant in either tier is left out rather than shown as a third state, and grants
belonging to other projects are not listed.
Skipping the gate
--dangerously-skip-permissions runs every tool with no prompt for the whole process.
Cycling to auto is the same idea inside the session, with a keystroke to get back out of it.
What the gate cannot override
APreToolUse hook runs before the gate. A hook that blocks a call blocks it in every mode,
auto and --dangerously-skip-permissions included, and you are never asked to approve a call a
hook is about to refuse. See Hooks.
