diff --git a/hive-c0re/src/meta.rs b/hive-c0re/src/meta.rs index 1d111c83..8a75e409 100644 --- a/hive-c0re/src/meta.rs +++ b/hive-c0re/src/meta.rs @@ -74,7 +74,6 @@ 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(); @@ -648,7 +647,6 @@ fn render_flake( operator_pronouns: &str, context_window_tokens: &std::collections::HashMap, agents: &[AgentSpec], - forge_base: &str, ) -> String { render_flake_with_lookup( hyperhive_flake, @@ -658,7 +656,6 @@ fn render_flake( operator_pronouns, context_window_tokens, agents, - forge_base, agent_canonical_inputs, ) } @@ -935,7 +932,6 @@ fn render_flake_with_lookup( operator_pronouns: &str, context_window_tokens: &std::collections::HashMap, agents: &[AgentSpec], - forge_base: &str, lookup: F, ) -> String where @@ -980,19 +976,20 @@ where let _ = writeln!(out, " hyperhive-docs.url = \"{docs_flake}\";"); out.push_str(" hyperhive-docs.flake = false;\n"); } - // Each agent's *persistent* config input is its canonical repo on the - // 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. + // Each agent's config input is its LOCAL applied mirror + // (`git+file://`), so the meta flake resolves entirely from + // on-disk state and boot never depends on the forge being reachable. + // The forge `agent-configs/` repos stay the review/audit surface + // (config PRs land there) but are not the flake's build input. deploy + + // rebuild re-lock this input to `applied/`'s current `main` head; + // `verify_commit` overrides it to a proposed `?rev=` for eval + // before that head moves. for spec in agents { let _ = writeln!( out, - " agent-{name}.url = \"git+{forge_base}/{org}/{name}.git\";", + " agent-{name}.url = \"git+file://{applied}\";", name = spec.name, - org = crate::forge::CONFIG_ORG, + applied = crate::paths::applied_dir(&spec.name).display(), ); // For each canonical input the agent declares in its own // `flake.nix` (detected by reading its applied `flake.lock`), @@ -1542,7 +1539,6 @@ 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. @@ -1586,7 +1582,6 @@ mod tests { "she/her", &std::collections::HashMap::new(), &[sample_spec("alice", false, 9001)], - "http://forge.test", ); assert!( !out.contains("hyperhive-docs"), @@ -1606,7 +1601,6 @@ mod tests { "she/her", &std::collections::HashMap::new(), &[sample_spec("alice", false, 9001)], - "http://forge.test", ); assert!( out.contains("nixpkgs.follows = \"hyperhive/nixpkgs\""), @@ -1640,7 +1634,6 @@ mod tests { sample_spec("bitburner", false, 9002), sample_spec("dmatrix", false, 9003), ], - "http://forge.test", lookup, ); // bitburner declares nixpkgs → follows emitted. @@ -1669,7 +1662,6 @@ 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 @@ -1704,7 +1696,6 @@ mod tests { "she/her", &std::collections::HashMap::new(), &[sample_spec("alice", false, 9001)], - "http://forge.test", ); unsafe { std::env::remove_var("HIVE_FORGE_URL"); @@ -1728,13 +1719,12 @@ mod tests { } #[test] - fn render_flake_agent_input_points_at_forge_config_repo() { - // The persistent agent config input must reference the canonical - // repo on the forge (git+http, org `agent-configs`), NOT the local - // `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. - // `forge_base` is an explicit param now, so no env mutation is needed. + fn render_flake_agent_input_points_at_local_applied_mirror() { + // The agent config input references the LOCAL applied mirror + // (`git+file://`), NOT the forge — so the meta flake + // resolves entirely from on-disk state and boot never depends on the + // forge being reachable. The forge `agent-configs/` repos stay the + // review surface, but they are not the flake's build input. let out = render_flake( "github:example/hyperhive", "path:/nix/store/bbbb-hyperhive-docs-source", @@ -1743,17 +1733,18 @@ mod tests { "she/her", &std::collections::HashMap::new(), &[sample_spec("alice", false, 9001)], - "http://forge.example.test", + ); + let want = format!( + "agent-alice.url = \"git+file://{}\"", + crate::paths::applied_dir("alice").display() ); assert!( - out.contains( - "agent-alice.url = \"git+http://forge.example.test/agent-configs/alice.git\"" - ), - "expected the agent input to point at the forge config repo:\n{out}" + out.contains(&want), + "expected the agent input to point at the local applied mirror ({want}):\n{out}" ); assert!( - !out.contains("agent-alice.url = \"git+file://"), - "the local applied/ path must no longer be the persistent input:\n{out}" + !out.contains("git+http"), + "no forge git+http URL must remain in the rendered flake:\n{out}" ); } @@ -1783,7 +1774,6 @@ mod tests { "she/her", &std::collections::HashMap::new(), &[sample_spec("alice", false, 9001)], - "http://forge.test", ) }; @@ -1866,7 +1856,6 @@ mod tests { "she/her", &std::collections::HashMap::new(), &[sample_spec("alice", false, 9001)], - "http://forge.test", ) }; unsafe { @@ -1951,7 +1940,6 @@ mod tests { "she/her", &std::collections::HashMap::new(), &[sample_spec("alice", false, 9001)], - "http://forge.test", ) }; unsafe {