diff --git a/docs/persistence.md b/docs/persistence.md index 03bf8982..e7cca484 100644 --- a/docs/persistence.md +++ b/docs/persistence.md @@ -32,8 +32,8 @@ header/targets split: Q&A (`HelperEvent::QuestionAsked` pushed into target's inbox, answered via `Answer` request). Migrated via `ALTER TABLE ADD COLUMN` against `pragma_table_info`. -- `scheduled_prompts` — recurring + one-shot prompt queue - (closes #444). `owner / body / interval_seconds (NULL = one-shot) / +- `scheduled_prompts` — recurring + one-shot prompt queue. + `owner / body / interval_seconds (NULL = one-shot) / next_fire_at_unix / created_at_unix / source ("operator" or "approval:") / cancelled_at_unix / description`. `owner` drives cancel-permission checks (operator vs the submitting @@ -101,9 +101,8 @@ Bin-loop helpers `build_row` + `record` land each row at `turn_end`; writes are best-effort, a sqlite hiccup logs + lets the turn loop continue. -No host-side vacuum yet — tracked as forge issue -[#10](http://localhost:3000/hyperhive/hyperhive/issues/10) -(target retention ~90 days, age-only sweep like events_vacuum). +No host-side vacuum yet — tracked separately. Target retention +~90 days, age-only sweep like events_vacuum. ### `/state/hyperhive-rate-limited` (per agent) @@ -136,13 +135,12 @@ Under `/var/lib/hyperhive/agents//`: precise changes from the manager; RW into the manager via the `/agents` tree bind. - `claude/` — claude OAuth credentials, bind-mounted RW to - `/home//.claude` inside the container (post-#658 — was - `/root/.claude` pre-#658 when every harness ran as root). + `/home//.claude` inside the container. - `state/` — durable notes, the events.sqlite db, and the turn-stats sqlite db. Bind-mounted to `/agents//state` - inside the container (uniform for sub-agents + manager - post-#604). The `$HYPERHIVE_STATE_DIR` env var exposes the - same path to in-container scripts. + inside the container (uniform for sub-agents + manager). + The `$HYPERHIVE_STATE_DIR` env var exposes the same path to + in-container scripts. Under `/var/lib/hyperhive/applied//` — the hive-c0re-only applied repo. Tracks `flake.nix` (module-only boilerplate; never @@ -199,13 +197,13 @@ task before rebinding — idempotent so a hive-c0re restart followed by `rebuild alice` recreates the agent's socket without a clean reinstall. -## First-boot agent-user migration (post-#658) +## First-boot agent-user migration -Pre-#658 the harness ran as root inside the container. #658 dropped -to a per-agent unix user (`hyperhive.user.name`, defaults to the -agent's logical label so each container has a uniquely-named user). -The transition needs a one-time data shuffle so existing operators -who deployed pre-#658 don't lose their claude session. +The harness runs as a per-agent unix user inside the container +(`hyperhive.user.name`, defaults to the agent's logical label so each +container has a uniquely-named user). Operators with legacy root-owned +state dirs need a one-time data shuffle so they don't lose their claude +session. `system.activationScripts.hive-agent-user-migrate` (in `nix/templates/harness-base.nix`) runs on every activation, @@ -217,25 +215,25 @@ container lifetime: chance to chown. Also re-applies on every rebuild in case the meta-flake's per-agent name evolves (rare). 2. **Migrate any leftover `/root/.claude` content into - `${homeDir}/.claude`** — pre-#658 `claude` wrote to root's + `${homeDir}/.claude`** — legacy `claude` wrote to root's empty home; the bind mount didn't exist yet. Marker (`/var/lib/hive-agent-user-migrated`) guards single-shot. `cp -an` (no-clobber) so any pre-existing files at the new location win — never blow over data already there. 3. **Chown the bind-mounted state dir** (`/agents/*/state`) - recursively so the new agent user can read/write it. Wildcard + recursively so the agent user can read/write it. Wildcard matches the single agent that container sees; `-h` skips symlinks the agent might have planted. -4. **Chown the `~/.claude/` bind-mount** recursively. Pre-#658 - `claude` wrote `.credentials.json` 0600 root:root; post-#658 - the harness reads `~/.claude/` as the agent user to decide +4. **Chown the `~/.claude/` bind-mount** recursively. Legacy + `claude` wrote `.credentials.json` 0600 root:root; the + current harness reads `~/.claude/` as the agent user to decide Online vs NeedsLogin in `login::has_session`. Without the chown the existing credentials get silently treated as "no session" and the operator re-prompts every boot. The activation script will eventually become unnecessary once no -operators have pre-#658 state dirs left to migrate; drop the body -+ marker check at that point. +operators have legacy root-owned state dirs left to migrate; drop +the body + marker check at that point. ## Matrix per-agent daemon + token-arrival trigger @@ -260,4 +258,4 @@ first time it ran and the MCP would have no backend until the next restart. The `.path` unit makes the appearance of the token re-fire the service so the daemon comes alive in the same boot cycle as provisioning. `matrix-avatar-sync.path` uses the same pattern for -the icon-upload oneshot (#571). +the icon-upload oneshot.