scopes
A grant names a scope — the S in “may P do A on S” — and that scope is just a folder path. The same folder tree does a second job: it decides what each agent can see, not only what it may touch. One tree, two jobs. Messages inside a folder are its own conversation; messages in a sibling folder show up as ambient context the agent reads unasked; messages in a child folder stay isolated. So the hierarchy you build for permissions is the same one that bounds context.
folder = scope
Every group is a folder under the data dir: solo/inbox, corp/eng/sre, corp/eng/oncall. The folder path doubles as the identity of the agent that runs there and as the scope rules for what it sees. Path depth sets the tier: the instance root (0 slashes, like main) is tier 0; one-slash folders (like corp/eng) are tier 1 — these are “world” groups; anything deeper is tier 2+. Siblings share a parent.
Because one agent runs per group, the folder wall does the isolation. The corp/eng/sre agent carries the SRE team’s conversation history, diary, and skills. corp/eng/oncall carries the oncall team’s. There is no shared chat history to muddy — each agent’s Claude Code session lives in its own folder, with its own prompt window and its own memory.
same-level siblings observe each other
Two folders under the same parent see each other’s messages as ambient <observed> context on every turn. The default sibling list is “all folders sharing my immediate parent.” So corp/eng/sre and corp/eng/oncall both observe traffic in the other — useful when an incident in one is relevant to the other team.
The agent only sees a bounded slice, not the whole sibling backlog: see OBSERVE_WINDOW_MESSAGES and OBSERVE_WINDOW_CHARS for the instance default; routes.observe_window_messages and routes.observe_window_chars override per route.
Each topic in a folder tracks its own sessions.observed_cursor, so one topic consuming an observed message does not hide it from another topic in the same folder (spec 5/F).
children are isolated
A child folder is not a sibling. corp/eng/oncall/incident-42 sits under oncall; the parent does not auto-observe the child, and the child does not auto-observe its uncles. To break the wall, route the child’s traffic up explicitly with a routing rule, or grant a specific cross-folder ACL.
This keeps deep hierarchies useful: spin up an incident folder, talk freely, archive when done — no noise upstream.
worked example
corp/
eng/
sre/ ← sees oncall (sibling)
oncall/ ← sees sre (sibling)
incident-42/ ← isolated; oncall does not auto-see it
An SRE asking a question in corp/eng/sre sees recent oncall chatter as ambient. An incident commander running corp/eng/oncall/incident-42 is talking only to the incident folder’s agent — the broader oncall channel is quiet, the incident folder stays focused.
per-topic observed cursor
Inside one folder, every topic tracks its own watermark over observed messages. So #triage and #deploy in the same folder both see the same ambient sidechannel; one consuming it doesn’t hide it from the other. The cursor is per (folder, topic) in sessions.observed_cursor.
go deeper
Folder hierarchy spec: specs/5/F. Topic lineage and the per-topic observed cursor: topics. How a message lands in a folder in the first place: routing.