docs: suppress reviewed write-good.Passive false positives
133 hits across 38 files, all previously classified during #4548's sweep and deliberately left un-rewritten (predicate-adjective state/necessity description, design-intent idiom, structural/type-description idiom, no-single-actor topology claim, parallel-triple exception, vale substring-match artifact — see hyperhive#4548's per-PR bodies for the per-hit reasoning). Wraps each one in a scoped <!-- vale write-good.Passive = NO/YES --> pair (the supported mechanism — TokenIgnores has a known offset-drift bug) rather than a blanket per-file or per-rule silence, so a *new* passive-voice hit anywhere in these files still fails once the rule gates CI (next commit). Table/list false positives (docs/swarm/credentials.md's renewal-table cells) wrap the whole block, not each cell. Part of #4546.
This commit is contained in:
parent
7abb16e6d5
commit
04e27c4fb6
38 changed files with 368 additions and 71 deletions
|
|
@ -1,11 +1,15 @@
|
|||
# Agent hierarchy & privileges
|
||||
|
||||
<!-- vale write-good.Passive = NO -->
|
||||
|
||||
Every agent has a place in an operator-editable parent/child tree, used
|
||||
to scope which agents can manage which others. This doc covers how
|
||||
hive-c0re stores and edits the tree today, the rules that are meant to run on top
|
||||
of it once enforcement is finished, and where the manager still gets
|
||||
special-cased in the meantime, as a tracked cleanup.
|
||||
|
||||
<!-- vale write-good.Passive = YES -->
|
||||
|
||||
## Where the tree lives
|
||||
|
||||
Topology lives in the hive-c0re-owned **meta repo**, alongside
|
||||
|
|
@ -31,7 +35,7 @@ not its tree position (see _Manager special-casing today_ below).
|
|||
### Reparenting
|
||||
|
||||
- CLI: `hivectl agent <child> set-parent --parent <new>` (or `--root`
|
||||
to promote). Exactly one of `--parent` / `--root` is required.
|
||||
to promote). Pass exactly one of `--parent` / `--root`.
|
||||
- Dashboard: `POST /api/topology/set-parent` (form fields `child`,
|
||||
optional `new_parent` — absent / empty ⇒ promote to root).
|
||||
- Wire: `HostRequest::SetParent { child, new_parent: Option<String> }`.
|
||||
|
|
@ -104,6 +108,8 @@ Enforcement of the ancestor rules above isn't fully wired yet, so the
|
|||
**manager (`ruth`) still gets some hard-coded special treatment**
|
||||
other agents don't:
|
||||
|
||||
<!-- vale write-good.Passive = NO -->
|
||||
|
||||
- **Naming/bootstrap** — the manager's broker recipient name, state-dir
|
||||
key, and nixos-container name are all `ruth` (container `h-ruth`).
|
||||
`hive-c0re` spawns it directly at boot if missing, with no operator
|
||||
|
|
@ -143,17 +149,18 @@ Manager}` switch picks the MCP tool allow-list claude sees. Both are
|
|||
container including the manager, so all token/state paths resolve
|
||||
through it the same way everywhere.
|
||||
- **Scattered ownership checks** — a handful of independent
|
||||
manager-only overrides exist across `hive-c0re` today: loose-ends
|
||||
visibility (manager sees hive-wide, sub-agents only their own),
|
||||
`destroy` refusing to act on the manager, and crash-watch skipping
|
||||
the manager (it autorestarts via systemd instead of going through
|
||||
the crash-watch loop). Each is planned to become an
|
||||
ancestor/descendant check instead of a manager-name check — see the
|
||||
module docs for `loose_ends.rs`, `stores/broker.rs`, `actions.rs`,
|
||||
and `workers/crash_watch.rs` for the current owner-check logic in
|
||||
each. (The harness handles reminder cancellation fully in-agent — see
|
||||
the note on `CancelLooseEndKind::Reminder` in
|
||||
`hive-c0re/src/socket_server/mod.rs`.)
|
||||
manager-only overrides exist across `hive-c0re` today: loose-ends
|
||||
visibility (manager sees hive-wide, sub-agents only their own),
|
||||
`destroy` refusing to act on the manager, and crash-watch skipping
|
||||
the manager (it autorestarts via systemd instead of going through
|
||||
the crash-watch loop). Each is planned to become an
|
||||
ancestor/descendant check instead of a manager-name check — see the
|
||||
module docs for `loose_ends.rs`, `stores/broker.rs`, `actions.rs`,
|
||||
and `workers/crash_watch.rs` for the current owner-check logic in
|
||||
each. (The harness handles reminder cancellation fully in-agent — see
|
||||
the note on `CancelLooseEndKind::Reminder` in
|
||||
`hive-c0re/src/socket_server/mod.rs`.)
|
||||
<!-- vale write-good.Passive = YES -->
|
||||
|
||||
None of the above is a stable interface — treat the module doc
|
||||
comments as the source of truth for exactly which checks exist today.
|
||||
|
|
@ -204,6 +211,8 @@ direct mentions, reviews, and assignments.
|
|||
path = [ "/run/wrappers" "/run/current-system/sw" ];
|
||||
```
|
||||
|
||||
<!-- vale write-good.Passive = NO -->
|
||||
|
||||
`/run/wrappers` (not `/run/wrappers/bin`) comes first so setuid
|
||||
wrappers — notably `sudo` — resolve before bare nix-store binaries; see
|
||||
[`docs/process/gotchas.md`](../process/gotchas.md) ("`systemd.services.*.path` appends
|
||||
|
|
@ -214,6 +223,8 @@ the non-setuid nix-store binary and every
|
|||
`services.hyperhive.agent.user.passwordlessSudo` grant fails with "must be owned by
|
||||
uid 0 and have the setuid bit set."
|
||||
|
||||
<!-- vale write-good.Passive = YES -->
|
||||
|
||||
### `serviceConfig` highlights
|
||||
|
||||
- `ExecStart = pkgs.hyperhive/bin/hive-agent` — same binary for every
|
||||
|
|
|
|||
|
|
@ -148,9 +148,10 @@ through the web UI or the forge.
|
|||
### Approval kinds (wire shapes)
|
||||
|
||||
`ApprovalKind` carries four variants; each maps to a different
|
||||
`commit_ref` encoding because that field is overloaded as the
|
||||
kind-specific payload carrier.
|
||||
`commit_ref` encoding because `ApprovalKind` overloads that field as
|
||||
the kind-specific payload carrier.
|
||||
|
||||
<!-- vale write-good.Passive = NO -->
|
||||
- `MergeConfigPr` — the config-change flow. Triggered automatically:
|
||||
when an agent opens (or force-pushes) a PR on its
|
||||
`agent-configs/<agent>` forge repo, hive-c0re's `/webhook/config-pr`
|
||||
|
|
@ -187,6 +188,7 @@ kind-specific payload carrier.
|
|||
`source = approval:<id>`; the worker fans the body out as
|
||||
inbox messages to each target at the scheduled time, recurring
|
||||
when `interval_seconds` is set.
|
||||
<!-- vale write-good.Passive = YES -->
|
||||
|
||||
### Scheduled prompts (submit paths)
|
||||
|
||||
|
|
|
|||
|
|
@ -108,6 +108,7 @@ One table:
|
|||
- `events(id, ts, kind, payload_json)` — every `LiveEvent` the
|
||||
harness emits during turn loop execution.
|
||||
|
||||
<!-- vale write-good.Passive = NO -->
|
||||
The harness both writes and vacuums it — this used to be a host-side
|
||||
sweep, but hive-c0re runs as the unprivileged `hive-core` user under
|
||||
privsep and can't delete agent-owned files (host-side deletes hit
|
||||
|
|
@ -128,6 +129,7 @@ host-side sweep was meant to prevent — but a compromised harness is
|
|||
already inside the container trust boundary
|
||||
([`docs/trust-boundary/security.md`](../trust-boundary/security.md)), and these are ephemeral local
|
||||
artifacts, so cleaning them up where they live is the honest fix.
|
||||
<!-- vale write-good.Passive = YES -->
|
||||
|
||||
Path overridable via `HYPERHIVE_EVENTS_DB` (for dev / no-`/harness`
|
||||
setups). On open failure the `Bus` falls back to no-store mode
|
||||
|
|
@ -238,6 +240,7 @@ harness keeps serving its web UI and MCP daemons but drives no turns,
|
|||
and inbox messages queue unacked until it's removed (see
|
||||
[turn loop](../turn-loop/README.md#the-loop)).
|
||||
|
||||
<!-- vale write-good.Passive = NO -->
|
||||
Unusually, it's read and written from **both** sides of the harness
|
||||
bind-mount, and that's the whole design: the harness stats it
|
||||
in-container via `hive-agent`'s `paths::paused_marker`, while hive-c0re
|
||||
|
|
@ -248,6 +251,7 @@ dashboard toggle. Because the file itself is the only shared state
|
|||
there's no protocol between them, no round-trip into the container, and
|
||||
pause keeps working when the harness is wedged or the container is
|
||||
stopped.
|
||||
<!-- vale write-good.Passive = YES -->
|
||||
|
||||
It lives in `/harness/` rather than `/state/` deliberately: `/state/`
|
||||
is the agent's own space to fill, and this is harness control state.
|
||||
|
|
@ -346,19 +350,23 @@ nothing argues for a parent reading it, let alone writing it. hive-c0re
|
|||
reads a child's harness dir **directly on the host** when it wants
|
||||
those stats, which needs no mount into the parent.
|
||||
|
||||
<!-- vale write-good.Passive = NO -->
|
||||
**`config` is read-only, including for the parent.** A config change is
|
||||
a PR on the child's config repo, made from a clone and merged after
|
||||
review — so the bind-mounted `config` dir is a *copy to read*, never a
|
||||
tree anyone edits in place. Mounting it writable would leave a second
|
||||
path to the same file that skips the review entirely, which makes the
|
||||
boundary a convention rather than a permission.
|
||||
<!-- vale write-good.Passive = YES -->
|
||||
|
||||
<!-- vale write-good.Passive = NO -->
|
||||
⚠️ Don't confuse it with the config-repo seeding hive-c0re does at
|
||||
spawn (`lifecycle::setup_proposed`): that writes the child's initial
|
||||
config repo as **hive-c0re, against the host path**, and `read_only` on a bind
|
||||
constrains writers *inside* a container only. The two are unrelated —
|
||||
conflating them can lead you to reason your way into thinking this
|
||||
mount should be writable when it shouldn't.
|
||||
<!-- vale write-good.Passive = YES -->
|
||||
|
||||
Per-child isolation still holds: a container only ever has its *own*
|
||||
dirs plus its direct children's bind-mounted, never a sibling's.
|
||||
|
|
@ -481,10 +489,12 @@ so it survives restarts and redeploys.
|
|||
verification until the hook is re-registered with the new value. It's
|
||||
generated automatically on first start; there's nothing to configure.
|
||||
|
||||
<!-- vale write-good.Passive = NO -->
|
||||
If the file is unreadable at startup the daemon still starts and logs
|
||||
`webhook secret unavailable`; the webhook endpoint then answers 503
|
||||
rather than accepting deliveries it can't verify. Everything else the
|
||||
controller serves is unaffected.
|
||||
<!-- vale write-good.Passive = YES -->
|
||||
|
||||
## Run-time dirs
|
||||
|
||||
|
|
@ -587,6 +597,7 @@ librsvg) and forwards its store path as `HIVE_ICON_PNG` on the daemon
|
|||
unit, gated on `services.hyperhive.agent.icon != null`. No icon configured → the env is
|
||||
unset → `sync_avatar` returns early and sets no avatar.
|
||||
|
||||
<!-- vale write-good.Passive = NO -->
|
||||
Idempotency is **per-account**: an `avatar-icon-hash` file in each
|
||||
account's matrix-sdk `state_dir`. The daemon hashes the PNG bytes and
|
||||
skips the upload when unchanged, because every upload mints a fresh
|
||||
|
|
@ -596,4 +607,5 @@ account gets its avatar when the `systemd.paths.hive-matrix-daemon` token
|
|||
watcher restarts the daemon (which re-runs the per-account bring-up), so
|
||||
no separate avatar trigger is needed. The daemon swallows avatar failures
|
||||
(logged, non-fatal) so they never break account bring-up or sync.
|
||||
<!-- vale write-good.Passive = YES -->
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue