docs: give turn-loop/ a README.md landing page

Part of hyperhive#1898 (b): every docs subdir should have a top-level
README.md link, achieved by moving/renaming where an existing file
already fits the role.

docs/turn-loop.md already served as the hub + index for the three
sub-pages under turn-loop/ (claude-invocation.md, config.md, mcp.md),
so it moves wholesale rather than leaving a redundant top-level
pointer stub. Fixes every inbound/relative link across the repo
(top-level README.md, CLAUDE.md, docs/persistence.md,
docs/tools/scheduling.md, the sub-pages own back-link, hive-agent
README + doc comments, hive-agent/Cargo.toml, .prettierignore per-file
exemption entry) - grepped the whole tree for both turn-loop.md and
turn-loop/ to find every reference rather than trusting a partial
list.

nix fmt clean, cargo check -p hive-agent clean.
This commit is contained in:
iris 2026-08-03 12:55:18 +02:00
commit 04b274753b
11 changed files with 21 additions and 21 deletions

View file

@ -16,6 +16,6 @@ docs/persistence.md
docs/terminal-rendering.md docs/terminal-rendering.md
docs/tools/forge.md docs/tools/forge.md
docs/tools/matrix.md docs/tools/matrix.md
docs/turn-loop.md docs/turn-loop/README.md
docs/web-ui/agent.md docs/web-ui/agent.md
docs/web-ui/dashboard.md docs/web-ui/dashboard.md

View file

@ -179,7 +179,7 @@ read them à la carte.
- **"How does the per-agent terminal classify + colour - **"How does the per-agent terminal classify + colour
events?"** → [`docs/terminal-rendering.md`](docs/terminal-rendering.md). events?"** → [`docs/terminal-rendering.md`](docs/terminal-rendering.md).
- **"How does claude get its prompt and what tools does it have?"** → - **"How does claude get its prompt and what tools does it have?"** →
[`docs/turn-loop.md`](docs/turn-loop.md) (index: the loop, binary shape, [`docs/turn-loop/`](docs/turn-loop/README.md) (index: the loop, binary shape,
turn outcomes; sub-pages: turn outcomes; sub-pages:
[`claude-invocation`](docs/turn-loop/claude-invocation.md), [`claude-invocation`](docs/turn-loop/claude-invocation.md),
[`config`](docs/turn-loop/config.md), [`mcp`](docs/turn-loop/mcp.md)). [`config`](docs/turn-loop/config.md), [`mcp`](docs/turn-loop/mcp.md)).
@ -239,7 +239,7 @@ The docs below own the details — this section just points at them.
- **NixOS / nspawn quirks** (bind mounts, conf flags, etc.): → - **NixOS / nspawn quirks** (bind mounts, conf flags, etc.): →
[`docs/gotchas.md`](docs/gotchas.md). [`docs/gotchas.md`](docs/gotchas.md).
- **Turn loop, sentinels (rate-limit, auth-failed), context - **Turn loop, sentinels (rate-limit, auth-failed), context
window:** → [`docs/turn-loop.md`](docs/turn-loop.md). window:** → [`docs/turn-loop/`](docs/turn-loop/README.md).
- **Two-step spawn, approval flow, flake.lock validation:** - **Two-step spawn, approval flow, flake.lock validation:**
[`docs/approvals.md`](docs/approvals.md). [`docs/approvals.md`](docs/approvals.md).
- **Pre-push lint hook** (catches tracker-tag and comment-block failures - **Pre-push lint hook** (catches tracker-tag and comment-block failures

View file

@ -46,7 +46,7 @@ Depth lives in [`docs/`](docs/) — pick the one matching your task:
| reading path | doc | | reading path | doc |
| --------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ | | --------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ |
| dashboard layout + endpoints | [`docs/web-ui.md`](docs/web-ui.md) ([shape](docs/web-ui/shape.md) · [dashboard](docs/web-ui/dashboard.md) · [agent](docs/web-ui/agent.md)) | | dashboard layout + endpoints | [`docs/web-ui.md`](docs/web-ui.md) ([shape](docs/web-ui/shape.md) · [dashboard](docs/web-ui/dashboard.md) · [agent](docs/web-ui/agent.md)) |
| claude turn loop + MCP tools | [`docs/turn-loop.md`](docs/turn-loop.md) | | claude turn loop + MCP tools | [`docs/turn-loop/`](docs/turn-loop/README.md) |
| config-edit + approval state machine | [`docs/approvals.md`](docs/approvals.md) | | config-edit + approval state machine | [`docs/approvals.md`](docs/approvals.md) |
| what survives destroy / purge / restart | [`docs/persistence.md`](docs/persistence.md) | | what survives destroy / purge / restart | [`docs/persistence.md`](docs/persistence.md) |
| naming, wire protocol, commit style | [`docs/conventions.md`](docs/conventions.md) | | naming, wire protocol, commit style | [`docs/conventions.md`](docs/conventions.md) |

View file

@ -239,7 +239,7 @@ Survives destroy/recreate, gone on `--purge`.
Empty marker file. Its presence parks the agent's turn loop: the Empty marker file. Its presence parks the agent's turn loop: the
harness keeps serving its web UI and MCP daemons but drives no turns, harness keeps serving its web UI and MCP daemons but drives no turns,
and inbox messages queue unacked until it's removed (see and inbox messages queue unacked until it's removed (see
[turn loop](turn-loop.md#the-loop)). [turn loop](turn-loop/README.md#the-loop)).
Unusually, it's read and written from **both** sides of the harness Unusually, it's read and written from **both** sides of the harness
bind-mount, and that's the whole design: the harness stats it bind-mount, and that's the whole design: the harness stats it

View file

@ -89,6 +89,6 @@ lifecycle events, or another container's boot log.
## See also ## See also
- `remind` (no-approval self-wake path) — documented in - `remind` (no-approval self-wake path) — documented in
[`docs/turn-loop.md`](../turn-loop.md). [`docs/turn-loop/`](../turn-loop/README.md).
- [`docs/approvals.md`](../approvals.md) — approval flow for - [`docs/approvals.md`](../approvals.md) — approval flow for
`request_schedule_prompt`. `request_schedule_prompt`.

View file

@ -14,7 +14,7 @@ agents) runs:
queued and unacked, so a resume drains the backlog instead of queued and unacked, so a resume drains the backlog instead of
losing it; reminders and todo wakes buffer in their channels. Set losing it; reminders and todo wakes buffer in their channels. Set
it with `hivectl agent <name> pause` or the dashboard toggle; see it with `hivectl agent <name> pause` or the dashboard toggle; see
[persistence](persistence.md#-harnesspaused-per-agent). [persistence](../persistence.md#-harnesspaused-per-agent).
1. Long-poll `Recv` on its socket. The host-side broker 1. Long-poll `Recv` on its socket. The host-side broker
(`broker.rs::recv_blocking_batch`) returns immediately if there's (`broker.rs::recv_blocking_batch`) returns immediately if there's
a pending message, otherwise waits up to 30 s for a broker `Sent` a pending message, otherwise waits up to 30 s for a broker `Sent`
@ -31,7 +31,7 @@ agents) runs:
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)); compaction is handled inside the
session (see session (see
[Compaction](turn-loop/claude-invocation.md#compaction)). Rate-limit [Compaction](claude-invocation.md#compaction)). Rate-limit
and auth-failure detection is described [below](#failure-detection-and-login). and auth-failure detection is described [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.
@ -94,12 +94,12 @@ loop (`serve_loop` / `handle_turn`) has no per-role branches.
flake sets it unconditionally for any container-deployed agent; flake sets it unconditionally for any container-deployed agent;
see `docs/conventions.md::Hive identity` for the env stack), see `docs/conventions.md::Hive identity` for the env stack),
opens turn-stats sqlite, prepares the on-boot files (see opens turn-stats sqlite, prepares the on-boot files (see
[claude-invocation](turn-loop/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`). (The forge notification poller the login flow first (`NeedsLogin`). (The forge notification poller
used to be spawned here too; it is its own process now — used to be spawned here too; it is its own process now —
`hive-forge-notify`, see [`forge.md`](forge.md).) `hive-forge-notify`, see [`forge.md`](../forge.md).)
`spawn_todo_socket` opens the todos store and, alongside `spawn_todo_socket` opens the todos store and, alongside
`todo_server::run` (the socket the out-of-process producers dial), `todo_server::run` (the socket the out-of-process producers dial),
@ -153,17 +153,17 @@ harness between turns.
## Sub-pages ## Sub-pages
The rest lives in three topic pages under [`turn-loop/`](turn-loop/): The rest lives alongside this page, in three topic files:
- **[claude-invocation.md](turn-loop/claude-invocation.md)** — how the harness - **[claude-invocation.md](claude-invocation.md)** — how the harness
spawns `claude --print` each turn, the two-pronged compaction (reactive + spawns `claude --print` each turn, the two-pronged compaction (reactive +
proactive), and the on-boot files it materialises (`--mcp-config`, proactive), and the on-boot files it materialises (`--mcp-config`,
`--system-prompt-file`). `--system-prompt-file`).
- **[config.md](turn-loop/config.md)** — the optional per-agent knobs the meta - **[config.md](config.md)** — the optional per-agent knobs the meta
flake wires in (reference docs, icon, passwordless sudo, dashboard links, flake wires in (reference docs, icon, passwordless sudo, dashboard links,
custom static files, connectivity overrides, claude plugins, cargo message custom static files, connectivity overrides, claude plugins, cargo message
filtering). filtering).
- **[mcp.md](turn-loop/mcp.md)** — the MCP tool surface claude sees: core tools, - **[mcp.md](mcp.md)** — the MCP tool surface claude sees: core tools,
privileged tool groups, self-wake, authoritative state, the tool envelope, privileged tool groups, self-wake, authoritative state, the tool envelope,
and the built-in tool whitelist. and the built-in tool whitelist.

View file

@ -116,7 +116,7 @@ window with two triggers baked into its `run`:
*still* overflows, `run` surfaces `Error::PromptTooLong`; `drive_turn` *still* overflows, `run` surfaces `Error::PromptTooLong`; `drive_turn`
then archives the session (session lifecycle stays hive-side) and the then archives the session (session lifecycle stays hive-side) and the
serve loop requeues the message so it redelivers into a fresh session serve loop requeues the message so it redelivers into a fresh session
(see [Turn outcomes](../turn-loop.md#turn-outcomes) — the wake prompt itself is tiny, so (see [Turn outcomes](README.md#turn-outcomes) — the wake prompt itself is tiny, so
the overflow was the accumulated context the archive clears). the overflow was the accumulated context the archive clears).
- **Proactive** — a turn finishes cleanly but the last inference's context - **Proactive** — a turn finishes cleanly but the last inference's context
size crossed the policy watermark. While the session is still healthy it size crossed the policy watermark. While the session is still healthy it

View file

@ -41,4 +41,4 @@ tempfile = "3"
# The sibling MCP server is its own bin crate now (`hive-agent-mcp`). # The sibling MCP server is its own bin crate now (`hive-agent-mcp`).
# Privilege boundary is enforced server-side at the socket (tool # Privilege boundary is enforced server-side at the socket (tool
# groups / manager surface). # groups / manager surface).
# See `docs/turn-loop.md::Harness binary shape`. # See `docs/turn-loop/README.md::Harness binary shape`.

View file

@ -15,7 +15,7 @@ understand or change: what happens between "a message lands in the
inbox" and "claude produces a reply", how login/auth is bootstrapped, inbox" and "claude produces a reply", how login/auth is bootstrapped,
how the per-agent web UI is served, or how turn/event stats get how the per-agent web UI is served, or how turn/event stats get
recorded. Architecture detail lives in recorded. Architecture detail lives in
[`docs/turn-loop.md`](../docs/turn-loop.md); this README is just the [`docs/turn-loop/`](../docs/turn-loop/README.md); this README is just the
map of the module tree. map of the module tree.
## Shape ## Shape
@ -48,4 +48,4 @@ map of the module tree.
Sibling: **`hive-agent-mcp`** (the MCP server this loop points claude Sibling: **`hive-agent-mcp`** (the MCP server this loop points claude
at every turn). Both are described together in at every turn). Both are described together in
[`docs/turn-loop.md::Harness binary shape`](../docs/turn-loop.md). [`docs/turn-loop/::Harness binary shape`](../docs/turn-loop/README.md).

View file

@ -118,7 +118,7 @@ impl LoginState {
/// infinite-401 loop a bare-existence check would produce when stale /// infinite-401 loop a bare-existence check would produce when stale
/// credentials are already on disk. Mtime-snapshot resumption rationale /// credentials are already on disk. Mtime-snapshot resumption rationale
/// and `DirSnapshot` two-axis design: see /// and `DirSnapshot` two-axis design: see
/// [`docs/turn-loop.md::The loop`](../../docs/turn-loop.md). /// [`docs/turn-loop/::The loop`](../../docs/turn-loop/README.md).
/// ///
/// # Panics /// # Panics
/// ///

View file

@ -4,7 +4,7 @@
//! generic and testable. Sibling: `hive-agent-mcp` (the MCP server this //! generic and testable. Sibling: `hive-agent-mcp` (the MCP server this
//! loop points claude at). //! loop points claude at).
//! Architecture lives in //! Architecture lives in
//! [`docs/turn-loop.md::Harness binary shape`](../../../docs/turn-loop.md). //! [`docs/turn-loop/::Harness binary shape`](../../../docs/turn-loop/README.md).
//! //!
//! Single bin crate: the module tree below (formerly this crate's `lib.rs`, //! Single bin crate: the module tree below (formerly this crate's `lib.rs`,
//! before lib + bin were collapsed into one) plus the serve loop. //! before lib + bin were collapsed into one) plus the serve loop.
@ -510,7 +510,7 @@ fn spawn_todo_socket(
/// Boot — wires up the web UI, login state, stats, plugins, forge /// Boot — wires up the web UI, login state, stats, plugins, forge
/// notifier, and either drops into `serve_loop` directly (`Online`) or /// notifier, and either drops into `serve_loop` directly (`Online`) or
/// parks on the login flow first (`NeedsLogin`). See /// parks on the login flow first (`NeedsLogin`). See
/// `docs/turn-loop.md::Boot wiring`. /// `docs/turn-loop/README.md::Boot wiring`.
async fn serve_main<S: Surface>(socket: &Path, poll_ms: u64) -> Result<()> { async fn serve_main<S: Surface>(socket: &Path, poll_ms: u64) -> Result<()> {
let port = std::env::var("HIVE_PORT") let port = std::env::var("HIVE_PORT")
.ok() .ok()