Commit graph hyperhive/docs
Author SHA1 Message Date
atlas
1db3cc32a1 job_queue: retire the now-off-wire step sub-step label
The `step` label was taken off the wire in #2661, when each deploy phase
became a first-class DAG node. Since then it has been written but never
read: `NodeRuntime` derives only `Debug, Default, Clone` — no serde — so
the field could not reach any client, and the only reads of it were the
dedup checks inside its own setters. This deletes the machinery.

Removed:

- `NodeRuntime.step`, `set_step`, `set_step_running`, and the
  `rt.step = None` clear in `complete_node`. `NodeRuntime` keeps its
  remaining `build_log_id` field (deliberately still a struct — collapsing
  it to a bare `Option<i64>` would churn every call site for no gain).
- `Ctx::step` and its ~15 call sites in `job_queue/exec.rs`. `Ctx` itself
  stays: it is the build-log sink, which `run_prebuild` and `run_swap`
  still use.
- `Coordinator::set_queue_step` and its 11 callers in `actions.rs`.
- `JobQueue::running_node_of`, reachable only from `set_queue_step`.
- `swap_update`'s `on_step` parameter and its one body call.
- The `set_step_only_on_running_and_signals_change` test.

Dropping the calls orphaned parameters, which are removed with their call
sites: `ctx` on ten executors that used it only as a step sink, and
`queue_entry_id` on `run_deploy_merge_verify` / `run_deploy_apply` /
`run_finalize_deploy` plus both `coord` and `queue_entry_id` on
`prepare_applied_target`. `run_deploy_tail` KEEPS its `queue_entry_id` —
that one has a genuine surviving use (the build-log link in the failure
comment posted to the PR).

One behavioural change, called out so it is not mistaken for a dropped
dashboard refresh: `Ctx::step` and `set_queue_step` each emitted a
`rebuild_queue_changed` snapshot when the label changed, and those
emissions go away with them. This is safe — the snapshot payload has no
step field, so those pushes carried nothing a client could observe. Real
state transitions still emit from the scheduler's claim and completion
paths, from `submit`, and from the three `actions.rs` sites. Net effect is
strictly fewer redundant SSE pushes.

Docs: `docs/coordinator.md` still listed `step` as a `NodeView` wire field
and `docs/web-ui/dashboard.md` documented a cyan `↳ <step>` sub-line under
each queue row. Neither has existed since #2661 — both corrected here, plus
the `job_queue/model.rs` module doc.

Not touched: `frontend/packages/dashboard/src/system-sections.css` has a
dead `.rqe-step` rule with no JS referencing it. Left for the frontend
owner rather than deleted here.

Closes: #2664
2026-07-26 15:24:35 +02:00
atlas
a6dc980700 feat: per-agent CPU and memory limits
The hive applies one `agentCpuQuota` / `agentMemoryMax` to every
container. That's the right default and the wrong ceiling: a build-heavy
agent needs headroom the other twelve don't, and raising the hive-wide
value to suit it hands that headroom to everyone.

Adds a per-agent override, persisted host-side and resolved per-field
against the hive defaults.

Follows the existing `meta/*.json` pattern (`capabilities.json`,
`tool-groups.json`): a host-side map read by `hive-c0re`, staged and
committed in the meta repo so every change lands in the audit trail.

```json
{ "sock": { "cpu_quota": "400%", "memory_max": "8G" } }
```

Fallback is **per field**, not per agent: an entry with only
`memory_max` leaves that agent on the hive-wide CPU quota. Absent file,
absent agent and absent field all resolve to the hive default, so the
feature is inert until someone opts an agent in.

Unlike the other meta files this one is **not** injected into the
container — a limit is something done *to* an agent, not something it
reads about itself.

```
hivectl agents set-limits sock --cpu-quota 400% --memory-max 8G
hivectl agents set-limits sock --reset
```

Values are validated before they're persisted: they go into a systemd
drop-in verbatim, and a typo there makes the unit fail to *start* —
turning a fat-fingered quota into a container that won't come back.

The command is declarative: each call replaces the agent's whole entry.
That makes a forgotten flag a silent revert, so a bare `set-limits
<name>` is rejected at the clap layer and clearing needs an explicit
`--reset`.

`ContainerView` gains `cpu_quota` / `memory_max`, both always populated:
there's no "unset" state to render, only "same as everyone else". They
reflect what the drop-in *says* — what the next start will enforce — not
a live cgroup reading.

The write goes through `meta::commit_resource_limits` rather than the
bare setter, so it's staged and committed under `META_LOCK`. Writing
without committing would leave the meta working tree dirty for the next
`prepare_deploy` to trip over.

Docs: `persistence.md` (the new meta file, and why it isn't injected),
`tools/hivectl.md` (the prose guide), `tools/hivectl-cli.md`
(regenerated clap dump).

Closes: internal/requests issue 25
2026-07-26 14:15:05 +02:00
atlas
20d8618624 docs: regenerate hivectl-cli.md for the pause/resume verbs 2026-07-26 03:11:33 +02:00
atlas
31008c83df feat: pause an agent's turn loop without stopping its container
A paused agent keeps its container, its claude session and its
dashboard/todo servers up, but stops driving turns. Messages queue
unacked and are drained on resume.

The whole protocol is a single marker file, `<harness>/paused`. That
directory is already a bind-mount shared between host and container, so
both sides just stat the same path: the harness reads it to decide
whether to drive a turn, hive-c0re reads it to render the badge and
writes/removes it for `hivectl pause|resume`. No new wire protocol, no
container round-trip, and it is sticky across restarts by construction.

Not calling `recv_next` while paused *is* the queueing semantic, so
there is no fencing to get wrong: reminders buffer in their unbounded
channel, the todo `Notify` permit coalesces, and a `request_next_turn`
that raced the pause survives because the gate sits above
`self_continue.take()`.

Graceful stop is handled host-side rather than in the harness: a paused
agent provably has no turn in flight, so `run_signal` skips the fence
entirely instead of eating the full `GRACEFUL_STOP_TIMEOUT` waiting for
a checkpoint turn that will never run.

`paused` is reported on `ContainerView` / `AgentStatusRow` for the
dashboard, orthogonal to `running` and reported for stopped containers
too.

Closes: hyperhive/hyperhive issue 2271
2026-07-26 03:11:33 +02:00
atlas
3429a8c5a6 job_queue: grow the rebuild subgraph from DeployApply (#2664)
The config-PR deploy's apply node still did the whole container rebuild
inline, through the last surviving `lifecycle::rebuild_no_meta` call. It
now merges, opens the two-phase meta deploy, and returns the ordinary
rebuild chain as a subgraph the scheduler grafts into the live DAG under
it. A new `FinalizeDeploy` node, gated on that graft, plants the deploy
tag and commits the staged lock.

Net effect: "did the agent come back up?" is answered by `Reconcile`
succeeding, the same way it is for every other rebuild, instead of by a
fused inline start — and each deploy phase is its own queue node, so the
dashboard shows which one is running.

The grafted nodes root on the apply node, so they land inside
`DeployWindow`'s subtree and re-enter the meta window and build slot it
already holds rather than deadlocking against them. The new happy-path
test runs on a one-slot queue specifically to pin that down.

`FinalizeDeploy`'s two git writes are fatal, deliberately: they are what
tells `DeployTail` a deploy confirmed good, so a node that merely warned
on them could report success while leaving the tail looking at the git
state of a failure — and the tail would then roll a good deploy back.
The trailing `meta::finalize_deploy` stays warn-only, since by then the
container already runs the new config.

The `failed/<id>` annotated tag moves into the tail, which is now the
only place holding a failed deploy. It reads the reason off the DAG via
a new `JobQueue::first_error`, and is gated on `main` having actually
moved — the rollback ref is parked *before* the merge, so its existence
alone does not mean a merge happened, and a pre-merge rejection must not
tag the previous, innocent head.

Removing the last inline rebuild orphaned a chain of now-dead code:
`rebuild_no_meta`, `container_exists`, `Coordinator::set_queue_build_log`
and `JobQueue::set_build_log_id_running`, all deleted here.
2026-07-26 02:28:03 +02:00
atlas
ff8ada77b7 docs: describe the deploy subtree
Rewrite the approval flow's step 4 as the three phases, with the reason
the rollback state is a git ref, and refresh the coordinator's node
inventory + dispatch table. Fix four doc comments that still pointed at
the deleted `run_merge_config_pr`.
2026-07-25 22:55:02 +02:00
atlas
dfadacd45f feat(job-queue): promote the meta-repo deploy window to a queue resource
The two-phase approval deploy keeps a bumped `flake.lock` staged
uncommitted for the whole container build, so no other meta mutation may
land inside that span — until now enforced by a process-global
`meta::exclusive()` mutex held inside each executor fn.

A `MutexGuard` cannot outlive the fn that takes it, which is what blocks
decomposing the opaque `ApprovalDeploy` node into scheduler-visible
sub-nodes: the window has to span them. Replace the mutex with
`Resource::MetaWindow`, a global capacity-1 queue resource declared by
every meta-mutating node kind (`NodeKind::needs_meta_window`). Resources
are held by a subtree root across its whole subtree, so a later increment
can hang the deploy's phases under one window-holding parent.

Same global serialisation as before, and the scheduler now blocks a node
from being claimed rather than parking a worker on a mutex.

Split the rebuild's meta preamble out of `Prebuild` into a new `MetaSync`
node. `Prebuild` must NOT hold the window: the old mutex was deliberately
scoped to drop before the multi-minute toplevel build, which only reads
the store, and a cap-1 global held across it would serialise every
agent's rebuild behind every other's. `MetaSync` is a sibling root that
`Prebuild` deps `AfterOk` on — not its parent, since a parent's resource
covers its whole subtree and would reintroduce exactly that problem.

Queue tests: shape assertions gain the extra node, which is the point of
the change (phases become nodes). The concurrency invariants are intact
but observed one step later — the `MetaSync` heads take turns on the
window, exactly as the runtime mutex made them, so those tests now
complete the heads before asserting that the prebuilds overlap.
2026-07-25 21:20:56 +02:00
damocles
2316287327 remove hive-agent-wake — no shipped consumer 2026-07-25 20:05:32 +02:00
damocles
a66b7ab298 feat(#2659): serve hive-matrix-mcp over persistent streamable-http, drop stdio bridge 2026-07-24 12:44:39 +02:00
damocles
c4fcf7fbf1 feat(#2659): serve hive-bash-mcp over persistent streamable-http, drop stdio bridge 2026-07-23 18:01:20 +02:00
damocles
e9df5def02 add agent-facing compact tool gated on context usage 2026-07-23 12:34:20 +02:00
atlas
30a2a2e9de feat(#2641): sudoless hivectl via a hive-admin group on the host socket
The host admin socket `/run/hyperhive/host.sock` was `0660 root:root` (no
SocketGroup), so hivectl needed sudo. Group-own it by a new `hive-admin`
group and add a `services.hyperhive.c0re.adminUsers` allowlist: listed users
join `hive-admin` and drive hivectl without root.

- `SocketGroup = "hive-admin"`, `SocketMode = "0660"` on the hive-c0re.socket
  unit.
- `/run/hyperhive` -> `0751` (traverse-only, no listing) so the group can reach
  the socket path; the socket's own `0660 hive-admin` mode gates the
  connection, and the per-agent subdirs keep their own restrictive perms.
- Empty `adminUsers` (the default) leaves `hive-admin` memberless -> root-only,
  as before.

The admin socket is full hive control (spawn/kill/destroy/deploy), so
`adminUsers` is an explicit, opt-in trust grant. Documented in
docs/boundary.md (host admin socket access) + docs/tools/hivectl.md.
2026-07-22 22:50:27 +02:00
damocles
c4deca99db fix(#2639): cancel_loose_end kind="todo" clears without a bash round-trip
Adds a real MCP-side path for the workaround #2639 documented: dial the
in-container HIVE_AGENT_SOCKET directly from cancel_loose_end (kind:"todo")
instead of shelling out via a tracked bash task (nc -U ...), which is what
was spawning a fresh completion todo on every clear and cascading forever.

hive-agent-mcp/src/mcp/render.rs: renamed local_todos's socket-dial guts
into a shared dial_agent_socket(req) helper, added mark_local_todo_done(id)
on top of it (MarkTodoDone request already existed server-side, unused
until now). mod.rs wires kind:"todo" into cancel_loose_end ahead of the
question/reminder/approval parse. args.rs + render.rs + docs/tools/bash.md
text updated to point at the new path instead of the old raw nc invocation.
2026-07-22 21:46:16 +02:00
damocles
e58457da17 feat(#2621): tighten bash task names to a valid ident ([a-z0-9-]) 2026-07-22 18:13:47 +02:00
damocles
3188e50ab8 docs(#2628): update bash tool descriptions, docs, and system prompt for the todo model (trim impl details for agent) 2026-07-22 17:34:12 +02:00
iris
6d281e4606 docs(#2552): never add #[allow(clippy::...)] — fix lints instead
add a clippy-discipline note to docs/conventions.md under 'Building &
local checks' and a short pointer bullet in CLAUDE.md so the rule is
visible at first read. covers the three most common patterns that surfaced
in practice (too_many_lines → extract helper, doc_markdown → backticks,
must_use → handle or discard) and gives a concrete worked example
(TurnAccum extraction in stats.rs).
2026-07-20 19:38:56 +02:00
damocles
da056d0043 fix(#2593): mark forge notifications read on broker-delivery 2026-07-19 18:41:51 +02:00
damocles
d124dd205a feat(#2554): add hivectl forge reconcile-config to reconcile local applied config against forge main 2026-07-17 12:55:42 +02:00
atlas
7df9f5d024 docs(#2502): meta flake input is the forge config repo, deploy overrides to local applied 2026-07-17 01:48:27 +02:00
damocles
5bb5a88aa0 restart preserves wanted intent instead of forcing all agents up (#2540) 2026-07-17 01:46:12 +02:00
atlas
afeddfced1 docs(#1977): drop exposeHostPorts proxy history from network.md
Trim the historical parenthetical about the dropped systemd-socket-proxyd
forwarder — argus flagged it (🟡 on the merged PR) and the constraint
(bind 0.0.0.0 or the bridge IP, not loopback) stands on its own without
the "why we dropped the proxy" narrative. No-history-in-docs preference.
2026-07-17 01:08:42 +02:00
damocles
2646877a22 document PostSwap in coordinator.md (#2390) 2026-07-17 01:06:33 +02:00
atlas
fcca929fde docs: refresh coordinator.md for the current one-DAG model
The #2439 agent-per-node chain removed submit-time dedup, DAG parent_id, and
child-DAG fan-out (everything grows in-DAG via append_subgraph). Update three
stale spots in docs/coordinator.md: the DAG is no longer a dedup unit;
in-DAG-appended nodes (not fan-out child DAGs) surface under the same polled
DAG id; and there is no cancel_children / parent-child cascade anymore.
2026-07-16 15:30:47 +02:00
atlas
14b602b354 docs(#2415): update docs/ci.md for c0re-owned runner registration
#2415 moved hive-ci runner registration off the boot-critical path into
hive-c0re (forge/ci_runner.rs) + hive-priv, retiring the host-side
hive-ci-prefetch.service. Update the doc's Container-design, Auto-registration
flow, and Security sections to describe the new flow: c0re validates .runner /
mints the token out of band, hive-priv writes the host env-file + restarts the
runner, the container boots immediately with a fail-fast precond +
Restart=on-failure self-heal.
2026-07-16 15:30:34 +02:00
damocles
f902592e71 forge_notify: append a comment racing the merge instead of dropping it (#2507) 2026-07-16 12:44:06 +02:00
damocles
30e48d202b keep hivectl verb help concise: short about + terse long help (#2512) 2026-07-16 10:02:16 +02:00
damocles
f1812335d1 route gateway htpasswd management through a daemon wire command (#2504) 2026-07-15 23:23:47 +02:00
atlas
419c9659a3 feat(#2007): export per-agent container cpu/mem/disk via otel
hive-c0re already samples each agent container's cgroup load for the
dashboard (stats/container_stats.rs); this rides those gauges out to the
configured OTLP endpoint, reusing the existing services.hyperhive.otel
config (endpoint + auth header) — no new toggle.

- New stats/otel_metrics.rs: exports via the OpenTelemetry Rust SDK (same
  crates as hive-metric) with the semconv container.* metric names +
  container.name attribute so off-the-shelf OTel/Grafana dashboards work,
  plus the hive agent label. container.cpu.time (counter, s, from cumulative
  cpu.stat usage_usec), container.memory.usage, container.memory.usage.limit;
  memory peak / on-disk storage / instantaneous cpu percent stay hyperhive.*
  custom (no semconv equivalent). Observable instruments read a shared
  snapshot an async task refreshes (gather() is async; SDK callbacks sync).
- container_stats: expose cpu_time_usec (cumulative) on ContainerResource.
- The OTLP auth header is loaded onto hive-c0re's own unit via systemd
  LoadCredential and read from $CREDENTIALS_DIRECTORY/otel-headers.
- docs/observability.md documents the host-emitted semconv metrics.

Host-side export, so it covers containers even when their agent is idle.
2026-07-15 22:51:31 +02:00
damocles
c238ffe1ff docs(#2352): regenerate hivectl-cli.md for the new agents/approvals verbs 2026-07-15 22:41:39 +02:00
damocles
cc67a05974 refactor(#2352): extract standalone hivectl crate, hive-c0re daemon-only 2026-07-15 22:36:13 +02:00
damocles
6aa7c9613b fix(#2495): surface [PR merged] on merge notifications instead of [comment on PR] 2026-07-15 21:36:22 +02:00
damocles
12ce346d02 refactor(#2416): drop the now-always-none Spawned.sha field + deny tag leftover 2026-07-15 21:03:52 +02:00
damocles
c2bd7db998 refactor(#2416): remove the non-pr config-change flow (request_apply_commit / applycommit) 2026-07-15 21:03:52 +02:00
atlas
fbbd5d921c feat(#2485): remove vestigial Noop + StartupSweep residuals
Since the boot sweep (#2450) and meta-update cascade (#2476) became
single DAGs that grow subgraphs in-place, nothing constructs the old
fan-out anchors/parents anymore:

- NodeKind::Noop (the old boot_root grouping anchor) — no constructors.
- Template::StartupSweep / Source::StartupSweep (the old fan-out parent
  template + cascade-child source) — replaced by Template::Boot and
  Source::AutoUpdate/MetaUpdate respectively.

Drops the three variants + their as_str arms + the Noop executor arm, and
refreshes the stale fan-out/anchor doc comments (Boot/MetaUpdate/Source
docs, coordinator.md, dashboard.md). Frontend: the queue-kind glyph moves
from the dead startup_sweep to boot (which had none), and the dead
rqe-source-startup_sweep style is dropped.

No behaviour change — pure dead-variant removal.
2026-07-15 20:54:19 +02:00
iris
a73216e8be fix agent-logs unit dropdown mismatch, add other hive daemons
Dashboard AGENT log tab sent unit=hive-ag3nt.service (the crate/dir
name) but the actual systemd unit is hive-agent.service, so every
fetch 400'd against the backend allow-list. Fixed the dropdown value
and, per the same issue's request, added the other per-agent daemons
(hive-mcp-http, hive-bash-daemon, hive-matrix-daemon) as selectable
units, plus hive-priv.service on the SYSTEM tab's host-daemon list.
Extended both backend allow-lists (post_journal / post_journal_host)
to match, and fixed a stale systemd.services.hive-ag3nt doc reference
in agent-hierarchy.md that had the same crate/unit-name confusion.
2026-07-15 20:41:59 +02:00
atlas
edf9fd036e feat(#2453): remove DAG parent_id now that every op is one DAG
With the meta-update cascade (#2476) and startup sweep (#2450) folded
into single DAGs that grow per-agent subgraphs via append_subgraph,
nothing links parent/child DAGs anymore — parent_id is dead.

hive-c0re: drop parent_id from Dag/DagSpec (+ the DagView copy); delete
append_children and cancel_children (no callers); simplify trim_history
(no more terminal-parent-with-live-children guard — a one-big-DAG is
terminal only when its whole graph settles); drop the rebuild() parent_id
param; QueueDag returns just the polled DAG (no fan-out children to
gather). hive-sh4re: drop the DagView.parent_id wire field.

frontend: a multi-step op is one DAG now, so renderRebuildQueue drops the
childrenOf/orphans cross-DAG grouping and renders each entry flat; its
per-agent subgraphs render as nodes within the one row (split by deps).
Removed the dead rqe-child style + isChild plumbing.

Docs + the child-DAG queue tests updated/removed to match.
2026-07-15 19:50:04 +02:00
atlas
2b3130f63c feat(#2476): grow the meta-update cascade in-DAG instead of child DAGs
MetaLock's non-sweep completion now grows one rebuild subgraph per
affected agent into the same DAG (append_subgraph), replacing the
fan-out-child-DAGs + cancel_children dance. Drops NodeOutput.fanout and
scheduler's fanout_specs. meta_update DAG carries Rebuilding transient so
each cascade agent gets crash-watch suppression at Swap (the property the
old child Rebuild DAGs held via their own transient); MetaLock head needs
no lease so the pseudo-agent gets no pill.

append_children/parent_id and child-DAG tests are intentionally left for
the #2453 capstone.
2026-07-15 19:09:05 +02:00
atlas
860484a193 refactor(#2439): build hive-wide stop/start/restart DAGs dynamically
Hive-wide `stop` / `start` / `restart` emit ONE DAG with a per-agent
subgraph each (concurrent on their own leases) instead of N DAGs — and each
subgraph is now built dynamically from the agent's live running state rather
than a fixed template shape:

- online agent: the full stop→reconcile (restart: stop-for-update→reconcile)
  chain; `graceful` prepends signal→drain.
- offline agent: just `SetWanted → Reconcile` (nothing to quiesce/stop; a
  restart of a down agent is really a start).

The head `SetWanted` (intent) and tail `Reconcile` (convergence guarantee)
are always present; only the mechanical `Signal`/`Drain`/`StopForUpdate`
nodes are state-conditional. Keeping `Reconcile` in every shape closes the
TOCTOU window — a race-up between the `is_running` read and node exec is
still converged in-DAG (with `StopForUpdate`-noop as the backstop) — with no
reliance on an external reconcile sweep.

The state-aware assembly needs an async `is_running` read, so it moves out
of the pure/sync `templates.rs` into `submit.rs`, layered as pure
`*_chain(running)` → pure `*_spec(targets)` (the unit-test seam) → async
`*_many` (reads live state + submits). `templates.rs` keeps only the shared
pure primitives (`node`/`after_ok`/`rebuild_nodes`).

Callers await the now-async submit fns (server, dashboard, socket_server).
Tests exercise both the online and offline shapes via the pure `*_spec`
seam. docs/coordinator.md shapes updated.
2026-07-15 00:29:54 +02:00
atlas
c8bd0f7180 test+docs(#2448): multi-agent restart test + doc shapes
- multi_agent_restart_is_one_dag_with_concurrent_per_agent_subgraphs:
  two agents restart in one DAG; both SetWanted heads are roots, each
  acquiring its own agent's lease concurrently. Existing single-agent
  shape/lease tests updated for the templates::restart(&[..], graceful)
  signature.
- coordinator.md + templates.rs module doc: restart takes an agent list;
  a hive-wide restart is one DAG with N per-agent subgraphs.
2026-07-14 23:11:02 +02:00
atlas
9a39a54820 refactor(#2449): dashboard + docs for the SetWanted node
- builds.js NODE_KIND_LABEL: 'set wanted' (and the previously-missing
  'noop') so the new head node renders with a label, not the raw kind.
- docs/coordinator.md + templates.rs module doc: the power-op DAG shapes
  now show the head SetWanted node; SetWanted added to the lease-needing
  list with the atomicity rationale.
2026-07-14 22:34:44 +02:00
atlas
e2b48d2014 refactor(#2441): update queue consumers + docs for agent-per-node
DagView no longer has a DAG-level agent, so consumers derive it from the
per-node agents:
- hivectl dag_progress.rs: dag_agents(d) helper (distinct node agents,
  comma-joined) in place of d.agent.
- dashboard builds.js: entryAgents(entry) helper likewise for the
  rebuild-queue card + live-log header + cancel confirms.
- docs/coordinator.md: lease prose (node-agent-keyed, global per agent),
  wire shape (NodeView.agent, no DagView.agent), and dropped the removed
  dedup section.
2026-07-14 21:58:40 +02:00
atlas
901ab6a779 fix(#2398): graceful restart as one atomic DAG, not compose-and-await
mara's review on #2436: no submit-await-submit composition, even
server-side. Adds Template::GracefulRestart (Signal -> Drain ->
StopForUpdate -> Reconcile, wanted=Up) mirroring how Restart already
does StopForUpdate -> Reconcile, plus submit::graceful_restart and
templates::graceful_restart. handle_restart_scoped now submits exactly
one DAG per agent up front for both the graceful and non-graceful
case -- no await_dags in the loop anymore.
2026-07-14 20:38:10 +02:00
atlas
60a253a2f6 fix(#1763): address argus review on PR #2430
- regenerate docs/tools/hivectl-cli.md for the new `subvol snapshot send` verb
- close the TOCTOU on the no-overwrite guard: File::options().create_new(true)
  (O_CREAT|O_EXCL) instead of exists()-then-create, so the guarantee is
  atomic against a concurrent request racing the same dest filename
- warn (not silently swallow) if cleaning up a partial export after a
  failed btrfs send itself fails, so a stuck garbage file masquerading
  as a completed export is visible in the log
2026-07-14 19:23:59 +02:00
atlas
8f8076b8ed fix(#2391): mandatory hive- prefixed snapshot label, nest subvol snapshot create/delete
Per mara's PR review:
- snapshot label is now mandatory (was optional w/ timestamp default)
  and must start with "hive-" — hive-priv enforces this as an
  allow-list on top of the existing credential-name charset check, so
  only hivectl-issued labels can reach the btrfs shellout.
- nest under `subvol snapshot create`/`subvol snapshot delete`
  instead of othering delete as a separate top-level `delete-snapshot`
  verb.

Per argus's review:
- regenerate docs/tools/hivectl-cli.md (hivectl markdown-docs) to
  include the new subcommands — CI's hivectl-docs-fresh check compares
  this file against generated output.
2026-07-14 18:54:31 +02:00
iris
dbf880ac66 extra-forges: fully dashboard-provisioned, no host config
Per mara's feedback on PR #2407 ("better: you can also provide url in
dashboard, same as with matrix, no host config"), drops
services.hyperhive.extraForges and the admin-API mint/revoke flow
entirely. The operator now creates a token on the external forge
themselves and pastes a label + base URL + access token into the
dashboard's FORGES tab, the same shape as the GitHub PAT flow plus the
base-URL field from the matrix extra-account flow. hive-c0re only ever
writes/deletes two local files per account (forge-<label>-token,
forge-<label>.json sidecar for the URL) via hive-priv — no remote
account creation, no admin token, no revoke-on-the-remote-side, no nix
config to enumerate.

- nix/host-modules/hive-forge/default.nix: removed the extraForges
  option, its label-format assertion, and the HYPERHIVE_EXTRA_FORGES
  env forwarding.
- hive-c0re/src/forge/extra.rs: deleted (REST admin-API provisioning,
  no longer needed).
- hive-c0re/src/dashboard/extra_forges.rs: GET /api/extra-forges?
  agent= lists an agent's stored forges by scanning its state dir
  (mirrors matrix_accounts.rs's filename-scan listing), POST
  /api/extra-forge-account (agent/label/base_url/token/
  action=add|remove) stores or removes an account.
- hive-sh4re/priv_proto.rs + hive-priv/main.rs: new
  WriteAgentExtraForgeAccount/DeleteAgentExtraForgeAccount priv
  requests (adds base_url, writes/deletes a JSON sidecar alongside the
  token).
- hive-c0re/src/priv_client.rs: matching wrapper functions.
- frontend/packages/dashboard/src/credentials.{html,js}: FORGES tab is
  a per-agent list + add-account paste form (label/base_url/token), no
  grant/revoke-from-catalog UI.
- docs/web-ui/dashboard.md: FORGES tab section rewritten.

Supersedes the design in PR #2407 (already approved+green on the old
admin-API model) — opening as a fresh PR against the same issues
rather than force-pushing over the approved one.
2026-07-14 18:38:55 +02:00
müde
0d416df1e8 fix: shared-netns infra containers must not run their own firewall 2026-07-14 00:08:33 +02:00
müde
d97659c06a docs: add the network topology map to network.md 2026-07-13 23:58:54 +02:00
müde
eba3f206ab docs: reflect the new nix layout and removed options 2026-07-13 22:23:20 +02:00
müde
935e967718 feat: hive DNS always follows the host resolver 2026-07-13 22:09:53 +02:00
müde
4a48ce5024 refactor: nix/host-modules + nix/agent-modules layout, update doc paths 2026-07-13 22:05:49 +02:00