Commit graph hyperhive/nix/templates
Author SHA1 Message Date
damocles
fcb5fae345 docs: catch up post-#658/#604/#660 + add operator hivectl section (#124) 2026-05-31 10:13:33 +02:00
damocles
dcaf1838e1 harness: unify hive-ag3nt + hive-m1nd into one binary picking role from HIVE_ROLE (#598) 2026-05-31 03:21:06 +02:00
atlas
d23fd8847d nix/templates: actually collapse agent-base + manager to role shims (#671 fixup)
The merge of #676 (commit 0951cd1) landed the role-driven harness service
in `harness-base.nix` but the rebase resolution accidentally kept the
legacy `systemd.services.hive-ag3nt` / `hive-m1nd` blocks in
agent-base.nix and manager.nix. Module merging silently accepts the
duplicate definitions because they evaluate to identical attrs — but
the whole point of #671 was to single-source the systemd unit + manager
forge defaults.

Collapses both templates to bare role-setters as originally intended:

    { ... }: {
      imports = [ ./harness-base.nix ];
      hyperhive.role = "agent";  # or "manager"
    }

Verified post-collapse:
- `nixosConfigurations.agent-base.config.systemd.services.hive-ag3nt
  .serviceConfig.ExecStart` -> `.../bin/hive-ag3nt serve`
- `nixosConfigurations.manager.config.systemd.services.hive-m1nd
  .serviceConfig.ExecStart` -> `.../bin/hive-m1nd serve`
- `agent-base` `.path` is `[ /run/wrappers/bin /run/current-system/sw ... ]`
- `manager` `.environment.HIVE_PORT` is `"8000"`

Follow-up to #671 (#676). No behaviour change — the duplicate
definitions were merging to the same values; this just deletes the
redundant copies so `harness-base.nix` is the true single source.
2026-05-31 00:07:55 +02:00
atlas
2e9c50ecc7 nix/harness-base: prepend /run/wrappers/bin to PATH (argus #676 / #672 fixup)
argus on #676 🔴: this PR deletes agent-base.nix + manager.nix and
moves the harness service to harness-base.nix without carrying
forward damocles's #672 fix (which adds `/run/wrappers/bin` to the
service PATH so the setuid sudo wrapper resolves before the bare
nix-store binary).

Pull the #672 fix forward: prepend `/run/wrappers/bin` to the unified
harness service's path list. Same shape as damocles's diff on
agent-base + manager, but applied once in harness-base.nix.

Without this, post-#658 `sudo` inside the container resolves to the
un-setuid nix-store binary and refuses with "must be owned by uid 0
and have the setuid bit set" even when
`hyperhive.user.passwordlessSudo = true` is configured.

Verified via `nix eval`:
- agent-base.systemd.services.hive-ag3nt.path[0] = "/run/wrappers/bin" ✓
- manager.systemd.services.hive-m1nd.path[0]    = "/run/wrappers/bin" ✓

#672 (damocles) supersedes when this lands — the two changes are
equivalent and the consolidated harness-base.nix is now the canonical
home for the fix.
2026-05-30 23:41:13 +02:00
atlas
0951cd1b3d nix/templates: merge manager + agent harness into harness-base.nix (#671)
mara on #671: "manager should not be as special anymore."

Single `harness-base.nix` now declares the harness systemd unit + the
manager-only forge defaults, driven by a new `hyperhive.role` option
(`"agent"` | `"manager"`, default `"agent"`). The two child templates
collapse to thin role-setters.

Mechanics:
- `hyperhive.role = "agent"` → `systemd.services.hive-ag3nt` running
  `hive-ag3nt serve`, default forge notification surface.
- `hyperhive.role = "manager"` → `systemd.services.hive-m1nd` running
  `hive-m1nd serve`, forge `keepSubscriptions = false` +
  `skipNotifyReasons = [ "subscribed" "participating" ]` (mentions-
  only inbox), plus standalone-eval fallbacks `HIVE_PORT = "8000"` +
  `HIVE_LABEL = "hm1nd"` (meta.rs overrides via the generated
  `applied/hm1nd/flake.nix`).

`agent-base.nix` (62 → 9 lines) and `manager.nix` (79 → 18 lines) are
now thin shims that just set the role and import `harness-base.nix`.

External surface unchanged: `nixosModules.{agent-base, manager}` +
`nixosConfigurations.{agent-base, manager}` still resolve identically.
meta.rs's role selection (`if isManager then hyperhive.nixosConfigurations.manager
else hyperhive.nixosConfigurations.agent-base`) keeps working without
edits.

Verified via `nix eval`:
- agent-base: role="agent", services=["hive-ag3nt"], forge.keepSubscriptions=true
- manager:    role="manager", services=["hive-m1nd"], forge.keepSubscriptions=false,
              forge.skipNotifyReasons=["subscribed","participating"],
              ExecStart=hive-m1nd/bin

Closes #671.
2026-05-30 23:41:13 +02:00
damocles
c73c8389ec harness: prepend /run/wrappers/bin to service path so sudo wrapper resolves (#658 fixup) 2026-05-30 23:40:16 +02:00
müde
b8647cf7dc harness: write claude configs to systemd RuntimeDirectory + chown ~/.claude on activation (#658 fixup) 2026-05-30 22:57:26 +02:00
müde
113e64e481 nix/harness: recursive chown of /run/hive (stale root-owned files survive container restart) 2026-05-30 22:19:22 +02:00
müde
de3f541729 nix/harness: ExecStartPre chown /run/hive to agent user (#658 fixup) 2026-05-30 22:14:32 +02:00
müde
ed046787e0 nix/harness: chown /run/hive to agent user (#658 fixup) 2026-05-30 22:08:06 +02:00
damocles
6b6c6775ee agents: drop root, run as per-agent unix user with passwordless sudo (#658) 2026-05-30 21:45:09 +02:00
atlas
3b500bba1b nix: pivot to services.hyperhive.* per mara directive (#612)
Per [mara on PR #615 comment 7349](http://localhost:3000/hyperhive/hyperhive/pulls/615#issuecomment-7349):
> follow nix conventions, services.hyperhive it is. the earlier we
> change this, the less breakage.

Renames the entire host-side option tree under `services.hyperhive.*`:

- `services.hive-c0re.*` → `services.hyperhive.c0re.*`
- `hyperhive.enable` → `services.hyperhive.enable`
- `hyperhive.domain` → `services.hyperhive.domain`
- `hyperhive.forge.*` → `services.hyperhive.forge.*`
- `hyperhive.matrix.*` → `services.hyperhive.matrix.*`

Per mara's "earlier = less breakage", the previous `services.hive-c0re.enable`
deprecation alias is dropped. Operators get a clear eval error on the
old paths pointing at the rename. Single migration moment.

Per-agent options in `nix/templates/harness-base.nix` (`hyperhive.model`,
`hyperhive.allowedRecipients`, etc.) stay at `hyperhive.*` — they're
container-level config, not services in the NixOS sense.

Verified via `nix flake check --no-build` + an end-to-end NixOS eval
exercising every renamed path.

Follow-up needed: rust source comments referencing the old NixOS
option names (`hive-c0re/src/{meta,coordinator,main,dashboard}.rs`)
should be updated in a separate pure-rust PR to keep this one
strictly nix-only.
2026-05-30 11:07:57 +02:00
atlas
32148179e6 refactor: move hive-c0re options to hyperhive namespace (#612)
- Move options.services.hive-c0re → options.hyperhive.c0re
- Add options.hyperhive.enable to auto-enable c0re + subsystems
- Add deprecation alias for services.hive-c0re.enable (backward compat)
- Update doc references in README, flake.nix, docs, harness-base.nix
- Simplifies config: 'hyperhive.enable = true' now enables everything

Existing operator configs using services.hive-c0re.enable will
continue to work but emit a deprecation warning. Aligns the option
namespace with the existing hyperhive.* family (matrix, forge, domain).

fixes #612
2026-05-30 11:07:57 +02:00
damocles
dc99e64b2d drop legacy /state mount for manager (#604) 2026-05-29 21:21:44 +02:00
damocles
30c9eed562 matrix-mcp: drop dual-line PathExists, trim watcher comments (mara nag) 2026-05-29 20:51:01 +02:00
damocles
688058c429 matrix-mcp: reframe state-mount comments as #604 migration fallback (mara nag) 2026-05-29 20:51:01 +02:00
damocles
b4bcd3da05 matrix-mcp: copy state-mount comment to hive-matrix-daemon.path (iris #603 suggestion) 2026-05-29 20:51:01 +02:00
damocles
e6c53045ad matrix: hive-matrix-mcp crate (daemon+stdio bridge) + harness wiring (#548 phase 3) 2026-05-29 20:51:01 +02:00
damocles
558511827c harness-base: systemd.paths trigger for matrix-avatar-sync (closes #571) 2026-05-29 16:35:33 +02:00
müde
c53640040a fix agent crash on start 2026-05-29 16:19:46 +02:00
damocles
7e041e6079 harness-base: matrix-avatar-sync oneshot mirroring forge avatar (#548 phase 2.5) 2026-05-29 13:18:23 +02:00
iris
73684fb00a rust+nix: load static assets at runtime, drop build.rs (#555)
Cuts every `include_bytes!`/`include_str!` of a non-rust path in
the workspace over to runtime file loads from `$HIVE_ASSETS_DIR`
(the `hyperhive-assets` derivation introduced in the previous
commit). After this commit the rust derivation has no compile-time
dependency on `branding/*` or `hive-ag3nt/prompts/*` anymore.

Call-site flips:

- `hive-c0re/src/forge.rs::CORE_AVATAR_PNG` /
  `CONFIG_ORG_AVATAR_PNG`: were `include_bytes!` of
  `branding/hyperhive.png` and `$OUT_DIR/agent-configs.png`. Now
  `ensure_core_avatar` / `ensure_config_org_avatar` `tokio::fs::read`
  via `hive_sh4re::assets::{core_avatar_png, config_org_avatar_png}`
  at startup. The `agent-configs.png` is now rendered by the
  `hyperhive-assets` derivation's rsvg-convert step (was
  `hive-c0re/build.rs` + librsvg on the rust derivation's
  nativeBuildInputs — both gone in the next commit).
- `hive-ag3nt/src/prompt.rs::TEMPLATE`: `render` now takes the
  template as an argument; `write_system_prompt` reads it once from
  `$HIVE_ASSETS_DIR/prompts/system.md` before calling render. The
  test module still `include_str!`s the production template so
  `cargo test --workspace` doesn't need `HIVE_ASSETS_DIR` set —
  this is the only remaining compile-time reference to the file
  from the rust workspace, gated to `#[cfg(test)]`.
- `hive-ag3nt/src/turn.rs::CLAUDE_SETTINGS`: was `include_str!`'d
  and written via `tokio::fs::write`; now `tokio::fs::copy` from
  `$HIVE_ASSETS_DIR/prompts/claude-settings.json` into the
  per-agent socket dir.
- `hive-ag3nt/src/web_ui.rs::DEFAULT_ICON`: was `include_str!`'d;
  now read on-demand from `$HIVE_ASSETS_DIR/branding/hyperhive.svg`
  inside `serve_icon`. Falls back to an empty body if missing so
  the endpoint never panics on a misconfigured container (matches
  the existing "per-agent icon.svg override" fallthrough).

`HIVE_ASSETS_DIR` wiring:

- Inside containers: `nix/templates/harness-base.nix`
  `environment.variables` sets it to
  `${pkgs.hyperhive-assets}/share/hyperhive` (resolved through
  the default overlay applied in `mkContainer`). Verified by
  building `agent-base-toplevel` and grepping the resulting
  `/etc/set-environment`.
- Host-side: `nix/modules/hive-c0re.nix` adds an `assets` option
  defaulting to `hyperhive.packages.${system}.assets`, threaded
  in from the flake's nixosModules wiring, and sets the same env
  var on the `hive-c0re` systemd unit so the daemon's
  `forge::ensure_*_avatar` startup hooks find the PNGs.

`hive-c0re/build.rs` deleted entirely; `[package].build` removed
from `hive-c0re/Cargo.toml`; rsvg-convert dependency lives in the
assets derivation only.

Validated: `nix build .#default .#checks.x86_64-linux.clippy
.#agent-base-toplevel .#manager-toplevel --fallback` all succeed.
`/etc/set-environment` in the toplevel shows
`HIVE_ASSETS_DIR="/nix/store/.../hyperhive-assets-0.1.0/share/hyperhive"`.
2026-05-29 12:59:48 +02:00
iris
65532e8387 frontend: tighten extraFiles target type to strMatching regex
damocles suggested using lib.types.strMatching for the target option
itself rather than relying solely on the post-hoc assertion. Pattern:
`^[A-Za-z0-9_][A-Za-z0-9_./-]*$` — first char alphanumeric/_, then
alphanumerics + _ + . + / + - allowed (so nested layouts like
"games/bitburner" still work).

This rejects at type-check time:
- leading `/` (absolute paths)
- leading `.` (so `..` as a full string blocked, also `./foo`)
- leading `-` (would parse as flag by some tools)
- spaces, control chars, weird unicode

The existing assertion stays — it catches mid-path `..` segments
(`foo/../bar`) that the regex can't reject without lookahead. POSIX
regex (which nix uses) doesn't support lookahead, so the
type-and-assertion split is the cleanest expression.

Refs #273.
2026-05-23 14:51:01 +02:00
iris
2951da32e7 frontend: tighten extraFiles target validation per damocles review
Follow-up to PR #350 review:

1. New assertion: hyperhive.frontend.extraFiles[*].target must be a
   relative path inside the static dir — leading '/' and '..'
   segments rejected at config eval time. Belt-and-braces against
   string-concat-into-paths escapes (the boundary doc flags this
   pattern even though agent.nix goes through operator review).

2. Documented overwrite semantics in the option doc: collision with
   a default-dist path or with a prior entry's target is a hard-fail
   (`refusing to overwrite existing path …`). To override a default
   file, fork `hyperhive.frontend.dist` instead — extraFiles is
   pure additions.

The collision-hard-fail behaviour was already implemented in
`mergedDist` (in commit a19e156); this commit just makes the
contract explicit in the docstring.

Refs #273, addresses damocles' notes on PR #350.
2026-05-23 14:51:01 +02:00
iris
892e034908 frontend: wire static-dir env var + per-agent extraFiles option
Phase 3 of #273. Container plumbing for the bundled frontend dist:

- flake.nix overlay: `pkgs.hyperhive-frontend` exposed for the
  agent / manager containers (mirrors the existing `pkgs.hyperhive`
  pattern); module argument `hyperhiveFrontend = system: self
  .packages.${system}.frontend` threads the package into the host
  hive-c0re module without forcing operators to apply the overlay
  on their host pkgs.

- `services.hive-c0re.frontend` option: pinned to the flake's
  frontend package by default, overridable for custom dashboard
  SPAs. The hive-c0re systemd service gets `HIVE_STATIC_DIR =
  ${cfg.frontend}/dashboard` — the Rust binary will pick it up
  in Phase 4.

- `hyperhive.frontend.dist` option: per-container, defaults to
  `pkgs.hyperhive-frontend`. Override to ship a fully custom
  agent SPA (advanced; the default + extraFiles flow handles the
  common 'add files' case).

- `hyperhive.frontend.extraFiles` option: attrsOf submodule
  (mirroring the `hyperhive.extraMcpServers` shape per damocles'
  request so existing #322-style assertions keep their grip).
  Each entry has `source` (path relative to agent.nix) and
  `target` (URL/disk prefix within the merged static tree,
  defaulting to the attribute name). Operator-named example:
  the bitburner agent drops `bitburner-dist` into
  `/bitburner/` alongside the default agent UI at `/`.

- `hyperhive.frontend.mergedDist` (readOnly): the runCommand
  derivation that composes `agent/` from the default dist plus
  every `extraFiles` entry. Aborts on overwrite so a filename
  collision becomes a build error rather than a silent dist swap.
  agent-base.nix + manager.nix set their respective systemd
  service `HIVE_STATIC_DIR` to this merged path.

Until Phase 4 lands, the env var is set but unused — the Rust
binaries still serve assets via `include_str!`. The cutover
happens in the next commit on this branch.

Refs #273.
2026-05-23 14:51:01 +02:00
damocles
e70ae7776c harness-base: add assertions for common agent config mistakes (closes #318) 2026-05-23 02:05:12 +02:00
damocles
77b249076f events: HIVE_DEFAULT_MODEL takes priority over persisted model (closes #319) 2026-05-23 00:38:17 +02:00
damocles
cd9831b39e forge-avatar-sync: fix data URI prefix and add jq to service path (closes #197) 2026-05-23 00:17:38 +02:00
damocles
a94b504883 forge_notify: skip-reasons drop-list filter, configurable via agent.nix 2026-05-22 22:29:32 +02:00
damocles
56d0b02c2f nix: drop unused weston-rdp.nix (closes #263) 2026-05-22 17:30:32 +02:00
damocles
4bc5237bea harness: fix sandbox-fallback conflict with lib.mkForce (closes #247) 2026-05-22 15:24:48 +02:00
damocles
6ca72074c4 docs: move sandbox threat model to docs/security.md, add code reference 2026-05-22 12:28:04 +02:00
damocles
a6bd4cf502 harness: document sandbox threat model and credential permission requirements 2026-05-22 10:57:13 +02:00
damocles
6974634326 harness: set sandbox-fallback = true to fix nix builds in containers (fixes #196) 2026-05-22 10:51:10 +02:00
damocles
8d3be74fd2 harness: fix hive-dashboard-links state dir — drop legacy /state, use /agents/*/state 2026-05-21 23:20:13 +02:00
damocles
66c481a07a harness+dashboard: declarative dashboardLinks option (closes #191) 2026-05-21 23:20:13 +02:00
damocles
317d580405 harness: fix tea-login using getent (not in PATH) — hardcode /root 2026-05-21 23:05:13 +02:00
damocles
f762348fca harness: fix tea-login writing to /.config instead of /root/.config 2026-05-21 22:52:37 +02:00
damocles
2d3a87f545 forge-avatar-sync: rasterize SVG at 512px 2026-05-21 22:37:45 +02:00
damocles
94f5f53ca9 harness: rasterize SVG icon to PNG for Forgejo avatar upload (fixes #197) 2026-05-21 22:37:45 +02:00
damocles
03fec39405 forge_notify: flip keepSubscriptions default — agents keep, manager auto-unsubs 2026-05-21 22:33:35 +02:00
damocles
d58a3a3303 manager: keepSubscriptions = true by default 2026-05-21 22:33:35 +02:00
damocles
1adfd604b6 forge_notify: hyperhive.forge.keepSubscriptions NixOS option 2026-05-21 22:33:35 +02:00
iris
dd32774e86 weston-vnc: disable idle blank + lock screen (idle-time=0)
The VNC desktop faded to black after weston's default 300s idle
timeout, and on wake desktop-shell showed its click-to-unlock lock
screen (a green circle) — pointless for an agent desktop viewed
over /screen, and confusing for the operator (issue #180).

Add [core] idle-time=0 to the generated weston.ini. Verified against
weston 14.0.1: idle-time parses to compositor->idle_time, and
weston_compositor_wake arms the idle timer with idle_time*1000 ms;
0 ms makes wl_event_source_timer_update disarm the timer, so the
compositor never transitions to IDLE and desktop-shell never locks.

closes #180
2026-05-21 19:34:10 +02:00
damocles
00281730bb harness: sync agent icon to Forgejo user avatar on rebuild (closes #141) 2026-05-21 18:29:33 +02:00
damocles
72522be8c0 harness: add hyperhive.autoCompact option (default true, false=disable proactive compaction) 2026-05-21 17:41:53 +02:00
iris
39bd46b244 agent icon: add hyperhive.icon option + GET /icon endpoint
Foundation for the per-agent icon feature (#137).

- harness-base.nix: new hyperhive.icon option (nullable path to an
  SVG). An agent commits an SVG into its config repo and references
  it as ./icon.svg; when set it lands at /etc/hyperhive/icon.svg.
- web_ui.rs: GET /icon serves the configured SVG, falling back to the
  bundled hyperhive logo when none is set — so it always returns an
  image and consumers can hit it unconditionally.

Closes #139
2026-05-21 01:06:34 +02:00
damocles
a95ca22b49 hive-forge: single command with subverbs instead of per-verb scripts 2026-05-20 21:45:01 +02:00
damocles
0a4cde88b0 add hive-forge-tools: shell wrappers for common forge API operations 2026-05-20 21:45:01 +02:00
iris
ddd0248619 harness-base: fix python3 -c quoting inside nix string
Two consecutive single quotes ('') inside a Nix indented string (''...'')
are treated as the string-end delimiter, breaking nix evaluation.
Switch the shell -c argument from double-quotes to single-quotes so
the Python string literals use double-quotes instead, avoiding any ''
sequences in the Nix source.
2026-05-20 21:01:26 +02:00