Watch
0
0
Fork
You've already forked hyperhive
0
Commit graph hyperhive/hive-agent/src/mcp_config.rs
Author SHA1 Message Date
atlas
11097ed336 remove the get_host_journal MCP tool and its capability
swarm-logs covers every host-tier unit this tool could reach, so the
second, capability-gated path into host journald earns nothing and is
removed outright rather than disabled behind a flag.

Removed end to end: the MCP tool definition + handler, the
GetHostJournal/HostJournal wire variants, hive-c0re's
dispatch_host_journal handler, the ReadHostJournal capability, and the
harness-side capability->--allowedTools gate. get_host_journal was the
only capability that mapped to an MCP tool, so allowed_capability_tools
could only ever return an empty vec; it goes too rather than linger as a
function that provably does nothing.

capabilities::has_cap/caps_for stay: #4624 gave ManageRootAgent's
bind-mount enforcement (hive-c0re/src/lifecycle/host_config.rs) a
second caller of has_cap, so they're no longer callerless once this
lands on top of it.

hive-sh4re's journal module (JournalPriority) had no consumer outside
this tool and is deleted.

An existing capabilities.json still naming read_host_journal does not
error: capabilities::prune_unknown drops unrecognised names with a
warn!, and an agent left with no capabilities has its entry removed. No
migration step is needed.

Untouched: hive-c0re/src/dashboard/journal.rs's
read_host_journal_response, which matches the name but is the private
helper behind the operator-only GET /api/journal-host dashboard route
and carries no capability check.
2026-09-21 19:31:45 +02:00
atlas
4f6407fdea collapse the roles.json mount grant into the ManageRootAgent capability
The hive had two spellings of "this agent may act on agents that aren't
its children": the `ManageRootAgent` capability, which nothing checked,
and a `can_manage_top_level_agents` role in a third meta store,
`roles.json`, which owned the real grant — the bind mounts that put
another agent's state (rw) and config (ro) inside the holder's
container. The two drifted independently, and with the parent/child
hierarchy removed the role's set (`parent.is_none()`) silently became
every agent while nothing said so.

Collapse them. The mount grant now hangs off
`Capability::ManageRootAgent`, looked up through the one capability
path that already exists (`capabilities::has_cap` over
`capabilities.json`) rather than a second mechanism. `roles.json` and
everything that read, wrote or reconciled it is gone, along with its
`meta.rs` staging and commit-label wiring; nothing in the tree reads
that file any more.

The enum variant keeps its name deliberately. Renaming it would turn
every `manage_root_agent` already stored in `capabilities.json` into an
unrecognised name that `prune_unknown` drops without asking. Its
meaning, not its spelling, is what changed: "may manage any agent". The
doc comment and the description string now say that.

`top_level_agents()`/`top_level_agents_in()` are replaced by
`all_agents()`/`all_agents_in()`. Under "manage any agent" the mounted
set is every agent by definition, so the code states it instead of
deriving it from a predicate that no longer discriminates — and the
call-site comment explains that, because it otherwise reads as a
widening. The holder is no longer bound as its own virtual child: that
reproduced the own-state and own-config mounts exactly, so dropping it
loses nothing.
2026-09-21 19:04:14 +02:00
atlas
729c5b4f42 hive-agent-mcp, hive-c0re, hive-sh4re: drop agent param from get_loose_ends
get_loose_ends now always returns the caller's own loose ends, for every
caller including the manager (ruth) — there is no separate manager
surface, ruth is a normal agent with different default capabilities.

- AgentGetLooseEndsArgs removed; get_loose_ends takes no args.
- Wire Request::GetLooseEnds collapses from an Option<String> target to
  a unit variant.
- hive-c0re's handle_get_loose_ends drops the "*" hive-wide branch and
  the subtree/capability resolver (resolve_agent_state_target); both
  are gone since there is no longer a target to resolve.
- loose_ends::hive_wide and Capability::QueryAgentState removed as
  dead code — their only callers were the two functions above.
- is_descendant_of is untouched (still used by lifecycle_handlers.rs
  and schedules.rs independently of this change).
- Docs updated: docs/turn-loop/mcp.md, docs/web-ui/dashboard.md,
  docs/process/conventions.md (Loose-ends wire shape + capabilities
  table), plus the doc comments in hive-core-agent-sock, mcp_config.rs
  and capabilities.rs that described the old shape.

Refs #4480
2026-09-20 05:36:49 +02:00
atlas
6ea81aae65 hive-c0re: render the new agent option paths into generated agent flakes
meta.rs writes each agent's flake, and it still named the pre-move
`hyperhive.*` paths — so every agent rebuild would print a rename
deprecation warning about a line no human wrote and no operator could fix.
A warning nobody can act on trains everyone to ignore the ones that matter,
which is the whole value of the alias shims.

Repoints the FORWARDED_VAR_OPTIONS table and every other emitted option
assignment (otel.*, docs.source, claudeCodePath, github.enable, user.name,
claudeMemoryMaxBytes) to `services.hyperhive.agent.*`, with the test
expectations that pin the rendered text. The flake input named `hyperhive`
(`hyperhive.url`, `hyperhive.inputs.nixpkgs.follows`,
`hyperhive.nixosConfigurations.*`), hive-tier `services.hyperhive.*` paths,
and the `@hyperhive.local` git identity share the word and are untouched.

Also repoints the same option paths where they appear in comments, rustdoc
and runtime message strings across the other crates — a refusal message
naming `hyperhive.allowedRecipients` sends an operator to a path that will
stop existing. Prose under docs/ is deliberately not in this commit.

Refs #4473
2026-09-17 20:19:30 +02:00
atlas
5ce0a357b4 subagent: grant claude's Bash when the agent holds the execution group
A subagent inherited the parent's built-in tool list, which correctly has
no `Bash` -- the agent reaches a shell through the `bash` MCP server, not
the built-in. Subagents get no such server, so the intersection was empty
and they could not run a command at all: no commits, no pushes, no gates.

Add `subagent_builtin_tools_for`/`_arg`, which reuse the shared resolver
and append `Bash` only when `Execution` -- the group that gates the `bash`
MCP server -- is present. Only the subagent spawn path calls them, so the
harness's own `--tools`/`--allowedTools` are unchanged.

The capability transfers; the mechanism does not.

Refs #4422
2026-09-15 18:48:51 +02:00
atlas
8b01dbeef1 permissions: give the built-in tool list one home, next to ToolGroup
The `--tools` list a harness session gets is not a constant: the base set
plus whatever the agent's `HIVE_TOOL_GROUPS` add (today, `web_tools` →
`WebFetch`/`WebSearch`). That resolution lived in `hive-agent`'s
`mcp_config`, which is fine while the harness is the only thing that
spawns a `claude` — and it is not: `hive-subagent-mcp` spawns one too.

`hive-agent` is binary-only (no `src/lib.rs`, no lib target), so nothing
can depend on it to reach `builtin_tools_arg`. The alternative to a
shared home is a second list in the subagent daemon, which diverges on
the first tool anyone adds to either — and diverging upward is a
subagent holding a built-in its parent does not have.

So move the base list, the `HIVE_TOOL_GROUPS` parse and the resolution
into `hive_sh4re::permissions`, beside `ToolGroup` — whose
`builtin_tools()` was already half of the answer. `hive-agent`
re-exports them, so `mcp_config::builtin_tools_arg()` still reads the
same at the call site, and `allowed_tools_arg` now derives its built-in
half from the same function rather than repeating the merge loop.

Behaviour is unchanged. The parse is `strum::EnumString` rather than a
`serde_json::from_value` round-trip through a `Value::String`: same
`snake_case` names (a test pins the two derives against each other),
without `hive-sh4re` needing `serde_json` outside its dev-dependencies.
It is now a pure function of its input, so the fallbacks are testable
without mutating the environment — which under edition 2024 is `unsafe`
and racy across a test binary's threads.

Refs #4416
2026-09-15 17:40:27 +02:00
damocles
349f7096ba subagents: fold hive-extra-mcp into hive-agent-sock per mara's rescoping 2026-09-13 13:57:53 +02:00
damocles
16eec3c314 subagents: add availableToSubagents opt-in toggle for extraMcpServers 2026-09-13 13:57:53 +02:00
atlas
576294012b docs: three comments point at a nix directory that does not exist
`nix/templates/harness/` is cited from `send_allow.rs` and twice from
`mcp_config.rs`, in the present tense, as where the NixOS module writes
the send allow-list, writes the extra-MCP spec, and defines the MCP http
port default. There is no such directory — `nix/templates/` holds only
`agent.nix` and `ruth.nix`.

All three describe things that live in `nix/agent-modules/mcp.nix`:
send-allow.json is written at :230, extra-mcp.json at :228, and the
`hyperhive.mcp.httpPort` option is declared at :143.

These are the mechanical half of #3923, which explicitly carved the
repointing out from the question of whether the reference gate should
widen. Nothing here changes that question.
2026-09-02 14:19:03 +02:00
iris
07b62612b0 docs: restructure into topic subdirectories, collapse duplicated index
Per mara's go-ahead on hyperhive#3902 ("getting started is good, but
terminal rendering does not go in there i think"):

Moved 21 top-level docs/*.md files into 7 new topic subdirectories
(existing web-ui/, turn-loop/, swarm/, tools/, crates/ untouched):
  getting-started/  setup.md
  agent-lifecycle/  agent-hierarchy.md, approvals.md, persistence.md
  trust-boundary/   boundary.md, security.md
  integrations/     forge.md, matrix.md, github.md, knowledge.md
  networking/       gateway.md, network.md, snapshot-store.md
  scheduler/        jobq.md, coordinator.md, ci.md, observability.md
  process/          conventions.md, gotchas.md, pr-review-gate.md
  web-ui/           terminal-rendering.md (moved into the EXISTING dir,
                    per mara's correction to the original getting-started
                    guess -- it's UI implementation detail, not onboarding)

The physical layout now matches docs/README.md's own topical headers,
which already amounted to this taxonomy -- see the scoping comment on
the issue for the two findings that motivated this (a genuine
duplication between CLAUDE.md's old "Reading paths" list and
docs/README.md's grouped one, since drifted out of sync with each
other; and the flat layout not matching the grouping we already had).

Fixed every cross-reference this moved across the whole repo (~120
files: docs/ internal links at every depth, Rust doc comments, nix
module option docs, crate READMEs) -- verified two ways: a grep sweep
confirming zero remaining references to any old path, and a script
that resolves every markdown link in docs/**/*.md + CLAUDE.md +
README.md against the filesystem and reports anything that doesn't
exist (zero broken links).

Collapsed CLAUDE.md's "Reading paths" section (the duplicate) down to
a pointer at docs/README.md, now the single index. Rewrote
docs/README.md itself to use the new subdirectory paths and added the
one doc it was missing that CLAUDE.md's old copy had (pr-review-gate.md).

Classified all 22 docs/*.md files first via a haiku subagent (mara's
suggestion) on two axes -- proposed grouping and operator-vs-
implementation focus -- before finalizing the taxonomy; spot-checked
the report and found internal inconsistencies (its classification
table disagreed with its own summary section for a few files), so this
taxonomy is my original proposal + the one correction mara gave
directly, not a blind application of the subagent's table. The
operator-focus data it gathered is still useful for a follow-up
content pass (docs skewing 'mixed' rather than pure operator-facing),
not addressed in this PR -- structure only.

nix fmt clean, both pre-push lints clean.
2026-09-02 01:55:37 +02:00
damocles
7516a4e10e remove hive-level infra-container restart from web ui and agents 2026-08-31 00:18:21 +02:00
atlas
07852cabc1 feat(3088): move the gateway's nginx + dnsmasq onto the host
The gateway's nginx + dnsmasq no longer run in their own nspawn container.
`nix/host-modules/hive-gateway/default.nix` loses the
`containers.hive-gateway` wrapper and everything that existed only to punch
holes in it: `privateNetwork = false`, `CAP_NET_ADMIN`, five bind mounts,
its own `stateVersion`, `networking.firewall.enable = false`,
`networking.resolvconf.enable = false`, and the `hive-gateway-resolv`
path+service pair. 465 -> 303 lines.

The container never bought isolation here. It shared the host netns by
necessity — nginx binds the host's :80/:443, dnsmasq answers on the bridge —
so each of those settings was undoing a boundary the gateway could not
afford in the first place.

Four things made it more than a deletion, none of them visible in the nix
diff:

- The self-signed cert service also imports the hive CA leaf, so removing it
  with the container would have left nginx naming a missing cert file, which
  it refuses to load at all.
- The nginx reload is a hive-priv verb. It still needs root, but no longer
  for the reason its doc gave, and `--machine=` was both transport and
  scope — so the unit name is now hard-coded in the helper as the
  containment.
- The lifecycle verb named a container that stops existing.
- `journalctl -M hive-gateway` had no machine to enter.

Per the operator's ruling, the operator verb keeps working and agents lose
it. `InfraContainer` answered three questions that used to share an answer;
it now splits into `name()` (identity), `target()` (Container vs HostUnit),
`service_unit()` (the systemd unit), and `agent_restartable()`, which the
MCP restart path checks before the capability so the refusal cannot read as
"ask for infra_admin". `SIBLING_CONTAINERS` drops the gateway — it gates the
requests that name a container as a string — while `FromStr` still accepts
it, because that answers what a name is, not who may act on it. The
dashboard's gateway journal reads host journald filtered to `nginx.service`.

Prose was corrected where it only named a location, and re-argued where the
container was doing security work: a `0666` per-agent socket was safe
because only the gateway container had the directory bind-mounted. There is
no mount now, so the directory permissions are the whole of the access
control — the constraint holds, its mechanism doesn't.

Gate: nix fmt / clippy --all-targets -D warnings / cargo test all clean (710
tests); hivectl-cli.md regenerated from the clap tree. The nix eval was run
in both TLS shapes at this commit: every delta in the rendered
virtualHosts is one of the three intended path moves, dnsmasq settings are
byte-identical, and the absence probe flips true -> false with bindMounts
emptied.
2026-08-11 18:01:03 +02:00
damocles
d3ac4de8fb hive-sh4re: split tool-group + capability enums into their own topic module 2026-08-10 23:05:18 +02:00
damocles
8a16d4ca7e always-on mark_todos_done: no ToolGroup ever exposed it, blocking every agent 2026-08-03 19:09:38 +02:00
damocles
2c11a437b4 hive-agent: enable the Skill built-in tool so installed skills are invokable 2026-07-27 22:28:28 +02:00
damocles
c4fcf7fbf1 feat(#2659): serve hive-bash-mcp over persistent streamable-http, drop stdio bridge 2026-07-23 18:01:20 +02:00
damocles
d7d46d347c feat(#2038): surface degraded mcp servers at turn start (observability) 2026-07-20 18:03:58 +02:00
damocles
3f1643c594 refactor(#2464): rename hive-ag3nt crate to hive-agent, collapse lib into main 2026-07-15 16:09:39 +02:00
Renamed from hive-ag3nt/src/mcp_config.rs (Browse further)