Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
42a7d2eb0a | ||
|
|
601ac647b5 | ||
|
|
5265af9589 | ||
|
|
f3e4f10dea | ||
|
|
494a326029 | ||
|
|
73bf7bef95 | ||
|
|
1433931904 | ||
|
|
6865b63016 |
4 changed files with 59 additions and 19 deletions
21
CLAUDE.md
21
CLAUDE.md
|
|
@ -81,7 +81,7 @@ hive-c0re/ host daemon + sibling operator CLI (lib + 2 bins)
|
||||||
fans out one Message per active target,
|
fans out one Message per active target,
|
||||||
re-arms recurring rows, deletes fired one-shots
|
re-arms recurring rows, deletes fired one-shots
|
||||||
src/events_vacuum.rs host-side hourly sweep of every agent's
|
src/events_vacuum.rs host-side hourly sweep of every agent's
|
||||||
/state/hyperhive-events.sqlite
|
/harness/hyperhive-events.sqlite
|
||||||
src/crash_watch.rs poll every 10s; fire HelperEvent::ContainerCrash
|
src/crash_watch.rs poll every 10s; fire HelperEvent::ContainerCrash
|
||||||
when a previously-running container disappears
|
when a previously-running container disappears
|
||||||
without an operator-initiated transient (or a
|
without an operator-initiated transient (or a
|
||||||
|
|
@ -130,6 +130,17 @@ hive-c0re/ host daemon + sibling operator CLI (lib + 2 bins)
|
||||||
read). Reconciled by `meta::sync_agents`;
|
read). Reconciled by `meta::sync_agents`;
|
||||||
operator/manager edits land via the
|
operator/manager edits land via the
|
||||||
eventual write API.
|
eventual write API.
|
||||||
|
src/tool_groups.rs per-agent tool-group config — reads/writes
|
||||||
|
`/var/lib/hyperhive/meta/tool-groups.json`;
|
||||||
|
`set_groups` + `groups_for` + `remove_agent`.
|
||||||
|
Wired into `render_flake` for `HIVE_TOOL_GROUPS`
|
||||||
|
injection; operator write via dashboard action.
|
||||||
|
src/limits.rs wire-protocol size limits (inline body cap,
|
||||||
|
reminder spill threshold) shared across agent
|
||||||
|
+ manager sockets. Single source of truth.
|
||||||
|
src/flake_check.rs pre-apply `flake.lock` validation — rejects
|
||||||
|
proposals missing `inputs.<X>.follows` wiring
|
||||||
|
(duplicate `original` node check).
|
||||||
src/forge.rs optional Forgejo wiring: per-agent users +
|
src/forge.rs optional Forgejo wiring: per-agent users +
|
||||||
tokens, the `agent-configs` org (`push_config`),
|
tokens, the `agent-configs` org (`push_config`),
|
||||||
and meta read access; mirrors each applied repo
|
and meta read access; mirrors each applied repo
|
||||||
|
|
@ -177,14 +188,14 @@ hive-ag3nt/ in-container harness crate; produces ONE `hive`
|
||||||
/api/compact, /api/model, /events/history,
|
/api/compact, /api/model, /events/history,
|
||||||
/screen, /screen/ws)
|
/screen, /screen/ws)
|
||||||
src/turn_stats.rs per-turn analytics sink (one sqlite row per
|
src/turn_stats.rs per-turn analytics sink (one sqlite row per
|
||||||
turn at /state/hyperhive-turn-stats.sqlite);
|
turn at /harness/hyperhive-turn-stats.sqlite);
|
||||||
schema + best-effort writer
|
schema + best-effort writer
|
||||||
src/stats.rs read-side aggregations over turn-stats.sqlite
|
src/stats.rs read-side aggregations over turn-stats.sqlite
|
||||||
backing the /stats page (bucketed Snapshot:
|
backing the /stats page (bucketed Snapshot:
|
||||||
turns / duration / tokens / model mix)
|
turns / duration / tokens / model mix)
|
||||||
src/events.rs LiveEvent + broadcast Bus + sqlite-backed history
|
src/events.rs LiveEvent + broadcast Bus + sqlite-backed history
|
||||||
(/state/hyperhive-events.sqlite) + TurnState +
|
(/harness/hyperhive-events.sqlite) + TurnState +
|
||||||
model selection (persisted at /state/hyperhive-model)
|
model selection (persisted at /harness/hyperhive-model)
|
||||||
src/turn.rs claude --print + stream-json pump; --compact retry;
|
src/turn.rs claude --print + stream-json pump; --compact retry;
|
||||||
proactive compaction + auto session-reset
|
proactive compaction + auto session-reset
|
||||||
src/mcp.rs embedded MCP server (rmcp): AgentServer + ManagerServer
|
src/mcp.rs embedded MCP server (rmcp): AgentServer + ManagerServer
|
||||||
|
|
@ -383,3 +394,5 @@ The docs below own the details — this section just points at them.
|
||||||
window:** → [`docs/turn-loop.md`](docs/turn-loop.md).
|
window:** → [`docs/turn-loop.md`](docs/turn-loop.md).
|
||||||
- **Two-step spawn, approval flow, flake.lock validation:** →
|
- **Two-step spawn, approval flow, flake.lock validation:** →
|
||||||
[`docs/approvals.md`](docs/approvals.md).
|
[`docs/approvals.md`](docs/approvals.md).
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -285,6 +285,7 @@ binary flavor.
|
||||||
| `messaging` | `send`, `recv`, `ask`, `answer` |
|
| `messaging` | `send`, `recv`, `ask`, `answer` |
|
||||||
| `meta` | `set_status`, `get_agent_meta` |
|
| `meta` | `set_status`, `get_agent_meta` |
|
||||||
| `inbox` | `get_loose_ends`, `cancel_loose_end`, `remind`, `request_next_turn` |
|
| `inbox` | `get_loose_ends`, `cancel_loose_end`, `remind`, `request_next_turn` |
|
||||||
|
| `execution` | `bash_run`, `bash_status` |
|
||||||
| `lifecycle` | `kill`, `start`, `restart`, `update` *(privileged)* |
|
| `lifecycle` | `kill`, `start`, `restart`, `update` *(privileged)* |
|
||||||
| `approvals` | `request_init_config`, `request_apply_commit`, `request_update_meta_inputs` *(privileged)* |
|
| `approvals` | `request_init_config`, `request_apply_commit`, `request_update_meta_inputs` *(privileged)* |
|
||||||
| `scheduling` | `request_schedule_prompt`, `fire_schedule_now`, `cancel_schedule`, `edit_schedule`, `list_schedules` *(privileged)* |
|
| `scheduling` | `request_schedule_prompt`, `fire_schedule_now`, `cancel_schedule`, `edit_schedule`, `list_schedules` *(privileged)* |
|
||||||
|
|
@ -307,7 +308,7 @@ the new `HIVE_TOOL_GROUPS` env var. Agents with no entry get no var.
|
||||||
**Runtime resolution** — at session start the harness reads `HIVE_TOOL_GROUPS`
|
**Runtime resolution** — at session start the harness reads `HIVE_TOOL_GROUPS`
|
||||||
(a comma-separated list of snake_case group names injected by the meta renderer
|
(a comma-separated list of snake_case group names injected by the meta renderer
|
||||||
from `tool-groups.json`). Unrecognised tokens are logged and skipped. Falls back
|
from `tool-groups.json`). Unrecognised tokens are logged and skipped. Falls back
|
||||||
to `ToolGroup::AGENT_DEFAULT` (`messaging`, `meta`, `inbox`) or
|
to `ToolGroup::AGENT_DEFAULT` (`messaging`, `meta`, `inbox`, `execution`) or
|
||||||
`ToolGroup::MANAGER_DEFAULT` (all groups) when the var is absent or empty.
|
`ToolGroup::MANAGER_DEFAULT` (all groups) when the var is absent or empty.
|
||||||
|
|
||||||
**Updating the surface** — when a new `#[tool]` fn is added to `AgentServer`
|
**Updating the surface** — when a new `#[tool]` fn is added to `AgentServer`
|
||||||
|
|
|
||||||
|
|
@ -64,17 +64,17 @@ Retention:
|
||||||
`cancelled_at_unix`, then `reap_cancelled` drops the row on
|
`cancelled_at_unix`, then `reap_cancelled` drops the row on
|
||||||
the next worker pass.
|
the next worker pass.
|
||||||
|
|
||||||
### `/state/hyperhive-events.sqlite` (per agent)
|
### `/harness/hyperhive-events.sqlite` (per agent)
|
||||||
|
|
||||||
Lives inside each container's bind-mounted `/state/` dir (host
|
Lives inside each container's bind-mounted `/harness/` dir (host
|
||||||
path: `/var/lib/hyperhive/agents/<name>/state/hyperhive-events.sqlite`).
|
path: `/var/lib/hyperhive/agents/<name>/harness/hyperhive-events.sqlite`).
|
||||||
One table:
|
One table:
|
||||||
|
|
||||||
- `events(id, ts, kind, payload_json)` — every `LiveEvent` the
|
- `events(id, ts, kind, payload_json)` — every `LiveEvent` the
|
||||||
harness emits during turn loop execution.
|
harness emits during turn loop execution.
|
||||||
|
|
||||||
The harness writes; the host vacuums. `hive-c0re::events_vacuum`
|
The harness writes; the host vacuums. `hive-c0re::events_vacuum`
|
||||||
runs hourly and sweeps every existing agent state dir, deleting
|
runs hourly and sweeps every existing agent harness dir, deleting
|
||||||
rows older than 7 days. Age-only — no row cap — so a chatty turn
|
rows older than 7 days. Age-only — no row cap — so a chatty turn
|
||||||
doesn't lose history sooner than a quiet one; disk pressure on a
|
doesn't lose history sooner than a quiet one; disk pressure on a
|
||||||
sustained burst is the cheaper problem to have. Centralising
|
sustained burst is the cheaper problem to have. Centralising
|
||||||
|
|
@ -82,12 +82,12 @@ retention on the host means a misbehaving harness can't disable
|
||||||
its own vacuum and agents don't need any cleanup wiring of their
|
its own vacuum and agents don't need any cleanup wiring of their
|
||||||
own.
|
own.
|
||||||
|
|
||||||
Path overridable via `HYPERHIVE_EVENTS_DB` (for dev / no-`/state`
|
Path overridable via `HYPERHIVE_EVENTS_DB` (for dev / no-`/harness`
|
||||||
setups). On open failure the `Bus` falls back to no-store mode
|
setups). On open failure the `Bus` falls back to no-store mode
|
||||||
rather than crashing the harness — events still broadcast over SSE,
|
rather than crashing the harness — events still broadcast over SSE,
|
||||||
just nothing persisted.
|
just nothing persisted.
|
||||||
|
|
||||||
### `/state/hyperhive-turn-stats.sqlite` (per agent)
|
### `/harness/hyperhive-turn-stats.sqlite` (per agent)
|
||||||
|
|
||||||
Per-turn analytics sink. One row per claude turn captures
|
Per-turn analytics sink. One row per claude turn captures
|
||||||
identity (`model`, `wake_from`, `result_kind`), timing
|
identity (`model`, `wake_from`, `result_kind`), timing
|
||||||
|
|
@ -149,7 +149,7 @@ Writes are best-effort: `append_stdout` / `append_stderr` / `finish`
|
||||||
log a warning on sqlite error and let the build continue. A failed
|
log a warning on sqlite error and let the build continue. A failed
|
||||||
log row never blocks a rebuild.
|
log row never blocks a rebuild.
|
||||||
|
|
||||||
### `/state/hyperhive-model` (per agent)
|
### `/harness/hyperhive-model` (per agent)
|
||||||
|
|
||||||
Single-line text file holding the claude model name currently
|
Single-line text file holding the claude model name currently
|
||||||
selected for this agent (default `haiku` when absent). Written by
|
selected for this agent (default `haiku` when absent). Written by
|
||||||
|
|
@ -169,11 +169,21 @@ Under `/var/lib/hyperhive/agents/<name>/`:
|
||||||
`/agents` tree bind.
|
`/agents` tree bind.
|
||||||
- `claude/` — claude OAuth credentials, bind-mounted RW to
|
- `claude/` — claude OAuth credentials, bind-mounted RW to
|
||||||
`/home/<name>/.claude` inside the container.
|
`/home/<name>/.claude` inside the container.
|
||||||
- `state/` — durable notes, the events.sqlite db, and the
|
- `state/` — durable notes and `hyperhive-harness.json`. Bind-mounted
|
||||||
turn-stats sqlite db. Bind-mounted to `/agents/<name>/state`
|
to `/agents/<name>/state` inside the container (uniform for
|
||||||
inside the container (uniform for sub-agents + manager).
|
sub-agents + manager). The `$HYPERHIVE_STATE_DIR` env var exposes
|
||||||
The `$HYPERHIVE_STATE_DIR` env var exposes the same path to
|
the same path to in-container scripts.
|
||||||
in-container scripts.
|
- `harness/` — harness-internal ephemeral state; not intended for
|
||||||
|
agent consumption. Bind-mounted to `/agents/<name>/harness`
|
||||||
|
inside the container (`$HYPERHIVE_HARNESS_DIR`). Contents:
|
||||||
|
- `bash-tasks/` — task JSON + stdout/stderr files for
|
||||||
|
background `bash_run` jobs. JSON files are
|
||||||
|
`<id>.json` (status + tails), `<id>.out` / `<id>.err`
|
||||||
|
(full captured output). Task files persist until container
|
||||||
|
purge.
|
||||||
|
- `hyperhive-events.sqlite` — turn-loop event log.
|
||||||
|
- `hyperhive-turn-stats.sqlite` — per-turn timing stats.
|
||||||
|
- `hyperhive-model` — single-line model name override file.
|
||||||
|
|
||||||
Under `/var/lib/hyperhive/applied/<name>/` — the hive-c0re-only
|
Under `/var/lib/hyperhive/applied/<name>/` — the hive-c0re-only
|
||||||
applied repo. Tracks `flake.nix` (module-only boilerplate; never
|
applied repo. Tracks `flake.nix` (module-only boilerplate; never
|
||||||
|
|
@ -207,7 +217,7 @@ step would re-fire).
|
||||||
- `PURG3` (opt-in via the dashboard button or
|
- `PURG3` (opt-in via the dashboard button or
|
||||||
`hive-c0re destroy --purge <name>`) — DESTR0Y plus wipes
|
`hive-c0re destroy --purge <name>`) — DESTR0Y plus wipes
|
||||||
`/var/lib/hyperhive/{agents,applied}/<name>/`. Config history,
|
`/var/lib/hyperhive/{agents,applied}/<name>/`. Config history,
|
||||||
claude creds, /state/ notes, and the events db are all gone.
|
claude creds, /state/ notes, and the harness dir are all gone.
|
||||||
No undo.
|
No undo.
|
||||||
|
|
||||||
The manager is non-destroyable from both paths (declarative
|
The manager is non-destroyable from both paths (declarative
|
||||||
|
|
@ -314,3 +324,4 @@ trigger from the `.path` watcher becomes a no-op. Setting it to
|
||||||
`false` lets re-fires actually re-execute. The trade-off is the
|
`false` lets re-fires actually re-execute. The trade-off is the
|
||||||
service unit shows `inactive (dead)` between fires — visible in
|
service unit shows `inactive (dead)` between fires — visible in
|
||||||
`journalctl` but harmless; the `.path` unit drives the lifecycle.
|
`journalctl` but harmless; the `.path` unit drives the lifecycle.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -148,7 +148,7 @@ default is set by `hyperhive.model` in the agent's `agent.nix`
|
||||||
(NixOS option; propagates via `HIVE_DEFAULT_MODEL` env var; falls
|
(NixOS option; propagates via `HIVE_DEFAULT_MODEL` env var; falls
|
||||||
back to `"haiku"` if unset). The operator can flip it at runtime
|
back to `"haiku"` if unset). The operator can flip it at runtime
|
||||||
with `/model <name>` in the web terminal — the next turn picks it
|
with `/model <name>` in the web terminal — the next turn picks it
|
||||||
up. The choice is persisted to `/state/hyperhive-model` so it
|
up. The choice is persisted to `/harness/hyperhive-model` so it
|
||||||
survives restart; override path: `HYPERHIVE_MODEL_FILE` env var
|
survives restart; override path: `HYPERHIVE_MODEL_FILE` env var
|
||||||
for tests.
|
for tests.
|
||||||
|
|
||||||
|
|
@ -369,6 +369,20 @@ it as a stdio child via `--mcp-config`. The hyperhive socket name is
|
||||||
continue without waiting for an external message. The next turn starts
|
continue without waiting for an external message. The next turn starts
|
||||||
with `from: "self"` and `body: "continue"`. No-op if new inbox
|
with `from: "self"` and `body: "continue"`. No-op if new inbox
|
||||||
messages arrive before this turn ends. No args.
|
messages arrive before this turn ends. No args.
|
||||||
|
- `bash_run(cmd, timeout_secs?)` — submit a shell command for
|
||||||
|
background execution (`sh -c <cmd>`). Returns a task ID immediately;
|
||||||
|
the command runs asynchronously in a harness-managed tokio task. Stdout
|
||||||
|
and stderr stream to `harness/bash-tasks/<id>.{out,err}`. When the
|
||||||
|
task completes (or times out, or the process errors), the harness wakes
|
||||||
|
the agent with a summary body — handle on a future turn. Default
|
||||||
|
timeout 180s; pass `timeout_secs` to override. Requires the
|
||||||
|
`execution` tool group.
|
||||||
|
- `bash_status(id)` — poll the status of a task submitted with
|
||||||
|
`bash_run`. Returns status (`pending`/`running`/`done`/`timed_out`/
|
||||||
|
`interrupted`), exit code, run duration, and the last 4 KiB of stdout
|
||||||
|
and stderr (full output in the `.out`/`.err` files). Tasks marked
|
||||||
|
`interrupted` had their process killed by a harness restart; a best-
|
||||||
|
effort wake was still sent so the agent is not silently blocked.
|
||||||
|
|
||||||
### Waking the agent from inside the container
|
### Waking the agent from inside the container
|
||||||
|
|
||||||
|
|
@ -573,3 +587,4 @@ The harness reads `/etc/hyperhive/bash-allow.json` and replaces
|
||||||
Commands outside the pattern list require confirmation — which in
|
Commands outside the pattern list require confirmation — which in
|
||||||
`--print` mode means they will not run. An empty list (default) keeps
|
`--print` mode means they will not run. An empty list (default) keeps
|
||||||
the current wholesale `Bash` entry.
|
the current wholesale `Bash` entry.
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue