Commit graph hyperhive/nix/templates
Author SHA1 Message Date
müde
4a48ce5024 refactor: nix/host-modules + nix/agent-modules layout, update doc paths 2026-07-13 22:05:49 +02:00
müde
7c9d72b9ca refactor: rename templates to agent.nix/ruth.nix, sweep stale name refs 2026-07-13 22:01:24 +02:00
müde
7ad2bb9211 refactor: replace deprecated no-op options with mkRemovedOptionModule 2026-07-13 21:58:30 +02:00
müde
281667d5a8 refactor: thread agent packages via option, drop overlay and forge-tools shim 2026-07-13 21:43:26 +02:00
müde
ecaad48fad refactor: split harness-base.nix into harness/ feature modules 2026-07-13 21:16:29 +02:00
atlas
650224c9c6 fix(#2399): split daemon/harness/MCP bins into per-binary packages
mara: "no, do split packages for the separate daemons" — instead of
grouping all daemon/harness/MCP bins into one hyperhive-daemon
derivation, each bin (hive-c0re, hive-priv, hive-agent,
hive-agent-mcp, hive-agent-wake, hive-bash-daemon, hive-bash-mcp,
hive-matrix-daemon, hive-matrix-mcp, hive-metric) is now its own
named package + overlay output, matching the existing hivectl /
hive-forge split. harness-base.nix's ExecStart/command lines now
point at the specific pkgs.hive-* each ExecStart needs, and
environment.systemPackages only carries the two bins actually
PATH-looked-up in-container (hive-agent-wake, hive-metric) instead
of the whole bundle.
2026-07-13 19:26:58 +02:00
atlas
5c08abc1b2 fix(#2399): agent containers get daemonBins, not the full hivectl/hive-forge bundle
Agent containers pulled in `pkgs.hyperhive` (packages.default: daemonBins +
hivectlPkg + hiveForgePkg) via environment.systemPackages and every
harness ExecStart. That shipped hivectl (a host-admin CLI dialing the
host admin socket, unreachable from inside a container, wrapped with
wireguard-tools for `hivectl wg`) plus a redundant second hive-forge
copy (already provided separately via hive-forge-tools.nix) into every
single agent's closure.

Expose the existing daemonBins split as packages.<system>.daemonBins
(mara: 'there should be split nix outputs already, use those' — no new
grouping derivation) + a hyperhive-daemon overlay entry, and repoint
harness-base.nix's systemPackages entry and all agent-run ExecStarts
(hive-agent, hive-agent-mcp, hive-bash-daemon, hive-matrix-daemon) plus
the bash/matrix MCP bridge commands at it instead of the full bundle.

nix flake check: daemonBins + agent-base-toplevel + ruth-toplevel all
evaluate cleanly (docs derivation failure is a preexisting dirty-tree
issue, unrelated).
2026-07-13 19:26:58 +02:00
atlas
4cdbbafc44 feat(#2363): full-DHCP for all agents — drop static agent_network_ip
All agent containers now receive their bridge IP dynamically via DHCP
from the dnsmasq pool instead of a hash-derived static address:

- nix/templates/harness-base.nix: networking.useDHCP = true
- nix/modules/hive-gateway.nix: expand DHCP pool to full usable range
  (.2 to .254 on /24) — was last-14-IPs-only
- hive-sh4re/src/priv_proto.rs: remove agent_ip from NetworkIsolation
- hive-c0re/src/lifecycle/mod.rs: drop agent_network_ip + DHCP_POOL_SIZE
- hive-c0re/src/lifecycle/host_config.rs: remove agent_network_ip call
- hive-priv/src/main.rs: LOCAL_ADDRESS= empty (DHCP assigns IP);
  HOST_ADDRESS still set so nixos-container installs default route
  before the DHCP lease arrives
- nix/dhcp-pool-size: deleted (no longer needed)

The nix/dhcp-pool-size single-source-of-truth file and all associated
Rust/Nix dual-constant plumbing are gone — there is no static map.
bridge_gateway_ip() is retained (still needed for HOST_ADDRESS).

Closes #2363
2026-07-13 11:57:14 +02:00
damocles
46007008a9 fix(#1970): bake token path into gh/git wrappers — env var didn't reach claude's bash-tool context 2026-07-11 14:12:25 +02:00
damocles
bd0e554447 fix(#1970): nested-path environment.etc."gitconfig" + mkIf — whole-set binding collided with sibling entries 2026-07-11 12:18:55 +02:00
damocles
af9b46e80a refactor(#1970): replace githubAccount option with hyperhive.github.enable gate (default true, github.com + x-access-token) 2026-07-11 12:18:55 +02:00
damocles
5fb4b9f4b0 wip(#1970): gh wrapper + git credential helper + gated env/gitconfig for githubAccount 2026-07-11 12:18:55 +02:00
damocles
303037689e wip(#1970): add hyperhive.githubAccount nix option (single-account, nullable) 2026-07-11 12:18:55 +02:00
damocles
1ba44b77ac feat(#2112): make http-mcp the sole transport for the built-in surface 2026-07-11 00:32:51 +02:00
atlas
3f7f24dd0b fix: correct hyperhive.user.gid description — gid works independently of uid 2026-07-10 13:54:03 +02:00
atlas
0d5f7e00b6 feat(#903): expose hyperhive.user.uid + gid options for optional UID pinning 2026-07-10 13:54:03 +02:00
iris
476a7a3c9f web_ui: support unix:<path> upstreams in extraWebProxies
reqwest has no UDS transport, so unix: upstreams dial the socket
directly with a raw hyper/1.1 client per request instead. http(s)://
upstreams are unaffected (still go through the existing reqwest path).

Adds hyper (client, http1), hyper-util (tokio IO adapter), and
http-body-util as direct hive-ag3nt dependencies - all three were
already present transitively via reqwest, this just uses them
directly for the new code path.
2026-07-10 12:53:09 +02:00
damocles
89ce8790ff feat(web_ui): per-path reverse-proxy via HIVE_EXTRA_WEB_PROXIES 2026-07-10 12:14:21 +02:00
atlas
6da7835ad9 fix(#2264): boot.tmp.useTmpfs = false — disk-backed /tmp for agents
Agent containers currently mount /tmp as a 3.2 GB tmpfs (RAM-backed).
Large scratch writes (nix-develop shells, cargo build dirs) eat container
RAM unnecessarily and can exhaust the tmpfs, losing in-flight work.

Set boot.tmp.useTmpfs = false so /tmp is disk-backed instead.
boot.tmp.cleanOnBoot (default true) preserves the ephemeral-per-boot
semantics — /tmp is cleared on container start, same as before.

Closes #2264. Supersedes PR #2299 (TMPDIR redirect + state/tmp).
2026-07-10 12:09:31 +02:00
atlas
9adf074504 feat(#2304): set weston VNC default resolution to 720p (1280x720)
Add [output] section to weston.ini with name=VNC-1 mode=1280x720.
The VNC backend's output is named VNC-1; the mode string sets the
compositor's framebuffer size that clients connect to.
2026-07-10 02:47:39 +02:00
müde
5b062dca55 refactor(hive-ag3nt): split hive bin into hive-agent / hive-agent-mcp / hive-agent-wake 2026-07-06 23:48:05 +02:00
atlas
03e07c7d37 chore(nix): fix remaining stale shared-netns references in harness-base.nix
- Option doc: 'Default points at the in-host tuwunel (shared netns)'
  → updated to reflect that c0re forwards the gateway URL at runtime
- DNS oneshot comment: 'inert in shared-netns mode' → removed since
  isolation is always on; oneshot always runs
2026-07-04 22:54:38 +02:00
atlas
9067398e3c chore(docs,nix): remove stale shared-netns references from matrix URL docs
Agents run in private netns (always-on isolation) and can't reach
host loopback directly. hive-c0re forwards HIVE_MATRIX_URL set to
`matrix.<domain>` via the gateway. Update two places that still
referenced the removed shared-netns path.
2026-07-04 22:54:38 +02:00
atlas
742f4ef916 feat(#2220): add low and max effort levels
claude --effort now accepts low, medium, high, xhigh, max.
Expand EFFORT_LEVELS from 3 to 5, update NixOS enum + description,
and fix the stale doc comment in web_ui.rs.

Closes #2220
2026-07-04 19:52:33 +02:00
atlas
3a4b8d9873 fix(#1748): route all nix invocations through the host daemon (NIX_REMOTE=daemon)
Root contexts (systemd services running as root, PID 1) default to
store=auto which resolves to the LOCAL nix store — bypassing the host
daemon, its remote builders (muede-pc2), and any prebuilt derivation
outputs already in the shared store. This causes spurious full
rebuilds of agent toplevels that the host already built and cached.

Two changes:

harness-base.nix:
- Add systemd.globalEnvironment.NIX_REMOTE = "daemon" — sets
  DefaultEnvironment in systemd.conf so every unit in the container
  inherits NIX_REMOTE=daemon. Non-root contexts already default to
  the daemon socket; this only matters for root services that would
  otherwise use the local store.
- Add NIX_REMOTE = "daemon" to environment.variables so interactive
  shells also have it set (redundant with /etc/profile.d/nix-daemon.sh
  but explicit and profile-agnostic).

hive-c0re.nix (hive-priv service):
- Add NIX_REMOTE = "daemon" to the service environment. hive-priv
  runs as root and invokes nixos-container update + nix prebuild; these
  must route through the host daemon so they see the shared store and
  remote builders, not a private local store.

The sandbox-fallback = true in harness-base.nix is kept as a belt-
and-suspenders fallback but becomes a no-op for the common case once
nix routes through the daemon (the daemon builds on the host where
sandboxing works).
2026-07-04 13:12:02 +02:00
damocles
a26bbb15fc feat(#2089): docs pointer via system-prompt line, drop CLAUDE.md mechanism 2026-07-04 12:07:17 +02:00
damocles
b5acd60cf5 feat(#2170): split docs/ into its own meta-flake input 2026-07-04 11:47:07 +02:00
damocles
6267bf56d0 feat(#2089): additive claude.md pointer to in-container docs 2026-07-04 11:30:33 +02:00
atlas
cb0a66147a fix(#2172): gate CLAUDE_CODE_OTEL_DIAG_STDERR on hyperhive.otel.debug
CLAUDE_CODE_OTEL_DIAG_STDERR was always set when OTEL is enabled, making
OTEL SDK errors (e.g. 404 from a misconfigured collector endpoint) appear
in every agent's stderr unconditionally. Move it behind a new opt-in flag.

Changes:
- nix/modules/hive-c0re.nix: add services.hyperhive.otel.debug (bool,
  default false); wire to HYPERHIVE_OTEL_DEBUG env on hive-c0re unit.
- hive-c0re/src/meta.rs: add debug field to OtelConfig; read
  HYPERHIVE_OTEL_DEBUG; emit hyperhive.otel.debug = true when set.
- nix/templates/harness-base.nix: add hyperhive.otel.debug internal
  option; move CLAUDE_CODE_OTEL_DIAG_STDERR out of otelSettingsEnv into
  a debug-gated lib.optionalAttrs block.

Default behaviour: OTEL exports silently (no stderr noise). Operators
troubleshooting collector connectivity set services.hyperhive.otel.debug
= true to re-enable the diagnostic output.
2026-07-03 22:12:56 +02:00
atlas
e4889fdd2c fix(#2149): use - as session prefix separator (mara) 2026-07-02 23:33:33 +02:00
atlas
d5e0f680a5 fix(#2149): use hive display name + / sep in remote-control session prefix
CLAUDE_REMOTE_CONTROL_SESSION_NAME_PREFIX: hive+<agent> → <hiveName>/<agent>
(hiveDisplayName already available in scope from OTEL resource attrs)
2026-07-02 23:33:33 +02:00
atlas
04692871cf feat(#2149): set base claude-code env in managed settings
Add `baseClaudeEnv` (always-on) and extend `otelSettingsEnv` with the
env vars from #2149:

Always-on (every agent):
- CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1
- CLAUDE_CODE_PLUGIN_PREFER_HTTPS=1
- CLAUDE_CODE_RESUME_INTERRUPTED_TURN=1  (recovers MCP-flap mid-turn)
- CLAUDE_CODE_SIMPLE_SYSTEM_PROMPT=1
- CLAUDE_CODE_SYNC_PLUGIN_INSTALL=1
- CLAUDE_REMOTE_CONTROL_SESSION_NAME_PREFIX=hive+<agent>
- DISABLE_AUTOUPDATER=1 / DISABLE_UPDATES=1  (nix owns packages)
- DISABLE_INSTALL_GITHUB_APP_COMMAND=1
- DO_NOT_TRACK=1
- ENABLE_CLAUDEAI_MCP_SERVERS=0  (hive supplies its own)
- FORCE_AUTOUPDATE_PLUGINS=1

OTEL-gated (when hyperhive.otel.enable):
- CLAUDE_CODE_ENABLE_FEEDBACK_SURVEY_FOR_OTEL=1
- CLAUDE_CODE_OTEL_DIAG_STDERR=1
- OTEL_METRICS_INCLUDE_VERSION=1

Because baseClaudeEnv includes per-agent values
(CLAUDE_REMOTE_CONTROL_SESSION_NAME_PREFIX = "hive+${userName}"),
jq is now always run at build time — the OTEL-off branch that returned
the static asset verbatim is removed.
2026-07-02 23:33:33 +02:00
damocles
a05d093d19 harden hive-mcp-http: restart=always + document failure-mode/port-collision (atlas review) 2026-07-01 18:39:28 +02:00
damocles
3c10b00460 feat(#2038): wire persistent hive-mcp-http daemon behind hyperhive.mcp.httpPort 2026-07-01 18:04:14 +02:00
damocles
621ee66133 fix(#2022): seed claude onboarding+trust via a boot-time oneshot 2026-06-29 18:41:42 +02:00
damocles
cd5b731884 refactor(#2058): drop claude.md docs pointer, keep nix option + --add-dir 2026-06-29 01:42:35 +02:00
damocles
362d392993 refactor(#2012): docs in own derivation, ship via claude --add-dir (no ~/.claude clobber) 2026-06-29 01:42:35 +02:00
damocles
e6bc621f59 fix(#2012): gc-safe docs claude.md via /etc indirection + option clobber note 2026-06-29 01:42:35 +02:00
damocles
3fb5cb863b feat(#2012): ship hyperhive docs as a nix asset + opt-in ~/.claude pointer 2026-06-29 01:42:35 +02:00
damocles
c99fa714d9 feat(#2050): set matrix avatar in the daemon over the live client 2026-06-28 01:38:21 +02:00
damocles
63e9e80232 fix(#2050): use single matrix-token* glob for avatar-sync path trigger 2026-06-28 01:38:21 +02:00
damocles
ef079bb6b1 feat(#2050): sync matrix avatar for dashboard-provisioned extra accounts 2026-06-28 01:38:21 +02:00
atlas
cc962d0685 feat(#2023): inject OTEL auth header at runtime, never in the nix store (mara: b)
Per mara: a secret in the nix store is not acceptable. The non-secret
OTEL config (telemetry-enable, endpoint, protocol, resource attributes)
stays in the world-readable managed settings json; the auth header is
handled separately at runtime so it never touches the store.

New hive-otel-header oneshot (only when otel.enable && headersCredential
is set): inherits the forwarded otel-headers systemd credential via
LoadCredential, reads it at start, and merges OTEL_EXPORTER_OTLP_HEADERS
into the agent's 0600 ~/.claude/settings.json env block via jq. claude
layers the user env on top of the managed settings, so both the harness
turn-loop and hivectl choom (same agent user) export with auth. The
token is read from disk at start and never copied into the nix store or
the world-readable managed file.

Ordering is best-effort (before=, not a hard dep): a failure leaves the
harness running and telemetry exporting unauthenticated. headersCredential
option description updated to reflect it's now wired.

nix fmt clean.
2026-06-27 20:31:10 +02:00
atlas
b20dd32189 docs(#2023): mark otel.headersCredential as not-yet-wired (argus review)
The option description still claimed the credential is loaded via
systemd LoadCredential, but this PR removed that path. Clarify that the
option is currently inert (only the unauthenticated OTEL export is
implemented) and that runtime header injection is a planned follow-up,
so configuring it doesn't silently no-op without explanation.
2026-06-27 20:31:10 +02:00
atlas
141764c6eb feat(#2023): ship OTEL via managed claude settings json, drop the wrapper
Per mara: configure OTEL in the generated claude settings json (what the
Claude Code docs suggest), not a launch wrapper or /etc shell file.

claude-code auto-discovers /etc/claude-code/managed-settings.json in
every context — the harness turn loop AND hivectl choom — so putting the
OTEL env there gives telemetry parity declaratively, with no wrapper and
no --settings plumbing.

- managed-settings.json: was a static shared .source; now, when OTEL is
  enabled, a per-agent build-time jq merge of the base asset + an env
  block (jq at build, not eval-time readFile, to avoid IFD). OTEL off =
  the static asset verbatim.
- otelSettingsEnv carries the static OTEL knobs + OTEL_RESOURCE_ATTRIBUTES
  with the agent name (build-time) and the hive/swarm names forwarded by
  meta.rs into environment.variables (mara: forward host config into
  agent config where needed).
- removed the hive-serve-otel ExecStart wrapper, the per-unit otelEnv,
  and the otel-headers LoadCredential from the harness service — the
  harness binary emits no OTEL itself; only claude does, and it now reads
  the settings json directly.

Known follow-ups (noted in code): the auth header (otel.headersCredential,
opt-in/default-null) is a secret and can't live in the world-readable
settings file — authenticated collectors need a runtime mechanism; this
PR covers the unauthenticated default.

nix fmt clean.
2026-06-27 20:31:10 +02:00
damocles
b231ed2392 feat(#1969): ship claude settings via /etc/claude-code/managed-settings.json 2026-06-26 23:06:04 +02:00
damocles
9f40bd13f9 fix(#1896): remove dead forge_notify reason drop-list + auto-unsubscribe 2026-06-24 23:07:48 +02:00
damocles
af10a4bfef fix(otel): cumulative metric temporality + metricIntervalMs knob (real metrics-export fix) 2026-06-24 20:28:37 +02:00
damocles
baa5ce3e1a gui: one shared dbus session bus for the gui session (#1906) 2026-06-24 00:06:07 +02:00
atlas
14ae7367cd fix(systemd): set explicit SyslogIdentifier on hyperhive-declared units
Follow-up to the harness fix: any unit whose ExecStart is a generated
wrapper (a NixOS `script =` block or a writeShellScript) gets its journal
SyslogIdentifier derived from the wrapper's store-path basename — an
opaque, unstable name. Pin an explicit stable identifier on every unit
hyperhive declares.

script/wrapper units (leaked store paths): forgejo-gpg-init,
hive-gateway-self-signed-cert, hive-tls-ca, hive-ci-prefetch,
hyperhive-isolated-dns, tea-login, forge-avatar-sync,
matrix-avatar-sync, hive-dashboard-links.

direct-binary units (basename already sane; explicit for tidiness +
future-proofing): hive-c0re, hive-priv, hive-matrix-daemon,
hive-bash-daemon, weston.

Only changes the displayed line identifier; journalctl -u <unit>
filtering (keys on _SYSTEMD_UNIT) is unaffected.
2026-06-23 22:53:33 +02:00