grant manage_root_agent by stored permission only, not by the name ruth
Permission::default_for and hive-sh4re's MANAGER_AGENT are gone: every agent with no permissions key holds Permission::DEFAULT, ruth included. The agent-name parameters that only fed default_for go with it (permissions::effective, HiveCopy::before_read/after_read and their callers). swarm-controller seeds the grant ruth held by name: at start, a declared ruth whose permissions are unset gets DEFAULT plus manage_root_agent written into her key, once, logged. A set key is never touched. It is a one-shot to delete once every swarm has passed it. The swarm UI setup assistant opens the create form with manage_root_agent checked, so a new ruth is created with the grant. permissions_import no longer adds ruth to the import or splits her default. Docs and help text no longer say ruth holds the grant by default; swarmctl-cli.md regenerated.
This commit is contained in:
parent
9258563f9c
commit
7b5400ecb8
26 changed files with 380 additions and 216 deletions
|
|
@ -78,9 +78,9 @@ module docs for the exact call chain.
|
|||
|
||||
## Hard-coded manager behaviour
|
||||
|
||||
The **manager (`ruth`)** differs from other agents in naming/bootstrap,
|
||||
its socket flavour and its default permissions; its prompt, tool
|
||||
allow-list and state dirs work as for every other agent.
|
||||
The **manager (`ruth`)** differs from other agents in naming/bootstrap
|
||||
and its socket flavour; its permissions, prompt, tool allow-list and
|
||||
state dirs work as for every other agent.
|
||||
|
||||
<!-- vale write-good.Passive = NO -->
|
||||
|
||||
|
|
@ -97,13 +97,13 @@ allow-list and state dirs work as for every other agent.
|
|||
both flavours; matrix, bash and forge don't call it — their
|
||||
notifications push a todo on the harness's in-agent socket (see
|
||||
[`docs/turn-loop/mcp.md`](../turn-loop/mcp.md#waking-the-agent-from-inside-the-container)).
|
||||
- **Storage/mounts** — the manager container gets
|
||||
- **Storage/mounts** — the `manage_root_agent` permission, which the swarm
|
||||
UI's setup assistant creates ruth with, gets a container
|
||||
`/var/lib/hyperhive/agents` bind-mounted RW at `/agents` (so it can
|
||||
manage any agent's state dir — config isn't authored there, since a
|
||||
real config change is a PR from a clone), plus RO mounts for
|
||||
`/applied` (diff against what's deployed) and `/meta` (system-wide
|
||||
deploy log). That grant is the `manage_root_agent` permission: ruth
|
||||
holds it by default, and any agent holding it gets the same mounts.
|
||||
deploy log). Any agent holding it gets the same mounts.
|
||||
The operator dashboard's `POST /api/meta-update` is the only path
|
||||
that writes `flake.lock`.
|
||||
- **Prompt** — identical for every container: `prompts/system.md`
|
||||
|
|
@ -115,8 +115,8 @@ allow-list and state dirs work as for every other agent.
|
|||
(`filter_role_blocks(SAMPLE, "manager")`).
|
||||
- **Tool allow-list** — the MCP tools claude sees come from the agent's
|
||||
permissions alone, the same mechanism for every agent
|
||||
([`docs/turn-loop/mcp.md`](../turn-loop/mcp.md)). Ruth's default
|
||||
permissions add only `manage_root_agent` (`Permission::default_for`).
|
||||
([`docs/turn-loop/mcp.md`](../turn-loop/mcp.md)). Ruth's permissions
|
||||
are the default plus `manage_root_agent`, stored for her like any grant.
|
||||
- **State dirs** — _not_ special-cased: `HYPERHIVE_STATE_DIR` is
|
||||
injected uniformly via `systemd.globalEnvironment` for every
|
||||
container including the manager, so all token/state paths resolve
|
||||
|
|
|
|||
|
|
@ -270,10 +270,13 @@ dirs.
|
|||
⚠️ nspawn bakes bind flags at container start, so hive-c0re restarts
|
||||
an agent, after its current turn, when its `manage_root_agent` changes.
|
||||
|
||||
The root agent holds the permission by default: an agent whose record
|
||||
leaves `permissions` unset gets the default, which includes
|
||||
`manage_root_agent` for `ruth` and for no other agent. Setting her
|
||||
permissions without it revokes it.
|
||||
No agent holds the permission by default: an agent whose record leaves
|
||||
`permissions` unset gets the default, which doesn't include
|
||||
`manage_root_agent`, whatever the agent's name. The swarm UI's setup
|
||||
assistant creates ruth with it. For a ruth that predates that, whose
|
||||
permissions were unset, swarm-controller writes the default plus
|
||||
`manage_root_agent` into her key once at start, so she keeps her mounts;
|
||||
it never touches a key that's already set.
|
||||
|
||||
Each proposed repo (`/agents/<n>/config/`) is pre-configured
|
||||
with `applied` as a git remote pointing at
|
||||
|
|
@ -331,8 +334,10 @@ Differences from sub-agents:
|
|||
(vs `agent-base`).
|
||||
- Web UI port via `lifecycle::agent_web_port("ruth")` — same
|
||||
FNV-1a hash as every other agent (8100..8999 range).
|
||||
- `set_nspawn_flags` adds two extra binds: `/var/lib/hyperhive/agents`
|
||||
→ `/agents` (RW) so the root agent can edit per-agent proposed repos,
|
||||
- The root agent holds `manage_root_agent` (the swarm UI's setup
|
||||
assistant creates her with it), for which `set_nspawn_flags` adds two extra binds:
|
||||
`/var/lib/hyperhive/agents` → `/agents` (RW) so the root agent can edit
|
||||
per-agent proposed repos,
|
||||
and `/var/lib/hyperhive/applied` → `/applied` (RO) so the root agent
|
||||
can `git fetch` deployed/failed/denied tags from any agent's
|
||||
authoritative applied repo (see "Root-agent view of applied" below).
|
||||
|
|
|
|||
|
|
@ -408,7 +408,8 @@ Contents:
|
|||
to live here; nothing reads or writes it now. An old copy in the meta repo
|
||||
is harmless and you can delete it.
|
||||
|
||||
The root agent has the meta dir RO-mounted at `/meta/`.
|
||||
An agent holding `manage_root_agent`, normally ruth, has the meta dir
|
||||
RO-mounted at `/meta/`.
|
||||
|
||||
Outside the meta repo, `/var/lib/hyperhive/swarm-agent-permissions.json`
|
||||
holds the permissions the swarm grants this hive's agents, as
|
||||
|
|
|
|||
|
|
@ -93,8 +93,10 @@ SSO login asks for its forge password once, to link the two.
|
|||
|
||||
hive-c0re creates no agent at startup. You create ruth, the manager agent,
|
||||
like any other: open the swarm UI start page and click the paperclip, which
|
||||
opens the create form with `ruth` filled in. The form declares her, creates
|
||||
her config repo and deploys her to the hive you pick.
|
||||
opens the create form with `ruth` filled in and the `manage_root_agent`
|
||||
permission checked: that permission mounts the other agents into her
|
||||
container so she can recover them. The form declares her, creates her
|
||||
config repo and deploys her to the hive you pick.
|
||||
|
||||
The swarm declares a new agent `paused`, so without a further step ruth runs
|
||||
but drives no turns. Open `/agents` in the swarm UI and set her `up` from her
|
||||
|
|
|
|||
|
|
@ -301,8 +301,8 @@ the agent's key in the `agent-permissions` KV bucket
|
|||
writes. Set them with `swarmctl agent permissions get|set|clear <agent>`
|
||||
(`/api/agents/{name}/permissions`), or on the swarm UI's create-agent screen
|
||||
(`permissions` in `POST /api/agents`). A missing key or an unset field means
|
||||
the default (`Permission::default_for`): `messaging`, `meta`, `inbox`,
|
||||
`execution`, plus `manage_root_agent` for `ruth`. `"permissions": []` grants
|
||||
the default (`Permission::DEFAULT`): `messaging`, `meta`, `inbox`,
|
||||
`execution`, for every agent whatever its name. `"permissions": []` grants
|
||||
none.
|
||||
|
||||
**How a change applies** —
|
||||
|
|
|
|||
|
|
@ -207,7 +207,7 @@ Clear every field for an agent, so it goes back to its own values
|
|||
|
||||
Show or change the permissions the swarm grants an agent.
|
||||
|
||||
The agent applies its tool permissions at its next turn; the hive running it restarts it, after its current turn, when `manage_root_agent` changes. Unset leaves the agent on the default: `messaging`, `meta`, `inbox`, `execution`, plus `manage_root_agent` for `ruth`.
|
||||
The agent applies its tool permissions at its next turn; the hive running it restarts it, after its current turn, when `manage_root_agent` changes. Unset leaves the agent on the default: `messaging`, `meta`, `inbox`, `execution`, whatever its name.
|
||||
|
||||
**Usage:** `swarmctl agent permissions <COMMAND>`
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue