diff --git a/hive-c0re/src/meta.rs b/hive-c0re/src/meta.rs index d22e0c68..7d824d38 100644 --- a/hive-c0re/src/meta.rs +++ b/hive-c0re/src/meta.rs @@ -74,6 +74,7 @@ pub async fn sync_agents(hive: &HiveEnv, agents: &[AgentSpec]) -> Result<()> { &hive.operator_pronouns, &hive.context_window_tokens, agents, + crate::forge::forge_http_base(), ); let flake_path = dir.join("flake.nix"); let on_disk = std::fs::read_to_string(&flake_path).unwrap_or_default(); @@ -634,6 +635,11 @@ pub async fn bulk_commit_topology( Ok(changed) } +#[allow( + clippy::too_many_arguments, + reason = "many genuine flake inputs (source flakes, port, pronouns, tokens, \ + agents, forge base); a params struct would just move the same fields" +)] fn render_flake( hyperhive_flake: &str, docs_flake: &str, @@ -642,6 +648,7 @@ fn render_flake( operator_pronouns: &str, context_window_tokens: &std::collections::HashMap, agents: &[AgentSpec], + forge_base: &str, ) -> String { render_flake_with_lookup( hyperhive_flake, @@ -651,6 +658,7 @@ fn render_flake( operator_pronouns, context_window_tokens, agents, + forge_base, agent_canonical_inputs, ) } @@ -927,6 +935,7 @@ fn render_flake_with_lookup( operator_pronouns: &str, context_window_tokens: &std::collections::HashMap, agents: &[AgentSpec], + forge_base: &str, lookup: F, ) -> String where @@ -972,18 +981,12 @@ where out.push_str(" hyperhive-docs.flake = false;\n"); } // Each agent's *persistent* config input is its canonical repo on the - // forge (`git+http:///agent-configs/.git`), authenticated by - // hive-core's git credential helper (which reads the live `forge-core-token` - // — no token in the URL or lock). The deploy re-lock + `verify_commit` eval - // keep pinning the local `applied/` override (`agent_input_override`), - // so a deploy never does a network fetch — only the persistent input tracks - // the forge. `HIVE_FORGE_URL` is the in-cluster gateway vhost, already - // forwarded into hive-core's env; fall back to the local forge for legacy - // deploys that predate the forwarding. - let forge_base = std::env::var("HIVE_FORGE_URL") - .ok() - .filter(|v| !v.is_empty()) - .unwrap_or_else(|| "http://localhost:3000".to_string()); + // forge (`git+{forge_base}/agent-configs/.git`, `forge_base` supplied + // by the caller from `HIVE_FORGE_URL`), authenticated by hive-core's git + // credential helper (which reads the live `forge-core-token` — no token in + // the URL or lock). The deploy re-lock + `verify_commit` eval keep pinning + // the local `applied/` override (`agent_input_override`), so a deploy + // never does a network fetch — only the persistent input tracks the forge. for spec in agents { let _ = writeln!( out, @@ -1535,6 +1538,7 @@ mod tests { "she/her", &std::collections::HashMap::new(), &[sample_spec("alice", false, 9001)], + "http://forge.test", ); // nixpkgs is a top-level input with an explicit URL; hyperhive // follows it. @@ -1578,6 +1582,7 @@ mod tests { "she/her", &std::collections::HashMap::new(), &[sample_spec("alice", false, 9001)], + "http://forge.test", ); assert!( !out.contains("hyperhive-docs"), @@ -1597,6 +1602,7 @@ mod tests { "she/her", &std::collections::HashMap::new(), &[sample_spec("alice", false, 9001)], + "http://forge.test", ); assert!( out.contains("nixpkgs.follows = \"hyperhive/nixpkgs\""), @@ -1630,6 +1636,7 @@ mod tests { sample_spec("bitburner", false, 9002), sample_spec("dmatrix", false, 9003), ], + "http://forge.test", lookup, ); // bitburner declares nixpkgs → follows emitted. @@ -1658,6 +1665,7 @@ mod tests { "she/her", &std::collections::HashMap::new(), &[sample_spec("alice", false, 9001)], + "http://forge.test", |_| Vec::new(), ); // No agent-side follows when the lookup reports nothing @@ -1692,6 +1700,7 @@ mod tests { "she/her", &std::collections::HashMap::new(), &[sample_spec("alice", false, 9001)], + "http://forge.test", ); unsafe { std::env::remove_var("HIVE_FORGE_URL"); @@ -1721,12 +1730,7 @@ mod tests { // `applied/` checkout — that's what lets the config live on the // forge instead of a hand-synced local copy. Auth is out-of-band via // hive-core's git credential helper, so no creds appear in the URL. - // - // SAFETY: single-threaded mutation of a process env var the other - // tests don't assert the absence of; restored before returning. - unsafe { - std::env::set_var("HIVE_FORGE_URL", "http://forge.example.test"); - } + // `forge_base` is an explicit param now, so no env mutation is needed. let out = render_flake( "github:example/hyperhive", "path:/nix/store/bbbb-hyperhive-docs-source", @@ -1735,10 +1739,8 @@ mod tests { "she/her", &std::collections::HashMap::new(), &[sample_spec("alice", false, 9001)], + "http://forge.example.test", ); - unsafe { - std::env::remove_var("HIVE_FORGE_URL"); - } assert!( out.contains( "agent-alice.url = \"git+http://forge.example.test/agent-configs/alice.git\"" @@ -1777,6 +1779,7 @@ mod tests { "she/her", &std::collections::HashMap::new(), &[sample_spec("alice", false, 9001)], + "http://forge.test", ) }; @@ -1859,6 +1862,7 @@ mod tests { "she/her", &std::collections::HashMap::new(), &[sample_spec("alice", false, 9001)], + "http://forge.test", ) }; unsafe { @@ -1943,6 +1947,7 @@ mod tests { "she/her", &std::collections::HashMap::new(), &[sample_spec("alice", false, 9001)], + "http://forge.test", ) }; unsafe {