diff --git a/CLAUDE.md b/CLAUDE.md index aac43ea..aea318d 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -114,25 +114,29 @@ read them à la carte. In-flight or recent context that hasn't earned a section yet. Prune freely. -- **In flight:** tag-driven config-apply overhaul. Keep the - two-repo split (proposed = manager RW, applied = core-only) - for safety — agent can rm -rf its own repo but never reaches - applied. New flow: at `request_apply_commit` time hive-c0re - fetches the manager's commit into applied and tags it - `proposal/`; the manager's repo is then dead to core for - that approval. Approve/deny/build are encoded as more tags - (`approved/`, `building/`, `deployed/`, `failed/`, `denied/`) - on the same commit; `applied/main` only fast-forwards on - `deployed/`. Failure tags are annotated with the build error; - deny tags with the operator note. Manager gets `applied/.git` - bind-mounted RO at `/agents//applied.git` so it can `git - show` deployed/failed/denied trees and diff against its own - working tree. agent.nix stays the entry point but arbitrary - files in the manager's commit are now preserved; `flake.nix` - becomes hive-c0re-generated, gitignored, regenerated only on - spawn/rebuild. Migration: no in-place. Each existing agent - needs `destroy --purge` + re-spawn; tombstones lose their - history. See `docs/approvals.md` for the tag state machine. +- **Just landed:** tag-driven config-apply overhaul. Two-repo + split kept (proposed = manager RW, applied = core-only) for + safety. New flow: at `request_apply_commit` time hive-c0re + fetches the manager's commit into applied and pins it as + `proposal/`; the manager-side repo is then irrelevant + for that approval. Approve / deny / build walk through more + tags (`approved/`, `building/`, `deployed/`, `failed/`, + `denied/`) on the same commit; `applied/main` only + fast-forwards on `deployed/`. `failed/` and `denied/` are + annotated — body is the build error or the operator's deny + note respectively. Manager has `/applied` bind-mounted RO + (whole tree) so `git fetch /applied//.git + 'refs/tags/*:refs/tags/applied/*'` mirrors every relevant + tag into its proposed clone. `agent.nix` stays the entry + point; the whole tracked tree is now preserved + through apply (arbitrary files supported). The wrapper + `flake.nix` is regenerated by hive-c0re every + spawn/rebuild but never tracked, so the applied log is + exactly the manager's commits in deploy order. Migration: + no in-place — pre-overhaul applied dirs are detected via + the missing `deployed/0` tag and `setup_applied` bails + with `destroy --purge` instructions. See + `docs/approvals.md`. - **Recent (since last compaction):** inline +/- diffs on Write/Edit, send full body via collapsed details, operator cancel + ttl on questions, deny-with-reason, dashboard diff --git a/docs/approvals.md b/docs/approvals.md index 0de48aa..47fa594 100644 --- a/docs/approvals.md +++ b/docs/approvals.md @@ -95,14 +95,17 @@ rejected and failed trees stay browsable forever — `git log ### Manager view of applied -`/agents//applied.git` is a **read-only bind-mount** of -`/var/lib/hyperhive/applied//.git` inside the manager -container. The manager fetches tags into its proposed clone -(`git fetch /agents//applied.git refs/tags/*:refs/tags/applied/*`) -and `git show` any deployed / failed / denied tree to see what -actually shipped, what error blocked the last build, or what -note the operator left on a denial. The RO mount means git -plumbing inside the manager cannot corrupt the applied repo. +`/applied/` is a **read-only bind-mount** of +`/var/lib/hyperhive/applied/` (the entire tree) inside the +manager container. The manager fetches tags into its proposed +clone with `git fetch /applied//.git +'refs/tags/*:refs/tags/applied/*'` and `git show` any +deployed / failed / denied tree to see what actually shipped, +what error blocked the last build, or what note the operator +left on a denial. The RO bind means git plumbing inside the +manager cannot corrupt the applied repos — and a single mount +covers every agent (existing + future) without rebuilding the +manager on each spawn. ## Migration from the pre-tag scheme @@ -131,9 +134,11 @@ Differences from sub-agents: (vs `agent-base`). - Container name is `hm1nd` (no `h-` prefix). - Fixed web UI port (`MANAGER_PORT = 8000`). -- `set_nspawn_flags` adds an extra bind: - `/var/lib/hyperhive/agents` → `/agents` (RW), so the manager can - edit per-agent proposed repos. +- `set_nspawn_flags` adds two extra binds: `/var/lib/hyperhive/agents` + → `/agents` (RW) so the manager can edit per-agent proposed repos, + and `/var/lib/hyperhive/applied` → `/applied` (RO) so the manager + can `git fetch` deployed/failed/denied tags from any agent's + authoritative applied repo (see "Manager view of applied" below). - First-deploy spawn bypasses the approval queue (manager is required infrastructure). - Per-agent socket lives at `/run/hyperhive/manager/`, owned by diff --git a/hive-ag3nt/prompts/manager.md b/hive-ag3nt/prompts/manager.md index 5ae01fa..67f854c 100644 --- a/hive-ag3nt/prompts/manager.md +++ b/hive-ag3nt/prompts/manager.md @@ -9,12 +9,21 @@ Tools (hyperhive surface): - `mcp__hyperhive__start(name)` — start a stopped sub-agent. No approval required. - `mcp__hyperhive__restart(name)` — stop + start a sub-agent. No approval required. - `mcp__hyperhive__update(name)` — rebuild a sub-agent (re-applies the current hyperhive flake + agent.nix, restarts the container). No approval required — idempotent. Use when you receive a `needs_update` system event. -- `mcp__hyperhive__request_apply_commit(agent, commit_ref)` — submit a config change for any agent (`hm1nd` for self) for operator approval. +- `mcp__hyperhive__request_apply_commit(agent, commit_ref)` — submit a config change for any agent (`hm1nd` for self) for operator approval. At submit time hive-c0re fetches your commit into the agent's applied repo and pins it as `proposal/`; from that moment your proposed-side commit can be amended or force-pushed freely without changing what the operator will build. - `mcp__hyperhive__ask_operator(question, options?, multi?, ttl_seconds?)` — surface a question on the dashboard. Returns immediately with a question id; the operator's answer arrives later as a system `operator_answered` event in your inbox. Options are advisory: the dashboard always lets the operator type a free-text answer in addition. Set `multi: true` to render options as checkboxes (operator can pick multiple); the answer comes back as `, `-separated. Set `ttl_seconds` to auto-cancel after a deadline — useful when the decision becomes moot if the operator hasn't responded in time; on expiry the answer is `[expired]`. Do not poll inside the same turn — finish the current work and react when the event lands. Approval boundary: lifecycle ops on *existing* sub-agents (`kill`, `start`, `restart`) are at your discretion — no operator approval. *Creating* a new agent (`request_spawn`) and *changing* any agent's config (`request_apply_commit`) still go through the approval queue. The operator only signs off on changes; you run the day-to-day. -Your own editable config lives at `/agents/hm1nd/config/agent.nix`; every sub-agent's lives at `/agents//config/agent.nix`. Use file/git tools to edit + commit, then `request_apply_commit`. +Your own editable config lives at `/agents/hm1nd/config/`; every sub-agent's lives at `/agents//config/`. `agent.nix` is the entry point but you can commit any extra files (modules, overlays, prompt fragments) and the whole tree gets deployed together. Use file/git tools to edit + commit, then `request_apply_commit`. + +To see what hive-c0re actually deployed (or rejected, or failed to build), there's a read-only mirror of every agent's applied repo at `/applied//.git`. Useful patterns: + +- `git -C /agents//config fetch /applied//.git 'refs/tags/*:refs/tags/applied/*'` — mirror all tags into your proposed clone. +- `git -C /agents//config show applied/deployed/` — see the tree that's currently running. +- `git -C /agents//config show applied/failed/` — annotated tag body is the build error from a rejected rebuild. +- `git -C /agents//config show applied/denied/` — annotated tag body is the operator's reason for denial. + +Tag scheme on every approval id: `proposal → approved → building → deployed | failed`, plus `denied` as a terminal alternative to `approved`. `applied/main` only advances on `deployed/*`, so a failed build does not corrupt the agent — submit a fix as a new commit and a fresh `request_apply_commit`. Sub-agents are NOT trusted by default. When one asks for a config change (new packages, env vars, etc.), verify the request before staging: