docs: fix genuine passive-voice hits in docs/turn-loop

Fifth batch of the ongoing write-good.Passive pass (hyperhive#4042):
read all 42 hits across the four docs/turn-loop files in context and
rewrote the 36 with a clearly nameable actor, usually one already
sitting in the same sentence or established a sentence or two earlier
(the broker, the harness, drive_turn, the renderer, hive-c0re, or a
specific fn/type named right there). Left 6 alone: predicate-adjective
copulas that only look passive ("is gone", "Bash is disallowed", "is
documented behavior" — nothing actually acts on the subject), a
config-conditional idiom with no in-file inconsistency to fix ("when
hyperhive.docs.enable is set"), and a paraphrase of what a rendered
message tells the agent ("the docs are mounted at that path").

Verified via vale before/after: 42 -> 6 write-good.Passive hits in
docs/turn-loop, exactly the 6 left alone; error count and other
warning categories unchanged. Re-read every changed line in its full
surrounding context after editing (not just the vale count) per the
lesson from the docs/process batch.
This commit is contained in:
iris 2026-09-08 12:37:41 +02:00 committed by mara
commit 645887d87c
4 changed files with 65 additions and 65 deletions

View file

@ -29,10 +29,10 @@ agents) runs:
6. Wait for claude to exit and classify the turn's outcome from the 6. Wait for claude to exit and classify the turn's outcome from the
stream + exit — success, compaction, rate-limit, auth-failure, or stream + exit — success, compaction, rate-limit, auth-failure, or
hard failure. The outcome drives the post-turn action (see hard failure. The outcome drives the post-turn action (see
[Turn outcomes](#turn-outcomes)); compaction is handled inside the [Turn outcomes](#turn-outcomes)); the session handles compaction
session (see internally (see
[Compaction](claude-invocation.md#compaction)). Rate-limit [Compaction](claude-invocation.md#compaction)). This page describes
and auth-failure detection is described [below](#failure-detection-and-login). rate-limit and auth-failure detection [below](#failure-detection-and-login).
7. Emit `LiveEvent::TurnEnd { ok, note }`. Sleep `poll_ms` to avoid 7. Emit `LiveEvent::TurnEnd { ok, note }`. Sleep `poll_ms` to avoid
tight loops on transient failures. tight loops on transient failures.
@ -79,10 +79,10 @@ regardless of who sends them):
transport — no per-turn stdio child (eliminates the re-registration transport — no per-turn stdio child (eliminates the re-registration
race). race).
A small `Surface` trait, with one zero-sized impl, factors
`hive-agent`'s wire types (`hive_core_agent_sock::{Request, Response}` `hive-agent`'s wire types (`hive_core_agent_sock::{Request, Response}`
one unified enum shared by the agent and manager sockets) and its turn one unified enum shared by the agent and manager sockets) and its turn
loop are factored through a small `Surface` trait with one zero-sized loop, so the loop itself has no per-role branches. See
impl, so the loop itself has no per-role branches. See
`hive-agent/src/main.rs`'s module `hive-agent/src/main.rs`'s module
doc for the trait shape. doc for the trait shape.
@ -96,8 +96,8 @@ opens turn-stats sqlite, prepares the on-boot files (see
[claude-invocation](claude-invocation.md#on-boot-files)), [claude-invocation](claude-invocation.md#on-boot-files)),
installs claude plugins, spawns `web_ui::serve` + `vacuum::run`, installs claude plugins, spawns `web_ui::serve` + `vacuum::run`,
and either drops into `serve_loop` directly (`Online`) or parks on and either drops into `serve_loop` directly (`Online`) or parks on
the login flow first (`NeedsLogin`). Forge notifications are polled by the login flow first (`NeedsLogin`). Their own process polls forge
their own process, not this loop — see `hive-forge-notify` in notifications, not this loop — see `hive-forge-notify` in
[`forge.md`](../integrations/forge.md). [`forge.md`](../integrations/forge.md).
Boot also opens the todos store and the socket in-container producers Boot also opens the todos store and the socket in-container producers

View file

@ -27,8 +27,8 @@ harness unit's PATH. By default that's the `claude-code` in the agent's
own nixpkgs (the meta flake's `nixpkgs` input) via own nixpkgs (the meta flake's `nixpkgs` input) via
`environment.systemPackages`. Since that's typically a release channel and `environment.systemPackages`. Since that's typically a release channel and
this package moves fast, the operator can pin one hive-wide with this package moves fast, the operator can pin one hive-wide with
`services.hyperhive.c0re.claudeCodePackage`: its store path is written `services.hyperhive.c0re.claudeCodePackage`: hive-c0re writes its
into each agent's flake, and `claude` on PATH becomes a symlink to it store path into each agent's flake, and `claude` on PATH becomes a symlink to it
instead of the container's own `claude-code` — so there's only ever one instead of the container's own `claude-code` — so there's only ever one
`claude` in the container. Agents pick up a new build on their `claude` in the container. Agents pick up a new build on their
next rebuild, not live. See docs/process/gotchas.md::`claude-code` is unfree. next rebuild, not live. See docs/process/gotchas.md::`claude-code` is unfree.
@ -37,21 +37,21 @@ Hive-enforced settings ship at `/etc/claude-code/managed-settings.json`
(claude-code's canonical managed-settings path — precedence #1, (claude-code's canonical managed-settings path — precedence #1,
read-only, un-overridable), wired in `nix/agent-modules/claude-settings.nix` read-only, un-overridable), wired in `nix/agent-modules/claude-settings.nix`
from the `prompts/claude-settings.json` asset. `effortLevel` is from the `prompts/claude-settings.json` asset. `effortLevel` is
deliberately not in that file — effort is controlled live via the deliberately not in that file — the `--effort` flag
`--effort` flag (`HIVE_DEFAULT_EFFORT` / the per-agent UI slider), which (`HIVE_DEFAULT_EFFORT` / the per-agent UI slider) controls effort
managed scope would otherwise lock. live, which managed scope would otherwise lock.
`<name>` is read from `Bus::model()` on each turn. The initial The harness reads `<name>` from `Bus::model()` on each turn.
default is set by `hyperhive.model` in the agent's `agent.nix` `hyperhive.model` in the agent's `agent.nix` sets the initial
(NixOS option; propagates via `HIVE_DEFAULT_MODEL` env var; falls default (NixOS option; propagates via `HIVE_DEFAULT_MODEL` env var; falls
back to `"haiku"` if unset). The operator can flip it at runtime back to `"haiku"` if unset). The operator can flip it at runtime
with `/model <name>` in the web terminal — the next turn picks it with `/model <name>` in the web terminal — the next turn picks it
up. The choice is persisted to `/harness/hyperhive-model` so it up. The harness persists the choice to `/harness/hyperhive-model` so it
survives restart; override path: `HYPERHIVE_MODEL_FILE` env var survives restart; override path: `HYPERHIVE_MODEL_FILE` env var
for tests. for tests.
Context-window size is looked up per-model via `harness_state::context_window_tokens(model)` looks up
`harness_state::context_window_tokens(model)`. Resolution order (first context-window size per-model. Resolution order (first
match wins): match wins):
1. `HIVE_CONTEXT_WINDOW_TOKENS_<KEY>` env var, where `KEY` 1. `HIVE_CONTEXT_WINDOW_TOKENS_<KEY>` env var, where `KEY`
@ -65,8 +65,8 @@ match wins):
3. Hard fallback: `200_000` (conservative; only reached outside 3. Hard fallback: `200_000` (conservative; only reached outside
NixOS where the env vars aren't set). NixOS where the env vars aren't set).
The effective window drives watermarks and is exposed at runtime The effective window drives watermarks; the harness exposes it at
via `/api/state.context_window_tokens` so the UI can show a runtime via `/api/state.context_window_tokens` so the UI can show a
percentage-of-window ctx badge. percentage-of-window ctx badge.
**Session identity — a constant title.** Every turn keys on one fixed, **Session identity — a constant title.** Every turn keys on one fixed,
@ -86,8 +86,8 @@ context (it won't carry our title). claude stores sessions in
`--name` writes the title into the file as a `custom-title` event, which `--name` writes the title into the file as a `custom-title` event, which
is what `--resume <title>` resolves against. We never pass bare is what `--resume <title>` resolves against. We never pass bare
`--continue` (it resumes the _latest_ session in the cwd — the hijack `--continue` (it resumes the _latest_ session in the cwd — the hijack
vector). Automemory and dynamic workflows (the `/workflows` feature) are vector). The managed settings at `/etc/claude-code/managed-settings.json`
disabled via the managed settings at `/etc/claude-code/managed-settings.json`: disable automemory and dynamic workflows (the `/workflows` feature):
`disableWorkflows` keeps the `/workflows` machinery from spawning sub-runs `disableWorkflows` keeps the `/workflows` machinery from spawning sub-runs
that burn usage on the harness's autonomous turns. Claude's own native that burn usage on the harness's autonomous turns. Claude's own native
autocompact is **on**, at the widest window claude-code allows — see autocompact is **on**, at the widest window claude-code allows — see
@ -98,10 +98,10 @@ primary mechanism; hyperhive still owns that).
`/new-session` slash command). It does _not_ touch the session inline — `/new-session` slash command). It does _not_ touch the session inline —
that would race a mid-write claude process. Instead `Bus::request_session_reset()` that would race a mid-write claude process. Instead `Bus::request_session_reset()`
sets a one-shot flag consumed at the next turn boundary by `drive_turn`, sets a one-shot flag consumed at the next turn boundary by `drive_turn`,
which **archives** the current session: the backing `<uuid>.jsonl` is which **archives** the current session: it renames the backing
renamed to `<uuid>.jsonl.archived` (dropped out of claude's `*.jsonl` `<uuid>.jsonl` to `<uuid>.jsonl.archived` (dropped out of claude's `*.jsonl`
resolution glob, history preserved on disk, only the file carrying _our_ resolution glob, history preserved on disk, only the file carrying _our_
title — any `choom` session sharing the cwd is left alone). The next title — it leaves any `choom` session sharing the cwd alone). The next
turn's `--resume <title>` then misses and self-heals into a fresh session. turn's `--resume <title>` then misses and self-heals into a fresh session.
## Compaction ## Compaction
@ -126,9 +126,9 @@ into its `run`:
_then_ `/compact`s, so the agent can persist in-flight state before the _then_ `/compact`s, so the agent can persist in-flight state before the
detail collapses into a summary. detail collapses into a summary.
**Both triggers above are checked between hive-agent's own turns** — the **hive-agent checks both triggers above between its own turns** —
percent watermark is read from the last completed turn's telemetry `PercentPolicy::should_compact` reads the percent watermark from the
(`PercentPolicy::should_compact`, checked after `attempt()` returns), and last completed turn's telemetry (checked after `attempt()` returns), and
the reactive path only fires once claude-code has already refused a whole the reactive path only fires once claude-code has already refused a whole
turn as too long. Neither can see context growth happening _inside_ a turn as too long. Neither can see context growth happening _inside_ a
single long turn's own tool-calling before it returns — a turn whose tool single long turn's own tool-calling before it returns — a turn whose tool
@ -188,8 +188,8 @@ still applies.
benefit over starting fresh. `drive_turn` **archives** the current benefit over starting fresh. `drive_turn` **archives** the current
session (same mechanism as the operator reset — rename `<uuid>.jsonl` session (same mechanism as the operator reset — rename `<uuid>.jsonl`
`.archived`) so the next turn's `--resume <title>` misses and starts `.archived`) so the next turn's `--resume <title>` misses and starts
fresh. Unlike proactive compaction the session is dropped entirely, not fresh. Unlike proactive compaction, `drive_turn` drops the session
compacted — and _no_ preceding checkpoint turn runs, because any turn entirely rather than compacting it — and _no_ preceding checkpoint turn runs, because any turn
before the reset would just re-warm the cache and defeat the purpose. before the reset would just re-warm the cache and defeat the purpose.
Set `HIVE_AUTO_RESET_WATERMARK_TOKENS=0` to disable. Autoreset and the Set `HIVE_AUTO_RESET_WATERMARK_TOKENS=0` to disable. Autoreset and the
operator reset are mutually exclusive per turn (both archive → fresh operator reset are mutually exclusive per turn (both archive → fresh
@ -250,9 +250,9 @@ needs to `chown` a bind mount), once at startup:
**Marker grammar.** `<!-- role:X -->` opens a block; any **Marker grammar.** `<!-- role:X -->` opens a block; any
`<!-- /role:X -->` closes the current block. The renderer always uses `<!-- /role:X -->` closes the current block. The renderer always uses
role `agent`, so blocks with other role tags are elided. Nesting is NOT role `agent`, so it elides blocks with other role tags. Nesting is NOT
supported — a stray opener with no closer runs until end of file. supported — a stray opener with no closer runs until end of file.
Whitespace inside markers is tolerated (`<!--role:foo-->` parses the The renderer tolerates whitespace inside markers (`<!--role:foo-->` parses the
same as `<!-- role:foo -->`). Content outside any marker is always same as `<!-- role:foo -->`). Content outside any marker is always
included. Today's `system.md` carries no markers (single agent role) — included. Today's `system.md` carries no markers (single agent role) —
the grammar stays wired for a future manager / multi-role prompt. the grammar stays wired for a future manager / multi-role prompt.

View file

@ -14,7 +14,7 @@ hyperhive.docs.enable = true; # default: false (true for the manager agent)
Makes the hyperhive `docs/` tree available inside the container at a nix Makes the hyperhive `docs/` tree available inside the container at a nix
store path read from `$HIVE_DOCS_DIR`, and injects a single pointer store path read from `$HIVE_DOCS_DIR`, and injects a single pointer
sentence into the agent's system prompt so it knows the docs exist and sentence into the agent's system prompt so it knows the docs exist and
where to find them. The tree is served by `claude --add-dir` so the full where to find them. `claude --add-dir` serves the tree so the full
markdown is readable during every turn. markdown is readable during every turn.
Enabled by default only for the root/manager agent (`nix/templates/ruth.nix`). Any Enabled by default only for the root/manager agent (`nix/templates/ruth.nix`). Any
@ -81,8 +81,8 @@ entry has:
| `url` | yes | Absolute URL — may include a different port (the dashboard renders it as a plain anchor). | | `url` | yes | Absolute URL — may include a different port (the dashboard renders it as a plain anchor). |
| `icon` | no | Emoji or short glyph prefix. Defaults to empty string. | | `icon` | no | Emoji or short glyph prefix. Defaults to empty string. |
The list is written to `<state>/hyperhive-dashboard-links.json` by a A one-shot systemd unit writes the list to
one-shot systemd unit at container boot. The harness's own web UI `<state>/hyperhive-dashboard-links.json` at container boot. The harness's own web UI
(`agent_links` in `hive-agent/src/web_ui/state.rs`) reads the file on (`agent_links` in `hive-agent/src/web_ui/state.rs`) reads the file on
each `/api/state` snapshot and appends the entries to the per-agent each `/api/state` snapshot and appends the entries to the per-agent
nav as `kind = External` links — no `hive-c0re` / operator-dashboard nav as `kind = External` links — no `hive-c0re` / operator-dashboard
@ -116,8 +116,8 @@ attribute defines one overlay entry:
(`"games/bitburner"` serves at `/games/bitburner/…`). (`"games/bitburner"` serves at `/games/bitburner/…`).
Constraints: `target` must start with an alphanumeric or `_` and Constraints: `target` must start with an alphanumeric or `_` and
contain only alphanumerics, `_`, `.`, `/`, `-`. `..` segments are contain only alphanumerics, `_`, `.`, `/`, `-`. A config assertion
rejected by a config assertion. The merge step refuses to overwrite rejects `..` segments. The merge step refuses to overwrite
files already present in the default dist — pick a target name that files already present in the default dist — pick a target name that
doesn't collide with existing paths (`static/`, `index.html`, etc.). doesn't collide with existing paths (`static/`, `index.html`, etc.).
@ -153,8 +153,8 @@ to the wrong machine. With `null` the `tea-login` and `forge-avatar-sync`
units aren't generated at all: an absent integration rather than a units aren't generated at all: an absent integration rather than a
misdirected one. You don't normally set this — hive-c0re renders the misdirected one. You don't normally set this — hive-c0re renders the
host's real forge URL into every agent, and refuses to write a meta host's real forge URL into every agent, and refuses to write a meta
flake without one, so `null` only survives where the agent modules are flake without one, so `null` only survives where nix evaluates the
evaluated outside a hive. agent modules outside a hive.
**`hyperhive.matrix.url`** — homeserver URL used by **`hyperhive.matrix.url`** — homeserver URL used by
`hive-matrix-daemon` when connecting via the matrix-sdk. hive-c0re `hive-matrix-daemon` when connecting via the matrix-sdk. hive-c0re
@ -170,7 +170,7 @@ agent's own netns to the agent itself, not the homeserver). With
`null` the daemon has no homeserver and no-ops exactly as it does `null` the daemon has no homeserver and no-ops exactly as it does
without a token. The hive only forwards `HIVE_MATRIX_URL` when it without a token. The hive only forwards `HIVE_MATRIX_URL` when it
actually has a matrix vhost to name, so `null` survives where a hive actually has a matrix vhost to name, so `null` survives where a hive
runs no homeserver, or where the agent modules are evaluated outside a runs no homeserver, or where nix evaluates the agent modules outside a
hive. hive.
## Claude Code plugins ## Claude Code plugins
@ -199,9 +199,9 @@ hyperhive.claudePluginsAutoUpdate = false; # default
to add custom marketplaces. Idempotent — re-adding an existing to add custom marketplaces. Idempotent — re-adding an existing
source is a no-op. source is a no-op.
- **`claudePlugins`** — list of plugin specs passed to - **`claudePlugins`** — list of plugin specs passed to
`claude plugin install <spec>`. Each spec is installed on every boot `claude plugin install <spec>`. The harness installs each spec on
(`install` is expected to be idempotent); failures log a warning but every boot, assuming `install` is idempotent; failures log a warning
don't abort boot. Defaults to Anthropic's `skill-creator` (so every but don't abort boot. Defaults to Anthropic's `skill-creator` (so every
agent can author, refine, and evaluate its own skills) plus agent can author, refine, and evaluate its own skills) plus
hyperhive's own `base` plugin — skills that apply to every agent hyperhive's own `base` plugin — skills that apply to every agent
regardless of role (currently just `state-hygiene`) — all without regardless of role (currently just `state-hygiene`) — all without
@ -234,8 +234,8 @@ window, leaving only warnings and errors.
The function handles `+toolchain` selectors (`cargo +nightly build`) The function handles `+toolchain` selectors (`cargo +nightly build`)
and passes through cleanly when `--message-format` is already present. and passes through cleanly when `--message-format` is already present.
Non-compile subcommands (`new`, `add`, third-party `cargo-*`) are It leaves non-compile subcommands (`new`, `add`, third-party
left untouched. `cargo-*`) untouched.
Set to `false` for agents that parse cargo's JSON output Set to `false` for agents that parse cargo's JSON output
programmatically and don't pass `--message-format json` themselves. programmatically and don't pass `--message-format json` themselves.
@ -256,12 +256,12 @@ is a no-op without the other:
- **`useApiKey`** tells the harness itself not to wait for a Claude OAuth - **`useApiKey`** tells the harness itself not to wait for a Claude OAuth
session: at boot, `LoginState::from_dir` reports `Online` without session: at boot, `LoginState::from_dir` reports `Online` without
checking `~/.claude/` (`hive_agent::login::using_api_key`, reads checking `~/.claude/` (`hive_agent::login::using_api_key`, reads
`HIVE_USE_API_KEY`), and the fact is stamped into the consolidated `HIVE_USE_API_KEY`), and the harness stamps the fact into the
harness state file so the operator dashboard also stops reading this consolidated harness state file so the operator dashboard also stops reading this
agent's empty `~/.claude/` as "needs login." An api-key agent that hits agent's empty `~/.claude/` as "needs login." An api-key agent that hits
a real 401 (the key itself is bad) still surfaces `needs_login`only a real 401 (the key itself is bad) still surfaces `needs_login`the
the boot-time "have I ever logged in" check is bypassed, not the harness skips only the boot-time "have I ever logged in" check, not
auth-failure path. the auth-failure path.
- **`backendEnvironmentFile`** points at an operator-managed file - **`backendEnvironmentFile`** points at an operator-managed file
(outside the nix store, one `KEY=value` per line, systemd (outside the nix store, one `KEY=value` per line, systemd
`EnvironmentFile` syntax) supplying the credentials `claude` itself `EnvironmentFile` syntax) supplying the credentials `claude` itself

View file

@ -1,8 +1,8 @@
# MCP surface # MCP surface
The harness ships an embedded MCP server (rmcp 2). The built-in The harness ships an embedded MCP server (rmcp 2). A persistent
`hyperhive` surface is served over streamable HTTP by a persistent `hive-mcp-http` daemon serves the built-in `hyperhive` surface over
`hive-mcp-http` daemon (loopback, `127.0.0.1:<hyperhive.mcp.httpPort>`, streamable HTTP (loopback, `127.0.0.1:<hyperhive.mcp.httpPort>`,
per-container private netns). Claude connects to its stable URL via per-container private netns). Claude connects to its stable URL via
`--mcp-config` rather than respawning a stdio child each turn, so the `--mcp-config` rather than respawning a stdio child each turn, so the
URL survives the per-turn claude re-spawn (and a host-side hive-c0re URL survives the per-turn claude re-spawn (and a host-side hive-c0re
@ -15,7 +15,7 @@ stdio bridge, `bash` runs its own persistent streamable-http listener
server name is `hyperhive`, so the tools land in claude as server name is `hyperhive`, so the tools land in claude as
`mcp__hyperhive__<tool>`. `mcp__hyperhive__<tool>`.
Tool access is gated by tool groups (`HIVE_TOOL_GROUPS`). The default Tool groups (`HIVE_TOOL_GROUPS`) gate tool access. The default
preset (`AGENT_DEFAULT`) includes `messaging`, `meta`, `inbox`, and preset (`AGENT_DEFAULT`) includes `messaging`, `meta`, `inbox`, and
`execution`. Privileged groups (`lifecycle`, `approvals`, `scheduling`, `execution`. Privileged groups (`lifecycle`, `approvals`, `scheduling`,
`diagnostics`) are opt-in via the P3RM1SS10NS tab. `diagnostics`) are opt-in via the P3RM1SS10NS tab.
@ -36,8 +36,8 @@ preset (`AGENT_DEFAULT`) includes `messaging`, `meta`, `inbox`, and
(the topology parent is always reachable regardless of this list — (the topology parent is always reachable regardless of this list —
that carve-out is structural, keyed on parent relationship, not name). that carve-out is structural, keyed on parent relationship, not name).
- `recv` — drain inbox. Always an immediate peek, never blocks. `max` - `recv` — drain inbox. Always an immediate peek, never blocks. `max`
(default 1, cap 5) drains up to N rows. Each returned row is prefixed with (default 1, cap 5) drains up to N rows. `recv` prefixes each returned row
`[msg #<id>]` (broker row id; note the highest id seen, then pass with `[msg #<id>]` (broker row id; note the highest id seen, then pass
it to `ack_until` to bulk-triage the batch). **Graceful shutdown**: when the harness it to `ack_until` to bulk-triage the batch). **Graceful shutdown**: when the harness
receives a stop signal, the inbox becomes fenced and `recv` returns an receives a stop signal, the inbox becomes fenced and `recv` returns an
explicit `from: "graceful-stop"` message instead of an empty inbox. explicit `from: "graceful-stop"` message instead of an empty inbox.
@ -47,17 +47,17 @@ preset (`AGENT_DEFAULT`) includes `messaging`, `meta`, `inbox`, and
other turn: if the context crossed the watermark the harness runs a other turn: if the context crossed the watermark the harness runs a
notes-checkpoint turn and then `/compact`. Compacting before shutdown notes-checkpoint turn and then `/compact`. Compacting before shutdown
keeps a later cold start cheap instead of re-uploading a large transcript. keeps a later cold start cheap instead of re-uploading a large transcript.
- `ack_until(up_to)` — bulk-mark inbox rows handled: every row with - `ack_until(up_to)` — bulk-mark inbox rows handled: it stamps every row
broker id `<= up_to` is stamped as acked in a single UPDATE. with broker id `<= up_to` as acked in a single UPDATE.
Recipient-scoped (agents can only ack their own rows). Use when a Recipient-scoped (agents can only ack their own rows). Use when a
restart redelivers a large backlog of already-handled messages: read restart redelivers a large backlog of already-handled messages: read
the highest `[msg #N]` from the set you've actually processed, then the highest `[msg #N]` from the set you've actually processed, then
`ack_until(N)` to prevent re-pop. Acked rows never redeliver. `ack_until(N)` to prevent re-pop. Acked rows never redeliver.
Transient pings (sentinel id 0) have nothing to ack and show no marker. Transient pings (sentinel id 0) have nothing to ack and show no marker.
**System messages** (from sender `system`): the higher-urgency **System messages** (from sender `system`): the broker delivers the
lifecycle events (`hive_sh4re::manager::HelperEvent`) are higher-urgency lifecycle events (`hive_sh4re::manager::HelperEvent`)
delivered as regular inbox messages (same `recv` path; body is a JSON as regular inbox messages (same `recv` path; body is a JSON
object with an `event` discriminant field). The **submitting agent** object with an `event` discriminant field). The **submitting agent**
(the root agent for top-level containers; an agent with the `approvals` (the root agent for top-level containers; an agent with the `approvals`
tool group for its own subtree) receives `container_crash`, tool group for its own subtree) receives `container_crash`,
@ -136,7 +136,7 @@ hive_name?, swarm_name?, matrix_accounts? }`. `matrix_accounts` is a
[`docs/tools/scheduling.md`](../tools/scheduling.md). [`docs/tools/scheduling.md`](../tools/scheduling.md).
- **Forge repos** (`forge`) — `create_repo` — the only agent path to - **Forge repos** (`forge`) — `create_repo` — the only agent path to
create a repo under the `agents/` org (direct forge token creation is create a repo under the `agents/` org (direct forge token creation is
disabled for agents). The repo is created in the c0re-owned `agents` disabled for agents). The repo lands in the c0re-owned `agents`
org; the calling agent gets write collaborator access; the default org; the calling agent gets write collaborator access; the default
branch is branch-protected (operator-team must approve merges, so the branch is branch-protected (operator-team must approve merges, so the
agent can't self-merge). Opt-in; not in any default preset. agent can't self-merge). Opt-in; not in any default preset.
@ -202,8 +202,8 @@ status hint lives in the wake prompt + UI header, not here.
`Skill` is what makes an installed plugin's `SKILL.md` invokable — `Skill` is what makes an installed plugin's `SKILL.md` invokable —
without it, a skill's `description` frontmatter never gets seen by without it, a skill's `description` frontmatter never gets seen by
the model no matter how well it matches the task. the model no matter how well it matches the task.
- Tool-group-gated built-ins: `WebFetch`, `WebSearch` (added when the - Tool-group-gated built-ins: `WebFetch`, `WebSearch` (added once the
`web_tools` tool group is enabled — see P3RM1SS10NS tab). operator enables the `web_tools` tool group — see P3RM1SS10NS tab).
- Denied by omission (absent from the harness `--tools` / - Denied by omission (absent from the harness `--tools` /
`--allowedTools`, so they "literally don't exist" in a harness turn): `--allowedTools`, so they "literally don't exist" in a harness turn):
`Bash`, `Task`, `NotebookEdit`, `TodoWrite`. `Bash`, `Task`, `NotebookEdit`, `TodoWrite`.