docs(#2067): trim choom prose in code, link to docs/tools/hivectl.md

This commit is contained in:
damocles 2026-06-28 23:58:34 +02:00 committed by mara
commit 2248881be8

View file

@ -110,15 +110,11 @@ enum Cmd {
}, },
/// Open an interactive Claude session inside an agent container. /// Open an interactive Claude session inside an agent container.
/// ///
/// Execs `machinectl shell <name>@h-<name>` running claude as the /// Runs claude as the agent user from its state dir with the harness's
/// agent user from its state dir, with the same settings / MCP config /// settings / MCP / system prompt. Bare `choom <name>` is a fresh
/// / system prompt the harness uses. Bare `choom <name>` launches a /// session; `--continue <id|name>` rejoins a prior one. Never collides
/// fresh blank session; `choom <name> --continue <id|name>` passes /// with the harness's live session. Requires root + a running
/// `--continue <value>` straight through to claude to rejoin a prior /// container. See `docs/tools/hivectl.md` (Choom) for details.
/// session (claude resolves whether the value is a session id or a
/// display name). It never collides with the harness's live session —
/// the harness pins its own session via `--resume`, so a blank choom
/// session is invisible to it. Requires root + a running container.
Choom { Choom {
/// Agent name (e.g. `damocles`, `iris`). /// Agent name (e.g. `damocles`, `iris`).
name: String, name: String,
@ -1029,49 +1025,29 @@ fn agent_exists(name: &str) -> Result<bool> {
/// Drop into an interactive Claude session in the agent container. /// Drop into an interactive Claude session in the agent container.
/// ///
/// Execs `machinectl shell <name>@h-<name> /bin/sh -lc '<script>'` where /// Execs `machinectl shell <name>@h-<name>` running claude as the agent
/// the script `cd`s into the agent's state dir and execs claude with the /// user from its state dir, reproducing the harness's per-turn claude
/// same flags the harness uses. Four things matter: /// invocation (flags, session selection, why it never collides with the
/// /// live harness session). See `docs/tools/hivectl.md` (Choom) for the
/// 1. **Run as the agent user** (`<name>@` prefix), not root, so claude /// full rationale. Inherits the caller's PTY; requires root + a running
/// reads the agent's `/home/<name>/.claude` OAuth creds. /// container.
/// 2. **Start in the agent's state dir** (`/agents/<name>/state`) so the
/// session + `CLAUDE.md` resolve against the right project.
/// 3. **Pass the harness's flags** (`--settings` / `--mcp-config` /
/// `--system-prompt-file` from `/run/hive-config/`), each only if its
/// file exists so a half-up container degrades to a bare session.
/// 4. **Pick the session explicitly.** Bare choom starts a fresh blank
/// session. `--continue <value>` is passed straight through as
/// `claude --continue <value>` to rejoin a prior session — claude
/// resolves whether the value is a session id or a display name (the
/// operator can `/rename` a session in-session for an easy handle).
/// Either way choom never clobbers the harness's live session: the
/// harness pins its own id via `--resume`, so a blank choom session
/// in this shared project dir is invisible to it.
///
/// Inherits the caller's PTY. Requires root + a running container.
fn choom(name: &str, continue_session: Option<&str>) -> Result<()> { fn choom(name: &str, continue_session: Option<&str>) -> Result<()> {
if !agent_exists(name)? { if !agent_exists(name)? {
bail!("no such agent: '{name}' (no state dir under /var/lib/hyperhive/agents/)"); bail!("no such agent: '{name}' (no state dir under /var/lib/hyperhive/agents/)");
} }
let container = hive_c0re::lifecycle::container_name(name); let container = hive_c0re::lifecycle::container_name(name);
// The agent's unix user name matches its agent name (meta-flake // Enter as the agent's unix user (== agent name) so claude reads the
// sets `hyperhive.user.name = <label>`); enter the session as that // right `$HOME/.claude`.
// user so claude sees the right `$HOME/.claude`.
let target = format!("{name}@{container}"); let target = format!("{name}@{container}");
let claude = "/run/current-system/sw/bin/claude"; let claude = "/run/current-system/sw/bin/claude";
// In-container state dir (host `/var/lib/hyperhive/agents/<name>/state` // Bind-mounted state dir; matches `hive-ag3nt::paths::state_dir()`.
// is bind-mounted here); matches `hive-ag3nt::paths::state_dir()`.
let state_dir = format!("/agents/{name}/state"); let state_dir = format!("/agents/{name}/state");
// Per-turn config dir the harness writes (RuntimeDirectory // Per-turn config the harness writes; matches `paths::config_dir()`.
// `hive-config`); matches `hive-ag3nt::paths::config_dir()`. These
// are the exact files the harness passes to claude each turn.
let cfg = "/run/hive-config"; let cfg = "/run/hive-config";
// `--continue <value>` (if given) is passed straight through to // `--continue <value>` passes straight through to claude. The value is
// claude; with none, claude starts a fresh blank session. The value // single-quoted into the shell script, so reject an embedded single
// is single-quoted into the shell script, so reject an embedded // quote (the only char that breaks single-quoting) to rule out
// single quote (the only char that breaks single-quoting) to rule // injection — session ids / display names never contain one.
// out injection — ids and display names never contain one.
let session_arg = match continue_session { let session_arg = match continue_session {
Some(val) => { Some(val) => {
if val.contains('\'') { if val.contains('\'') {
@ -1081,12 +1057,9 @@ fn choom(name: &str, continue_session: Option<&str>) -> Result<()> {
} }
None => "set --;".to_string(), None => "set --;".to_string(),
}; };
// Build the claude argv as the harness does, but only include each // Build claude's argv as the harness does, each flag included only
// flag when its file is present so a half-up container falls back to // when its file is present so a half-up container degrades to a bare
// a bare session rather than a hard claude error. `name` is // session. `name` is `[a-z0-9._-]` so there's nothing to quote.
// constrained to `[a-z0-9._-]` so there's nothing to quote. choom
// never collides with the harness's live session in this same project
// dir: the harness pins its own session id via `--resume`.
let inner = format!( let inner = format!(
"cd {state_dir} || exit 1; {session_arg} \ "cd {state_dir} || exit 1; {session_arg} \
[ -f {cfg}/claude-settings.json ] && set -- \"$@\" --settings {cfg}/claude-settings.json; \ [ -f {cfg}/claude-settings.json ] && set -- \"$@\" --settings {cfg}/claude-settings.json; \