docs(persistence): dedupe destroy/purge + agent_power against other sections, trim historical framing
This commit is contained in:
parent
79a02f6859
commit
c14d932687
1 changed files with 43 additions and 47 deletions
|
|
@ -79,16 +79,13 @@ header/targets split, and the per-agent power-intent registry:
|
|||
`scheduled_prompts(id)` — requires `PRAGMA foreign_keys = ON`
|
||||
per connection (set at open).
|
||||
- `agent_power` — one tiny row per agent: `agent PK / wanted (up |
|
||||
offline) / updated_at` — the durable power *intent* behind the job
|
||||
queue's desired-state reconciliation
|
||||
(`docs/coordinator.md::Job queue`; owner: `hive-c0re/src/stores/power.rs`).
|
||||
Written synchronously by every operator/agent power action
|
||||
(dashboard start/stop, `hivectl stop`, the MCP kill/start tools,
|
||||
spawn approval); read by `Reconcile` nodes and the boot reconcile.
|
||||
Intent survives hive-c0re restarts — in-flight queue work
|
||||
deliberately does not. Agents without a row are seeded from
|
||||
observed state on first touch (running ⇒ `up`); destroy deletes
|
||||
the row.
|
||||
offline) / updated_at`, owned by `hive-c0re/src/stores/power.rs`.
|
||||
This is the durable power *intent* the job queue reconciles the
|
||||
observed container state against; intent survives hive-c0re
|
||||
restarts even though in-flight queue work doesn't. See
|
||||
[`docs/coordinator.md`'s Desired-state
|
||||
section](coordinator.md#desired-state-spec-vs-status) for who
|
||||
writes and reads it and how reconciliation works.
|
||||
|
||||
Retention:
|
||||
|
||||
|
|
@ -190,12 +187,10 @@ Shape:
|
|||
The turn loop is the only writer today, but it still goes
|
||||
read-modify-write under a shared in-process lock and merges into the
|
||||
existing object rather than reconstructing it — so a second writer
|
||||
preserves fields it doesn't own, and the lock closes the lost-update
|
||||
window between a writer's read and its rename. (The forge notification
|
||||
poller used to be that second writer, for a delivery-dedupe cursor. It
|
||||
persists nothing now — forge's own read-state is the durable record of
|
||||
what has been delivered — and it is a separate process, which an
|
||||
in-process lock could not have serialised anyway.)
|
||||
would preserve fields it doesn't own, and the lock closes the
|
||||
lost-update window between a writer's read and its rename. The lock
|
||||
is in-process only, so it wouldn't serialise a writer running as a
|
||||
separate process; none of today's writers are.
|
||||
|
||||
hive-c0re reads this file on each `build_all` sweep (~10s) via
|
||||
`container_view::read_harness_flags`. Falls back to the legacy individual
|
||||
|
|
@ -209,11 +204,12 @@ Full stdout + stderr capture for every `nixos-container` / `nix
|
|||
build` invocation the lifecycle layer fires. One row per invocation;
|
||||
the row accumulates lines as the child runs.
|
||||
|
||||
Replaces the legacy 32-line stderr ring buffer that `lifecycle::run`
|
||||
kept. The ring tail routinely truncated real eval errors ("tried
|
||||
alternatives" blocks alone are often 30+ lines), so failures bailed
|
||||
with an arbitrary tail whose full stream only lived in the host
|
||||
journal. With this table the dashboard can surface the entire log.
|
||||
Capturing the full stream (rather than a short tail buffer) matters
|
||||
because real eval errors routinely run long — "tried alternatives"
|
||||
blocks alone are often 30+ lines — so a truncated tail would cut off
|
||||
the actual failure and leave only the host journal holding the
|
||||
complete output. With this table the dashboard can surface the entire
|
||||
log.
|
||||
|
||||
Two indices:
|
||||
- `(agent, started_at)` — backs the per-agent latest-N lookup used
|
||||
|
|
@ -323,11 +319,9 @@ notes, clearing a stuck sentinel) as well as reading it.
|
|||
|
||||
**`harness` is not mounted at all.** It holds the child's own runtime
|
||||
material — `bash-tasks/`, the turn-stats and event sqlite dbs — and
|
||||
nothing argues for a parent reading it, let alone writing it. It used to
|
||||
be mounted RW for "the same management reasons" as `state`, which was
|
||||
never an argument so much as the side-effect of one loop treating all
|
||||
three dirs alike. hive-c0re reads a child's harness dir **directly on the
|
||||
host** when it wants those stats, which needs no mount into the parent.
|
||||
nothing argues for a parent reading it, let alone writing it. hive-c0re
|
||||
reads a child's harness dir **directly on the host** when it wants
|
||||
those stats, which needs no mount into the parent.
|
||||
|
||||
**`config` is read-only, including for the parent.** A config change is
|
||||
a PR on the child's config repo, made from a clone and merged after
|
||||
|
|
@ -339,8 +333,9 @@ boundary a convention rather than a permission.
|
|||
⚠️ Not to be confused with the seeding done when an `InitConfig`
|
||||
approval resolves: that writes the child's initial config repo as
|
||||
**hive-c0re, against the host path**, and `read_only` on a bind
|
||||
constrains writers *inside* a container only. The two are unrelated, and
|
||||
reading them as the same thing is what kept this mount writable.
|
||||
constrains writers *inside* a container only. The two are unrelated —
|
||||
conflating them is an easy way to reason your way into thinking this
|
||||
mount should be writable when it shouldn't.
|
||||
|
||||
Per-child isolation still holds: a container only ever has its *own*
|
||||
dirs plus its direct children's bind-mounted, never a sibling's.
|
||||
|
|
@ -396,25 +391,21 @@ deleted.
|
|||
|
||||
## Destroy vs purge
|
||||
|
||||
- `DESTR0Y` (default) — stops + removes the nspawn container,
|
||||
drops the systemd drop-in, fails any pending approvals. State
|
||||
dirs stay put; the agent appears in the dashboard's K3PT ST4T3
|
||||
section as a tombstone with `⊕ R3V1V3` and `PURG3` actions.
|
||||
`R3V1V3` queues a Spawn approval that reuses the kept state on
|
||||
approve (no re-login).
|
||||
- `PURG3` (opt-in via the dashboard button or
|
||||
`hivectl agent <name> destroy --purge`) — DESTR0Y plus wipes
|
||||
`/var/lib/hyperhive/{agents,applied}/<name>/`. Config history,
|
||||
claude creds, /state/ notes, and the harness dir are all gone.
|
||||
No undo.
|
||||
See [For operators](#for-operators) above for what each action does to
|
||||
an agent's state. The mechanics, for completeness:
|
||||
|
||||
The root/bootstrap container is **imperative** infrastructure — managed
|
||||
end-to-end by hive-c0re, not declared in the host's NixOS config.
|
||||
`auto_update::ensure_root_agent` recreates it on the next hive-c0re
|
||||
startup if it's absent (bypassing the approval queue, as required
|
||||
infrastructure). A soft policy guard in `actions::destroy` currently
|
||||
refuses to destroy it; even without that guard, destroying it would only
|
||||
be transient — hive-c0re brings it back on the next startup.
|
||||
- `DESTR0Y` also drops the systemd drop-in and fails any pending
|
||||
approvals; the tombstone's `⊕ R3V1V3` button queues a Spawn approval
|
||||
that reuses the kept state on approve.
|
||||
- `PURG3` wipes `/var/lib/hyperhive/{agents,applied}/<name>/` — the
|
||||
union of everything `DESTR0Y` left behind.
|
||||
|
||||
The root/bootstrap agent's specialness is implemented as a soft policy
|
||||
guard in `actions::destroy` that refuses to destroy it, backstopped by
|
||||
`auto_update::ensure_root_agent`, which recreates it on the next
|
||||
hive-c0re startup if it's ever absent (bypassing the approval queue,
|
||||
as required infrastructure) — so even without the guard, destroying it
|
||||
would only be transient.
|
||||
|
||||
### btrfs subvolumes for `/var/lib/hyperhive/agents/<name>`
|
||||
|
||||
|
|
@ -443,6 +434,11 @@ until an explicit opt-in upgrade.
|
|||
Per-subvolume disk-usage accounting and optional quotas are a
|
||||
follow-up (the qgroup work), not part of the base migration.
|
||||
|
||||
This is the same subvolume `hivectl agent <name> subvol snapshot push`
|
||||
sends to the swarm's snapshot store — see
|
||||
[`docs/snapshot-store.md`](snapshot-store.md) for what a pushed
|
||||
snapshot contains and how the store authenticates a sender.
|
||||
|
||||
## Run-time dirs
|
||||
|
||||
`/run/hyperhive/` is tmpfs-backed (systemd `RuntimeDirectory=`) but
|
||||
|
|
|
|||
Loading…
Reference in a new issue