From 411cf86632dd6231a01fe6a675a81a66e1cfce70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?m=C3=BCde?= Date: Sun, 17 May 2026 01:40:28 +0200 Subject: [PATCH] nix fmt + rustfmt sweep --- hive-ag3nt/src/bin/hive-ag3nt.rs | 10 ++-- hive-ag3nt/src/bin/hive-m1nd.rs | 18 ++++++- hive-ag3nt/src/events.rs | 12 +++-- hive-ag3nt/src/mcp.rs | 8 +-- hive-ag3nt/src/turn.rs | 3 +- hive-c0re/src/actions.rs | 24 +++------ hive-c0re/src/agent_server.rs | 32 +++++++----- hive-c0re/src/approvals.rs | 20 +++++-- hive-c0re/src/dashboard.rs | 4 +- hive-c0re/src/forge.rs | 6 +-- hive-c0re/src/lifecycle.rs | 4 +- hive-c0re/src/manager_server.rs | 35 ++++++------- hive-c0re/src/meta.rs | 4 +- hive-c0re/src/migrate.rs | 27 +++++----- hive-c0re/src/server.rs | 7 +-- nix/templates/harness-base.nix | 90 +++++++++++++++++++------------- 16 files changed, 171 insertions(+), 133 deletions(-) diff --git a/hive-ag3nt/src/bin/hive-ag3nt.rs b/hive-ag3nt/src/bin/hive-ag3nt.rs index 48def74..ec17fc0 100644 --- a/hive-ag3nt/src/bin/hive-ag3nt.rs +++ b/hive-ag3nt/src/bin/hive-ag3nt.rs @@ -204,10 +204,12 @@ async fn serve( // responsiveness if recv() times out. tokio::time::sleep(interval).await; } - Ok(AgentResponse::Ok - | AgentResponse::Status { .. } - | AgentResponse::Recent { .. } - | AgentResponse::QuestionQueued { .. }) => { + Ok( + AgentResponse::Ok + | AgentResponse::Status { .. } + | AgentResponse::Recent { .. } + | AgentResponse::QuestionQueued { .. }, + ) => { tracing::warn!("recv produced unexpected response kind"); } Ok(AgentResponse::Err { message }) => { diff --git a/hive-ag3nt/src/bin/hive-m1nd.rs b/hive-ag3nt/src/bin/hive-m1nd.rs index 89eab9f..d4bdd72 100644 --- a/hive-ag3nt/src/bin/hive-m1nd.rs +++ b/hive-ag3nt/src/bin/hive-m1nd.rs @@ -76,11 +76,25 @@ async fn main() -> Result<()> { )); match initial { LoginState::Online => { - serve(&cli.socket, Duration::from_millis(poll_ms), bus, &files, turn_lock).await + serve( + &cli.socket, + Duration::from_millis(poll_ms), + bus, + &files, + turn_lock, + ) + .await } LoginState::NeedsLogin => { turn::wait_for_login(&claude_dir, login_state, poll_ms).await; - serve(&cli.socket, Duration::from_millis(poll_ms), bus, &files, turn_lock).await + serve( + &cli.socket, + Duration::from_millis(poll_ms), + bus, + &files, + turn_lock, + ) + .await } } } diff --git a/hive-ag3nt/src/events.rs b/hive-ag3nt/src/events.rs index c8b0b08..979b5f4 100644 --- a/hive-ag3nt/src/events.rs +++ b/hive-ag3nt/src/events.rs @@ -23,15 +23,19 @@ const HISTORY_CAPACITY: usize = 2000; /// Path to the persisted event db. Overridable via `HYPERHIVE_EVENTS_DB` /// for dev / tests; otherwise derived from the agent's state dir. fn events_db_path() -> PathBuf { - std::env::var_os("HYPERHIVE_EVENTS_DB") - .map_or_else(|| crate::paths::state_dir().join("hyperhive-events.sqlite"), PathBuf::from) + std::env::var_os("HYPERHIVE_EVENTS_DB").map_or_else( + || crate::paths::state_dir().join("hyperhive-events.sqlite"), + PathBuf::from, + ) } /// Path to the persisted model file. Overridable via `HYPERHIVE_MODEL_FILE` /// for dev / tests; otherwise derived from the agent's state dir. fn model_file_path() -> PathBuf { - std::env::var_os("HYPERHIVE_MODEL_FILE") - .map_or_else(|| crate::paths::state_dir().join("hyperhive-model"), PathBuf::from) + std::env::var_os("HYPERHIVE_MODEL_FILE").map_or_else( + || crate::paths::state_dir().join("hyperhive-model"), + PathBuf::from, + ) } fn load_model() -> Option { diff --git a/hive-ag3nt/src/mcp.rs b/hive-ag3nt/src/mcp.rs index 9fc3ddb..542abfb 100644 --- a/hive-ag3nt/src/mcp.rs +++ b/hive-ag3nt/src/mcp.rs @@ -482,7 +482,10 @@ impl ManagerServer { let (resp, retries) = self .dispatch(hive_sh4re::ManagerRequest::Start { name: args.name }) .await; - annotate_retries(format_ack(resp, "start", format!("started {name}")), retries) + annotate_retries( + format_ack(resp, "start", format!("started {name}")), + retries, + ) }) .await } @@ -651,8 +654,7 @@ pub const SERVER_NAME: &str = "hyperhive"; /// state and silently evaporates on /compact or session reset — agents /// should plan in /state notes instead. Edit later as our trust model /// evolves. -pub const ALLOWED_BUILTIN_TOOLS: &[&str] = - &["Bash", "Edit", "Glob", "Grep", "Read", "Write"]; +pub const ALLOWED_BUILTIN_TOOLS: &[&str] = &["Bash", "Edit", "Glob", "Grep", "Read", "Write"]; /// Which MCP tool surface to advertise via `--allowedTools`. The agent /// list is the strict subset of the manager list, so we just thread the diff --git a/hive-ag3nt/src/turn.rs b/hive-ag3nt/src/turn.rs index c050ca3..1ff442c 100644 --- a/hive-ag3nt/src/turn.rs +++ b/hive-ag3nt/src/turn.rs @@ -108,8 +108,7 @@ pub async fn write_system_prompt( mcp::Flavor::Agent => include_str!("../prompts/agent.md"), mcp::Flavor::Manager => include_str!("../prompts/manager.md"), }; - let pronouns = - std::env::var("HIVE_OPERATOR_PRONOUNS").unwrap_or_else(|_| "she/her".to_owned()); + let pronouns = std::env::var("HIVE_OPERATOR_PRONOUNS").unwrap_or_else(|_| "she/her".to_owned()); let body = template .replace("{label}", label) .replace("{operator_pronouns}", &pronouns); diff --git a/hive-c0re/src/actions.rs b/hive-c0re/src/actions.rs index 1e6da8d..c3d7015 100644 --- a/hive-c0re/src/actions.rs +++ b/hive-c0re/src/actions.rs @@ -192,9 +192,7 @@ async fn run_apply_commit( // re-lock to the proposal commit on the prepare_deploy step // below. On build failure we roll main back to prev_main_sha so // a crash leaves the agent on its last-good tree. - if let Err(e) = - lifecycle::git_update_ref(applied_dir, "refs/heads/main", &proposal_ref).await - { + if let Err(e) = lifecycle::git_update_ref(applied_dir, "refs/heads/main", &proposal_ref).await { return ( Err(anyhow::anyhow!("ff main to {proposal_ref}: {e:#}")), None, @@ -204,20 +202,14 @@ async fn run_apply_commit( // main is ahead; working tree didn't sync. Roll main back to // keep the two consistent before bailing. let _ = lifecycle::git_update_ref(applied_dir, "refs/heads/main", &prev_main_sha).await; - return ( - Err(anyhow::anyhow!("read-tree to main: {e:#}")), - None, - ); + return (Err(anyhow::anyhow!("read-tree to main: {e:#}")), None); } // Phase 1 of the meta two-phase deploy: relock without committing. if let Err(e) = crate::meta::prepare_deploy(&approval.agent).await { let _ = lifecycle::git_update_ref(applied_dir, "refs/heads/main", &prev_main_sha).await; let _ = lifecycle::git_read_tree_reset(applied_dir, "refs/heads/main").await; - return ( - Err(anyhow::anyhow!("meta prepare_deploy: {e:#}")), - None, - ); + return (Err(anyhow::anyhow!("meta prepare_deploy: {e:#}")), None); } // Container-level rebuild against meta#. @@ -379,13 +371,9 @@ pub async fn deny(coord: &Coordinator, id: i64, note: Option<&str>) -> Result<() { let tag_name = format!("denied/{id}"); let body = note.unwrap_or("").to_owned(); - if let Err(e) = lifecycle::git_tag_annotated( - &applied_dir, - &tag_name, - &proposal_ref, - &body, - ) - .await + if let Err(e) = + lifecycle::git_tag_annotated(&applied_dir, &tag_name, &proposal_ref, &body) + .await { tracing::warn!(%id, error = ?e, "plant denied tag failed"); } else { diff --git a/hive-c0re/src/agent_server.rs b/hive-c0re/src/agent_server.rs index a4d3329..8ba71fc 100644 --- a/hive-c0re/src/agent_server.rs +++ b/hive-c0re/src/agent_server.rs @@ -18,11 +18,7 @@ pub struct AgentSocket { pub handle: JoinHandle<()>, } -pub fn start( - agent: &str, - socket_path: &Path, - coord: Arc, -) -> Result { +pub fn start(agent: &str, socket_path: &Path, coord: Arc) -> Result { let agent = agent.to_owned(); if let Some(parent) = socket_path.parent() { std::fs::create_dir_all(parent) @@ -215,21 +211,29 @@ async fn dispatch(req: &AgentRequest, agent: &str, coord: &Arc) -> let now = std::time::SystemTime::now(); let future = match now.checked_add(std::time::Duration::from_secs(*seconds)) { Some(t) => t, - None => return AgentResponse::Err { - message: format!("InSeconds overflow: {seconds}s exceeds system time range"), - }, + None => { + return AgentResponse::Err { + message: format!( + "InSeconds overflow: {seconds}s exceeds system time range" + ), + }; + } }; let duration = match future.duration_since(std::time::UNIX_EPOCH) { Ok(d) => d, - Err(e) => return AgentResponse::Err { - message: format!("system time before UNIX_EPOCH: {e}"), - }, + Err(e) => { + return AgentResponse::Err { + message: format!("system time before UNIX_EPOCH: {e}"), + }; + } }; match i64::try_from(duration.as_secs()) { Ok(ts) => Ok(ts), - Err(e) => return AgentResponse::Err { - message: format!("unix timestamp exceeds i64 range: {e}"), - }, + Err(e) => { + return AgentResponse::Err { + message: format!("unix timestamp exceeds i64 range: {e}"), + }; + } } } ReminderTiming::At { unix_timestamp } => Ok(*unix_timestamp), diff --git a/hive-c0re/src/approvals.rs b/hive-c0re/src/approvals.rs index b5cbca9..2e9dad9 100644 --- a/hive-c0re/src/approvals.rs +++ b/hive-c0re/src/approvals.rs @@ -103,7 +103,13 @@ impl Approvals { conn.execute( "INSERT INTO approvals (agent, kind, commit_ref, requested_at, status, description) VALUES (?1, ?2, ?3, ?4, 'pending', ?5)", - params![agent, kind_to_str(kind), commit_ref, now_unix(), description], + params![ + agent, + kind_to_str(kind), + commit_ref, + now_unix(), + description + ], )?; Ok(conn.last_insert_rowid()) } @@ -164,8 +170,16 @@ impl Approvals { /// approval so the caller can run the action and pass the agent name. pub fn mark_approved(&self, id: i64) -> Result { let conn = self.conn.lock().unwrap(); - let current: Option<(String, String, String, i64, String, Option, Option)> = - conn.query_row( + let current: Option<( + String, + String, + String, + i64, + String, + Option, + Option, + )> = conn + .query_row( "SELECT agent, kind, commit_ref, requested_at, status, fetched_sha, description FROM approvals WHERE id = ?1", params![id], diff --git a/hive-c0re/src/dashboard.rs b/hive-c0re/src/dashboard.rs index 4a80218..8617f05 100644 --- a/hive-c0re/src/dashboard.rs +++ b/hive-c0re/src/dashboard.rs @@ -1023,8 +1023,8 @@ async fn run_meta_update(coord: &Arc, inputs: & touched_agents }; - let current_rev = crate::auto_update::current_flake_rev(&coord.hyperhive_flake) - .unwrap_or_default(); + let current_rev = + crate::auto_update::current_flake_rev(&coord.hyperhive_flake).unwrap_or_default(); // Sequential rebuild loop — the META_LOCK guards meta-side // races but parallel nix builds also serialise via nix-daemon, // so sequential is just as fast in practice and keeps logs diff --git a/hive-c0re/src/forge.rs b/hive-c0re/src/forge.rs index d969776..228fd6e 100644 --- a/hive-c0re/src/forge.rs +++ b/hive-c0re/src/forge.rs @@ -43,11 +43,7 @@ fn token_path(name: &str) -> PathBuf { /// Probe whether `hive-forge` exists as a nixos-container. Cheap — /// `nixos-container list` is just a directory scan in /etc. pub async fn is_present() -> bool { - let Ok(out) = Command::new("nixos-container") - .arg("list") - .output() - .await - else { + let Ok(out) = Command::new("nixos-container").arg("list").output().await else { return false; }; if !out.status.success() { diff --git a/hive-c0re/src/lifecycle.rs b/hive-c0re/src/lifecycle.rs index 760d4b4..345375a 100644 --- a/hive-c0re/src/lifecycle.rs +++ b/hive-c0re/src/lifecycle.rs @@ -873,7 +873,9 @@ async fn run(args: &[&str]) -> Result<()> { // in the last few lines. let stderr_cmdline = cmdline.clone(); let stderr_tail: std::sync::Arc>> = - std::sync::Arc::new(std::sync::Mutex::new(std::collections::VecDeque::with_capacity(32))); + std::sync::Arc::new(std::sync::Mutex::new( + std::collections::VecDeque::with_capacity(32), + )); let stderr_tail_pump = stderr_tail.clone(); let pump_stderr = tokio::spawn(async move { let mut lines = BufReader::new(stderr).lines(); diff --git a/hive-c0re/src/manager_server.rs b/hive-c0re/src/manager_server.rs index 5f90a57..c25cbb0 100644 --- a/hive-c0re/src/manager_server.rs +++ b/hive-c0re/src/manager_server.rs @@ -228,8 +228,7 @@ async fn dispatch(req: &ManagerRequest, coord: &Arc) -> ManagerResp message: "update: hyperhive_flake has no canonical path".into(), }; }; - let _guard = - coord.transient_guard(name, crate::coordinator::TransientKind::Rebuilding); + let _guard = coord.transient_guard(name, crate::coordinator::TransientKind::Rebuilding); let result = crate::auto_update::rebuild_agent(coord, name, ¤t_rev).await; drop(_guard); match result { @@ -362,24 +361,20 @@ async fn submit_apply_commit( ) .map_err(|e| anyhow::anyhow!("queue approval row: {e:#}"))?; let tag = format!("proposal/{id}"); - let sha = match crate::lifecycle::git_fetch_to_tag( - &applied_dir, - &proposed_dir, - commit_ref, - &tag, - ) - .await - { - Ok(s) => s, - Err(e) => { - // Surface the failure on the approval row so the - // dashboard reflects it instead of leaving a phantom - // pending entry. The note doubles as the operator-visible - // explanation of why the approval can't be approved. - let _ = coord.approvals.mark_failed(id, &format!("{e:#}")); - return Err(anyhow::anyhow!("git_fetch_to_tag: {e:#}")); - } - }; + let sha = + match crate::lifecycle::git_fetch_to_tag(&applied_dir, &proposed_dir, commit_ref, &tag) + .await + { + Ok(s) => s, + Err(e) => { + // Surface the failure on the approval row so the + // dashboard reflects it instead of leaving a phantom + // pending entry. The note doubles as the operator-visible + // explanation of why the approval can't be approved. + let _ = coord.approvals.mark_failed(id, &format!("{e:#}")); + return Err(anyhow::anyhow!("git_fetch_to_tag: {e:#}")); + } + }; coord .approvals .set_fetched_sha(id, &sha) diff --git a/hive-c0re/src/meta.rs b/hive-c0re/src/meta.rs index 4aa79b1..8f5bb88 100644 --- a/hive-c0re/src/meta.rs +++ b/hive-c0re/src/meta.rs @@ -252,9 +252,7 @@ fn render_flake( // Free-text operator string — escape backslash + double-quote so a // pronouns value like `he/him \ "rare"` round-trips into a valid // nix string literal without breaking the flake. - let pronouns_escaped = operator_pronouns - .replace('\\', "\\\\") - .replace('"', "\\\""); + let pronouns_escaped = operator_pronouns.replace('\\', "\\\\").replace('"', "\\\""); let _ = writeln!( out, " dashboardPort = {dashboard_port};\n operatorPronouns = \"{pronouns_escaped}\";\n mkAgent = {{ name, isManager, port }}:" diff --git a/hive-c0re/src/migrate.rs b/hive-c0re/src/migrate.rs index bf5e9f2..9076aa5 100644 --- a/hive-c0re/src/migrate.rs +++ b/hive-c0re/src/migrate.rs @@ -68,23 +68,24 @@ pub async fn run(coord: &Arc) -> Result<()> { if let Err(e) = migrate_applied_repo(name).await { tracing::warn!(%name, error = ?e, "migration: applied repo rewrite failed"); } - if let Err(e) = lifecycle::setup_proposed(&Coordinator::agent_proposed_dir(name), name) - .await + if let Err(e) = + lifecycle::setup_proposed(&Coordinator::agent_proposed_dir(name), name).await { tracing::warn!(%name, error = ?e, "migration: setup_proposed failed"); } } // Phase 3: meta repo. - let agents = lifecycle::agents_for_meta_listing().await.unwrap_or_default(); - if let Err(e) = - meta::sync_agents( - &coord.hyperhive_flake, - coord.dashboard_port, - &coord.operator_pronouns, - &agents, - ) + let agents = lifecycle::agents_for_meta_listing() .await + .unwrap_or_default(); + if let Err(e) = meta::sync_agents( + &coord.hyperhive_flake, + coord.dashboard_port, + &coord.operator_pronouns, + &agents, + ) + .await { tracing::warn!(error = ?e, "migration: meta sync_agents failed"); } @@ -109,7 +110,8 @@ pub async fn run(coord: &Arc) -> Result<()> { all_ok = false; } } - if all_ok && !names.is_empty() + if all_ok + && !names.is_empty() && let Err(e) = std::fs::write(repoint_marker(), b"done\n") { tracing::warn!(error = ?e, "migration: write repoint marker failed"); @@ -142,8 +144,7 @@ async fn migrate_applied_repo(name: &str) -> Result<()> { return Ok(()); } let want = lifecycle::initial_flake_nix(); - std::fs::write(&flake_path, want) - .with_context(|| format!("write {}", flake_path.display()))?; + std::fs::write(&flake_path, want).with_context(|| format!("write {}", flake_path.display()))?; raw_git( &dir, &[ diff --git a/hive-c0re/src/server.rs b/hive-c0re/src/server.rs index c11a894..639475e 100644 --- a/hive-c0re/src/server.rs +++ b/hive-c0re/src/server.rs @@ -104,9 +104,10 @@ async fn dispatch(req: &HostRequest, coord: Arc) -> HostResponse { } HostRequest::RequestSpawn { name } => { tracing::info!(%name, "request_spawn"); - let id = coord - .approvals - .submit_kind(name, hive_sh4re::ApprovalKind::Spawn, "", None)?; + let id = + coord + .approvals + .submit_kind(name, hive_sh4re::ApprovalKind::Spawn, "", None)?; tracing::info!(%id, %name, "spawn approval queued"); HostResponse::success() } diff --git a/nix/templates/harness-base.nix b/nix/templates/harness-base.nix index b78179e..f6e7354 100644 --- a/nix/templates/harness-base.nix +++ b/nix/templates/harness-base.nix @@ -1,4 +1,9 @@ -{ pkgs, lib, config, ... }: +{ + pkgs, + lib, + config, + ... +}: { # Shared scaffolding for any hyperhive harness container — both # sub-agents (`agent-base.nix`) and the manager (`manager.nix`) extend @@ -8,7 +13,10 @@ options.hyperhive.allowedRecipients = lib.mkOption { type = lib.types.listOf lib.types.str; default = [ ]; - example = [ "alice" "manager" ]; + example = [ + "alice" + "manager" + ]; description = '' Names this agent is allowed to `send` to via `mcp__hyperhive__send`. Empty list (the default) means @@ -29,37 +37,42 @@ }; options.hyperhive.extraMcpServers = lib.mkOption { - type = lib.types.attrsOf (lib.types.submodule { - options = { - command = lib.mkOption { - type = lib.types.str; - description = "Absolute path to the MCP server binary. Use `\${pkgs.foo}/bin/foo` or `/run/current-system/sw/bin/foo`."; + type = lib.types.attrsOf ( + lib.types.submodule { + options = { + command = lib.mkOption { + type = lib.types.str; + description = "Absolute path to the MCP server binary. Use `\${pkgs.foo}/bin/foo` or `/run/current-system/sw/bin/foo`."; + }; + args = lib.mkOption { + type = lib.types.listOf lib.types.str; + default = [ ]; + description = "Args passed to the MCP server binary."; + }; + env = lib.mkOption { + type = lib.types.attrsOf lib.types.str; + default = { }; + description = "Environment variables for the MCP server child process."; + }; + allowedTools = lib.mkOption { + type = lib.types.listOf lib.types.str; + default = [ "*" ]; + example = [ + "send_message" + "join_room" + ]; + description = '' + Tool names this MCP server is auto-approved to call via + `--allowedTools`. Single entry `"*"` (the default) means + "every tool from this server" — convenient but trusting. + Tighten to a specific list when you only want a subset. + Names are bare (e.g. `send_message`); the harness prepends + `mcp____` at build time. + ''; + }; }; - args = lib.mkOption { - type = lib.types.listOf lib.types.str; - default = [ ]; - description = "Args passed to the MCP server binary."; - }; - env = lib.mkOption { - type = lib.types.attrsOf lib.types.str; - default = { }; - description = "Environment variables for the MCP server child process."; - }; - allowedTools = lib.mkOption { - type = lib.types.listOf lib.types.str; - default = [ "*" ]; - example = [ "send_message" "join_room" ]; - description = '' - Tool names this MCP server is auto-approved to call via - `--allowedTools`. Single entry `"*"` (the default) means - "every tool from this server" — convenient but trusting. - Tighten to a specific list when you only want a subset. - Names are bare (e.g. `send_message`); the harness prepends - `mcp____` at build time. - ''; - }; - }; - }); + } + ); default = { }; example = lib.literalExpression '' { @@ -120,7 +133,10 @@ options.hyperhive.claudePlugins = lib.mkOption { type = lib.types.listOf lib.types.str; default = [ ]; - example = [ "formatter@my-marketplace" "thinking-tools@anthropics" ]; + example = [ + "formatter@my-marketplace" + "thinking-tools@anthropics" + ]; description = '' Claude Code plugins to install at harness boot. Each entry is passed verbatim to `claude plugin install ` once per @@ -134,8 +150,7 @@ }; config = { - environment.etc."hyperhive/extra-mcp.json".text = - builtins.toJSON config.hyperhive.extraMcpServers; + environment.etc."hyperhive/extra-mcp.json".text = builtins.toJSON config.hyperhive.extraMcpServers; environment.etc."hyperhive/send-allow.json".text = builtins.toJSON config.hyperhive.allowedRecipients; @@ -181,7 +196,10 @@ Type = "oneshot"; RemainAfterExit = true; }; - path = [ pkgs.tea pkgs.coreutils ]; + path = [ + pkgs.tea + pkgs.coreutils + ]; script = '' set -eu CONFIG=/root/.config/tea/config.yml