diff --git a/hive-ag3nt/src/forge_notify.rs b/hive-ag3nt/src/forge_notify.rs index d36e1bcd..2a97547a 100644 --- a/hive-ag3nt/src/forge_notify.rs +++ b/hive-ag3nt/src/forge_notify.rs @@ -17,7 +17,6 @@ //! `PATCH /notifications/threads/{id}` so it does not re-fire. If delivery //! fails the thread is left unread so it resurfaces next tick. -use std::collections::HashSet; use std::path::{Path, PathBuf}; use std::time::Duration; @@ -81,28 +80,9 @@ pub async fn run(socket: PathBuf, is_manager: bool) { // socket becoming available right at boot. interval.tick().await; - // HIVE_FORGE_KEEP_SUBSCRIPTIONS=1 disables auto-unsubscribe for agents - // that intentionally consume the full repo notification firehose (e.g. triage). - let keep_subscriptions = std::env::var("HIVE_FORGE_KEEP_SUBSCRIPTIONS") - .map(|v| v == "1" || v.eq_ignore_ascii_case("true")) - .unwrap_or(false); - - // Repos we have already unsubscribed this process lifetime. Persists - // across polls so we don't hammer DELETE on every cycle. - let mut unsubbed_repos: HashSet = HashSet::new(); - loop { interval.tick().await; - poll_once( - &client, - &forge_url, - &token, - &socket, - is_manager, - keep_subscriptions, - &mut unsubbed_repos, - ) - .await; + poll_once(&client, &forge_url, &token, &socket, is_manager).await; } } @@ -242,15 +222,7 @@ async fn format_notification( } } -async fn poll_once( - client: &reqwest::Client, - forge_url: &str, - token: &str, - socket: &Path, - is_manager: bool, - keep_subscriptions: bool, - unsubbed_repos: &mut HashSet, -) { +async fn poll_once(client: &reqwest::Client, forge_url: &str, token: &str, socket: &Path, is_manager: bool) { let url = format!("{forge_url}/api/v1/notifications?all=false&limit=50"); let resp = match client .get(&url) @@ -338,35 +310,5 @@ async fn poll_once( debug!(%id, "forge_notify: marked read"); } } - - // Auto-unsubscribe from broad repo watches when the notification - // reason is "subscribed" (agent watching the whole repo). Skipped - // when HIVE_FORGE_KEEP_SUBSCRIPTIONS=1 — triage and other firehose - // consumers set this to retain broad repo visibility. - let reason = notif["reason"].as_str().unwrap_or(""); - if !keep_subscriptions && reason == "subscribed" { - if let Some(repo) = notif["repository"]["full_name"].as_str() { - if !unsubbed_repos.contains(repo) { - let unsub_url = format!("{forge_url}/api/v1/repos/{repo}/subscription"); - match client - .delete(&unsub_url) - .header("Authorization", format!("token {token}")) - .send() - .await - { - Ok(r) if r.status().is_success() || r.status().as_u16() == 404 => { - debug!(%repo, "forge_notify: unsubscribed from repo watch"); - unsubbed_repos.insert(repo.to_owned()); - } - Ok(r) => { - debug!(%repo, status = %r.status(), "forge_notify: unsub non-2xx (ignored)"); - } - Err(e) => { - debug!(%repo, error = ?e, "forge_notify: unsub request failed (ignored)"); - } - } - } - } - } } } diff --git a/nix/templates/harness-base.nix b/nix/templates/harness-base.nix index e1bd2879..e8f43d12 100644 --- a/nix/templates/harness-base.nix +++ b/nix/templates/harness-base.nix @@ -159,20 +159,6 @@ ''; }; - options.hyperhive.forge.keepSubscriptions = lib.mkOption { - type = lib.types.bool; - default = true; - description = '' - When true (the default), the forge notification poller will NOT - auto-unsubscribe from repo watches after delivering a - "subscribed"-reason notification. Sub-agents keep their broad - subscriptions so they stay informed about repos they contribute to. - Set to false for agents (e.g. the manager) that use reason-based - filtering and do not need firehose-level repo visibility — they will - auto-unsubscribe after receiving a watched-repo notification. - ''; - }; - options.hyperhive.claudeMarketplaces = lib.mkOption { type = lib.types.listOf lib.types.str; default = [ "anthropics/claude-plugins-official" ]; @@ -297,8 +283,6 @@ # Zero watermark disables proactive compaction; the reactive path # (compact-on-overflow) still fires when the session is truly full. HIVE_COMPACT_WATERMARK_TOKENS = "0"; - } // lib.optionalAttrs config.hyperhive.forge.keepSubscriptions { - HIVE_FORGE_KEEP_SUBSCRIPTIONS = "1"; }; boot.isNspawnContainer = true; diff --git a/nix/templates/manager.nix b/nix/templates/manager.nix index c040cae5..f88e2fba 100644 --- a/nix/templates/manager.nix +++ b/nix/templates/manager.nix @@ -2,10 +2,6 @@ { imports = [ ./harness-base.nix ]; - # Manager auto-unsubscribes from repo watches (uses mention-only filtering - # via HIVE_FORGE_NOTIFY_REASONS). Sub-agents default to keepSubscriptions=true. - hyperhive.forge.keepSubscriptions = false; - # HIVE_PORT/HIVE_LABEL/gitconfig are also injected by the generated # `applied/hm1nd/flake.nix` (see `lifecycle::setup_applied`); the values # here are the base config so the container stays sensible if anyone