Watch
0
0
Fork
You've already forked hyperhive
0
Commit graph hyperhive/hive-priv
Author SHA1 Message Date
iris
0e84fe8bc4 docs: the handbook follows the three layers: swarm, hives, agents
The handbook's sections were agent-lifecycle, integrations, swarm, tools,
trust-boundary and web-ui, which do not follow how the system is built, so a
reader could not tell which layer a page is about. Its pages now sit in
swarm/, hives/ and agents/, with the accounts an agent can hold outside the
system in external-accounts/.

- swarm/: forge, matrix and the knowledge repo join the swarm pages, and so
  does the swarmctl reference.
- hives/: the dashboard, hivectl and its reference, and the operator/agent
  boundary, with a README that takes over the old web-ui and tools pages.
- agents/: the roster, persistence, config changes, the agent's own web page
  (was web-ui/agent) and the security model, with a README.
- external-accounts/: GitHub and GitLab.

Pages are moved whole; none is split yet. Every reference follows: relative
links in the docs, `docs/2-handbook/...` paths in code comments, the nix
checks that regenerate the CLI references and the ignore list, and docs/README.md,
whose handbook section is now by layer.
2026-11-07 12:19:36 +01:00
iris
30a8f71bb5 docs: the trust-boundary pages keep the operator guidance, the mechanism moves to implementation
boundary.md keeps the model, the design rule, why network isolation
matters and host admin socket access; the hive-priv socket activation and
the per-agent socket directory move to 4-implementation/trust-boundary.
security.md keeps the agent trust model and the path-name rule; the nix
builds mode with its threat model, and the hive-c0re privilege separation,
move to their own pages there. Headings and text move as they were, with
one level shaved off the heading depth. Links, code and nix pointers, and
the docs index follow the moves.
2026-11-06 19:45:11 +01:00
iris
6739bb903d docs: sort the top-level directories into five sections by what the reader wants
Every docs directory moves under 1-getting-started, 2-handbook,
4-implementation or 5-project; the options reference (section 3) comes from
the website and has no directory here. trust-boundary stays whole under the
handbook for now. web-ui, swarm and tools split between handbook and
implementation, and the command-line references move to
2-handbook/reference. Links, path references in code and nix, and the docs
index follow the moves; no page content changes.
2026-11-06 18:46:57 +01:00
atlas
a71e7cea75 allow erofs as the idmapped store filesystem
nspawn idmaps the store on erofs, which the VM test's store uses; the
allowlist from the store check refused it and failed the namespaced-agent
subtest in vm-nightly #7084. vm-nightly #7030 ran the same agent on the
same erofs store green. The magic is EROFS_SUPER_MAGIC_V1 from the
kernel's linux/magic.h; libc has no constant.

Refs #5888
2026-11-06 17:02:44 +01:00
atlas
419d087702 say the store check is an allowlist: only ext4, btrfs and xfs pass 2026-11-06 12:37:04 +01:00
atlas
af739dc8ea refuse a namespaced agent whose /nix/store cannot be idmapped
Refs #5888
2026-11-06 12:37:03 +01:00
atlas
cd1b77b078 pin state as the first data dir with a comment and a test 2026-11-06 11:36:17 +01:00
atlas
76f5ede645 make a userns data move resumable and refuse before the first chown 2026-11-06 11:36:17 +01:00
atlas
18e4f195e5 hive-priv: refuse injecting strings in the limits drop-in and the container conf
memory_max and cpu_quota are checked against the shapes systemd takes
before write_resource_limits makes any file. validate_bind_path also
refuses whitespace, control bytes, backslash, dollar and backtick, which
the start script expands unquoted in EXTRA_NSPAWN_FLAGS. bridge must be
an interface name and gateway_ip an IPv4 literal. Each refusal names its
field.

Closes #6086
2026-11-06 10:06:11 +01:00
atlas
5485151ba6 add a per-agent nix builds mode, host or none, carried like privateUsers 2026-11-06 09:18:42 +01:00
atlas
b0a6a28d10 tests use mockall for expectation-style doubles, starting with the builder and hive-priv seams 2026-11-03 14:16:01 +01:00
atlas
6a1e47532d hive-priv: test main.rs's request dispatch and validation, and infra.rs
check_socket_activation and response_of are extracted from socket_listener
and dispatch unchanged, and infra.rs takes a &impl Spawn, so tests run
stand-ins instead of systemctl.
2026-11-03 10:27:47 +01:00
atlas
6d04be6c62 hive-priv: test seams are traits, not closure bags 2026-11-03 08:31:12 +01:00
atlas
666f8975a2 hive-priv: stop streaming spin after stderr closes 2026-11-02 22:49:26 +01:00
atlas
18dd5535de hive-priv: test container.rs's start, stop and config decisions 2026-11-02 21:11:22 +01:00
atlas
fd5e9c74e8 hive-priv: test storage.rs's path, name and ownership decisions 2026-11-02 20:55:36 +01:00
atlas
9a773349a8 a failed container start shows the unit's own journal lines in the op output 2026-11-01 17:06:36 +01:00
atlas
f5a609911c read privateUsers from the closure record at start, and move the data owner option under hive-controller 2026-11-01 17:06:18 +01:00
atlas
7412a0f1bd walk an agent's dirs by fd when moving them, and refuse a gid that differs from the uid 2026-11-01 17:06:18 +01:00
atlas
bfdf603d12 run opted-in agents in a user namespace with a dedicated data owner 2026-11-01 17:06:18 +01:00
damocles
3c09e14a76 drop the config and /applied mounts: an agent reads its config by cloning agent-configs, and the prompt says so 2026-11-01 17:02:12 +01:00
atlas
35a49aaf42 keep the knowledge .git overlay unconditional 2026-11-01 14:06:19 +01:00
atlas
23b0c4cd55 overlay config .git only when the source has one; record a failed start in the op output 2026-11-01 14:06:19 +01:00
atlas
6b800600e2 bind a container apply to the closure realised for the agent, and record the deployed pins on drift
hive-priv applies only the path its last RealiseClosure returned for that agent. On drift the swap and create record the pins of the commit the closure was built from.
2026-10-29 22:36:58 +01:00
atlas
4590b04cac remove the hive's local build of agent closures
A rebuild or create downloads the closure the swarm built and applies it; with none to deploy it fails and changes nothing. hive-priv takes a store path instead of an internal/meta commit and builds nothing.
2026-10-29 22:17:07 +01:00
atlas
74f463c40e move the c0re host options to deploy.hive-controller 2026-10-29 01:08:41 +01:00
atlas
24afc89ab3 run the root check warn-only on hyperhive's own containers, per unit, not on the container@ template 2026-10-28 23:50:58 +01:00
atlas
c191975aab check every container's root before its start, through the container@ template 2026-10-28 23:50:58 +01:00
atlas
86e80250bb remove the partial salvage dir when a salvage fails
- a failure between creating the dir and the rename removes that dir only
- give the ephemeral-rootfs vm test a 4 GiB disk so the space check passes
2026-10-28 23:01:04 +01:00
atlas
836b15a46e harden the ephemeral-root salvage: clone, check space, lock
- clone each file with FICLONE, copy the data only where that fails
- skip the salvage when the copy would leave too little free space
- hold a per-container flock and one copy at a time across containers
- run WriteNspawnFlags on the blocking pool
2026-10-28 23:01:04 +01:00
atlas
6708ef804f root the build the pre-start check names 2026-10-28 21:59:43 +01:00
atlas
a44a7256a7 check the container root before each start 2026-10-28 21:59:43 +01:00
atlas
81439fa710 run agent containers on an ephemeral root, salvaging the old one first
hive-priv copies a stopped container's root to the agent's work dir and
renames it aside before passing nspawn --ephemeral; the agent's nix state
moves to the persistent profiles bind. Adds the agent-ephemeral-rootfs vm
test and a module-eval case for the nix state redirect.
2026-10-28 20:00:12 +01:00
atlas
b551eb02ff send agent traffic through squid once its hive announces it 2026-10-28 17:24:34 +01:00
atlas
c16cf1756f download an agent's cached closure in prebuild, building locally when that fails 2026-10-28 10:23:45 +01:00
atlas
11914e3e9a use a neutral path in the non-repo mount test 2026-10-26 22:06:51 +01:00
atlas
7dd5d30da8 remove the /shared bind from agent containers 2026-10-26 21:33:05 +01:00
atlas
b79896c237 hive reads the forge for nix as its own account, not core
hive-c0re copies the hive's store read token to /run/hyperhive/forge-hive-token
for nix's git credential helper, and no longer mints, reads or falls back to
the core admin token. drops the core user sweep, avatar upload, webhook
cleanup and hive-priv's RunForgeAdmin.
2026-10-25 18:06:48 +01:00
atlas
4aa11b3a94 build agents only from internal/meta; delete the hive's local meta flake
The hive no longer renders, locks or commits a meta flake. A rebuild's
MetaSync node picks the internal/meta commit and records it with the
hyperhive and config pins it holds; Prebuild, Swap and Create build from it,
and a head that does not pin the agent's current config fails the build
naming the agent. hive-priv's meta_rev is required.

Removed: meta.rs sync/lock/render, the manual-rebuild relock, the boot
sweep's hyperhive bump (MetaLock), the update-meta-inputs form and its
panel, MetaWindow, the hive's hyperhive_rev setting.

Kept: agent_set::refresh holds what sync_agents also did (topology.json, the
gateway's agent-socket map and nginx include), called from spawn, destroy,
rebuild and the migration.

The boot reconcile and the stale-start upgrade compare the agent's marker
with the hyperhive pin of internal/meta; the dashboard's deployed chip reads
the config marker a successful build writes.
2026-10-25 15:32:16 +01:00
atlas
7c0a622d41 build agents from internal/meta when it pins their config
A rebuild's MetaSync resolves the head of the swarm's internal/meta once and
records it; the prebuild and the swap build that flake instead of the hive's
own, and a first deploy does the same in Create. hive-priv takes the commit as
a validated meta_rev on UpdateContainer and CreateContainer and builds from its
own forge URL (HIVE_PRIV_FORGE_URL).

The head is used only when its flake lists the agent at the config commit the
forge's main is at; otherwise, and when the repo has no commit or this hive has
no core token file for nix's git, the hive renders locally as before.

hive-c0re's and hive-priv's gitconfig now share the forge credential helper and
rewrite the forge's https URLs to http, which hive-priv lacked.
2026-10-24 21:13:24 +02:00
atlas
f3c0a87c0f hand agents the queue address at container start
HIVE_AGENT_NATS_URL now reaches each container in its hive facts, from
the host's deploy.hive-controller.queue.agentNatsUrl, instead of being
rendered into the meta flake. The agent option
services.hyperhive.agent.queue.natsUrl is removed; the harness unit
imports the queue credential whenever the token endpoint is set.

On deploy every agent rebuilds once (the rendered flake loses the
address), and the harness reads the address from the facts file
hive-priv writes before each start.

Refs #4857
2026-10-24 21:13:24 +02:00
atlas
156dd541e6 hive-priv: count a process being reaped as dead in the build-timeout test
The timeout kill was sound; the test's liveness probe was not. is_dead
read /proc/<pid>/stat and counted only state Z as dead. While init reaps
a zombie, the task shows state X (EXIT_DEAD) for a few microseconds
before its /proc entry goes away. When the poll loop's first probe saw Z
and the final assert's re-probe landed in that window and saw X, the
test failed at once with "grandchild <pid> outlived the timeout". CI run
#6059 shows this: the hive-priv binary finished in 2.00s, so the 5s poll
never ran.

is_dead now counts X as well, so it is monotone (running, Z, X, gone)
and the re-probe can no longer flip it back to alive. A unit test pins
the Z/X/S/R parsing.

Stress loop: the test binary filtered to this test, 2000 runs, 32 in
parallel, with 8 busy-loop CPU hogs. Before: 4/2000 failed, all with the
CI signature (finished in ~2.01s). After: 0/2000.
2026-10-22 07:14:08 +02:00
atlas
9113651c10 hand agents the dashboard port, pinned claude and otel labels at container start
The three values that differ per host (deploy.hive-controller.dashboardPort,
claudeCodePackage and otel.extraResourceAttributes) no longer go into the
meta flake. hive-priv writes them into the container's
/etc/hyperhive-hive-facts with the hive name and domain, and the agent
reads them at boot:

- HIVE_DASHBOARD_PORT reaches every unit through the hive-facts generator;
  the web UI still defaults to 7000 without it.
- `claude` on PATH is a wrapper that runs HYPERHIVE_CLAUDE_CODE_PATH's
  claude when it is there, and the container's own claude-code otherwise.
  The host's serve.json keeps gc-rooting the pinned build.
- OTEL_RESOURCE_ATTRIBUTES moves out of the units' Environment= into a
  boot-time generator, which appends HYPERHIVE_OTEL_EXTRA_RESOURCE_ATTRIBUTES.

The agent options services.hyperhive.agent.claudeCodePath (now a removed
option) and otel.extraResourceAttributes go; only the meta render set them.
render_flake takes no HiveEnv any more, so the memory-cap render test and
render_hive_flake_at, which only existed to vary HiveEnv into the render,
go with it.

Refs #4857
2026-10-22 07:11:46 +02:00
atlas
6ac637c7e3 hive-priv: split main.rs into one module per op family
No behaviour change: a pure move plus pub(crate) visibility. PrivRequest,
hive-priv-sock and every validation rule are untouched; the 58 tests move
next to the code they test, unchanged.

Why (#5476): the 28 root ops shared one 4.3k-line file, so no op family
could be reviewed on its own and every new root op landed there by default.

main.rs keeps the socket loop and the dispatch table. container (lifecycle),
container_config (nspawn flags, systemd drop-ins, daemon-reload), storage
(btrfs subvolumes, quotas, snapshots, du), files (pause marker, socket dir,
legacy tmpfiles) and infra (gateway nginx, forge admin, infra containers)
each carry their own validation; shared holds the agent-name checks, the
credential-name charset and StagedFile, plus the tests' scratch helpers
(one counter crate-wide, so test dirs stay unique).

hive-priv/README.md is in the diff because it named src/main.rs as the
home of container_flake_action and now describes the module layout.
2026-10-18 03:55:37 +02:00
atlas
4f75e2a71a hive-priv refuses bind-mount edits on the swarm's forge and matrix containers
The forge and matrix containers belong to the services host, not to a
hive. hive-priv's container-name validator still accepted hive-forge and
hive-matrix for WriteNspawnFlags, WriteResourceLimits and
RemoveServiceDropin; hive-c0re only ever sends h-<agent> names there.

- hive-priv-sock/src/lib.rs: drop SIBLING_CONTAINERS, its only user was
  the validator, and its test.
- hive-priv/src/main.rs: the validator accepts only h-<name> and returns
  the logical name, so write_resource_limits loses its non-h- fallback;
  test that all three requests refuse both names.
- hive-priv/README.md, docs/trust-boundary/security.md: the allowlist
  no longer lists the forge and matrix.

Fixes #5508
2026-10-18 00:21:45 +02:00
atlas
d4f3d1ef8e hive: stop controlling the swarm's forge and matrix containers
The forge and matrix are swarm services; per mara's ruling on #5475
(shape a) a hive no longer starts, stops or restarts them.

- hive-priv-sock: InfraContainer keeps only Gateway; InfraTarget goes,
  service_unit maps the gateway to nginx.service directly. A
  ControlInfraContainer naming Forge/Matrix fails to decode.
- hive-host-sock: LifecycleScope drops forge/matrix and refuses unknown
  fields, so an older hivectl's --forge is an error rather than an
  all-false scope meaning everything.
- hive-c0re: scoped_infra selects only the gateway.
- hivectl: --forge/--matrix removed from stop/start/restart.
- docs: services.md says how the forge and matrix are managed;
  security.md, coordinator.md and hivectl-cli.md follow.
- hive-host-sock, hivectl/power.rs: Stop and RestartScoped doc comments name the gateway (host nginx.service), not infra containers.
2026-10-17 23:27:44 +02:00
atlas
c87a4d2c1a agents: read the hive's name and domain at runtime, not from the build
Part of #5081 (slice S0-1a). An agent's closure no longer depends on the
name or domain of the hive that renders it.

- hive-priv writes /etc/hyperhive-hive-facts (HYPERHIVE_HIVE_NAME,
  HYPERHIVE_HIVE_DOMAIN) into the container from the same WriteNspawnFlags
  call that writes /etc/hyperhive-bridge-dns. hive-c0re passes the values
  from its own unit env. hive-priv refuses a value outside [A-Za-z0-9._-].
- A systemd environment generator in the agent (hive-facts.nix) loads the
  file into the container manager's environment, so every unit sees it,
  as with the systemd.globalEnvironment entries the render used to emit.
  It also builds CLAUDE_REMOTE_CONTROL_SESSION_NAME_PREFIX
  (<hive>-<agent>), which left claude's managed settings.
- meta.rs stops forwarding HYPERHIVE_HIVE_{NAME,DOMAIN} and stops setting
  services.hyperhive.agent.hiveName. The option is removed (both
  spellings now fail with a removal message).
- otel.nix drops the agent's hive= resource label. The swarm collector
  upserts hive per authenticated receiver (swarm-otel.nix resource/<h>,
  on both the metrics and logs pipelines), so stored series keep it.

The otel first hop, otel enable and the dashboard port are still baked;
they are S0-1b.
2026-10-12 10:52:21 +02:00
atlas
884fb3e08b dashboard: remove the L0GS page and its journal backend
Logs live at swarm level now (VictoriaLogs, read through Grafana
Explore). The hive dashboard's own journal viewer goes, with
everything that existed only to serve it:

- frontend: /logs.html, logs.js, logs.css, the H0M3 "Logs" tile and
  the per-agent menu's "journal logs ->" link. The build-log list
  rules BU1LDS used from logs.css move into builds.css.
- hive-c0re: GET /api/journal/{name} and GET /api/journal-host, and
  priv_client::read_container_journal.
- hive-priv / hive-priv-sock: the ReadContainerJournal request, its
  JournalQuery/JournalOutput wire types and the journalctl -M executor.
- nix: hive-c0re's systemd-journal supplementary group, whose only
  reader was the journal-host handler.
- docs: the L0GS section, the API entry and the security table row.

Closes #5113
Closes #3819
2026-10-12 01:26:33 +02:00
damocles
25893d0f95 hive-c0re, hive-priv: demote three routine, non-actionable log sites 2026-10-08 00:46:23 +02:00
atlas
960cf9ce30 container stats: bound hive-c0re's wait for the disk measurement, no total for an agent with no paths
hive-c0re waited on hive-priv's answer with no timeout, so a hung
hive-priv would stall the disk sampler indefinitely. The wait is now
hive-priv's own 10 min bound plus a minute (the bound is shared as
MEASURE_AGENT_DISK_TIMEOUT); a timeout is an error, so the agent shows
unknown.

An agent with none of state/, work/ or the rootfs has no measurable
size. hive-priv now answers with an error for it instead of a total of
0, which read as a real measurement.
2026-10-05 18:56:46 +02:00