From 97e2a993e309352178672d485e135f158bfbba9a Mon Sep 17 00:00:00 2001 From: iris Date: Tue, 8 Sep 2026 14:21:11 +0200 Subject: [PATCH] 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). --- docs/tools/bash.md | 22 +++++++++++----------- docs/tools/forge.md | 24 ++++++++++++------------ docs/tools/hivectl.md | 30 +++++++++++++++--------------- docs/tools/lifecycle.md | 4 ++-- docs/tools/matrix.md | 12 ++++++------ docs/tools/scheduling.md | 6 +++--- 6 files changed, 49 insertions(+), 49 deletions(-) diff --git a/docs/tools/bash.md b/docs/tools/bash.md index f263a902..cc2fd715 100644 --- a/docs/tools/bash.md +++ b/docs/tools/bash.md @@ -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=` - response is returned. **Defaults to 3** — pass `wait_seconds: 0` + the task keeps running and the daemon returns the normal + `task started: 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()` 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. diff --git a/docs/tools/forge.md b/docs/tools/forge.md index f764a729..38a01712 100644 --- a/docs/tools/forge.md +++ b/docs/tools/forge.md @@ -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 ` / `issue ` 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/`)** — 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 --run ` downloads a CI Actions artifact. `` is the run number from the run-page URL (`/actions/runs/`, 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-.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. `` 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//jobs//attempt//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 --list-allowed` prints the instance's actual configured shortcode list (`GET /settings/ui`'s `allowed_reactions`) instead of guessing — - instance-global, ``/`--comment` are ignored on this path. + instance-global, this path ignores ``/`--comment`. - Do NOT use raw `curl` for forge access -- the CLI handles auth, error checking, and output formatting. - `issue-create --label ` / `pr-create --label ` 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 ` / `list --milestone ` are repeatable and diff --git a/docs/tools/hivectl.md b/docs/tools/hivectl.md index 40d92c05..e3f8d79a 100644 --- a/docs/tools/hivectl.md +++ b/docs/tools/hivectl.md @@ -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 `/forge-token`. Re-running refreshes the + `create-user` persists the token to `/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 ` shows the divergence between the agent's local applied config checkout and its forge `agent-configs/` `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 ` with no flags is rejected — clearing requires the +default. To avoid a forgotten flag silently wiping an override, hivectl +rejects a bare `set-limits ` 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.`. 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 diff --git a/docs/tools/lifecycle.md b/docs/tools/lifecycle.md index beef184c..3e9d1708 100644 --- a/docs/tools/lifecycle.md +++ b/docs/tools/lifecycle.md @@ -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. diff --git a/docs/tools/matrix.md b/docs/tools/matrix.md index eac16a92..d3fc1efe 100644 --- a/docs/tools/matrix.md +++ b/docs/tools/matrix.md @@ -110,8 +110,8 @@ Incoming room events wake the agent via `AgentRequest::Wake` with bulleted list (`- : : ` or `- : 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 () — 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.`) and `--allowedTools` (as `mcp____`). 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..packages.${pkgs.system}.default` — the resolved sha lands in the agent's own `flake.lock` and rolls up to meta's. diff --git a/docs/tools/scheduling.md b/docs/tools/scheduling.md index 830bbcab..c7857847 100644 --- a/docs/tools/scheduling.md +++ b/docs/tools/scheduling.md @@ -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()`