| Filename | Latest commit message | Latest commit date |
|---|---|---|
Splits what was one `Cancelled` outcome into two, because they were two
different facts wearing one name:
- `Skipped` — the node's own edges ruled it out. Expected; the failure
branch of a run that succeeded is `Skipped`. A parent's roll-up
**ignores** it.
- `Cancelled` — the work was dropped before it could start. Still
not-success for the roll-up, as before.
Without that split, branching on outcome defeats itself: exactly one
branch is always ruled out, `any_child_failed` counted it, and every DAG
containing a branch would have rolled up failed no matter how the run
went. Caught in review before it was written, not after.
`AFTER_ANY` becomes `{Done, Failed, Skipped}` — "anything except the work
being dropped". That is what it always meant; it only swept in
cancellation because cancellation wasn't distinguishable from
elimination. Audited every user rather than assuming, which is how the
one regression in my own proposal surfaced: `{Done, Failed}` would have
refused to run rebuild's recovery `Reconcile` after a failed `MetaSync`
(that eliminates `Prebuild`, so the tail's dep is `Skipped`, not
`Failed`) and left the container down.
With that, the templates stop computing outcomes and let the graph pick:
- `ResolveApproval { approval_id, outcome }` — one tail per outcome, each
edged to accept only its own, so exactly one is ever runnable.
- `EmitRebuilt { agent, ok }` — a pair. `ok` is not derived, it is which
of the two the graph let run.
Edges are conjunctive, so "any of these roots failed" is not directly
sayable. The composition: the success branch is `AFTER_OK` on every root
(so it is itself eliminated the moment one doesn't succeed), and the
failure branch keys off *that* elimination. The failure branch also
waits on every root — without it, a failed `Prebuild` eliminates the
success branch immediately and the failure would be announced while the
recovery `Reconcile` was still running. The tests caught that one.
Deletes, all of them #2770's host-side debt:
- `Claim.deps`, `DepOutcome`, `Claim::deps_state`, `Claim::deps_error`
and the dep-snapshotting loop in `claim_ready`. Executors read their
own variant now; nothing inspects anything.
- `NodeKind::is_tail()` and the `cancel` exemption built on it. Sparing
is derived from the edges: `cancel` keeps a node iff one of its edges
accepts `Cancelled`. An approval tail names it and survives to resolve
the row; `Reconcile` doesn't and is cancelled with the rest. My earlier
claim that this couldn't dissolve was only true while `AFTER_ANY`
accepted cancellation.
`resolve_approval_dag` / `deploy_terminal_tag` now take `TerminalState`
rather than the wire `State`, so both matches are exhaustive instead of
ending in a catch-all.
Skipped nodes are filtered off the wire alongside `Done` ones. That costs
some dashboard detail on a failed rebuild — which steps were skipped —
and the tests say so with a pointer to the follow-up. Surfacing them as
`Cancelled` instead would be worse: the client roll-up ranks `Cancelled`
above `Running`, so a successful DAG with a not-taken branch would read
as cancelled.
|
||
| .. | ||
| src | ||
| Cargo.toml | ||
| README.md | ||
hive-c0re
The unprivileged host daemon (runs as hive-core). Owns the sqlite
broker, the approval/question/schedule queues, the generic job-DAG
queue, container lifecycle, gateway/forge/matrix provisioning,
per-container stats, and the axum operator dashboard. Largest crate in
the workspace — bin-only, no separate lib.
When to use it
Host-level, cross-container orchestration: spawning/rebuilding/
destroying agent containers, the approval flow, dashboard-visible
state, provisioning per-agent forge/matrix/gateway accounts. Agent-side
behavior (turn loop, MCP tools) lives in hive-agent/hive-agent-mcp
instead — this daemon only talks to agents over the socket wire types
in hive-sh4re.
Shape
Cohesive clusters live in directory submodules, each re-exported at
the crate root (crate::broker::… keeps resolving regardless of which
subdirectory a module actually lives in). One line each — read the
module's own //! doc-comment for real detail, don't expect this file
to track it:
dashboard/— the operator dashboard (containers, approvals, schedules, questions, logs, topology).job_queue/— the job-DAG queue + desired-state reconciliation (docs/coordinator.md).lifecycle/—nixos-containerlifecycle + per-agent config flake generation.stores/— sqlite-backed stores (broker, queues, audit, power).workers/— background sweeps (crash watch, scheduled prompts, auto-update, knowledge sync).agent_config/— per-agent registries (tool groups, capabilities, resource limits, topology).stats/— dashboard metrics aggregation + OTEL export.socket_server/— the unix-socket request server shared by per-agent + manager sockets.forge/— optional Forgejo wiring (docs/forge.md).coordinator.rs— top-level wiring forserve.meta.rs,migrate.rs— the meta flake + schema/state migrations.matrix.rs,gateway_nginx.rs,webhook_secret.rs,priv_client.rs— matrix provisioning, gateway vhosts, webhook secrets, and thehive-privclient respectively.
See the top-level CLAUDE.md/docs/ index for the full reading-path
map.