docs: fix genuine passive-voice hits in docs/tools (hand-written files)

Read all 62 write-good.Passive hits across the 6 hand-written files in
docs/tools/ (bash.md, lifecycle.md, forge.md, hivectl.md, matrix.md,
scheduling.md) in context. Excludes forge-cli.md/hivectl-cli.md/
swarmctl-cli.md (57 more hits) -- those are CI-generated from the
clap doc-comment strings in hive-forge/hivectl/swarmctl, freshness-
checked against the committed markdown, so a fix there has to go in
the Rust source and get regenerated -- separate batch.

33 rewritten to active, actor usually already established in the same
paragraph or given via a 'by X' clause (the daemon, hive-c0re,
hive-forge, hivectl, hyperhive itself, or an established module name
like nix/agent-modules/mcp.nix). Several sibling-inconsistency fixes:
a passive clause next to an already-active sibling stating the same
fact (lifecycle.md's server-scoping sentence, forge.md's clone-derives
sentence, hivectl.md's daemon-hashes-passwords sentence, matrix.md's
daemon-upserts-a-todo paragraph).

29 left alone: no-X-is-Y / no-X-is-needed invariant idioms, config-state
conditionals (whenever/when X is set/configured/given), requirement-
list idiom, a false-positive tokenization (vale matching 'are read'
inside 'read-only'), definitional facts about CLI/attrset structure
with no real actor, hypothetical/counterfactual clauses describing a
rejected design alternative, a forward-looking not-yet-real removal,
compressed bullet-fragment conventions, and one deliberately-parallel
sentence structure left both halves alone to avoid breaking the
symmetry.

Verified via vale on the 6 touched files, diffed against main's exact
baseline (not just the Passive count): write-good.Passive 62 -> 29
exactly, every other category unchanged in count AND location
(TooWordy 16, Microsoft.We 1, Microsoft.FirstPerson 1, and the same
4 pre-existing Microsoft.Contractions errors at the same 4 lines).
This commit is contained in:
iris 2026-09-08 14:21:11 +02:00 committed by mara
commit 97e2a993e3
6 changed files with 49 additions and 49 deletions

View file

@ -25,14 +25,14 @@ delivered the terminal result inline, in which case no todo is created
- `wait_seconds` — inline poll before returning (capped at 30).
When the task finishes within the window the full status is
returned immediately and no todo is created; when the window expires
the task keeps running and the normal `task started: id=<id>`
response is returned. **Defaults to 3** — pass `wait_seconds: 0`
the task keeps running and the daemon returns the normal
`task started: id=<id>` response. **Defaults to 3** — pass `wait_seconds: 0`
to disable inline waiting and always get the immediate response.
- `name` — optional caller-chosen task id. When set it replaces the
autogenerated hex id, so it surfaces in `status(<name>)` lookups and
the loose-ends list — a memorable label instead of an opaque id. A name
is **reusable once its previous task has finished**; submitting a
name whose task is still `pending`/`running` is rejected. Allowed
is **reusable once its previous task has finished**; the daemon
rejects a name whose task is still `pending`/`running`. Allowed
characters: `[a-z0-9-]` (a valid identifier — lowercase, digits,
hyphen; max 63). Omit for the autogenerated id.
@ -48,7 +48,7 @@ Poll the status of a task submitted with `run`. Returns:
- last 4 KiB of stdout and stderr (full output in the `.out` / `.err` files)
`wait_seconds` — optional inline poll (capped at 30): when the task
finishes within the window the full status is returned immediately.
finishes within the window the call returns the full status immediately.
Useful to avoid a separate round-trip when the task is expected to
finish soon.
@ -77,7 +77,7 @@ in the agent's loose-ends; handle it on a future turn.
- `force: true` — SIGKILL.
If a SIGINT'd task doesn't exit, call `kill` again with `force: true`.
A still-pending task is cancelled before it starts. The task ends as
The daemon cancels a still-pending task before it starts. The task ends as
`killed` and surfaces in the loose-ends like any completion.
Exposed as `mcp__bash__kill`.
@ -86,7 +86,7 @@ Exposed as `mcp__bash__kill`.
`run` and `status` live in the `bash` MCP server, not `hyperhive`. The
tool names in claude are `mcp__bash__run` and `mcp__bash__status`.
The `Bash` built-in tool is blocked — all shell execution goes through
hyperhive blocks the `Bash` built-in tool — all shell execution goes through
this structured path so tasks get task-id tracking and structured output.
## Architecture
@ -109,8 +109,8 @@ When a bash task changes state, `hive-bash-daemon` upserts a single keyed
todo (`key = task id`) on the harness's in-agent socket (`HIVE_AGENT_SOCKET`)
— "running" at start, then the completion summary when it finishes. The
summary change signals the harness turn loop directly (in-process, no broker
round-trip), so the agent is driven a turn to handle it via `get_loose_ends`,
then clears the todo with `cancel_loose_end(kind: "todo", id: N)` (dials the
round-trip), so the harness drives a turn for the agent to handle it via
`get_loose_ends`, then clears the todo with `cancel_loose_end(kind: "todo", id: N)` (dials the
in-container socket directly — no bash task involved, so clearing doesn't
spawn another todo; see #2639). Same mechanism the matrix daemon uses for
unread rooms. An inline `wait_seconds` / `status` observation that already
@ -123,5 +123,5 @@ loose-end follows.
`tools()` returns `["run", "status"]` which the harness expands to
`mcp__hyperhive__run` / `mcp__hyperhive__status` — tools that don't
exist in the hyperhive MCP server (dead entries). Removing `execution`
from an agent's groups has no effect on bash availability. Bash is
registered separately via the `extraMcpServers` path described above.
from an agent's groups has no effect on bash availability.
`nix/agent-modules/mcp.nix` registers Bash separately via the `extraMcpServers` path described above.

View file

@ -22,7 +22,7 @@ markdown-docs > docs/tools/forge-cli.md`.
## Verbs
**Kind-namespaced commands (preferred):** issue/PR operations are grouped
**Kind-namespaced commands (preferred):** hive-forge groups issue/PR operations
under `issue` and `pr` parent commands — `hive-forge pr close 42`,
`hive-forge issue create --title …`, `hive-forge pr status --pr 42`. The
`pr <verb>` / `issue <verb>` forms validate the number's kind (for example `pr close`
@ -172,7 +172,7 @@ hive-forge -r internal/knowledge pr-create --agit \
```
`clone` derives the dest dir from the repo basename (override with a
positional arg); `--branch` / `--depth` are passed through. The clone
positional arg); it passes `--branch` / `--depth` through. The clone
URL and the `origin` remote it leaves behind carry no credentials —
`clone` instead configures `origin`'s `credential.helper` to invoke
`hive-forge credential-helper` (a hidden verb, not meant to be run by
@ -224,8 +224,8 @@ scope. Two paths exist depending on where the repo should live:
**Agent repos (`agents/<name>`)** — Use the `mcp__hyperhive__create_repo`
MCP tool (requires the `forge` tool group). hive-c0re creates the repo in
the c0re-owned `agents/` org, adds you as a write collaborator (not
owner), and enables branch protection (operator-team merge approval
required — you can't self-merge). Clone URL is returned immediately.
owner), enables branch protection (operator-team merge approval
required — you can't self-merge), and returns the clone URL immediately.
This is the standard path for agents that need a working repo.
**Other repos** — Use the CLI verbs below (`repo-create` / `repo-add-collaborator`).
@ -245,8 +245,8 @@ and print its URL. Key flags:
active repo (see the repo-resolution chain above). Companion to
`repo-create`. The
`--permission` flag accepts `read` / `write` (default) / `admin`.
`hive-c0re` uses this internally when an agent's config repo is
initialised.
`hive-c0re` uses this internally when it initialises an agent's config
repo.
**`repo-labels [PATTERN]`** — list every label defined on the repo,
optionally filtered by a name substring (case-sensitive). Distinct from
@ -272,7 +272,7 @@ to discover valid label names before triaging or to audit the label set.
- `artifact-get <name> --run <n>` downloads a CI Actions artifact. `<n>`
is the run number from the run-page URL (`/actions/runs/<n>`, which
`pr-status` surfaces as a CI context's target_url). Forgejo 15 serves
artifacts only via the web route, not REST, and that route is keyed by
artifacts only via the web route, not REST, and keys that route by
the run's internal global id, so the verb translates the run number
first. Saves a zip to `/tmp/forge-artifact-<name>.zip` by default; pass
`-o -` to stream to stdout.
@ -280,9 +280,9 @@ to discover valid label names before triaging or to audit the label set.
run's job step logs. `<n>` is the run number from the run-page URL
(same value `artifact-get` takes; `pr-status` surfaces it as a CI
context's target_url). Two log sources, tried in **completeness
order**: the **durable persisted-log download** the run page's "view
order**: the verb tries the **durable persisted-log download** the run page's "view
raw logs" link uses (`…/runs/<n>/jobs/<job>/attempt/<a>/logs`, a flat
whole-job log) is tried first — complete once it exists, which covers
whole-job log) first — complete once it exists, which covers
any run that has already finished; it's only absent while the job is
still running, in which case the verb falls back to the web run-view
**streamer** the run page polls (rich per-step framing, but only a
@ -324,7 +324,7 @@ to discover valid label names before triaging or to audit the label set.
extra request per comment, no server-side inline count). `reaction
<n> --list-allowed` prints the instance's actual configured shortcode
list (`GET /settings/ui`'s `allowed_reactions`) instead of guessing —
instance-global, `<n>`/`--comment` are ignored on this path.
instance-global, this path ignores `<n>`/`--comment`.
- Do NOT use raw `curl` for forge access -- the CLI handles auth,
error checking, and output formatting.
- `issue-create --label <name>` / `pr-create --label <name>` are
@ -332,8 +332,8 @@ to discover valid label names before triaging or to audit the label set.
unknown name is an error, not a silent drop** — the command fails
listing the names that didn't resolve plus every label the repo has,
so it's fixable from the message without a second call. On
`pr-create --agit`, labels are applied as a follow-up call once the
PR number is parsed back out of the push output (the AGit push
`pr-create --agit`, hive-forge applies labels as a follow-up call once
it parses the PR number back out of the push output (the AGit push
itself has no label field), so they're silently skipped if that
parse fails — same fallback as the deferred multi-line body.
- `list --label <name>` / `list --milestone <name>` are repeatable and

View file

@ -40,13 +40,13 @@ hivectl forge reconcile-config iris --verbose # include the full diff, not
```
- For **agents** (name has a state dir under `/var/lib/hyperhive/agents/`):
token is persisted to `<state>/forge-token`. Re-running refreshes the
`create-user` persists the token to `<state>/forge-token`. Re-running refreshes the
token (idempotent — scope always matches current `TOKEN_SCOPES`).
- For **non-agents** (humans): creates the account and prints the token to
stdout; no state dir is created. Re-running after account already exists
re-mints the token and prints it again — safe for password resets.
- Without `--password` / `--password-stdin` a random throwaway password
is used (fine for agents — they auth by token).
- Without `--password` / `--password-stdin` `create-user` uses a random
throwaway password (fine for agents — they auth by token).
- `reconcile-config <agent>` shows the divergence between the agent's local
applied config checkout and its forge `agent-configs/<agent>` `main`, then
reconciles. `--from forge` resets the local checkout to forge `main` (takes
@ -125,8 +125,8 @@ hivectl gateway delete-user bob # remove user
hivectl gateway list-users # list all usernames, one per line
```
Passwords are hashed with BCrypt (cost 12) by the daemon. The file is
created if it doesn't exist. Re-running `create-user` with the same
The daemon hashes passwords with BCrypt (cost 12). It creates the file
if it doesn't exist. Re-running `create-user` with the same
username updates the password hash in place.
## Agents
@ -175,8 +175,8 @@ resume drains the backlog rather than dropping it. Points worth knowing:
_stopped_ agent makes it come up parked.
- **Not a DAG.** Unlike `restart`/`stop`, there's no container operation
to sequence, so it applies immediately with nothing to wait on.
- **Stopping a paused agent is still fast.** The graceful-stop
handshake is skipped for a paused agent (it would never answer), which
- **Stopping a paused agent is still fast.** hivectl skips the graceful-stop
handshake for a paused agent (it would never answer), which
is safe precisely because the pause check sits at the top of the loop:
a paused agent has no turn in flight to checkpoint.
- Visible as ` paused` in `list-agents`'s STATUS column, as a `paused`
@ -196,15 +196,15 @@ Overrides the hive-wide `services.hyperhive.c0re.agentCpuQuota` /
[`persistence.md`](../agent-lifecycle/persistence.md)). Values are systemd's
`CPUQuota=` / `MemoryMax=` syntax: a percentage (`400%` = four full
cores) for CPU; a size (`8G`), a percentage of physical RAM, or
`infinity` for memory. Both are validated before they're persisted
`infinity` for memory. `set-limits` validates both before persisting them
they go into a systemd drop-in verbatim, and a typo there makes the
unit fail to start.
**Declarative, not incremental**: each invocation replaces the agent's
whole entry. `set-limits sock --memory-max 8G` leaves `sock` with _only_
a memory override, reverting any previously set CPU quota to the hive
default. To avoid a forgotten flag silently wiping an override, a bare
`set-limits <name>` with no flags is rejected — clearing requires the
default. To avoid a forgotten flag silently wiping an override, hivectl
rejects a bare `set-limits <name>` with no flags — clearing requires the
explicit `--reset`.
The command rewrites the container's drop-in and reloads systemd, so
@ -226,7 +226,7 @@ before you were added to `hive-admin` won't see it until you log back in
It also needs the daemon socket, unlike the other exec-into-a-container
paths: the "is this actually an agent?" pre-flight reads the agents root,
which is owned by the daemon's user and not group-readable, so the check
which the daemon's user owns and which isn't group-readable, so the check
is a `HostRequest` rather than a local `stat`. A rootless `choom` therefore
tells you it needs root, instead of reporting a permission problem with
the state dir.
@ -308,13 +308,13 @@ hivectl open forge # the forge (Forgejo) web UI
hivectl open matrix # the matrix GUI (fluffychat)
```
The URL is resolved from the running daemon (`HostRequest::Urls`), which
hivectl resolves the URL from the running daemon (`HostRequest::Urls`), which
reads the per-surface public URLs from c0re's service env — so custom
forge / matrix domains resolve correctly instead of assuming
`forge.<domain>`. The URL is **always printed** (the reliable core, since
the host is typically headless / driven over SSH), then `xdg-open` is tried
as a convenience — a missing or failing opener is reported as a note, not
an error.
the host is typically headless / driven over SSH), then hivectl tries
`xdg-open` as a convenience, reporting a missing or failing opener as a
note, not an error.
A surface has no URL when it isn't browser-reachable: `home` needs
`services.hyperhive.domain`; `forge` needs

View file

@ -1,8 +1,8 @@
# Lifecycle and approvals tools
Two tool groups govern agent lifecycle management and config changes.
Both are scoped to **direct children only** (topology-enforced: the
server rejects any name that's not a direct child of the calling
The server scopes both to **direct children only** (topology-enforced: it
rejects any name that's not a direct child of the calling
agent per `topology.json`). Privileged agents (for example ruth) may operate
on any sub-agent — the topology scope applies to all others.

View file

@ -110,8 +110,8 @@ Incoming room events wake the agent via `AgentRequest::Wake` with
bulleted list (`- <room>: <sender>: <body>` or `- <room>: N unread`
per room)
The same per-room breakdown is included in the `UnreadMatrix` entry
returned by `get_loose_ends` so unread rooms surface in the
hive-matrix-daemon includes the same per-room breakdown in the `UnreadMatrix`
entry `get_loose_ends` returns, so unread rooms surface in the
loose-ends list between turns.
**Invite wakes**: the daemon sweeps `invited_rooms()` after every sync
@ -123,8 +123,8 @@ in-agent socket, which drives a turn. The daemon does **not**
autojoin — the agent calls `list_invites` to see pending invites and
`resolve_invite` to accept or reject them.
**Pending invites as loose ends**: pending invites are upserted as
keyed todos and appear in `get_loose_ends` output as
**Pending invites as loose ends**: the daemon upserts pending invites as
keyed todos, which appear in `get_loose_ends` output as
`[matrix] invited to <room> (<room_id>) — use list_invites to see
pending invites, resolve_invite to accept or reject`. The keyed todo
is cleared when a `resolve_invite` (or `join_room`) call resolves the
@ -146,8 +146,8 @@ merges every entry into `--mcp-config` (under `mcpServers.<key>`)
and `--allowedTools` (as `mcp__<key>__<pattern>`).
The agent's `flake.nix` forwards every flake input to `agent.nix` as
the `flakeInputs` module arg, so external MCP-server flakes are pulled
in by adding them to `inputs.*` and referenced as
the `flakeInputs` module arg, so you pull in external MCP-server flakes
by adding them to `inputs.*` and reference them as
`flakeInputs.<name>.packages.${pkgs.system}.default` — the resolved
sha lands in the agent's own `flake.lock` and rolls up to meta's.

View file

@ -12,7 +12,7 @@ your topology subtree.
### `request_schedule_prompt(targets, body, first_fire_at_unix, interval_seconds?, description?)`
Queue an operator-approval for a scheduled prompt. On approve,
`body` is fanned out to each agent in `targets` at
hive-c0re fans `body` out to each agent in `targets` at
`first_fire_at_unix` (Unix timestamp). Recurring when `interval_seconds`
is set, one-shot otherwise.
@ -42,8 +42,8 @@ autocancels when every target is removed).
### `fire_schedule_now(id)`
Fire a scheduled prompt out of band immediately. Recurring schedules
keep their cadence — the manual fire is additive. One-shot schedules
are consumed by the manual fire and cancelled afterwards.
keep their cadence — the manual fire is additive. The manual fire
consumes one-shot schedules and cancels them afterwards.
### `list_schedules()`