docs: scrub self-ref cookies across 5 files (#719 batch 2)
All five files scrubbed to 0 issue-ref cookies. Most refs were '(closes #NNN)' style attribution after closed work landed. - docs/turn-loop.md: 6 → 0 (#598 unified binary, #419 auth-fail, #542 mtime resumption, #519 role markers, #442 spawn path, #474/#478 partial edit) - docs/approvals.md: 5 → 0 (#317 flake validation, #250 withdraw, #441 rebuild-queue dispatch, #753 manager port hash, #425 crash-watch grace) - docs/terminal-rendering.md: 2 → 0 (#666 ask-operator inline) - docs/conventions.md: 3 → 0 (#753 port hash, #692 parent sentinel, #486 reparenting) - docs/security.md: 4 → 0 (#240 + #658 ×2 + #673/#678 attribution) Combined with PR #810 (docs/web-ui.md 14→0), this PR closes the small / medium files. Remaining: agent-hierarchy.md (13), gotchas.md (13), persistence.md (13). gateway.md is atlas's lane.
This commit is contained in:
parent
a8d8159038
commit
5ca96b8c85
5 changed files with 27 additions and 29 deletions
|
|
@ -30,7 +30,7 @@ happens after a decision lands.
|
|||
applied.
|
||||
3a. **Flake validation (ApplyCommit only):** after the proposal tag
|
||||
is planted, hive-c0re reads `proposal/<id>:flake.lock` and
|
||||
runs two checks (closes #317). If either check fails, no
|
||||
runs two checks. If either check fails, no
|
||||
pending approval is created for the operator — the row is
|
||||
marked failed and surfaces on the dashboard with the
|
||||
validation message:
|
||||
|
|
@ -66,7 +66,7 @@ happens after a decision lands.
|
|||
### Withdrawing a pending approval
|
||||
|
||||
The manager can call `cancel_loose_end(kind: "approval", id)` to
|
||||
withdraw an approval that hasn't been acted on yet (closes #250).
|
||||
withdraw an approval that hasn't been acted on yet.
|
||||
The row transitions to `ApprovalStatus::Cancelled` (distinct from
|
||||
`Denied`/`Failed`), the dashboard pulls the card out of the
|
||||
pending pane, and `ApprovalResolved { status: "cancelled" }` fires
|
||||
|
|
@ -202,7 +202,7 @@ approval id to retry. Because tags are first-class git objects,
|
|||
rejected and failed trees stay browsable forever — `git log
|
||||
--tags` in the applied repo is the audit trail.
|
||||
|
||||
### Dispatch via `rebuild_queue` (#441)
|
||||
### Dispatch via `rebuild_queue`
|
||||
|
||||
Long-running approval work — `ApplyCommit`, `UpdateMetaInputs`,
|
||||
`Spawn` — no longer runs inline inside `actions::approve`. Instead
|
||||
|
|
@ -344,7 +344,7 @@ Differences from sub-agents:
|
|||
(vs `agent-base`).
|
||||
- Container name is `hm1nd` (no `h-` prefix).
|
||||
- Web UI port via `lifecycle::agent_web_port("hm1nd")` — same
|
||||
FNV-1a hash as every other agent (8100..8999 range) since #753.
|
||||
FNV-1a hash as every other agent (8100..8999 range).
|
||||
- `set_nspawn_flags` adds two extra binds: `/var/lib/hyperhive/agents`
|
||||
→ `/agents` (RW) so the manager can edit per-agent proposed repos,
|
||||
and `/var/lib/hyperhive/applied` → `/applied` (RO) so the manager
|
||||
|
|
@ -424,8 +424,8 @@ regular claude turn so the manager can react. Variants
|
|||
such transient was cleared in the last 30s (`RECENT_TRANSIENT_GRACE`
|
||||
tombstone, three `POLL_INTERVAL`s — closes the race where a
|
||||
lifecycle op finishes between two crash-watch polls and the
|
||||
container shows briefly as "stopped without transient" before the
|
||||
next start, #425). Manager can `start` it again or escalate.
|
||||
container shows briefly as "stopped without transient" before
|
||||
the next start). Manager can `start` it again or escalate.
|
||||
- `NeedsLogin { agent }` — sub-agent has no claude session yet.
|
||||
Manager can't act directly (interactive OAuth); typically flags
|
||||
the operator.
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ exist because something already went wrong without them.
|
|||
- The manager is `hm1nd` (no `h-` prefix, fixed name).
|
||||
- `MAX_AGENT_NAME` in `lifecycle.rs` enforces the cap.
|
||||
- Per-agent web UI port = `WEB_PORT_BASE + FNV1a(name) % WEB_PORT_RANGE`
|
||||
(8100..8999) for every agent including the manager (#753); dashboard
|
||||
(8100..8999) for every agent including the manager; dashboard
|
||||
`cfg.dashboardPort` (default 7000).
|
||||
|
||||
## Identity = socket
|
||||
|
|
@ -32,12 +32,12 @@ angle-bracket and asterisk shapes below are structurally safe.
|
|||
(`agent_server::handle_send` fans out via `Coordinator::broadcast_send`).
|
||||
- `operator` — the human at the dashboard. Messages accumulate in the
|
||||
inbox view; no agent ever `recv`'s them.
|
||||
- `<parent>` — the sender's parent per `topology.json` (`#692`).
|
||||
Rewritten at send time by `topology::resolve_recipient`: looks up
|
||||
- `<parent>` — the sender's parent per `topology.json`. Rewritten at
|
||||
send time by `topology::resolve_recipient`: looks up
|
||||
`parent_of(sender)` and falls back to `operator` when the sender is
|
||||
a root agent (or absent from topology entirely). Lets agents address
|
||||
their parent without learning the label, so runtime reparenting
|
||||
(`#486`) propagates with zero agent-side restart.
|
||||
propagates with zero agent-side restart.
|
||||
|
||||
When the resolver rewrites `<parent>`, the broker stores the
|
||||
*resolved* label as the message's recipient — the dashboard and
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
# Security model
|
||||
|
||||
## Nix builds and credential isolation (issue #240)
|
||||
## Nix builds and credential isolation
|
||||
|
||||
### Background
|
||||
|
||||
|
|
@ -19,12 +19,11 @@ any file in the container that the nixbld user can read.
|
|||
**What is NOT exposed**:
|
||||
|
||||
- `/home/<name>/.claude/` — mode `0700`, owned by the per-agent
|
||||
user `<name>` (post-#658 — was `/root/.claude` owned by root
|
||||
pre-#658). nixbld users cannot read it.
|
||||
user `<name>`. nixbld users cannot read it.
|
||||
- `$HYPERHIVE_STATE_DIR/forge-token` (= `/agents/<name>/state/forge-token`)
|
||||
— written at mode `0600` by `hive-c0re/src/forge.rs` and chowned to the
|
||||
per-agent uid:gid by `lifecycle::chown_to_agent` (post-#673/#678).
|
||||
nixbld users cannot read it.
|
||||
per-agent uid:gid by `lifecycle::chown_to_agent`. nixbld users
|
||||
cannot read it.
|
||||
|
||||
**Policy**: all credential files written to agent state directories MUST be mode
|
||||
`0600` or stricter. Do not create world-readable secret files in agent state dirs.
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ parent's negative pull.
|
|||
| `.tool-use` (flat) | `→ Name args…` | cyan | tool_use w/o rich renderer | stream-json |
|
||||
| `.tool-use` `<details>` | `Write/Edit <path> · +N` (no `→`) | cyan, body is +/- diff | `renderRichToolUse` Write/Edit | stream-json |
|
||||
| `.tool-use` `<details open>` | `send → to · NL`, `ask → to`, `answer #id` | cyan, body is markdown | rich renderer for send / ask / answer | stream-json |
|
||||
| `.tool-use .ask-answer-inline-slot` | (sub-block under `ask → operator`) | inherits row | inline answer form bound by `reconcileAskBinds` to the loose-end | #666 |
|
||||
| `.tool-use .ask-answer-inline-slot` | (sub-block under `ask → operator`) | inherits row | inline answer form bound by `reconcileAskBinds` to the loose-end | rich renderer |
|
||||
| `.tool-result` (flat) | `← <txt>` | muted | short `tool_result` (≤120c, non-recv) | stream-json |
|
||||
| `.tool-result-block` `<details>` | `Nl · headline` | muted, body is text | long generic `tool_result` | stream-json |
|
||||
| `.tool-result-block` `<details open>` | `recv ← <txt>` | muted, body is markdown | `tool_result` correlated to a prior `recv` tool_use via id | stream-json |
|
||||
|
|
@ -105,7 +105,7 @@ isn't in the built-in `fmtToolUse` switch:
|
|||
This keeps `mcp__matrix__send_message` and similar from
|
||||
dumping raw JSON.
|
||||
|
||||
## Inline ask-operator answer (#666)
|
||||
## Inline ask-operator answer
|
||||
|
||||
When an agent calls `mcp__hyperhive__ask` with `to == "operator"`
|
||||
(default), the rich tool-use renderer mounts an empty
|
||||
|
|
|
|||
|
|
@ -6,8 +6,8 @@ claude has access to in return.
|
|||
## The loop
|
||||
|
||||
Each agent harness (`hive serve`, with role picked from `$HIVE_ROLE`
|
||||
— `"agent"` for sub-agents, `"manager"` for the manager; post-#598
|
||||
this is one binary not two) runs:
|
||||
— `"agent"` for sub-agents, `"manager"` for the manager — one
|
||||
binary, not two) runs:
|
||||
|
||||
1. Long-poll `Recv` on its socket. The host-side broker
|
||||
(`broker.rs::recv_blocking_batch`) returns immediately if there's
|
||||
|
|
@ -31,8 +31,8 @@ this is one binary not two) runs:
|
|||
(`Bus::emit_status("rate_limited")`), sleeps
|
||||
`HIVE_RATE_LIMIT_SLEEP_SECS` (default 300), then retries.
|
||||
The dashboard and per-agent page show a `⊘ rate limited` badge
|
||||
while the harness is parked. **Auth-failed detection** (closes
|
||||
#419): both stdout and stderr pumps also match
|
||||
while the harness is parked. **Auth-failed detection**: both
|
||||
stdout and stderr pumps also match
|
||||
`AUTH_FAIL_MARKERS` (`"authentication_failed"`, `401`, etc.).
|
||||
On match the harness writes `{state_dir}/hyperhive-needs-login`,
|
||||
emits `needs_login_idle` status, requeues the inflight message
|
||||
|
|
@ -40,7 +40,7 @@ this is one binary not two) runs:
|
|||
the same path used at boot. The operator re-authenticates via
|
||||
the per-agent web UI login flow; on success the sentinel is
|
||||
cleared and the queued message drives the next turn normally.
|
||||
**Mtime-snapshot resumption** (closes #542): `wait_for_login`
|
||||
**Mtime-snapshot resumption**: `wait_for_login`
|
||||
snapshots the `~/.claude/` dir (newest file mtime + file count)
|
||||
at entry and only resumes when that snapshot advances — not
|
||||
just when credentials exist on disk. This prevents a silent
|
||||
|
|
@ -176,8 +176,8 @@ socket at `/run/hive/` once at startup:
|
|||
- `claude-system-prompt.md` — rendered from
|
||||
`hive-ag3nt/prompts/system.md` by `hive_ag3nt::prompt::render`:
|
||||
HTML-comment markers (`<!-- role:agent -->...<!-- /role:agent -->`,
|
||||
same for `role:manager`) gate the role-specific blocks (closes
|
||||
#519); everything else is shared. Five placeholders are then
|
||||
same for `role:manager`) gate the role-specific blocks; everything
|
||||
else is shared. Five placeholders are then
|
||||
substituted: `{label}` (short agent name), `{qualified_label}`
|
||||
(hive-qualified `name@domain` form), `{operator_pronouns}`,
|
||||
`{hive_identity}` (e.g. `` on hive `pr1ma` ``; empty when
|
||||
|
|
@ -350,10 +350,9 @@ meta's.
|
|||
`agent.nix`, commits the changes, and calls `request_apply_commit`
|
||||
with the commit sha — the first ApplyCommit on a freshly-init'd
|
||||
config creates the container. Fails if a proposed repo for this
|
||||
name already exists. (The pre-#442 path through a separate
|
||||
manager-side `request_spawn` was removed; operator can still
|
||||
direct-spawn an empty agent from the dashboard's `◆ R3QU3ST SP4WN`
|
||||
button which routes via `HostRequest::RequestSpawn`.)
|
||||
name already exists. (The operator can also direct-spawn an empty
|
||||
agent from the dashboard's `◆ R3QU3ST SP4WN` button, which routes
|
||||
via `HostRequest::RequestSpawn`.)
|
||||
- `kill(name)` — graceful stop. No approval required.
|
||||
- `start(name)` — start a stopped sub-agent. No approval.
|
||||
- `restart(name)` — stop + start. No approval.
|
||||
|
|
@ -398,7 +397,7 @@ meta's.
|
|||
approval (use `remind` for unapproved self-wake). Long downtime
|
||||
fires once per recurring row on resume (catch-up clamp).
|
||||
- `edit_schedule(id, body?, description?, interval_seconds?, next_fire_at_unix?, targets_add?, targets_remove?)` —
|
||||
partial-update a schedule (#474/#478). Pass only the fields to
|
||||
partial-update a schedule. Pass only the fields to
|
||||
change; absent fields are left alone. `targets_add` / `targets_remove`
|
||||
mutate the recipient list in the same transaction; re-adding a
|
||||
previously-cancelled target drops its tombstone + history (fresh
|
||||
|
|
|
|||
Loading…
Reference in a new issue