From 4e7a9b93d919fbb0eca877fad720ae6500f62a7d Mon Sep 17 00:00:00 2001 From: damocles Date: Thu, 2 Jul 2026 11:52:37 +0200 Subject: [PATCH 1/2] =?UTF-8?q?choom:=20map=20--continue=20=20to=20cla?= =?UTF-8?q?ude=20--resume=20=E2=80=94=20claude's=20own=20--continue=20take?= =?UTF-8?q?s=20no=20value=20(closes=20#2127)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/tools/hivectl-cli.md | 4 ++-- docs/tools/hivectl.md | 20 +++++++++++--------- hive-c0re/src/bin/hivectl.rs | 27 +++++++++++++++++---------- 3 files changed, 30 insertions(+), 21 deletions(-) diff --git a/docs/tools/hivectl-cli.md b/docs/tools/hivectl-cli.md index 4626758a..6259e361 100644 --- a/docs/tools/hivectl-cli.md +++ b/docs/tools/hivectl-cli.md @@ -379,7 +379,7 @@ Generate the federation peer-config block for THIS hive — the nix a peer opera Open an interactive Claude session inside an agent container. -Runs claude as the agent user from its state dir with the harness's settings / MCP / system prompt. Bare `choom ` is a fresh session; `--continue ` rejoins a prior one. Never collides with the harness's live session. Requires root + a running container. See `docs/tools/hivectl.md` (Choom) for details. +Runs claude as the agent user from its state dir with the harness's settings / MCP / system prompt. Bare `choom ` is a fresh session; `--continue ` rejoins a prior one. Never collides with the harness's live session. Requires root + a running container. See `docs/tools/hivectl.md` (Choom) for details. **Usage:** `hivectl choom [OPTIONS] ` @@ -389,7 +389,7 @@ Runs claude as the agent user from its state dir with the harness's settings / M ###### **Options:** -* `--continue ` — Resume a prior claude session by id or display name, passed through as `claude --continue `. Omit for a fresh blank session. A value is required when the flag is given +* `--continue ` — Resume a prior claude session by its session id, passed through as `claude --resume ` (claude's own `--continue` takes no value — it resumes the cwd's latest session, which is the harness's, so choom never uses it). Omit for a fresh blank session. A value is required when the flag is given diff --git a/docs/tools/hivectl.md b/docs/tools/hivectl.md index 51f3ec47..03de41cc 100644 --- a/docs/tools/hivectl.md +++ b/docs/tools/hivectl.md @@ -127,17 +127,19 @@ running claude from the agent's state dir. Requires root (same as all `machinectl shell` operations). ```bash -hivectl choom iris # fresh blank Claude session in iris's container -hivectl choom iris --continue # rejoin a prior session by id or display name +hivectl choom iris # fresh blank Claude session in iris's container +hivectl choom iris --continue # rejoin a prior session by id ``` -Bare `choom` starts a fresh blank session. `--continue ` is -passed straight through as `claude --continue ` to rejoin a -prior session — claude resolves whether the value is a session id or a -display name (you can `/rename` a session in-session for an easy -handle). A value is required when the flag is given. Either way choom -never collides with the harness's live session in the same project dir: -the harness pins its own id via `--resume`, so a blank choom session is +Bare `choom` starts a fresh blank session. `--continue ` maps to +`claude --resume ` to rejoin a prior session by its session id. +(It is deliberately NOT passed as `claude --continue ` — claude's +own `--continue` is a bare flag that takes no argument and resumes the +cwd's *latest* session, i.e. the harness's; a value after it would be +consumed as the first prompt, silently poking the live harness session.) +A value is required when the flag is given. Either way choom never +collides with the harness's live session in the same project dir: the +harness pins its own id via `--resume`, so a blank choom session is invisible to it. The container must be running. choom reproduces the harness's own claude invocation so the operator diff --git a/hive-c0re/src/bin/hivectl.rs b/hive-c0re/src/bin/hivectl.rs index 3b3a9e2e..e5c2297a 100644 --- a/hive-c0re/src/bin/hivectl.rs +++ b/hive-c0re/src/bin/hivectl.rs @@ -112,15 +112,18 @@ enum Cmd { /// /// Runs claude as the agent user from its state dir with the harness's /// settings / MCP / system prompt. Bare `choom ` is a fresh - /// session; `--continue ` rejoins a prior one. Never collides - /// with the harness's live session. Requires root + a running + /// session; `--continue ` rejoins a prior one. Never + /// collides with the harness's live session. Requires root + a running /// container. See `docs/tools/hivectl.md` (Choom) for details. Choom { /// Agent name (e.g. `damocles`, `iris`). name: String, - /// Resume a prior claude session by id or display name, passed - /// through as `claude --continue `. Omit for a fresh - /// blank session. A value is required when the flag is given. + /// Resume a prior claude session by its session id, passed + /// through as `claude --resume ` (claude's own + /// `--continue` takes no value — it resumes the cwd's latest + /// session, which is the harness's, so choom never uses it). + /// Omit for a fresh blank session. A value is required when + /// the flag is given. #[arg(long = "continue", value_name = "SESSION")] continue_session: Option, }, @@ -1044,16 +1047,20 @@ fn choom(name: &str, continue_session: Option<&str>) -> Result<()> { let state_dir = format!("/agents/{name}/state"); // Per-turn config the harness writes; matches `paths::config_dir()`. let cfg = "/run/hive-config"; - // `--continue ` passes straight through to claude. The value is - // single-quoted into the shell script, so reject an embedded single - // quote (the only char that breaks single-quoting) to rule out - // injection — session ids / display names never contain one. + // `--continue ` maps to `claude --resume ` — claude's + // own `--continue` is a bare flag (no argument): passing a value + // after it made claude resume the cwd's latest session and treat the + // value as the first PROMPT, silently poking the harness session. + // `--resume ` is the actual rejoin-by-id surface. The + // value is single-quoted into the shell script, so reject an + // embedded single quote (the only char that breaks single-quoting) + // to rule out injection — session ids never contain one. let session_arg = match continue_session { Some(val) => { if val.contains('\'') { bail!("invalid --continue value '{val}': must not contain a single quote"); } - format!("set -- --continue '{val}';") + format!("set -- --resume '{val}';") } None => "set --;".to_string(), }; From 2f43077e3106862cde78e7db6d457ea567219b22 Mon Sep 17 00:00:00 2001 From: damocles Date: Thu, 2 Jul 2026 19:48:54 +0200 Subject: [PATCH 2/2] rename choom flag --continue to --resume to match the claude flag it maps to (mara review) --- docs/tools/hivectl-cli.md | 4 ++-- docs/tools/hivectl.md | 25 ++++++++++----------- hive-c0re/src/bin/hivectl.rs | 42 ++++++++++++++++++------------------ 3 files changed, 36 insertions(+), 35 deletions(-) diff --git a/docs/tools/hivectl-cli.md b/docs/tools/hivectl-cli.md index 6259e361..ace96cb9 100644 --- a/docs/tools/hivectl-cli.md +++ b/docs/tools/hivectl-cli.md @@ -379,7 +379,7 @@ Generate the federation peer-config block for THIS hive — the nix a peer opera Open an interactive Claude session inside an agent container. -Runs claude as the agent user from its state dir with the harness's settings / MCP / system prompt. Bare `choom ` is a fresh session; `--continue ` rejoins a prior one. Never collides with the harness's live session. Requires root + a running container. See `docs/tools/hivectl.md` (Choom) for details. +Runs claude as the agent user from its state dir with the harness's settings / MCP / system prompt. Bare `choom ` is a fresh session; `--resume ` rejoins a prior one. Never collides with the harness's live session. Requires root + a running container. See `docs/tools/hivectl.md` (Choom) for details. **Usage:** `hivectl choom [OPTIONS] ` @@ -389,7 +389,7 @@ Runs claude as the agent user from its state dir with the harness's settings / M ###### **Options:** -* `--continue ` — Resume a prior claude session by its session id, passed through as `claude --resume ` (claude's own `--continue` takes no value — it resumes the cwd's latest session, which is the harness's, so choom never uses it). Omit for a fresh blank session. A value is required when the flag is given +* `--resume ` — Resume a prior claude session by its session id, passed through as `claude --resume ` (claude's `--continue` takes no value — it resumes the cwd's latest session, which is the harness's, so choom never uses it; this flag matches the claude flag it maps to). Omit for a fresh blank session. A value is required when the flag is given diff --git a/docs/tools/hivectl.md b/docs/tools/hivectl.md index 03de41cc..6af3b932 100644 --- a/docs/tools/hivectl.md +++ b/docs/tools/hivectl.md @@ -127,20 +127,21 @@ running claude from the agent's state dir. Requires root (same as all `machinectl shell` operations). ```bash -hivectl choom iris # fresh blank Claude session in iris's container -hivectl choom iris --continue # rejoin a prior session by id +hivectl choom iris # fresh blank Claude session in iris's container +hivectl choom iris --resume # rejoin a prior session by id ``` -Bare `choom` starts a fresh blank session. `--continue ` maps to -`claude --resume ` to rejoin a prior session by its session id. -(It is deliberately NOT passed as `claude --continue ` — claude's -own `--continue` is a bare flag that takes no argument and resumes the -cwd's *latest* session, i.e. the harness's; a value after it would be -consumed as the first prompt, silently poking the live harness session.) -A value is required when the flag is given. Either way choom never -collides with the harness's live session in the same project dir: the -harness pins its own id via `--resume`, so a blank choom session is -invisible to it. The container must be running. +Bare `choom` starts a fresh blank session. `--resume ` passes +through as `claude --resume ` to rejoin a prior session by its +session id — the flag name deliberately matches the claude flag it maps +to. (choom never uses claude's `--continue`: that's a bare flag that +takes no argument and resumes the cwd's *latest* session, i.e. the +harness's; a value after it would be consumed as the first prompt, +silently poking the live harness session.) A value is required when the +flag is given. Either way choom never collides with the harness's live +session in the same project dir: the harness pins its own id via +`--resume`, so a blank choom session is invisible to it. The container +must be running. choom reproduces the harness's own claude invocation so the operator lands in a faithful copy of the agent's environment: diff --git a/hive-c0re/src/bin/hivectl.rs b/hive-c0re/src/bin/hivectl.rs index e5c2297a..3a5a743a 100644 --- a/hive-c0re/src/bin/hivectl.rs +++ b/hive-c0re/src/bin/hivectl.rs @@ -112,20 +112,20 @@ enum Cmd { /// /// Runs claude as the agent user from its state dir with the harness's /// settings / MCP / system prompt. Bare `choom ` is a fresh - /// session; `--continue ` rejoins a prior one. Never + /// session; `--resume ` rejoins a prior one. Never /// collides with the harness's live session. Requires root + a running /// container. See `docs/tools/hivectl.md` (Choom) for details. Choom { /// Agent name (e.g. `damocles`, `iris`). name: String, /// Resume a prior claude session by its session id, passed - /// through as `claude --resume ` (claude's own - /// `--continue` takes no value — it resumes the cwd's latest - /// session, which is the harness's, so choom never uses it). - /// Omit for a fresh blank session. A value is required when - /// the flag is given. - #[arg(long = "continue", value_name = "SESSION")] - continue_session: Option, + /// through as `claude --resume ` (claude's `--continue` + /// takes no value — it resumes the cwd's latest session, which + /// is the harness's, so choom never uses it; this flag matches + /// the claude flag it maps to). Omit for a fresh blank session. + /// A value is required when the flag is given. + #[arg(long = "resume", value_name = "SESSION")] + resume_session: Option, }, /// Stop containers hive-wide in one operator action. Bare `hivectl /// stop` stops **everything** — all sub-agents plus the ci, forge, @@ -634,8 +634,8 @@ async fn main() -> Result<()> { }, Cmd::Choom { name, - continue_session, - } => choom(&name, continue_session.as_deref()), + resume_session, + } => choom(&name, resume_session.as_deref()), Cmd::Quota { cmd } => match cmd { QuotaCmd::Enable => quota_enable().await, QuotaCmd::Show { name } => quota_show(name.as_deref()).await, @@ -1034,7 +1034,7 @@ fn agent_exists(name: &str) -> Result { /// live harness session). See `docs/tools/hivectl.md` (Choom) for the /// full rationale. Inherits the caller's PTY; requires root + a running /// container. -fn choom(name: &str, continue_session: Option<&str>) -> Result<()> { +fn choom(name: &str, resume_session: Option<&str>) -> Result<()> { if !agent_exists(name)? { bail!("no such agent: '{name}' (no state dir under /var/lib/hyperhive/agents/)"); } @@ -1047,18 +1047,18 @@ fn choom(name: &str, continue_session: Option<&str>) -> Result<()> { let state_dir = format!("/agents/{name}/state"); // Per-turn config the harness writes; matches `paths::config_dir()`. let cfg = "/run/hive-config"; - // `--continue ` maps to `claude --resume ` — claude's - // own `--continue` is a bare flag (no argument): passing a value - // after it made claude resume the cwd's latest session and treat the - // value as the first PROMPT, silently poking the harness session. - // `--resume ` is the actual rejoin-by-id surface. The - // value is single-quoted into the shell script, so reject an - // embedded single quote (the only char that breaks single-quoting) - // to rule out injection — session ids never contain one. - let session_arg = match continue_session { + // `--resume ` passes through as `claude --resume ` — + // the rejoin-by-id surface. (claude's `--continue` is a bare flag + // that resumes the cwd's latest session — the harness's — and would + // consume a trailing value as the first PROMPT; choom never uses + // it.) The value is single-quoted into the shell script, so reject + // an embedded single quote (the only char that breaks + // single-quoting) to rule out injection — session ids never + // contain one. + let session_arg = match resume_session { Some(val) => { if val.contains('\'') { - bail!("invalid --continue value '{val}': must not contain a single quote"); + bail!("invalid --resume value '{val}': must not contain a single quote"); } format!("set -- --resume '{val}';") }