docs(approvals): reframe stale 'the manager' as the root agent
The last docs/ piece of the manager-cleanup. The manager is no longer a structural role — root-ness is purely topological. Reframe: - title 'Approvals + manager + helper events' -> 'Approvals + helper events' - section headers: 'Manager view of applied'/'Manager policy'/'Manager (ruth) is hive-c0re-managed'/'Helper events to the manager' -> root-agent / root-bootstrap-container equivalents - body prose: 'the manager (ruth)' -> 'the root agent' (or 'the submitter' in the approval-flow steps) - authority semantics: 'manager-only' -> approvals are submitted by an agent with the approvals tool group, for its direct children - dropped the stale 'the manager refuses to destroy itself' line (the bootstrap container is now destroyable + transient; recreated on startup) Kept the genuine code/protocol identifiers (nixosConfigurations.manager, manager_server, role:manager prompt block, notify_manager, the /run/hyperhive/manager/ socket path) — renaming those would diverge from the source (de-hardcoding is its own backend cleanup).
This commit is contained in:
parent
e816cf4d72
commit
136102cd27
1 changed files with 43 additions and 33 deletions
|
|
@ -11,9 +11,12 @@ informed about what happens after a decision lands.
|
||||||
## End-to-end approval flow
|
## End-to-end approval flow
|
||||||
|
|
||||||
1. The submitting agent (the child's parent, holding the `approvals`
|
1. The submitting agent (the child's parent, holding the `approvals`
|
||||||
tool group) edits files under the child's `/agents/<name>/config/`
|
tool group) edits files in the child's proposed config repo
|
||||||
(any tracked path, but `agent.nix` is the contract entry point) and
|
(any tracked path, but `agent.nix` is the contract entry point)
|
||||||
commits with its own git identity.
|
and commits with its own git identity. The parent's container has
|
||||||
|
the child's proposed config repo bind-mounted read-write at
|
||||||
|
`/agents/<name>/config/` (topology-driven via `set_nspawn_flags`;
|
||||||
|
the agent's *own* config at `/agents/<self>/config/` is read-only).
|
||||||
2. The submitting agent submits the commit sha via `request_apply_commit(agent,
|
2. The submitting agent submits the commit sha via `request_apply_commit(agent,
|
||||||
commit_ref)`. `commit_ref` must be a commit **sha** (7-40 hex
|
commit_ref)`. `commit_ref` must be a commit **sha** (7-40 hex
|
||||||
chars, short or full) — a branch or tag name is rejected so the
|
chars, short or full) — a branch or tag name is rejected so the
|
||||||
|
|
@ -88,7 +91,9 @@ without it has nothing of its own to withdraw.
|
||||||
`InitConfig` approvals are the first step in a two-step spawn
|
`InitConfig` approvals are the first step in a two-step spawn
|
||||||
flow. On approve, hive-c0re seeds the proposed config repo with
|
flow. On approve, hive-c0re seeds the proposed config repo with
|
||||||
a default `agent.nix` template and sends `HelperEvent::ConfigReady { agent }`
|
a default `agent.nix` template and sends `HelperEvent::ConfigReady { agent }`
|
||||||
to the root agent. The submitting agent then reviews,
|
to the root agent's inbox (current limitation — all helper events route
|
||||||
|
to the root agent via `notify_manager` regardless of which agent
|
||||||
|
submitted; tracked in #1953). The submitting agent then reviews,
|
||||||
edits, and commits the template before calling `request_apply_commit`
|
edits, and commits the template before calling `request_apply_commit`
|
||||||
to proceed to an `ApplyCommit` approval. The first `ApplyCommit`
|
to proceed to an `ApplyCommit` approval. The first `ApplyCommit`
|
||||||
creates the container; subsequent ones rebuild it with new config.
|
creates the container; subsequent ones rebuild it with new config.
|
||||||
|
|
@ -400,26 +405,32 @@ The dashboard deep-links into this org — a `config repo` link
|
||||||
per container row and a `commit on forge` link per approval
|
per container row and a `commit on forge` link per approval
|
||||||
card. See `docs/web-ui.md`.
|
card. See `docs/web-ui.md`.
|
||||||
|
|
||||||
### Root-agent view of applied + meta
|
### Submitting agent's view of config repos
|
||||||
|
|
||||||
The root agent container gets three host-side bind mounts via
|
Every parent agent's container has its **direct children's** proposed
|
||||||
`set_nspawn_flags`:
|
config repos bind-mounted read-write (topology-driven: `lifecycle.rs`
|
||||||
|
calls `bind_child_agent_dirs` for each entry in
|
||||||
|
`topology::children_of(agent_name)`). An agent with the `approvals`
|
||||||
|
tool group can therefore edit, commit, and submit changes for any of
|
||||||
|
its direct children directly inside its container at `/agents/<child>/config/`.
|
||||||
|
|
||||||
- `/var/lib/hyperhive/agents/` → `/agents/` (RW) — proposed
|
Agents holding the `can_manage_top_level_agents` topology role get
|
||||||
repos. The root agent edits + commits per-agent config here.
|
additional host-side bind mounts via `set_nspawn_flags`:
|
||||||
- `/var/lib/hyperhive/applied/` → `/applied/` (RO) — every
|
|
||||||
agent's authoritative applied repo, including `.git`.
|
- `/var/lib/hyperhive/agents/` → `/agents/` (RW) — all top-level
|
||||||
|
agents' proposed repos (not just direct children).
|
||||||
|
- `/var/lib/hyperhive/applied/` → `/applied/` (RO) — every agent's
|
||||||
|
authoritative applied repo, including `.git`.
|
||||||
- `/var/lib/hyperhive/meta/` → `/meta/` (RO) — the swarm-wide
|
- `/var/lib/hyperhive/meta/` → `/meta/` (RO) — the swarm-wide
|
||||||
deploy flake.
|
deploy flake.
|
||||||
|
|
||||||
This is the **root agent's** view — RW over *every* agent's config. An
|
The root agent holds this role; a sub-manager that only manages a
|
||||||
agent with the `approvals` group that owns a subtree (a sub-manager) has
|
subtree does not, and only has its direct children's config dirs.
|
||||||
the equivalent RW scoped to its own children's config repos.
|
|
||||||
|
|
||||||
Each proposed repo (`/agents/<n>/config/`) is pre-configured
|
Each proposed repo (`/agents/<n>/config/`) is pre-configured
|
||||||
with `applied` as a git remote pointing at
|
with `applied` as a git remote pointing at
|
||||||
`/applied/<n>/.git`. Useful incantations from inside the
|
`/applied/<n>/.git`. Useful incantations from inside an agent with
|
||||||
root agent's container:
|
the full `/applied` mount:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
git -C /agents/<n>/config fetch applied
|
git -C /agents/<n>/config fetch applied
|
||||||
|
|
@ -433,9 +444,8 @@ git -C /meta log --oneline # swarm-wide deplo
|
||||||
cat /meta/flake.lock | jq '.nodes | with_entries(select(.key | startswith("agent-")))'
|
cat /meta/flake.lock | jq '.nodes | with_entries(select(.key | startswith("agent-")))'
|
||||||
```
|
```
|
||||||
|
|
||||||
The RO binds block push at the kernel level, so the root agent
|
The RO binds block push at the kernel level — git plumbing inside the
|
||||||
can only fetch / read — git plumbing inside the container
|
container cannot corrupt either authoritative repo.
|
||||||
cannot corrupt either authoritative repo.
|
|
||||||
|
|
||||||
## Migration from the pre-tag / pre-meta schemes
|
## Migration from the pre-tag / pre-meta schemes
|
||||||
|
|
||||||
|
|
@ -495,25 +505,25 @@ updates the root agent itself.
|
||||||
|
|
||||||
## Root-agent policy
|
## Root-agent policy
|
||||||
|
|
||||||
From `hive-ag3nt/prompts/system.md` (`<!-- role:manager -->` block,
|
The system prompt (`hive-ag3nt/prompts/system.md`, rendered via
|
||||||
rendered via `hive_ag3nt::prompt::render`): the root agent does NOT
|
`hive_ag3nt::prompt::render`) is the **same for every agent**; what
|
||||||
rubber-stamp sub-agent config requests. It verifies (role match,
|
varies is which MCP tools are surfaced (gated by tool groups and
|
||||||
package legitimacy, cheaper alternative, blast radius) before
|
capabilities in `agent.nix`). There is no `role:manager` block that
|
||||||
committing and calling `request_apply_commit`.
|
renders only for the root agent. The root agent's approval-gating
|
||||||
|
behaviour comes from its CLAUDE.md / agent-specific instructions, not
|
||||||
|
the system prompt template.
|
||||||
|
|
||||||
For ambiguous cases or anything that needs human signal, the
|
`ask(question, options?, multi?, ttl_seconds?, to?)` is available to
|
||||||
the root agent calls `ask(question, options?, multi?, ttl_seconds?, to?)` —
|
**any agent** — it queues a question and returns the id immediately.
|
||||||
queues the question and returns the id immediately. When `to` is
|
When `to` is omitted (or `"operator"`) the question shows up on the
|
||||||
omitted (or `"operator"`) the question shows up on the dashboard;
|
dashboard; when `to` is another agent's name, the recipient receives a
|
||||||
when `to` is a sub-agent's name, the recipient receives a
|
|
||||||
`HelperEvent::QuestionAsked` and answers via their own `answer`
|
`HelperEvent::QuestionAsked` and answers via their own `answer`
|
||||||
tool. Either way the answer arrives back as
|
tool. Either way the answer arrives back as
|
||||||
`HelperEvent::QuestionAnswered { id, question, answer, answerer }`
|
`HelperEvent::QuestionAnswered { id, question, answer, answerer }`
|
||||||
in the asker's inbox. Storage is `hive-c0re::operator_questions`
|
in the asker's inbox. Storage is `hive-c0re::operator_questions`
|
||||||
(sqlite) — same table, with a nullable `target` column
|
(sqlite) — same table, with a nullable `target` column
|
||||||
(NULL = operator). Dispatch goes through
|
(NULL = operator). Dispatch goes through
|
||||||
`hive-c0re/src/questions.rs::{handle_ask, handle_answer}` so both
|
`hive-c0re/src/questions.rs::{handle_ask, handle_answer}`. The answer flow is:
|
||||||
the agent + root-agent surfaces stay aligned. The answer flow is:
|
|
||||||
|
|
||||||
```
|
```
|
||||||
POST /answer-question/{id} agent: Answer { id, answer }
|
POST /answer-question/{id} agent: Answer { id, answer }
|
||||||
|
|
@ -526,7 +536,7 @@ POST /answer-question/{id} agent: Answer { id, answer }
|
||||||
Two more paths resolve a pending question with a sentinel answer:
|
Two more paths resolve a pending question with a sentinel answer:
|
||||||
|
|
||||||
- `POST /cancel-question/{id}` (✗ CANC3L button on the dashboard)
|
- `POST /cancel-question/{id}` (✗ CANC3L button on the dashboard)
|
||||||
resolves with `[cancelled]`. The root agent sees a terminal state
|
resolves with `[cancelled]`. The asking agent sees a terminal state
|
||||||
and can fall back.
|
and can fall back.
|
||||||
- `ttl_seconds` deadline: a tokio watchdog spawned at submit time
|
- `ttl_seconds` deadline: a tokio watchdog spawned at submit time
|
||||||
fires `answer(id, "[expired]")` once the ttl runs out. Already-
|
fires `answer(id, "[expired]")` once the ttl runs out. Already-
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue