Watch
0
0
Fork
You've already forked hyperhive
0

docs: handbook states what the code does (fact sweep fixes)

This commit is contained in:
atlas 2026-11-10 00:51:59 +01:00 • committed by mara
commit 409e7ee5a0

View file

@ -70,26 +70,21 @@ merged by an operator on the forge (see [Config changes](#config-changes)).
### Reminder delivery: file-path semantics
A reminder may carry a `file_path` (the agent-visible path inside its
container, for example `/agents/<name>/state/foo.md`). On delivery hive-c0re:
container, for example `/agents/<name>/state/foo.md`). The agent's own
harness (`hive-agent`, inside the container) delivers the reminder when it
falls due:
1. **Translates** the container path to the host path
(`/var/lib/hyperhive/agents/<name>/state/foo.md`) so c0re can write
from outside the container.
2. **Validates** the path: rejects anything outside the agent's own state
subtree, containing `..` (path traversal), or with an empty relative
tail. On rejection hive-c0re skips the write and delivers the
original message inline with a warning — the reminder still fires.
3. **Defends against symlink escape**: after `create_dir_all`, hive-c0re
canonicalizes the parent dir and re-verifies it lives under the agent's host
state root. hive-c0re opens the final file with
`O_NOFOLLOW | O_CREAT | O_TRUNC` so an existing symlink at the
basename can't redirect the write to an arbitrary host path.
4. **Writes the body to disk** and delivers a short pointer message in its
place, keeping the agent's inbox / wake-prompt small while the agent
reads the bulky payload out of band.
1. **Validates** the path: it must resolve under the agent's own state
directory, with no `..` components and a non-empty relative tail. On
rejection, or on a write failure, the harness delivers the original
message inline with a warning note — the reminder still fires.
2. **Writes the body to disk** at that path and delivers a short pointer
message in its place, keeping the agent's inbox / wake-prompt small
while the agent reads the bulky payload out of band.
`Broker::deliver_reminders_batch` handles atomicity of the inbox INSERT + `reminders.sent_at` UPDATE; the scheduler only computes the
body strings before calling it.
The write happens inside the agent's container, so hive-c0re takes no
part in it and there is no symlink-escape defence: the harness is the
agent, and the container boundary is the sandbox.
### Destroy semantics
@ -122,8 +117,9 @@ deploys.
What `hive-c0re` still keeps under `/var/lib/hyperhive/meta/` is plain
state, bound read-only into the root agent's container as `/meta`:
`topology.json`, the swarm resource limits, and the permission seed files of a
hive that predates the swarm's permissions. `agent_set::refresh(agents:
`topology.json` and the swarm resource limits. The permissions the swarm
grants live outside it, in `/var/lib/hyperhive/swarm-agent-permissions.json`.
`agent_set::refresh(agents:
&[AgentSpec])` keeps `topology.json`, the gateway's agent-socket map and its
nginx include in line with the live agents. `provision_container`, `destroy`,
`rebuild` and the startup migration call it. It refuses an empty agent list,
@ -243,8 +239,8 @@ mounts via `set_nspawn_flags`:
- `/var/lib/hyperhive/meta/` → `/meta/` (RO) — the hive's plain state
(topology, swarm limits).
An agent without the permission only has its direct children's config
dirs.
An agent without the permission gets only its own `state`, `harness` and
`work` dirs: no other agent's dirs and no `/meta`.
⚠️ nspawn bakes bind flags at container start, so hive-c0re restarts
an agent, after its current turn, when its `manage_root_agent` changes.