Commit graph

1,384 commits

Author SHA1 Message Date
damocles
057c673be8 fix: remove issue tag from comment in bash_runner 2026-06-03 12:30:30 +02:00
damocles
a1c6736ba5 feat(#1106): transient wake for bash tasks — bypass broker sqlite 2026-06-03 12:30:30 +02:00
damocles
b9b58554e8 fix: restart-all only lists successfully restarted agents 2026-06-03 12:29:11 +02:00
damocles
26f2c1f59b feat(#1107): hivectl agents restart / restart-all commands 2026-06-03 12:29:11 +02:00
damocles
ce52419fe4 fix(#1100): add .mailmap to deduplicate agent contributor emails 2026-06-03 12:29:01 +02:00
atlas
ee0ffa64f8 gateway: rate-limit nginx reload retries after failure
RELOAD_PENDING stays true on any failed reload, and reload_if_pending
fires on every 10-second spawn_poll tick. When the gateway is down or
nginx config is bad this hammers systemctl indefinitely.

Fix: track LAST_FAILED_RELOAD (unix timestamp). reload_if_pending backs
off to one attempt per RELOAD_RETRY_SECS (30s) after a failure. Fresh
write() calls reset the backoff so new topology changes still attempt
reload immediately.

Fixes #1113.
2026-06-03 12:28:42 +02:00
damocles
e54c1b84d7 feat(#1095): add wait_seconds to bash_run for inline fast-command completion 2026-06-03 11:26:22 +02:00
damocles
60047eb01d feat(#1104): surface full output file path in bash_status when truncated 2026-06-03 11:25:54 +02:00
atlas
cb5ee66311 fix(#1111): drop rusqlite bundled feature — use system libsqlite3
rusqlite was compiled with features=["bundled"] which embeds the
SQLite C source and compiles it via the cc crate on every fresh
dependency build. libsqlite3 is already in nativeBuildInputs (pkgs.sqlite
+ pkgs.pkg-config) so the system library is always available in the
nix sandbox. Dropping bundled removes the C compilation step from
the dep tree.
2026-06-03 11:24:04 +02:00
atlas
aa6d5b9ce1 fix: remove issue tags from forge.rs comments 2026-06-03 11:23:26 +02:00
atlas
0850128090 fix(#1012): guard ensure_user_email with marker; add login_name to PATCH body
sync_agent called ensure_user_email on every tick, which sent
PATCH /api/v1/admin/users/{name} without the required login_name
field. Forgejo's EditUserOption handler was resetting use_custom_avatar
to false on each call, clobbering the avatar uploaded by the
forge-avatar-sync one-shot service.

Two-part fix:
- add login_name to the PATCH body (Forgejo EditUserOption requires it)
- write EMAIL_ALIGNED_MARKER_PREFIX{name} on first success; skip the
  PATCH on all subsequent sync_agent ticks

Marker follows the same one-shot pattern as CORE_AVATAR_MARKER and
CONFIG_ORG_AVATAR_MARKER. Delete the marker to force re-alignment.
2026-06-03 11:23:26 +02:00
damocles
16f13e3b25 fix(#1118): coalesce multi-hop reparent notifications for offline agents 2026-06-03 11:21:09 +02:00
atlas
302e5e2869 docs: remove forward-looking issue reference from network.md 2026-06-03 11:19:29 +02:00
atlas
b89c5f5334 network: fix stale assertion messages; move prose to docs/network.md 2026-06-03 11:19:29 +02:00
atlas
3db51deace network: default network.enable to services.hyperhive.enable 2026-06-03 11:19:29 +02:00
atlas
8e50ddf016 network: revert isolateContainers default to false 2026-06-03 11:19:29 +02:00
atlas
a141d157ba network: default isolateContainers to true 2026-06-03 11:19:29 +02:00
atlas
c1b40ef819 network: fix dead assertion + document HIVE_NETWORK_SUBNET host-address
Two argus review fixups:

1. Move isolateContainers assertion to an unconditional `lib.mkIf
   cfg.isolateContainers` arm. The prior placement inside
   `mkIf (enable && isolateContainers)` was dead code — the assertion
   could never fire because both flags were already true by the time the
   block activated. Now `isolateContainers=true; enable=false;` raises
   a NixOS assertion error at eval time.

2. Add comment on HIVE_NETWORK_SUBNET noting it carries the host-side
   bridge IP (e.g. "10.42.0.1/24"), not the canonical network address
   ("10.42.0.0/24"). Rust consumer must normalize via bitwise AND before
   subnet membership checks or address arithmetic.
2026-06-03 11:19:29 +02:00
atlas
39b4c65922 network: add isolateContainers option for #14 netns isolation
Adds `services.hyperhive.network.isolateContainers` (bool, default
false). When enabled alongside `network.enable`, activates:

- IP forwarding + NAT masquerade so isolated agents reach the internet
- nftables DROP rule blocking bridge-subnet → loopback (defence-in-depth
  against compromised agent reaching the c0re dashboard)
- `HIVE_NETWORK_ISOLATION`, `HIVE_NETWORK_BRIDGE`, `HIVE_NETWORK_SUBNET`
  injected into the hive-c0re service env; the Rust lifecycle reads these
  to set `PRIVATE_NETWORK`, `LOCAL_ADDRESS`, and `HOST_BRIDGE` in each
  agent container's conf

Config block rewritten as `lib.mkMerge [...]` — the prior `lib.mkIf //
lib.mkIf` pattern was invalid nix (mkIf returns a tagged value, not an
attrset; // on it is a type error). See docs/network.md for full design.
2026-06-03 11:19:29 +02:00
damocles
7e5a21522a feat(#1102): add list_invites and join_room to matrix MCP 2026-06-03 01:18:47 +02:00
iris
b13a6911b7 feat(#1098): replace deployed:hash chip with config link in three-dot menu
Remove the deployed sha plain-text badge from the card head.
Add a forge-linked menu item to the three-dot menu instead:
'deployed:abc123def012 ↗' opens agent-configs/<name>/commit/<sha>
on the hive forge in a new tab.

Only shown when both c.deployed_sha and forgeBase are present.
buildAgentMenu now takes forgeBase as second arg; call site passes
the same forgeBase computed for nav-strip links.

CSS: add text-decoration: none + box-sizing to .agent-menu-item
so <a> link items render identically to the <button> items.
2026-06-03 01:11:56 +02:00
müde
d96a924d77 fix(#702): set git safe.directory for cross-user repo reads
Privsep splits repo ownership: hive-priv (root) fetches the hive-core-owned
meta/applied repos via nix, and hive-c0re (hive-core) fetches the agent-owned
proposed-config repos. git/libgit2's dubious-ownership guard rejects both
('repository path is not owned by current user'), failing every rebuild.
Install a root-trusted gitconfig with safe.directory=* in each service's
HOME; both already have read access — this only satisfies the guard.
2026-06-03 00:52:42 +02:00
müde
40be58b0b9 fix(#702): heal proposed-config ownership in agent-user-migrate
The migration chown stomped agents/<name>/config (the proposed-config repo)
to hive-core like everything else, but hive-agent-user-migrate only re-chowned
state/harness/.claude on boot, leaving config core-owned. config is owned by
the editing parent/manager agent (core only pulls from it), so chown it to
this user too. RO self-mount in an agent's own container fails harmlessly.
2026-06-03 00:37:55 +02:00
müde
d272803d58 fix(#702): spare agent creds from migration chown; give nix a writable HOME
Two privsep follow-ups, both in the hive-c0re service:

1. The migration 'chown -R hive-core /var/lib/hyperhive' (which only
   started running once ExecStartPre stopped failing 203/EXEC) stomped every
   agent's bind-mounted creds — agents/<name>/{claude,state,harness,config}
   are owned by the per-agent/manager users — logging all agents out with no
   way back in. Scope it to everything *except* agents/, plus the agents/
   dir node itself so c0re can still create new per-agent subdirs. Each
   container's hive-agent-user-migrate activation chowns the contents back.

2. nix (prebuild 'nix build', flake-check, meta eval in c0re; nixos-container
   update->nix in priv) writes its cache under $HOME/.cache. Both services
   run as users with no home -> HOME=/var/empty (unwritable) -> Lix cache
   init fails, rebuilds error out. Set HOME to each service's StateDirectory
   (adding one for hive-priv).
2026-06-03 00:33:15 +02:00
müde
e7b6896e4c fix(#702): give hive-priv a PATH; route forge/matrix list through priv
hive-priv had no PATH, so the nixos-container it runs for every container
op (incl. lifecycle::list) failed ENOENT. build_all swallows that into an
empty list — the 'no managed containers' symptom. Give the helper the
minimal set nixos-container shells out to (nixos-container, nix, util-linux,
e2fsprogs) on top of the systemd/coreutils/findutils already in the unit
PATH, rather than the whole system profile.

Also route forge/matrix is_present() through priv_client::list_containers
instead of spawning nixos-container directly from unprivileged hive-c0re.
2026-06-03 00:05:17 +02:00
müde
1e4066b9cb fix(#702): hive-c0re ExecStartPre fails 203/EXEC — coreutils has no sh
The state-migration chown invoked ${pkgs.coreutils}/bin/sh, which does not
exist (coreutils ships chown, not sh), so ExecStartPre exited 203/EXEC on
every boot. hive-c0re hit its start limit and never came up, so the gateway
returned 502 Bad Gateway. Call chown directly with the +- prefix (run as
root, tolerate failure) instead of going through a shell for '|| true'.
2026-06-02 23:49:51 +02:00
müde
9e12012a95 fix(#702): route container journal reads through hive-priv
The privsep drop to the hive-core user left four journalctl -M <container>
call sites shelling out directly. -M enters the container namespace via the
machine bus, which needs root, so all container-journal reads failed with
Permission denied. Add a ReadContainerJournal verb to hive-priv and route
dashboard get_journal, manager get_logs, the rebuild-failure journal tail,
and the agent host-journal -M path through it. Host-journal reads (no -M)
stay direct via systemd-journal group membership.
2026-06-02 23:43:02 +02:00
iris
5da7f6cd3a feat(#1097): overhaul schedule table style and layout
- Wrap table in .schedules-table-wrap (overflow-x: auto) so it
  never exceeds the page width on narrow viewports
- Add .schedules-table-next-col (width: 8em) and
  .schedules-table-every-col (width: 7em) with white-space: nowrap
  to stop those columns from stealing space from the body column
- Align visual style with the perm page tables: unified border on
  all cells (was: border-top row separator only), bg-elev thead,
  font-size 0.82em (was 0.9em), min-width: 100% on the table itself
2026-06-02 22:50:25 +02:00
iris
a389ead6de fix(#1096): remove container name/port chip from dashboard card
Drop the 'h-sock :8421' meta span from the agent card head.
ContainerView.container is now #[serde(skip)] since no frontend
code reads it; the field stays in Rust for internal use.
c.port remains serialized — used for fallback agent UI URLs.
2026-06-02 22:48:41 +02:00
iris
a8ffdf31e0 docs(#1014): update stale root→ruth references in conventions, approvals, agent-hierarchy 2026-06-02 22:48:10 +02:00
damocles
0bec3af933 feat(#702): drop hive-c0re from root to hive-core user (privsep phase 2) 2026-06-02 22:45:12 +02:00
damocles
5e0da97ee5 fix: update stale doc comment example root→ruth in capabilities.rs 2026-06-02 18:18:06 +02:00
damocles
89665b94de feat(#1014): rename manager agent root→ruth across all crates + frontend 2026-06-02 18:18:06 +02:00
damocles
0c5760b0da feat(#1014): rename manager agent 'root' to 'ruth' in lifecycle + sh4re 2026-06-02 18:18:06 +02:00
atlas
268c2a66ad fix(#1087): use correct "cmd" tag in matrix wake signal
hive_sh4re::Request uses #[serde(tag = "cmd")] so Wake serialises as
{"cmd":"wake",...}. The wake.rs in hive-matrix-mcp was sending
{"kind":"wake",...} — the harness could not deserialise the message
and silently discarded every incoming matrix event.

Also: drain the server's response line instead of just shutting the
write half. Without the drain the server got ECONNRESET writing back,
which logged a spurious error even though the wake itself was now
processed.

Root cause of the matrix notification blackhole reported in #1087.
2026-06-02 17:27:25 +02:00
damocles
eae0e875cf feat(#1086): serialize perm changes through rebuild queue
add QueueKind::PermChange — dashboard tool-group and capability
handlers no longer write the shared JSON files inline. instead they
enqueue a PermChange entry; the FIFO worker applies the file write
then calls rebuild_agent so the updated env var takes effect.

concurrent batch-apply actions for different agents previously raced
on tool-groups.json / capabilities.json (last write wins, earlier
change silently dropped). serialising through the queue prevents this.

dedup check extended with perm-type discriminant so tool-groups and
capabilities changes for the same agent are kept as distinct entries
and never collapse into one slot.
2026-06-02 16:42:22 +02:00
damocles
dce2bd0686 feat(#343): route container restart through rebuild queue 2026-06-02 13:34:24 +02:00
damocles
817d94023d feat(#1081): add --approve/--request-changes/--comment to pr-reviews 2026-06-02 13:33:30 +02:00
iris
5d4b62ccca fix: Diagnostics description — get_logs reads sub-agent container journal, not host journal 2026-06-02 12:53:50 +02:00
iris
2368bec634 feat(#1082): add description() to ToolGroup + Capability; expose in API + UI tooltips
- hive-sh4re: ToolGroup::description() and Capability::description() return
  short human-readable strings for each variant
- hive-c0re: ToolGroupsSnapshot and CapabilitiesSnapshot now include a
  `descriptions` map (name → description); get_capabilities now iterates
  Capability::ALL instead of hardcoding the list
- tabs.js: renderToolGroups + renderCapabilities use descriptions[name] as
  the column header title attribute (native browser tooltip on hover)
2026-06-02 12:53:50 +02:00
iris
4a632fabcc docs(CLAUDE.md): fix stale systemd-run reference in gateway_nginx.rs entry
Argus flagged that since PR #1054 the nginx reload path is
`gateway_systemctl(["reload", "nginx"])` = `systemctl -M hive-gateway reload nginx`.
Replace the stale `systemd-run --machine=hive-gateway` reference.
2026-06-02 12:47:36 +02:00
iris
b8b571b626 docs(CLAUDE.md): add missing hive-c0re modules to file map
Four modules were absent: capabilities.rs, build_logs.rs,
gateway_nginx.rs, priv_client.rs. Added at their natural
positions alongside related modules.
2026-06-02 12:47:36 +02:00
iris
0da736f2a1 fix(docs): web_tools is a tool group, not a capability
Remove web_tools from the C4P4B1L1T13S table in dashboard.md and add
it to the T00L GR0UPS section with a note that it gates Claude built-ins
rather than MCP tools. Fix turn-loop.md to say 'tool-group-gated' and
'web_tools tool group' throughout.
2026-06-02 12:47:18 +02:00
iris
91ad9877dc docs(web-ui): add P3RM1SS10NS to dashboard tab list in index 2026-06-02 12:47:18 +02:00
iris
de8c446a3a docs: document web_tools capability in turn-loop and dashboard 2026-06-02 12:47:18 +02:00
iris
834d9cb2c4 docs(web-ui): update CSS bundle description for split stylesheet layout 2026-06-02 12:47:18 +02:00
iris
f55d3baa0a docs(web-ui): add P3RM1SS10NS to tab strip list and URL hash list 2026-06-02 12:47:18 +02:00
iris
b3ccd1500c docs(web-ui): document P3RM1SS10NS tab and tool-groups/capabilities endpoints 2026-06-02 12:47:18 +02:00
iris
5946c8fbd8 docs(gotchas): update stale 'claude's Bash tool' reference to bash_run
The Bash built-in is now denied; bash_run is the correct MCP tool.
2026-06-02 12:46:53 +02:00
iris
50f14f28ff fix(dashboard): have get_capabilities iterate Capability::ALL
The hardcoded vec was a maintenance hazard — any new capability added
to Capability::ALL would silently be omitted from the permissions UI
column list until get_capabilities was manually updated.

Now both the GET and POST handlers derive their known-capability lists
from the same Capability::ALL source of truth.
2026-06-02 12:46:12 +02:00