Commit graph hyperhive/hive-c0re/src/manager_server.rs
Author SHA1 Message Date
damocles
eb3c6cd0c4 cleanup(#1177): unify manager socket path, remove dead manager-name branches, rename ensure_manager 2026-06-03 20:39:45 +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
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
damocles
89665b94de feat(#1014): rename manager agent root→ruth across all crates + frontend 2026-06-02 18:18:06 +02:00
damocles
dce2bd0686 feat(#343): route container restart through rebuild queue 2026-06-02 13:34:24 +02:00
atlas
5c5ca38fe8 fix(#999): resolve all clippy warnings across the workspace
All crates now pass `cargo clippy --workspace -- -D warnings` cleanly.

Fixes span six crates (hive-sh4re, hive-ag3nt, hive-c0re, hive-forge,
hive-priv, hive-matrix-mcp was already clean):

- doc_markdown: wrap snake_case, type names, constants in backticks
- collapsible_if / collapsible_match: fold nested ifs into let-chains
- duration_suboptimal_units: Duration::from_secs(N) → from_mins/from_hours
- implicit_hasher: allow on HashMap-param fns where generalization is risky
- items_after_statements: hoist use to function tops
- map(f).unwrap_or(x) → map_or(x, f); map(f).unwrap_or_else(g) → map_or_else
- is_ok_and / is_none_or in place of map().unwrap_or(bool)
- needless_continue: {} instead of continue in loop match arms
- match_same_arms: Ok(None) | Err(_) merged
- format_push_str: write!() instead of push_str(&format!())
- while let replaces loop { let Some(..) = x else { break } }
- struct_excessive_bools / dead_code: allow on purpose-built structs
- too_many_lines / too_many_arguments: allow where refactor not worth it
- unused_async: remove async from poll_once in bash_runner
- needless_borrow: fix &repo deref in hive-forge comments verb
- cast_possible_truncation: allow u64→usize in fetch_tail

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-01 22:31:06 +02:00
damocles
68f488d81f refactor(#1019): unify agent + manager server dispatch via dispatch_shared 2026-06-01 21:09:40 +02:00
damocles
b9ecacaafe fix(#1004,#1006): get_host_journal - JournalPriority enum, grep/since/until, default 30/max 100, verbatim container, fix doc comment 2026-06-01 20:57:36 +02:00
damocles
dc8a4e2baf feat(#1004,#1006): capability system + read_host_journal / get_host_journal MCP tool 2026-06-01 20:57:36 +02:00
iris
ab278affc7 rename(#162): scrub remaining hm1nd references from comments and MCP instructions
All functional renames (MANAGER_NAME, MANAGER_AGENT → "root") were done in
earlier commits. This cleans up the stale `hm1nd` strings that remained in
doc comments, test fixture labels, and the manager MCP server instructions
(which told the manager its config lived at /agents/hm1nd/config/agent.nix).
2026-06-01 19:18:02 +02:00
damocles
e7e0675d22 rename: role badge stays 'manager'; unify harness unit name to hive-ag3nt 2026-06-01 17:33:09 +02:00
damocles
4c2398a38e rename(162): role badge manager -> root, update hm1nd comment 2026-06-01 17:33:09 +02:00
damocles
2bdb8c7d51 hive-c0re: scrub manager-surface cookies + SetParent doc fix (#715 batch 7) 2026-05-31 17:53:45 +02:00
damocles
a91cf4493f get_agent_meta: include hive_name + swarm_name in response (#710) 2026-05-31 12:50:19 +02:00
damocles
6c2cd078f1 set_status: reject multi-line and over-200-char text (#720) 2026-05-31 11:54:08 +02:00
damocles
7142e95c8f broker: resolve <parent> sentinel to topology parent at send time (#692) 2026-05-31 11:39:27 +02:00
müde
8571e3243a c0re: chmod 0666 mcp.sock after bind so in-container agent user can connect (#658 fixup) 2026-05-30 23:15:16 +02:00
iris
9ed58ab96d clippy: fix lints that crane's cargoClippy properly enforces (#538)
The naersk → crane swap in the parent commit flips clippy from
silently passing to actually failing on `-D warnings` (naersk's
`mode = "clippy"` mangled the `--` separator so the deny never took
effect). This commit clears the surfaced lints so the workspace
builds clean under the new enforcement — every fix is mechanical and
preserves behaviour. Tests still pass (160 across the workspace).

Auto-fixes via `cargo clippy --fix`:
- `doc_markdown` (19 sites): bare identifiers in doc comments
  wrapped in backticks
- `format_in_format_args`, `explicit_into_iter_loop`,
  `redundant_closure_for_method_calls`, `useless_conversion`, and
  a few more — mechanical rewrites of the kind cargo can apply
  safely.

Hand-fixed:
- `match_same_arms` (forge_notify::is_atx_heading): two arms returning
  `true` collapsed into a single `matches!` pattern.
- `cast_sign_loss` + `format_push_string` (mcp.rs status formatter):
  guarded `i64 → u64` through `u64::try_from(…).unwrap_or(0)` (status
  timestamps are always positive in practice; clamp the skew edge to
  0) and swapped `out.push_str(&format!(…))` for `write!` into the
  buffer with an infallible-writer `let _ =`.
- `doc_lazy_continuation` in turn.rs + manager_server.rs + sh4re/lib.rs:
  doc paragraphs that the markdown parser was treating as list-item
  continuations got either a separating blank line or a `/`-for-`+`
  word swap so the parser stops seeing a list.
- `unused_async` (manager_server::handle_request_schedule_prompt):
  function has no `.await`; dropped the `async` and its `.await` call
  site.
- `needless_pass_by_value` (scheduled_prompts::submit): take
  `&NewSchedule` instead of moving the struct in; updated two prod
  callers and eight test sites to pass references.
- `type_complexity` (approvals::mark_cancelled): hoisted the
  7-tuple SELECT row shape into a `type CancelLookupRow = (…);` alias.

Allow-with-reason for intentional patterns:
- `option_option` (6 sites across dashboard / scheduled_prompts /
  manager_server): `Option<Option<T>>` carries three-state PATCH
  semantics (missing key = leave alone, `Some(None)` = clear,
  `Some(Some(v))` = set). Collapsing to `Option<T>` loses the
  "clear" state.
- `dead_code` (rebuild_queue::QueueKind::Destroy /
  QueueSource::CrashRecover; topology::parent_of / default_seed):
  wire-shape variants + API surfaces kept for the upcoming features
  (#361 follow-ups, future `Destroy` queue routing, crash-recovery
  path). Allowed at the variant / function level with the rationale
  in `reason = "…"`.
- `too_many_lines` on three specific call-sites: a 117-line
  exhaustive-variant test (dashboard_events::kind_tag_matches_…),
  the meta-flake string template renderer
  (meta::render_flake_with_lookup), and the notification poll loop
  (forge_notify::poll_once) — splitting any of them would just hide
  the contiguous shape they exist to keep visible.

`nix flake check` formatting target is still broken on main itself
(pre-existing nixfmt drift across ~28 files unrelated to this PR);
left alone here so the scope stays "crane port + lints the port
exposed" and the operator's review doesn't have to triage drive-by
nixfmt churn.
2026-05-29 01:45:48 +02:00
damocles
dca62fda40 harness: remove deprecated manager-side request_spawn surface (closes #442) 2026-05-27 18:58:04 +02:00
damocles
99bf4d635d scheduled prompts: add/remove targets on edit (#474 fast-follow) 2026-05-26 17:06:48 +02:00
damocles
9fee1a1e56 scheduled prompts: edit existing schedule (closes #474) 2026-05-26 16:07:13 +02:00
damocles
3cd9240594 scheduled prompts: fire-now operator + manager surfaces (closes #467) 2026-05-26 15:55:35 +02:00
damocles
a31cd8bb15 dashboard: operator-direct schedule submit + cancel endpoints (#444 step 3) 2026-05-26 01:27:25 +02:00
damocles
aa7d8d9c9a c0re: schedule_prompt approval kind + worker + manager surface (#444 step 2) 2026-05-26 01:27:25 +02:00
damocles
57a753d80a c0re: address argus review nits on #434 2026-05-25 23:52:00 +02:00
damocles
008aad0bc5 c0re: also reject apply_commit when flake.lock is stale (#317) 2026-05-25 23:52:00 +02:00
damocles
45833d0793 c0re: reject apply_commit on duplicate flake inputs (#317) 2026-05-25 23:52:00 +02:00
iris
7b4917b256 container_view: clear live-only fields when stopped (#432)
per mara's review on #433, move the gating from the dashboard into
the host so a stopped container's stale on-disk state (rate_limited
sentinel, hyperhive-needs-login, last-turn-stats row, status blob)
never reaches the wire in the first place. when build_all sees
is_running == false:

  - needs_login → false
  - ctx_tokens / context_window_tokens → None
  - rate_limited → false
  - status_text / status_set_at → None

static / declared fields (extra_links, deployed_sha,
pending_reminders, needs_update, parent) stay populated regardless
of run state.

extend AgentMeta (both AgentResponse + ManagerResponse) with a
`running: bool` field so get_agent_meta callers can tell whether
the target is up — answers the second half of #432 ("agent meta
should probably show the info that it is not running as well").
read_agent_status_live wraps the existing read_agent_status with
the same is_running gate so the manager/agent socket handlers don't
have to know about sentinel semantics.

format_agent_meta now prints a `running: yes|no` line so claude
sees the run state in plain text alongside hyperhive_rev.

frontend follow-up in the same commit: drop the redundant
`c.running &&` guards on ctx_tokens / status_text in
renderContainers — the backend now guarantees those fields are
absent when the container is stopped, so the existing
truthy-check is sufficient. the `■ not running` badge + icon /
links fetch short-circuits stay (those are pure presentation /
network-noise wins the backend can't address).
2026-05-25 23:35:03 +02:00
damocles
11db5c2a8f rebuild_queue: switch dashboard / auto-update / manager call sites to enqueue 2026-05-23 12:05:09 +02:00
damocles
73871f18c3 set_status: consolidate whoami into get_agent_meta with optional name 2026-05-23 11:32:33 +02:00
damocles
77fdaf0d1e set_status: add get_agent_meta tool for inter-agent status queries 2026-05-23 11:32:33 +02:00
damocles
8e8e8a771f set_status: add status_set_at timestamp (mtime of status file) 2026-05-23 11:32:33 +02:00
damocles
fe2933b213 feat: add set_status MCP tool and status field to whoami/dashboard (closes #325) 2026-05-23 11:32:33 +02:00
damocles
3f08051bda lifecycle: seed applied repo at template commit, not main, for first-spawn diff 2026-05-22 21:29:52 +02:00
damocles
66f1568e8f apply_commit handles first-time spawns, request_spawn deprecated 2026-05-22 10:52:02 +02:00
damocles
3e098c56ff update_meta_inputs: require operator approval, rename to request_update_meta_inputs 2026-05-22 10:49:20 +02:00
damocles
597e4ba03a manager: add update_meta_inputs tool to update flake.lock on demand (closes #235) 2026-05-22 10:49:20 +02:00
damocles
3b44410427 manager: receive forge notifications (ManagerRequest::Wake) 2026-05-21 19:05:53 +02:00
iris
1f52746bd9 manager: add optional agent param to reminder RPCs
CountPendingReminders and ReminderRollup were hardcoded to
MANAGER_AGENT. Both now take agent: Option<String> — None keeps the
current behavior (manager's own), Some(name) returns that agent's
reminder stats. The broker functions already take an agent name, so
this is a thin wire-protocol change. Callers (web UI stats page,
post-turn counts) pass None.

Closes #122
2026-05-20 22:14:09 +02:00
iris
d348ce885f manager: add optional agent param to GetLooseEnds
GetLooseEnds now takes agent: Option<String>:
- None   = manager's own loose ends (default; the bug fix)
- Some("*")    = hive-wide view (every approval/question/reminder)
- Some("name") = that agent's loose ends

The get_loose_ends MCP tool exposes this as an optional agent arg, so
the manager can still scan the whole swarm on demand. The web UI and
post-turn counts pass None (manager's own).
2026-05-20 21:44:17 +02:00
iris
873d5a083d manager: scope GetLooseEnds to manager's own items
hive_wide returns ALL agents' reminders and questions, causing other
agents' reminders (e.g. triage) to appear on the manager's web page
and in the get_loose_ends MCP tool. The MCP tool spec says it shows
your own pending items — switch to for_agent(MANAGER_AGENT) which
includes all approvals (manager is sole submitter), questions where
the manager is asker/target, and only the manager's own reminders.

Fixes #118
2026-05-20 21:44:17 +02:00
damocles
80dd5bb69e two-step agent spawn: request_init_config + request_spawn 2026-05-20 14:40:15 +02:00
damocles
67b47872e0 add optional in_reply_to field on send for conversation threading 2026-05-20 13:35:27 +02:00
iris
91bfa269fd add reminder rollup RPC and broker query
Surface reminder activity statistics (scheduled, delivered, pending counts)
for each agent over configurable time windows. Needed by the per-agent
stats page to display reminder metrics.

Adds:
- ReminderStats struct and ReminderRollup request/response variants
- Broker::reminder_rollup_for(agent, since_secs) method
- Agent and manager socket handlers for the new RPC
- SocketReply mapping for response conversion
2026-05-20 13:24:17 +02:00
damocles
24b10becc9 get_logs: resolve the broker-logical 'manager' alias to the hm1nd machine 2026-05-20 10:48:24 +02:00
damocles
0a79912b67 get_logs: resolve machine name via container_name like every other verb 2026-05-20 10:48:24 +02:00
müde
5aad2d67e1 forge: mirror applied config repos to a private agent-configs org
on startup (and after every applied-repo ref mutation) core pushes
each agent's hive-c0re-owned applied repo — main plus every
proposal/approved/building/deployed/failed/denied tag — to
agent-configs/<name> on the local forge. the org is private and
agents are not members, so core is the only principal that can read
it.

the tokenised push url is passed inline, never stored as a named
remote: the applied repo is bind-mounted read-only into the manager,
so a token in .git/config would leak the core admin credential to an
agent.

push_config is best-effort at every site (ensure_all, spawn,
approve, deny, submit) — a missing or down forge never blocks a
deploy.
2026-05-20 10:24:50 +02:00
damocles
f8795dc029 fix: request_apply_commit resolves sha locally + rejects non-sha refs 2026-05-20 09:48:05 +02:00
damocles
5d27ae3048 recv: fold batch drain into recv(max) — one tool, uniform list response 2026-05-19 01:07:30 +02:00
damocles
77b89bf2c6 broker: recv_batch(max) — drain a bursty inbox in one round-trip 2026-05-19 00:47:21 +02:00