diff --git a/docs/conventions.md b/docs/conventions.md index cbd3e46b..3282cffd 100644 --- a/docs/conventions.md +++ b/docs/conventions.md @@ -365,7 +365,6 @@ that allows the underlying resource access. | `manage_root_agent` | may lifecycle-manage the root/manager agent via `kill`/`start`/`restart` | | `read_host_journal` | `get_host_journal` MCP tool is registered + `GET /journal-host` requests are served | | `query_agent_state` | may call `get_loose_ends` / `CountPendingReminders` targeting non-child agents | -| `infra_admin` | may call `restart(name)` on hive infrastructure containers (`hive-ci`, `hive-forge`, `hive-matrix` — **not** `hive-gateway`, which is the host's nginx and is operator-only); each restart is logged to the dashboard AUDIT trail | **Config storage** — per-agent capabilities live in `/var/lib/hyperhive/meta/capabilities.json` alongside `tool-groups.json`. diff --git a/docs/web-ui/dashboard.md b/docs/web-ui/dashboard.md index eaca8607..6cad964d 100644 --- a/docs/web-ui/dashboard.md +++ b/docs/web-ui/dashboard.md @@ -106,7 +106,7 @@ Passive / rare-interaction state. No longer a dashboard tab — it's a standalone page reached from the **Core** tile on the H0M3 hub (served at `/core.html`), with the same minimal chrome as `/logs.html`: a `← home` back-link + a `createTabStrip` sub-tab nav (**K3PT ST4T3** default, -then **C0NT41N3R L04D**, then **1NFR4**). The page is its own esbuild bundle (`core.js`) +then **C0NT41N3R L04D**). The page is its own esbuild bundle (`core.js`) that cold-loads `/api/state` and subscribes to `/api/dashboard/stream` for `tombstones_changed`, `capabilities_changed`, and `tool_groups_changed` (the latter two re-render the stale-perms sub-section when permission @@ -159,27 +159,10 @@ omitted — agents share the host netns, so there is no per-container net counter (per-agent network needs the netns-isolation roadmap in `docs/network.md`). -**1NFR4** — start / stop / restart the four hive infrastructure services -(`hive-ci`, `hive-forge`, `hive-gateway`, `hive-matrix`) directly from the -dashboard, without needing an `infra_admin` agent's `restart` MCP tool. -Three are containers; `hive-gateway` is the host's `nginx.service`, and is -the one an agent may **not** restart — this panel is the way it gets -bounced. One row per service: name, a `badge-ok`/`badge-fail` -running/stopped dot, and `↺ R3ST4RT` + `■ ST0P` (running) or `▶ ST4RT` -(stopped) buttons, same themed-confirm pattern as the K3PT ST4T3 -tombstone actions. Backed by -`POST /api/infra-container/{name}/{action}` (`action` ∈ -`start|stop|restart`), which calls the same -`priv_client::control_infra_container` helper the agent-facing -`infra_admin` path uses — no new privileged-helper surface, no -capability check (the dashboard is already operator-authenticated). -Every attempt is written to the audit log (actor `"operator"`, action -`start_infra`/`stop_infra`/`restart_infra`) alongside agent-driven infra -restarts. Status rows ride the `infra_containers` field on -`GET /api/state`'s `StateSnapshot` (`{name, running}`, live -`systemctl is-active container@.service` read); `core.js` polls -`/api/state` every 5 s only while the 1NFR4 sub-tab is active, same -cadence/lifecycle as C0NT41N3R L04D's polling. +Hive infrastructure services (`hive-ci`, `hive-forge`, `hive-gateway`, +`hive-matrix`) have no dashboard panel — `hivectl stop`/`start`/`restart` +is the only control surface, a separate host-admin-socket path with no +HTTP route and no agent-facing equivalent. ## BU1LDS page (`/builds.html`) @@ -440,7 +423,6 @@ The current capabilities are: | `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 | | `query_agent_state` | allows `get_loose_ends(agent: "")` calls targeting other agents | -| `infra_admin` | allows `restart` on hive infrastructure containers (`hive-ci`, `hive-forge`, `hive-matrix`; the gateway is operator-only); each restart is logged to the AUDIT trail | Each row is one agent. Columns are the capability names returned by `GET /api/capabilities` as `caps: Vec`. Checking or unchecking @@ -730,7 +712,7 @@ navigation. A dedicated log-viewer page (not a tab pane — a separate HTML page), reachable from the Logs tile on the H0M3 hub. Minimal chrome: a `← home` back link and a three-item sub-tab strip. Tab -routing is hash-based (`#agent`, `#system`, `#audit`); default is +routing is hash-based (`#agent`, `#infra`, `#system`); default is `#agent`. (Build log history has moved to the BU1LDS page — see above.) **AGENT sub-tab** — per-container journald viewer. Two selects: agent @@ -746,6 +728,16 @@ deep-link directly to a specific agent's journal. A "fetched N ago" chip appears after the `↻ refresh` button following each successful fetch and ticks every 30 s. +**INFRA sub-tab** — journald viewer for the four hive infrastructure +containers (`hive-ci`, `hive-forge`, `hive-gateway`, `hive-matrix`), a +fixed client-side list (`INFRA_NAMES` in `logs.js` — no dashboard API +exposes just the name list). No unit filter (infra containers don't run +the per-agent hive daemons) — always the full machine journal (or, for +the gateway, the host journal filtered to its own unit). Fetches +`GET /api/journal/{name}?lines=500`, same "fetched N ago" ticker as +AGENT. A `?agent=` deep-link routes here instead of AGENT when +the name is one of the four infra containers. + **SYSTEM sub-tab** — host-side service logs. Unit selector (`hive-c0re.service` / `hive-priv.service`). Fetches `GET /api/journal-host?unit=&lines=500` on activation @@ -754,24 +746,6 @@ chip ticks every 30 s. Available to the operator unconditionally (not capability-gated — the endpoint lives on the hive-c0re dashboard, behind the gateway). -**AUDIT sub-tab** — operator-visible trail of agent-initiated -privileged actions (e.g. infra-container restarts via `infra_admin`). -Lazy-fetched on tab show (like SYSTEM) from `GET /api/audit-log`, which -returns `{ entries, total }` — `entries` newest-first, server-clamped to -the latest 500; `total` drives a "latest 500 of N" count so the clamp is -never silent. Rendered as a filterable table (when / agent / action / -target / outcome / detail); the filter box is a client-side substring -match over the cached rows. The outcome badge colours `ok` green and -`err` red, with an `err` whose `detail` starts `denied:` (a capability -refusal) shown amber and labelled `denied` so it reads apart from an -execution failure. `ts_unix` is an RFC 3339 string; a 30 s ticker keeps the -relative "ago" column honest while the tab is in view. The backing -`audit_log` store records every privileged-action attempt (ok / err / -denied). New entries live-append without a refresh: an `audit_entry_added` -event on `/api/dashboard/stream` (the flattened row) is prepended to the table -and the "latest N of M" count bumped, de-duped by id against the cold -fetch. - ## Container row A full-height **square agent icon** (5em, capped) on the left. The @@ -1208,12 +1182,6 @@ below — some endpoints aren't in it yet. build logs. - `GET /api/journal/{name}?unit=&lines=` — journalctl viewer for a managed container; rendered in the side panel. -- `GET /api/audit-log` — agent-initiated privileged-action audit - trail. Returns `{ entries, total }`: `entries` is a `Vec` - (`id`, `ts_unix` as RFC 3339, `agent`, `action`, `target`, `outcome` - `"ok"`/`"err"`, `detail` nullable), newest first, server-clamped to - 500; `total` is the full row count for a "latest 500 of N" header. - Backs the LOGS page AUDIT sub-tab. - `GET /static/marked.js` serves the vendored `marked` bundle used for markdown previews. - `GET /api/state-file?path=` — bounded @@ -1254,16 +1222,6 @@ below — some endpoints aren't in it yet. a background `du -sxb` of the agent's state dir + container writable rootfs every ~5 min, `-x` excluding the shared read-only nix store. `null` until the first sample lands. -- `POST /api/infra-container/{name}/{action}` — start / stop / restart a - hive infra service (C0R3 › 1NFR4 panel). `name` parses into the - `InfraContainer` allowlist (`hive-ci`/`hive-forge`/`hive-gateway`/ - `hive-matrix`, 400 on unknown), and the variant decides the unit — - `container@.service`, or `nginx.service` for the gateway. - `action` ∈ `start|stop|restart`. Calls - the same `priv_client::control_infra_container` helper the - `infra_admin` agent path uses; records an `audit_log` entry - (`start_infra`/`stop_infra`/`restart_infra`, actor `"operator"`) either - way. - `POST /api/cancel-reminder/{id}` — hard-delete a pending reminder. - `POST /api/retry-reminder/{id}` — re-arm a reminder whose delivery failed (clears the failure state so the scheduler retries). @@ -1429,10 +1387,6 @@ payload): - `meta_update_running` (running: bool) — emitted when a `nix flake update` ripple starts or completes. BU1LDS M3T4 1NPUTS tab uses this to show/hide the "⏳ meta-update running" banner. -- `audit_entry_added` (flattened `AuditEntry` fields: id, ts_unix, - agent, action, target, outcome, detail) — a single new audit-log - row. L0GS AUDIT sub-tab live-prepends the row and bumps the - "latest N of M" count, de-duped by id against the cold fetch. `/api/state` is **only fetched on cold-load and on the few forms that mutate non-event-derived state** (PURG3 + diff --git a/frontend/packages/dashboard/build.mjs b/frontend/packages/dashboard/build.mjs index b18e14ea..f4e16c3b 100644 --- a/frontend/packages/dashboard/build.mjs +++ b/frontend/packages/dashboard/build.mjs @@ -5,7 +5,7 @@ // dist/dashboard.html the operator dashboard SPA — served // at GET /dashboard.html // dist/flow.html served at GET /flow.html -// dist/logs.html served at GET /logs.html (AGENT/SYSTEM/AUDIT) +// dist/logs.html served at GET /logs.html (AGENT/INFRA/SYSTEM) // dist/core.html served at GET /core.html (C0R3: kept // state / container load) // dist/builds.html served at GET /builds.html (BU1LDS: @@ -18,7 +18,7 @@ // tab routing + refreshState // dist/static/flow.js /flow.html entry — broker terminal + // @-mention composer -// dist/static/logs.js /logs.html entry — agent/system/audit +// dist/static/logs.js /logs.html entry — agent/infra/system // log viewer sub-tabs // dist/static/builds.js /builds.html entry — rebuild queue, // meta inputs, build log history diff --git a/frontend/packages/dashboard/src/core.css b/frontend/packages/dashboard/src/core.css index 15fad5e8..df95e008 100644 --- a/frontend/packages/dashboard/src/core.css +++ b/frontend/packages/dashboard/src/core.css @@ -22,11 +22,11 @@ body.core-shell { panes; ensure it wins over any inherited display. */ .core-pane[hidden] { display: none; } -/* ─── K3PT ST4T3 + 1NFR4 container cards ──────────────────────────── +/* ─── K3PT ST4T3 container cards ──────────────────────────────────── core.html doesn't load dashboard.css (that's the operator SPA), so the .container-row card styles aren't inherited. Redefine them - here so tombstone and infra entries look like proper cards (similar - to agent cards on the main dashboard) rather than bare list items. */ + here so tombstone entries look like proper cards (similar to agent + cards on the main dashboard) rather than bare list items. */ .containers { list-style: none; padding: 0; diff --git a/frontend/packages/dashboard/src/core.html b/frontend/packages/dashboard/src/core.html index b1ee18c8..e2dcaf1a 100644 --- a/frontend/packages/dashboard/src/core.html +++ b/frontend/packages/dashboard/src/core.html @@ -16,12 +16,14 @@ /core.html) carved out of the dashboard's old SYST3M tab so the dashboard tab strip stays lean. Same minimal chrome as /logs.html — a `← home` back-link to the H0M3 hub + a - sub-tab nav. Three sub-tabs: kept state (tombstones), - container load, and infra containers (start/stop/restart the four - hive infra containers). Rebuild queue + meta inputs have moved to + sub-tab nav. Two sub-tabs: kept state (tombstones) + and container load. Rebuild queue + meta inputs have moved to /builds.html (the build lifecycle hub). Default tab: K3PT ST4T3. - The section
ids (tombstones-section, container-load-section, - infra-containers-section) match what core.js's renderers target. --> + The section
ids (tombstones-section, container-load-section) + match what core.js's renderers target. Hive infra containers + (`hive-ci`, `hive-forge`, `hive-gateway`, `hive-matrix`) have no + dashboard panel — `hivectl stop`/`start`/`restart` is the only + control surface. -->