Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
20e26ad28d | ||
|
|
80c33f5108 | ||
|
|
7e0190e27c | ||
|
|
c24ca4dfe1 | ||
|
|
ec5c7d49c4 | ||
|
|
adb76f3cdf | ||
|
|
d6debd4762 |
9 changed files with 47 additions and 45 deletions
|
|
@ -7,10 +7,10 @@ exist because something already went wrong without them.
|
||||||
|
|
||||||
- Containers are length-bounded by `nixos-container` (≤ 11 chars).
|
- Containers are length-bounded by `nixos-container` (≤ 11 chars).
|
||||||
- Sub-agents are `h-<name>` with `<name>` ≤ 9 chars.
|
- Sub-agents are `h-<name>` with `<name>` ≤ 9 chars.
|
||||||
- The manager is `ruth` (fixed name).
|
- One agent is the bootstrap/root container, with a fixed name (`ruth` today).
|
||||||
- `MAX_AGENT_NAME` in `lifecycle.rs` enforces the cap.
|
- `MAX_AGENT_NAME` in `lifecycle.rs` enforces the cap.
|
||||||
- Per-agent web UI port = `WEB_PORT_BASE + FNV1a(name) % WEB_PORT_RANGE`
|
- Per-agent web UI port = `WEB_PORT_BASE + FNV1a(name) % WEB_PORT_RANGE`
|
||||||
(8100..8999) for every agent including the manager; dashboard
|
(8100..8999) for every agent; dashboard
|
||||||
`cfg.dashboardPort` (default 7000).
|
`cfg.dashboardPort` (default 7000).
|
||||||
|
|
||||||
## Hive identity (label + domain + display names)
|
## Hive identity (label + domain + display names)
|
||||||
|
|
@ -55,9 +55,8 @@ peer's name when the caller knows it's hive-local.
|
||||||
|
|
||||||
There are no auth tokens on the per-agent unix sockets. The socket
|
There are no auth tokens on the per-agent unix sockets. The socket
|
||||||
*path* identifies the principal; perms come from "who has the
|
*path* identifies the principal; perms come from "who has the
|
||||||
bind-mount." A sub-agent only sees its own `/run/hive/mcp.sock`; the
|
bind-mount." A sub-agent only sees its own `/run/hive/mcp.sock`;
|
||||||
manager has access to its privileged socket; hive-c0re owns the host
|
hive-c0re owns the host admin socket.
|
||||||
admin socket.
|
|
||||||
|
|
||||||
### Wake injection
|
### Wake injection
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,7 @@ somewhere."
|
||||||
| `MetaUpdate` | `nix flake update` on the meta flake. The worker runs the lock bump itself, then enqueues a cascade of `Rebuild` entries with `parent_id` set to the meta-update's id. |
|
| `MetaUpdate` | `nix flake update` on the meta flake. The worker runs the lock bump itself, then enqueues a cascade of `Rebuild` entries with `parent_id` set to the meta-update's id. |
|
||||||
| `Spawn` | First-deploy of a new agent (approval-driven). Same serialisation as `Rebuild` from the operator's POV. |
|
| `Spawn` | First-deploy of a new agent (approval-driven). Same serialisation as `Rebuild` from the operator's POV. |
|
||||||
| `Destroy` | For future use (`destroy --purge` does real I/O). Variant exists so the wire shape doesn't change later; not currently routed through the queue. |
|
| `Destroy` | For future use (`destroy --purge` does real I/O). Variant exists so the wire shape doesn't change later; not currently routed through the queue. |
|
||||||
| `Restart` | Stop + start a container without touching config (~5-10s). Routed through the queue so it serialises against in-flight rebuilds for the same agent — prevents a restart racing a rebuild mid-flight. Sources: dashboard ↺ button, manager `restart` MCP tool. |
|
| `Restart` | Stop + start a container without touching config (~5-10s). Routed through the queue so it serialises against in-flight rebuilds for the same agent — prevents a restart racing a rebuild mid-flight. Sources: dashboard ↺ button, the `restart` MCP tool. |
|
||||||
| `PermChange` | Write a tool-group or capability change to the shared JSON file (`tool-groups.json` / `capabilities.json`), then rebuild the agent so the updated `HIVE_TOOL_GROUPS` / `HIVE_CAPABILITIES` env var takes effect. Serialising the file write through the queue prevents concurrent dashboard batch-apply actions from racing on the shared file. After a successful file write, emits `CapabilitiesChanged` or `ToolGroupsChanged` SSE snapshot so the P3RM1SS10NS tab updates live. |
|
| `PermChange` | Write a tool-group or capability change to the shared JSON file (`tool-groups.json` / `capabilities.json`), then rebuild the agent so the updated `HIVE_TOOL_GROUPS` / `HIVE_CAPABILITIES` env var takes effect. Serialising the file write through the queue prevents concurrent dashboard batch-apply actions from racing on the shared file. After a successful file write, emits `CapabilitiesChanged` or `ToolGroupsChanged` SSE snapshot so the P3RM1SS10NS tab updates live. |
|
||||||
| `GracefulStop` | Quiesce then stop a container (the `?graceful=1` path on `/kill/<agent>`). Signals the harness (its next `Recv` returns `GracefulStop` — the inbound fence — so it runs one stop-checkpoint turn to flush durable `/state`, then exits), waits for it to drain (bounded by a 3-min timeout → hard-stop fallback), then runs the normal container-stop teardown. Queued so it can't race an in-flight rebuild for the same agent. |
|
| `GracefulStop` | Quiesce then stop a container (the `?graceful=1` path on `/kill/<agent>`). Signals the harness (its next `Recv` returns `GracefulStop` — the inbound fence — so it runs one stop-checkpoint turn to flush durable `/state`, then exits), waits for it to drain (bounded by a 3-min timeout → hard-stop fallback), then runs the normal container-stop teardown. Queued so it can't race an in-flight rebuild for the same agent. |
|
||||||
|
|
||||||
|
|
@ -55,7 +55,7 @@ since the current run started).
|
||||||
|
|
||||||
| Source | Meaning |
|
| Source | Meaning |
|
||||||
|--------|---------|
|
|--------|---------|
|
||||||
| `Manual` | Operator clicked rebuild / update-all / meta-update on the dashboard, or any other direct human action (CLI, manager tool). |
|
| `Manual` | Operator clicked rebuild / update-all / meta-update on the dashboard, or any other direct human action (CLI, an agent MCP tool). |
|
||||||
| `AutoUpdate` | Legacy startup-sweep source (flat, no parent). Replaced by `StartupSweep` for new boots. |
|
| `AutoUpdate` | Legacy startup-sweep source (flat, no parent). Replaced by `StartupSweep` for new boots. |
|
||||||
| `StartupSweep` | Child of a `StartupSweep` parent entry; boot-time per-agent rebuild with the sweep as the visual group header. |
|
| `StartupSweep` | Child of a `StartupSweep` parent entry; boot-time per-agent rebuild with the sweep as the visual group header. |
|
||||||
| `Approval` | Triggered by an operator-approved `ApprovalKind::{Spawn, ApplyCommit}`. |
|
| `Approval` | Triggered by an operator-approved `ApprovalKind::{Spawn, ApplyCommit}`. |
|
||||||
|
|
|
||||||
|
|
@ -269,9 +269,8 @@ firewall-open would defeat the single-front-door story.
|
||||||
`httpsPort` — the gateway always terminates TLS (self-signed floor), so
|
`httpsPort` — the gateway always terminates TLS (self-signed floor), so
|
||||||
both are always served.
|
both are always served.
|
||||||
|
|
||||||
The manager hashes into the same port range as sub-agents (no
|
Every agent hashes into the same port range (no special case), so
|
||||||
"manager pinned at 8000" special case), so one range opening covers
|
one range opening covers every container.
|
||||||
every container.
|
|
||||||
|
|
||||||
The dashboard port (`cfg.dashboardPort`, default 7000) is *not*
|
The dashboard port (`cfg.dashboardPort`, default 7000) is *not*
|
||||||
listed in either case — it binds `127.0.0.1` only, so a firewall
|
listed in either case — it binds `127.0.0.1` only, so a firewall
|
||||||
|
|
|
||||||
|
|
@ -96,7 +96,7 @@ across `destroy`/recreate (`--purge` wipes them).
|
||||||
## Persistent notes dir per agent
|
## Persistent notes dir per agent
|
||||||
|
|
||||||
`/var/lib/hyperhive/agents/<name>/state/` bind-mounts to
|
`/var/lib/hyperhive/agents/<name>/state/` bind-mounts to
|
||||||
`/agents/<name>/state` (RW; uniform for sub-agents + manager).
|
`/agents/<name>/state` (RW; uniform for all agents).
|
||||||
The harness exposes the same path
|
The harness exposes the same path
|
||||||
via `$HYPERHIVE_STATE_DIR`. System prompts tell agents to keep
|
via `$HYPERHIVE_STATE_DIR`. System prompts tell agents to keep
|
||||||
durable knowledge here (`notes.md`, anything else). The harness also
|
durable knowledge here (`notes.md`, anything else). The harness also
|
||||||
|
|
@ -111,8 +111,8 @@ collision rate gets meaningful; at 2–3 agents you can still get
|
||||||
unlucky. Operator resolves a collision by renaming the offending
|
unlucky. Operator resolves a collision by renaming the offending
|
||||||
agent (different hash → different port) and rebuilding. No state
|
agent (different hash → different port) and rebuilding. No state
|
||||||
file, no probing, no port-allocation drift — the value is
|
file, no probing, no port-allocation drift — the value is
|
||||||
reproducible from just the name. Every agent — including the
|
reproducible from just the name. Every agent hashes into
|
||||||
manager — hashes into 8100..8999 via the same FNV-1a; dashboard
|
8100..8999 via the same FNV-1a; dashboard
|
||||||
at `cfg.dashboardPort` (default 7000).
|
at `cfg.dashboardPort` (default 7000).
|
||||||
|
|
||||||
## Restart races on TCP bind
|
## Restart races on TCP bind
|
||||||
|
|
|
||||||
|
|
@ -130,7 +130,7 @@ address arithmetic.
|
||||||
`lifecycle::set_nspawn_flags` when creating or updating containers. Each
|
`lifecycle::set_nspawn_flags` when creating or updating containers. Each
|
||||||
agent gets a deterministic IP derived from its name so the address is
|
agent gets a deterministic IP derived from its name so the address is
|
||||||
reproducible across destroy/recreate. This applies uniformly to all
|
reproducible across destroy/recreate. This applies uniformly to all
|
||||||
containers including the manager — no special case.
|
containers — no special case.
|
||||||
|
|
||||||
`HOST_ADDRESS` is the bridge gateway IP (the address part of
|
`HOST_ADDRESS` is the bridge gateway IP (the address part of
|
||||||
`HIVE_NETWORK_SUBNET`, via `lifecycle::bridge_gateway_ip` — taken verbatim
|
`HIVE_NETWORK_SUBNET`, via `lifecycle::bridge_gateway_ip` — taken verbatim
|
||||||
|
|
@ -163,9 +163,9 @@ wiring is runtime:
|
||||||
an instant no-op in shared-netns mode (the marker is absent, so
|
an instant no-op in shared-netns mode (the marker is absent, so
|
||||||
`ConditionPathExists` skips it).
|
`ConditionPathExists` skips it).
|
||||||
|
|
||||||
**Why isolation is safe for the manager**: all hive-c0re communication goes
|
**Why isolation is safe**: all hive-c0re communication goes
|
||||||
through unix domain sockets (`/run/hive/mcp.sock` for agent requests,
|
through unix domain sockets (`/run/hive/mcp.sock` for agent requests,
|
||||||
`/run/hive/priv.sock` for privileged ops, per-agent manager sockets).
|
`/run/hive/priv.sock` for privileged ops).
|
||||||
These are bind-mounted into containers via the nspawn conf. UDS paths
|
These are bind-mounted into containers via the nspawn conf. UDS paths
|
||||||
traverse the VFS, not the network stack, so `PRIVATE_NETWORK=1` does not
|
traverse the VFS, not the network stack, so `PRIVATE_NETWORK=1` does not
|
||||||
affect them.
|
affect them.
|
||||||
|
|
|
||||||
|
|
@ -180,16 +180,16 @@ Survives destroy/recreate, gone on `--purge`.
|
||||||
|
|
||||||
Under `/var/lib/hyperhive/agents/<name>/`:
|
Under `/var/lib/hyperhive/agents/<name>/`:
|
||||||
|
|
||||||
- `config/` — the proposed nix repo (manager-editable). Bind-mounted
|
- `config/` — the proposed nix repo (root-agent-editable). Bind-mounted
|
||||||
**read-only** to `/agents/<name>/config` inside the sub-agent's own
|
**read-only** to `/agents/<name>/config` inside the sub-agent's own
|
||||||
container so the agent can inspect what defines it and request
|
container so the agent can inspect what defines it and request
|
||||||
precise changes from the manager; RW into the manager via the
|
precise changes from the root agent; RW into the root agent via the
|
||||||
`/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 and `hyperhive-harness.json`. Bind-mounted
|
- `state/` — durable notes and `hyperhive-harness.json`. Bind-mounted
|
||||||
to `/agents/<name>/state` inside the container (uniform for
|
to `/agents/<name>/state` inside the container (uniform for
|
||||||
sub-agents + manager). The `$HYPERHIVE_STATE_DIR` env var exposes
|
all agents). The `$HYPERHIVE_STATE_DIR` env var exposes
|
||||||
the same path to in-container scripts. Notable files written here
|
the same path to in-container scripts. Notable files written here
|
||||||
by the harness:
|
by the harness:
|
||||||
- `hyperhive-status` — single-line free-text status string written
|
- `hyperhive-status` — single-line free-text status string written
|
||||||
|
|
@ -237,8 +237,8 @@ sibling's.
|
||||||
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
|
||||||
edited after first spawn) + `agent.nix` (the actual config; the
|
edited after first spawn) + `agent.nix` (the actual config; the
|
||||||
manager's edits land here via the approval flow) + any other
|
root agent's edits land here via the approval flow) + any other
|
||||||
files the manager committed. `.git/` carries the proposal /
|
files committed via the approval flow. `.git/` carries the proposal /
|
||||||
approved / building / deployed / failed / denied tag history.
|
approved / building / deployed / failed / denied tag history.
|
||||||
|
|
||||||
Under `/var/lib/hyperhive/meta/` — the swarm-wide deploy flake plus
|
Under `/var/lib/hyperhive/meta/` — the swarm-wide deploy flake plus
|
||||||
|
|
@ -251,7 +251,7 @@ Contents:
|
||||||
canonical "what's deployed where." The git log is the deploy
|
canonical "what's deployed where." The git log is the deploy
|
||||||
audit trail (one commit per successful deploy or hyperhive bump).
|
audit trail (one commit per successful deploy or hyperhive bump).
|
||||||
- `topology.json` — parent/child agent graph
|
- `topology.json` — parent/child agent graph
|
||||||
(`{ "alice": "manager", "bob": "alice", "manager": null }`).
|
(`{ "alice": "root", "bob": "alice", "root": null }`).
|
||||||
Written by `topology::set_parent`; read by the dashboard, the
|
Written by `topology::set_parent`; read by the dashboard, the
|
||||||
renderer, and `<parent>` / `<children>` recipient resolution.
|
renderer, and `<parent>` / `<children>` recipient resolution.
|
||||||
- `tool-groups.json` — per-agent MCP tool group grants
|
- `tool-groups.json` — per-agent MCP tool group grants
|
||||||
|
|
@ -263,7 +263,7 @@ Contents:
|
||||||
`capabilities::set_caps`; injected as `HIVE_CAPABILITIES` env
|
`capabilities::set_caps`; injected as `HIVE_CAPABILITIES` env
|
||||||
var. Absent agents have no extra capabilities.
|
var. Absent agents have no extra capabilities.
|
||||||
|
|
||||||
Manager has the meta dir RO-mounted at `/meta/`.
|
The root agent has the meta dir RO-mounted at `/meta/`.
|
||||||
|
|
||||||
Marker file `/var/lib/hyperhive/.meta-migration-done` is
|
Marker file `/var/lib/hyperhive/.meta-migration-done` is
|
||||||
written by the startup migration after every container has
|
written by the startup migration after every container has
|
||||||
|
|
@ -285,8 +285,13 @@ step would re-fire).
|
||||||
claude creds, /state/ notes, and the harness dir 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 root/bootstrap container is **imperative** infrastructure — managed
|
||||||
container; would fight with the host's NixOS config).
|
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.
|
||||||
|
|
||||||
### btrfs subvolumes for `/var/lib/hyperhive/agents/<name>`
|
### btrfs subvolumes for `/var/lib/hyperhive/agents/<name>`
|
||||||
|
|
||||||
|
|
@ -323,8 +328,7 @@ Without that, every restart wipes bind sources and existing
|
||||||
containers can't be started.
|
containers can't be started.
|
||||||
|
|
||||||
- `/run/hyperhive/host.sock` — admin socket (host-side CLI).
|
- `/run/hyperhive/host.sock` — admin socket (host-side CLI).
|
||||||
- `/run/hyperhive/manager/mcp.sock` — manager-privileged socket.
|
- `/run/hyperhive/agents/<name>/mcp.sock` — per-agent socket
|
||||||
- `/run/hyperhive/agents/<name>/mcp.sock` — per-sub-agent socket
|
|
||||||
(bind-mounted into the container as `/run/hive/mcp.sock`).
|
(bind-mounted into the container as `/run/hive/mcp.sock`).
|
||||||
|
|
||||||
On startup, `Coordinator::register_agent` drops any prior socket
|
On startup, `Coordinator::register_agent` drops any prior socket
|
||||||
|
|
|
||||||
|
|
@ -109,10 +109,10 @@ known operations; there is no arbitrary command pass-through:
|
||||||
| `RestartMatrixDaemon` | `systemctl --machine=h-<name> restart hive-matrix-daemon.service` |
|
| `RestartMatrixDaemon` | `systemctl --machine=h-<name> restart hive-matrix-daemon.service` |
|
||||||
|
|
||||||
**Container allowlist** — every request is validated against an
|
**Container allowlist** — every request is validated against an
|
||||||
allowlist before any operation: only names matching `h-<agent>` (the
|
allowlist before any operation: only names matching the agent-name
|
||||||
standard agent prefix), the manager container, or the known sibling
|
convention (char-validated) or the known sibling service containers
|
||||||
service containers (`hive-gateway`, `hive-forge`, `hive-matrix`,
|
(`hive-gateway`, `hive-forge`, `hive-matrix`, `hive-ci`) are accepted.
|
||||||
`hive-ci`) are accepted. Arbitrary container names are rejected.
|
Arbitrary container names are rejected.
|
||||||
|
|
||||||
**Socket-activated** — systemd starts `hive-priv` on the first
|
**Socket-activated** — systemd starts `hive-priv` on the first
|
||||||
incoming connection (`LISTEN_FDS=1`); it is not running between calls.
|
incoming connection (`LISTEN_FDS=1`); it is not running between calls.
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
# Web UI
|
# Web UI
|
||||||
|
|
||||||
Two web surfaces share the same skeleton: the dashboard (port 7000)
|
Two web surfaces share the same skeleton: the dashboard (port 7000)
|
||||||
and the per-agent UIs (every container — including the manager —
|
and the per-agent UIs (every container hashes into :8100-8999 via
|
||||||
hashes into :8100-8999 via `lifecycle::agent_web_port`'s FNV-1a).
|
`lifecycle::agent_web_port`'s FNV-1a).
|
||||||
Both are SPAs — `GET /` returns a static shell, `/api/state`
|
Both are SPAs — `GET /` returns a static shell, `/api/state`
|
||||||
returns JSON, JS renders. No full-page reloads.
|
returns JSON, JS renders. No full-page reloads.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -144,7 +144,7 @@ lock graph with a `visited` set — `follows` aliases and rev-less
|
||||||
nodes are skipped. A `select all / select none`
|
nodes are skipped. A `select all / select none`
|
||||||
control sits above the tree. Checking inputs + submitting bumps
|
control sits above the tree. Checking inputs + submitting bumps
|
||||||
the lock in `/meta/` and rebuilds the selected agents in
|
the lock in `/meta/` and rebuilds the selected agents in
|
||||||
sequence; each outcome reaches the manager as a `rebuilt`
|
sequence; each outcome reaches the root agent as a `rebuilt`
|
||||||
system event. `POST /meta-update`. While a lock-bump ripple runs,
|
system event. `POST /meta-update`. While a lock-bump ripple runs,
|
||||||
the panel shows a pulsing "⏳ meta-update running" banner and the
|
the panel shows a pulsing "⏳ meta-update running" banner and the
|
||||||
update button is disabled (snapshot field `meta_update_running`,
|
update button is disabled (snapshot field `meta_update_running`,
|
||||||
|
|
@ -305,7 +305,7 @@ The current capabilities are:
|
||||||
|
|
||||||
| Name | Effect |
|
| Name | Effect |
|
||||||
|------|--------|
|
|------|--------|
|
||||||
| `manage_root_agent` | allows the `set_status` / lifecycle tools on the root manager |
|
| `manage_root_agent` | allows the `set_status` / lifecycle tools on the root agent |
|
||||||
| `read_host_journal` | unlocks `get_host_journal` to read journald from inside a container |
|
| `read_host_journal` | unlocks `get_host_journal` to read journald from inside a container |
|
||||||
| `query_agent_state` | allows `get_loose_ends(agent: "<name>")` calls targeting other agents |
|
| `query_agent_state` | allows `get_loose_ends(agent: "<name>")` calls targeting other agents |
|
||||||
|
|
||||||
|
|
@ -319,7 +319,7 @@ agents in the assignment map have no extra capabilities.
|
||||||
|
|
||||||
**T00L GR0UPS** — per-agent tool-group permissions. Tool groups are
|
**T00L GR0UPS** — per-agent tool-group permissions. Tool groups are
|
||||||
named buckets of MCP tools; each agent starts with a role default
|
named buckets of MCP tools; each agent starts with a role default
|
||||||
(agents: `messaging`, `meta`, `inbox`, `execution`; manager: all
|
(sub-agents: `messaging`, `meta`, `inbox`, `execution`; root agent: all
|
||||||
groups). Checking / unchecking stages which groups are active for the
|
groups). Checking / unchecking stages which groups are active for the
|
||||||
agent; the page-level **save all** button (below) commits it. Columns
|
agent; the page-level **save all** button (below) commits it. Columns
|
||||||
come from `GET /api/tool-groups`. A rebuild is queued so
|
come from `GET /api/tool-groups`. A rebuild is queued so
|
||||||
|
|
@ -367,7 +367,7 @@ share enough conceptual ground to live together.
|
||||||
scheduled prompts. **Single-table layout**: each schedule is
|
scheduled prompts. **Single-table layout**: each schedule is
|
||||||
one `<tr>`; columns are
|
one `<tr>`; columns are
|
||||||
`# | src | next | every | owner | body | …agents… | actions`.
|
`# | src | next | every | owner | body | …agents… | actions`.
|
||||||
Agent columns are dynamic — `operator` + `manager` + every
|
Agent columns are dynamic — `operator` + `root` + every
|
||||||
live container + any extra name that appears as a target on
|
live container + any extra name that appears as a target on
|
||||||
some schedule but isn't a current container (same
|
some schedule but isn't a current container (same
|
||||||
`buildTargetChips` membership rule the new/edit forms use,
|
`buildTargetChips` membership rule the new/edit forms use,
|
||||||
|
|
@ -583,7 +583,7 @@ stream sits a terminal-style compose box: `@name` picks the recipient
|
||||||
(sticky via localStorage; auto-complete from the live container list,
|
(sticky via localStorage; auto-complete from the live container list,
|
||||||
Tab/Enter to confirm; `@*` broadcasts). `POST /api/op-send` drops
|
Tab/Enter to confirm; `@*` broadcasts). `POST /api/op-send` drops
|
||||||
`{from:"operator", to, body}` into the broker; the resulting SSE frame
|
`{from:"operator", to, body}` into the broker; the resulting SSE frame
|
||||||
re-renders the terminal row. Manager is addressed as `@root`.
|
re-renders the terminal row. The root agent is addressed as `@root`.
|
||||||
|
|
||||||
## H0M3 page (`/`)
|
## H0M3 page (`/`)
|
||||||
|
|
||||||
|
|
@ -925,12 +925,12 @@ frosted-mauve bar slides up from the bottom of the viewport
|
||||||
- `■ ST0P` — running agents only
|
- `■ ST0P` — running agents only
|
||||||
- `▶ ST4RT` — stopped agents only
|
- `▶ ST4RT` — stopped agents only
|
||||||
- `↻ R3BU1LD` — always available
|
- `↻ R3BU1LD` — always available
|
||||||
- `DESTR0Y` / `PURG3` — sub-agents only (disabled if manager selected)
|
- `DESTR0Y` / `PURG3` — sub-agents only (disabled if the root/bootstrap container selected)
|
||||||
- `⇡ M0V3 → ROOT` — promote selected agents to top-level
|
- `⇡ M0V3 → ROOT` — promote selected agents to top-level
|
||||||
(parent = null); disabled when all selected are already at root.
|
(parent = null); disabled when all selected are already at root.
|
||||||
Backend `topology::set_parent` refuses moves it can't satisfy
|
Backend `topology::set_parent` refuses moves it can't satisfy
|
||||||
(e.g. moving the manager) and the refusal surfaces in the
|
(e.g. a move that would create a cycle) and the refusal surfaces
|
||||||
failure roll-up.
|
in the failure roll-up.
|
||||||
- `⇢ M0V3 → [select]` — inline picker available for any
|
- `⇢ M0V3 → [select]` — inline picker available for any
|
||||||
selection size. The dropdown lists every container that isn't IN
|
selection size. The dropdown lists every container that isn't IN
|
||||||
the selection itself nor a descendant of any selected agent
|
the selection itself nor a descendant of any selected agent
|
||||||
|
|
@ -958,14 +958,14 @@ renderApprovals`) with three stacked sections:
|
||||||
so a stale approval stands out; the `.stale` class flips
|
so a stale approval stands out; the `.stale` class flips
|
||||||
precisely at the 3600s boundary rather than at the next
|
precisely at the 3600s boundary rather than at the next
|
||||||
`renderApprovals` call.
|
`renderApprovals` call.
|
||||||
- **what-changed body** — the manager's description, then
|
- **what-changed body** — the submitting agent's description, then
|
||||||
drill-in triggers: `↳ view diff` opens the diff in the side
|
drill-in triggers: `↳ view diff` opens the diff in the side
|
||||||
panel; `↳ commit on forge ↗` deep-links the proposal commit
|
panel; `↳ commit on forge ↗` deep-links the proposal commit
|
||||||
into `agent-configs/<agent>` (shown only when `forge_present`).
|
into `agent-configs/<agent>` (shown only when `forge_present`).
|
||||||
Spawn approvals show a one-line "container will be created"
|
Spawn approvals show a one-line "container will be created"
|
||||||
note instead.
|
note instead.
|
||||||
- **decision actions** — `◆ APPR0VE` and `DENY`. Deny pops a
|
- **decision actions** — `◆ APPR0VE` and `DENY`. Deny pops a
|
||||||
`prompt()` for an optional reason carried to the manager as
|
`prompt()` for an optional reason carried to the submitting agent as
|
||||||
`HelperEvent::ApprovalResolved.note`.
|
`HelperEvent::ApprovalResolved.note`.
|
||||||
|
|
||||||
The diff panel has a 3-way base toggle — **vs applied** (the
|
The diff panel has a 3-way base toggle — **vs applied** (the
|
||||||
|
|
@ -1012,7 +1012,7 @@ that's a browser-level decision, not ours.
|
||||||
updates derived approvals state from the event.
|
updates derived approvals state from the event.
|
||||||
- `POST /api/deny/{id}` (`note=<reason>`, optional) — deny a pending
|
- `POST /api/deny/{id}` (`note=<reason>`, optional) — deny a pending
|
||||||
approval with an optional operator-supplied reason. The reason
|
approval with an optional operator-supplied reason. The reason
|
||||||
travels to the manager as `HelperEvent::ApprovalResolved.note`
|
travels to the submitting agent as `HelperEvent::ApprovalResolved.note`
|
||||||
and also rides on the dashboard's `ApprovalResolved` event.
|
and also rides on the dashboard's `ApprovalResolved` event.
|
||||||
Dashboard prompts via the themed `themedPrompt()` dialog on
|
Dashboard prompts via the themed `themedPrompt()` dialog on
|
||||||
click — a resizable `<textarea>` where Enter submits and
|
click — a resizable `<textarea>` where Enter submits and
|
||||||
|
|
@ -1157,7 +1157,7 @@ that's a browser-level decision, not ours.
|
||||||
- `POST /api/schedules` — operator-direct schedule create:
|
- `POST /api/schedules` — operator-direct schedule create:
|
||||||
`{ targets, body, first_fire_at_unix, interval_seconds?, description? }`.
|
`{ targets, body, first_fire_at_unix, interval_seconds?, description? }`.
|
||||||
Agent-initiated schedules go through the approval queue instead
|
Agent-initiated schedules go through the approval queue instead
|
||||||
(manager MCP `request_schedule_prompt`).
|
(via the `request_schedule_prompt` MCP tool).
|
||||||
- `PATCH /api/schedules/{id}` — partial edit. JSON body
|
- `PATCH /api/schedules/{id}` — partial edit. JSON body
|
||||||
`{ body?, description?, interval_seconds?, next_fire_at_unix?,
|
`{ body?, description?, interval_seconds?, next_fire_at_unix?,
|
||||||
targets_add?, targets_remove? }`.
|
targets_add?, targets_remove? }`.
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue