Commit graph hyperhive/hive-c0re
Author SHA1 Message Date
damocles
78db47b00b fix: auto-create knowledge webhook + periodic pull fallback
hive-c0re now auto-creates the Forgejo push webhook for
internal/knowledge at startup (ensure_webhook). this is what was
missing — the webhook endpoint existed but was never registered in
forgejo, so merging iris's PR didn't trigger a pull.

also adds a periodic hourly pull as a fallback (and an immediate pull
at startup to reconcile commits that landed while c0re was offline).

fixes #1244.
2026-06-04 12:12:20 +02:00
damocles
1c5936febb fix: recover from M_UNKNOWN_TOKEN in hive-matrix-daemon
when the homeserver rejects the token (stale session after state wipe or
expiry), the daemon now deletes the token file + matrix-sdk state dir
and exits cleanly instead of crash-looping.

hive-c0re's matrix::ensure_all sweep now runs periodically every 30
minutes (in addition to startup) so deleted token files get
re-provisioned without requiring a hive-c0re restart. the systemd.paths
watcher on the token file path then restarts the daemon with a fresh
token.
2026-06-04 12:12:20 +02:00
atlas
1d062d1e3e fix: route gateway nginx control through hive-priv
systemctl --machine=hive-gateway requires root (machine-bus transport
enters the container namespace). hive-c0re is unprivileged, so every
call to nginx_active_state() and gateway_systemctl() silently failed
with exit 1, causing a continuous 30s retry loop without ever
syncing nginx.

Fix:
- Move state-aware nginx logic into hive-priv ReloadGatewayNginx:
  check ActiveState, then reload/reset-start/start accordingly.
  hive-priv already runs as root and has machine-bus rights.
- Remove nginx_active_state() and gateway_systemctl() from
  gateway_nginx.rs (they were always running unprivileged, always
  failing silently).
- Make write(), reload_if_pending(), reload_gateway_nginx() async so
  they can call the async priv_client without a blocking bridge.
- Update callers in agent_sockets::spawn_poll and meta::sync_agents
  to await the now-async functions.

The priv_client::reload_gateway_nginx() call and PrivRequest::ReloadGatewayNginx
wire type already existed — the gateway_nginx module was just not using them.
2026-06-04 09:48:56 +02:00
damocles
c634dab2a6 refactor: unify AgentServer + ManagerServer into HiveServer {socket, flavor} 2026-06-04 00:20:17 +02:00
damocles
84383568b2 fix: true atomic bulk topology -- apply_set_parent + single write, add # Errors docs 2026-06-03 23:24:55 +02:00
damocles
7ec0a36d7a fix(#1218): bulk topology move uses one git commit via new set-parent-bulk endpoint 2026-06-03 23:24:55 +02:00
atlas
34bc4c0b06 fix: route forge_admin through hive-priv; auto-recover matrix passwords
forge_admin() spawned nixos-container run hive-forge directly from the
hive-core process. nixos-container run uses nsenter to enter the container
namespaces, which requires root. hive-core is unprivileged, so every call
failed with: nsenter: stat of /proc/<pid>/ns/user failed: Permission denied

Fix: add RunForgeAdmin { args } to PrivRequest. hive-priv (root) handles
it by spawning nixos-container run hive-forge -- runuser -u forgejo --
forgejo --work-path /var/lib/forgejo admin <args>. forge_admin() now calls
priv_client::run_forge_admin().

matrix: ensure_user_for hit M_USER_IN_USE then failed when the stored
password file was missing (state dirs wiped but homeserver kept accounts).
Previously required manual hivectl matrix reset-password <name>.

Fix: add auto_reset_password() — calls the admin API (PUT
/_synapse/admin/v2/users/@<name>:<server> with the hive admin token) to
set a new random password, then proceeds with login. Falls back to the
existing manual-recovery error if the admin token is unavailable.

Closes #1234
2026-06-03 23:21:45 +02:00
damocles
94c2d651c0 feat(#1178): add list_containers tool to AgentServer (topology-scoped to descendants) 2026-06-03 23:08:31 +02:00
damocles
3fa31a414f feat(#791): add request_init_config + request_apply_commit to AgentServer (topology-scoped) 2026-06-03 22:52:52 +02:00
damocles
2722e1548c feat(#1178): add kill + update tools to AgentServer (topology-scoped) 2026-06-03 22:18:03 +02:00
damocles
29c7f64bd3 refactor(#1202): introduce HiveEnv + AgentPaths to reduce arg repetition 2026-06-03 22:09:08 +02:00
atlas
e7785b4948 docs: add # Errors doc to ensure_hive_space 2026-06-03 22:01:37 +02:00
atlas
60582c0be4 feat: create hive Matrix Space on boot and invite all agents 2026-06-03 21:56:13 +02:00
damocles
cff3b6ff85 fix(#1201): prevent sync_agents from dropping all agents on list() failure 2026-06-03 21:46:38 +02:00
damocles
cd1f77b640 fix(#1198): create internal/knowledge as public, patch existing private repos 2026-06-03 21:39:31 +02:00
damocles
69a48f086c fix(#1190): consistent param order in set_resource_limits, drop stale blank line 2026-06-03 21:39:14 +02:00
damocles
d1fbb4aef8 feat(#1184): make agent CPU quota and memory limit configurable 2026-06-03 21:39:14 +02:00
atlas
a604fbf197 fix: address argus review nits on matrix admin additions
- drop stale --server flag reference from ensure_admin_user doc comment
- simplify M_USER_IN_USE recovery message: point at hivectl commands
- add #[must_use] to admin_token_path()
- rename tracing field rename_error in migration warn log (was error,
  which held rename err but fired on read failure — misleading)
2026-06-03 21:32:23 +02:00
atlas
c4a8b90236 fix: drop --server flag from hivectl matrix; discover server_name from homeserver
Add matrix::discover_server_name() via GET /_matrix/key/v2/server
(unauthenticated federation endpoint, always returns server_name).
hivectl is always talking to the local hive — no reason to require
the operator to spell out the server_name.
2026-06-03 21:32:23 +02:00
atlas
8757dc615d feat: hive matrix admin user + hivectl matrix promote-user/reset-password
- provision @hive:<server> as the first matrix account in ensure_all()
  (Conduit/tuwunel makes the first registered user admin automatically)
- add hivectl matrix sync-admin — manual re-provision of the admin token
- add hivectl matrix promote-user <name> --server <name> — promote via
  Synapse-compat admin API using the hive admin token
- add hivectl matrix reset-password <name> --server <name> — reset an
  agent's password + persist it so ensure_user_for can re-login; follow
  with hivectl matrix create-user <name> to mint a fresh access token
- both commands fall back to HYPERHIVE_MATRIX_SERVER_NAME env var for
  --server when omitted
2026-06-03 21:32:23 +02:00
atlas
47e9c1cc1b fix(#1185): move matrix-password outside purgeable agent_state_root
The password file was stored at agent_notes_dir/matrix-password which
lives inside agent_state_root — wiped by destroy --purge. On re-spawn
with the same agent name, the matrix user still exists in the homeserver
but the stored password is gone, making re-login impossible.

Move password to /var/lib/hyperhive/matrix-creds/<name>-password which
is not deleted by purge. On re-spawn, ensure_user_for finds M_USER_IN_USE,
reads the preserved password, re-logins, and writes a fresh token.

Also:
- add one-time migration that moves existing passwords from the old path
  to the new location on first access after upgrade
- remove chown_to_agent on the password file (it is now host-only, not
  inside the agent bind-mount tree)
- fix the error message to give actionable recovery steps instead of
  suggesting hivectl matrix create-user --password which is rejected for
  agent accounts
2026-06-03 21:32:23 +02:00
damocles
fcd170e8b8 fix: rename hive-knowledge → knowledge in dashboard.rs doc comment 2026-06-03 20:56:17 +02:00
damocles
cfd677ae7d fix review: rename hive-knowledge → knowledge throughout, drop false re-clone claim from pull() doc 2026-06-03 20:56:17 +02:00
damocles
a176d675cf address review: drop 'service endpoints', fix container_mount doc, remove redundant write warning 2026-06-03 20:56:17 +02:00
damocles
41befe3839 feat(#1167): hive-wide knowledge repo — forge, local clone, bind-mount, webhook 2026-06-03 20:56:17 +02:00
damocles
4bb0d7f310 remove history comments from code 2026-06-03 20:39:45 +02:00
damocles
eb3c6cd0c4 cleanup(#1177): unify manager socket path, remove dead manager-name branches, rename ensure_manager 2026-06-03 20:39:45 +02:00
damocles
049ae47191 fix(#1164,#1171): harness writes status file, c0re just rescans 2026-06-03 18:33:07 +02:00
damocles
a9ce8a945f fix(#1160): restart agent on failed rebuild if it was running 2026-06-03 18:32:38 +02:00
damocles
452766b35f fix(#1165): validate send recipient before queuing message 2026-06-03 18:32:38 +02:00
damocles
5a9ede10df feat(#792): agent restart tool — topology-checked restart of direct children 2026-06-03 18:23:28 +02:00
damocles
79265e04f8 cleanup(#1014): remove manager pinning from frontend — no special treatment for ruth 2026-06-03 16:44:29 +02:00
damocles
6feab54882 cleanup(#1014): remove is_manager from ContainerView, add manager_name to StateSnapshot 2026-06-03 16:44:29 +02:00
damocles
c44fa14f7c fix(#1145): clone logs/cmdline in priv_run match arms to avoid use-after-move 2026-06-03 15:22:23 +02:00
atlas
68e30b857c feat(#1137): rich unread summary in loose ends and wake signal
- hive-sh4re: UnreadMatrix gains summary: String field (per-room breakdown)
- hive-matrix-mcp/protocol: add RoomUnread struct + UnreadSummary request
- hive-matrix-mcp/handlers: collect_unread() fetches per-room data;
  single-unread rooms include truncated last-message body + sender;
  multi-unread rooms carry count only
- hive-matrix-mcp/wake: format_unread_summary() builds wake body from
  RoomUnread slice; terse one-liner for single-room/single-message,
  bulleted list for multi-room; always appends read-hint
- hive-matrix-mcp/timeline: wake body now covers all rooms with unread
  at fire time, not just the triggering event; falls back to per-event
  teaser if notification counts haven't updated yet
- hive-ag3nt/mcp: matrix_unread_summary() replaces matrix_unread_rooms();
  UnreadMatrix loose end carries per-room summary lines; render shows
  room breakdown with sender: body for single-unread rooms
2026-06-03 13:56:00 +02:00
damocles
1386439591 fix(#1116): address review nits - dedup log callback, comment stderr truncation 2026-06-03 12:40:23 +02:00
damocles
68451eb205 feat(#1116): stream nixos-container create/update output live into build_logs 2026-06-03 12:34:16 +02:00
iris
cd3ba24c3d fix(#1112): build agent nav-links from disk; drop broken TCP proxy
get_agent_links was proxying to http://127.0.0.1:{port}/api/state.
Since all agents now bind exclusively to a unix socket (HIVE_WEB_SOCKET
set unconditionally in harness-base.nix), the TCP fetch always fails
silently, returning [] — so the nav-strip icons on every card disappear.

Replace with container_view::build_nav_links(), which reconstructs the
same link list from disk:
  - stats.html always (container kind)
  - /{name} and /agent-configs/{name} when forge-token is present (forge kind)
  - extras from hyperhive-dashboard-links.json (external kind)

The GUI screen link is intentionally omitted — /etc/hyperhive/gui.json
lives inside the agent container and is not host-visible. GUI agents
are rare; the omission is acceptable until a host-visible marker lands.

No new dependencies. reqwest is no longer used in dashboard.rs for
this handler (still used by forge.rs and hivectl.rs).
2026-06-03 12:32:09 +02:00
damocles
3c012efbea fix(#883): warn + bail on unparseable subnet instead of silently writing empty LOCAL_ADDRESS; doc /0 corner case 2026-06-03 12:31:54 +02:00
damocles
ec8fcb29ce test: add normalization test for bridge-IP subnet form (atlas note) 2026-06-03 12:31:54 +02:00
damocles
3bb07b1fde feat(#14): network isolation rust side — PRIVATE_NETWORK + veth wiring in set_nspawn_flags 2026-06-03 12:31:54 +02:00
damocles
ed50b858c5 fix(#1115): commit perm+topology changes under META_LOCK to prevent dirty working tree 2026-06-03 12:31:48 +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
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
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
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