Watch
0
0
Fork
You've already forked hyperhive
0

docs: scheduled prompts are swarm-level; the hive page is a read-only list

Drops docs/tools/scheduling.md and every description of hive-level
schedule creation, the worker, the removed MCP tools, the scheduling tool
group and the removed endpoints/events, pointing at docs/swarm/schedules.md.
This commit is contained in:
atlas 2026-10-04 21:23:18 +02:00
commit b4a2aeb5ba
18 changed files with 90 additions and 346 deletions

View file

@ -25,7 +25,7 @@ from the dashboard tab strip.
live on their own pages too, all reachable from the
H0M3 hub (not the tab strip). Count pills on SW4RM
(container count), Y3R C4LL (pending approvals + unread
operator messages), and SCH3DUL3S (active schedules).
operator messages), and SCH3DUL3S (active schedules left to copy).
- **Banner-thin** (`░▒▓█▓▒░ HYPERHIVE / HIVE-C0RE / WE ARE THE WIRED ░▒▓█▓▒░`)
— sits below the tab strip.
- **Server-warnings banner** — a generic, sticky top-of-page strip shown
@ -50,7 +50,7 @@ from the dashboard tab strip.
page prepends a `(N)` prefix — `(3) pr1ma // h1ve-c0re` — so the
operator can see the call count in an unfocused browser tab without
opening the dashboard. The page sets the prefix on the initial
`/api/state` cold-load and updates it live via `approval_added` /
`/api/state` cold-load and updates it live via
`approval_resolved` SSE events; it's preserved when `hive_name` /
`swarm_name` later replace the raw title.
@ -332,7 +332,7 @@ named buckets of MCP tools; each agent starts with a role default
(sub-agents: `messaging`, `meta`, `inbox`, `execution` —
`ToolGroup::AGENT_DEFAULT`; hive-c0re seeds the root agent to
`ToolGroup::MANAGER_DEFAULT` — `messaging`, `meta`, `inbox`,
`lifecycle`, `approvals`, `scheduling`, `execution`,
`lifecycle`, `approvals`, `execution`,
that is, every group except `forge` and `web_tools`). Checking /
unchecking stages which groups are active for the agent; the
page-level **save all** button (below) commits it. Columns come from
@ -341,7 +341,7 @@ takes effect.
<!-- vale write-good.Passive = YES -->
The current tool groups are: `messaging`, `meta`, `inbox`, `lifecycle`,
`approvals`, `scheduling`, `forge`, `execution`,
`approvals`, `forge`, `execution`,
`web_tools`. All listed in `ToolGroup::ALL` in `hive-sh4re`. The
`web_tools` group is special: it carries no MCP tools; instead it adds
Claude's built-in `WebFetch` and `WebSearch` to `--tools` /
@ -374,83 +374,31 @@ isn't clobbered.
## SCH3DUL3S tab
Anything that fires at a future time. The operator creates schedules
inline in the table (last row); agent self-paced
reminders surface at the bottom as a sibling list — they
share enough conceptual ground to live together.
A read-only list of the scheduled prompts still in the hive's store.
The hive no longer fires them: scheduled prompts live at swarm level
([`swarm/schedules.md`](../swarm/schedules.md)), and a warning banner at
the top of the tab says the page is due for removal and points at
`swarmctl schedule`. The list is there so the operator can recreate each
row with `swarmctl schedule add`.
**N3W SCH3DUL3 / QU3U3D SCH3DUL3S** — operator-managed
scheduled prompts. **Single-table layout**: each schedule is
one `<tr>`; columns are
`# | src | next | every | owner | body | …agents… | actions`.
Agent columns are dynamic — `operator` + `root` + every
live container + any extra name that appears as a target on
some schedule but isn't a current container (same
`buildTargetChips` membership rule the new/edit forms use,
so table and forms agree on what's addressable). Column
headers tilt –45° via CSS so each column reads as a narrow
~28px strip; per-agent cells render as:
**Single-table layout**: each schedule is one `<tr>`; columns are
`# | src | next | every | owner | body | …agents…`. Agent columns are
dynamic — every live container plus any extra name that appears as a
target on some schedule but isn't a current container (struck through
as gone). Column headers render vertically so each column reads as a
narrow ~28px strip; per-agent cells show `✓` for an active target, a
muted `✕` for a cancelled one, and nothing when the agent isn't a
target. Hovering a target cell shows its last fire and result.
- **active target** → `<button>✓</button>` that cancels just
that one target on selection
- **cancelled target** → muted `✕` glyph (no button —
re-adding goes through the edit form's targets multi-select)
- **not a target** → empty cell
The `next` column shows the stored next fire time as an absolute UTC
timestamp, the value to pass as `--at`; paused and cancelled rows say
so instead, with the time in the cell's tooltip. The body cell
truncates; hovering shows the full body and description.
Per-schedule action column:
- **`↯ fire now`** — sends an out-of-band manual pulse to every
active target (recurring schedules keep their cadence; the manual
fire consumes one-shots). Disabled for paused schedules.
- **`⏸` / `▶` pause/resume toggle** — only on recurring schedules
(the operator may also pause one-shots to delay a one-time fire, so
the button always appears). Paused rows show a `⏸ paused` badge in
the `next` column; the table sorts them to the middle bucket (after
active, before cancelled). A paused schedule doesn't fire regardless of
`next_fire_at`; resuming (`▶`) clears the pause without adjusting
the next-fire time. POSTs to `/api/schedules/{id}/pause` or
`/api/schedules/{id}/resume`.
- **`✎ edit`** — expands an inline edit form as a colspan'd row
directly under the schedule's row (body / description / interval /
next-fire / targets all editable; targets are a multi-select diff'd
against the original active set so unchecked-was-active =
`targets_remove`, checked-not-originally-active = `targets_add`;
submit PATCHes `/api/schedules/{id}`).
- **`✕`** — cancels the whole schedule
(`POST /api/schedules/{id}/cancel`).
The `next` column cell (`.sched-due`) carries a `data-due-at`
Unix timestamp attribute; a shared 1s ticker rewrites it
in-place showing `fmtDuration` while in the future and
`overdue X ago` once the fire time has passed — same
zero-re-render pattern as the reminder due-at labels.
The table's last row is a permanent inline creation row:
inputs live directly in table cells (targets as checkboxes,
body textarea that expands on focus, datetime-local pre-filled
to 5 minutes from now, mini d/h/m/s number inputs (blank or
all-zero = one-shot), description). Select `+` to POST to
`/api/schedules` as JSON (or `⌫` to clear the half-filled row);
carry-state preserves partially typed inputs across re-renders. The tab pill shows the count of active
schedules (at least one live target not yet cancelled).
Refreshed on tab activation and after each submit/cancel. Backed by
`GET /api/schedules`. No hive-c0re changes for the table layout
— it renders entirely from existing `schedulesState` +
`containersState`.
**QU3U3D R3M1ND3RS** — reminders agents have scheduled for
themselves (via the `remind` tool) but not yet delivered.
Each row shows the owner, due time, and message; a `CANC3L`
button hard-deletes (`POST /api/cancel-reminder/{id}`) and a
`R3TRY` button re-arms one whose delivery failed
(`POST /api/retry-reminder/{id}`). Backed by `GET /api/reminders`.
Lives in the SCH3DUL3S tab alongside operator schedules so the
operator has one place for everything time-fired. The due-time
label (`.reminder-due`) carries a `data-due-at` Unix timestamp
attribute; a shared 1s ticker rewrites it in-place — showing
`in Xm Ys` while the reminder is in the future and
`overdue X ago` once the deadline passes — without triggering a
full re-render of the list.
The tab has no controls: nothing creates, edits, pauses, fires or
cancels a row. The tab pill shows the count of active schedules (at least one
live target not yet cancelled). Fetched from `GET /api/schedules` on
tab activation and on each dashboard state load.
## ST4TS page (`/stats.html`)
@ -880,7 +828,6 @@ renderApprovals`) with three stacked sections:
| kind | glyph | chip |
|---|---|---|
| `update_meta_inputs` | `↻` | `meta-update` |
| `schedule_prompt` | `⏱` | `schedule` |
<!-- vale write-good.Passive = NO -->
The chip ticks live every second via a `data-requested-at`
@ -889,8 +836,7 @@ renderApprovals`) with three stacked sections:
the `.stale` class flips precisely at the 3600s boundary rather
than at the next `renderApprovals` call.
- **what-changed body** — the submitting agent's description, then the
kind's payload: the inputs to bump (`update_meta_inputs`) or the prompt to
schedule (`schedule_prompt`).
kind's payload: the inputs to bump (`update_meta_inputs`).
- **decision actions** — `◆ APPR0VE` and `DENY`. Deny pops a
`prompt()` for an optional reason carried to the submitting agent as
`HelperEvent::ApprovalResolved.note`.
@ -1075,42 +1021,9 @@ below — some endpoints aren't in it yet.
rows with both fields omitted rather than erroring on them.
Returns `200 "ok"` on
success.
- `GET /api/schedules` — list all schedules (active and
recently cancelled) for the SCH3DUL3S scheduled-prompts panel.
- `POST /api/schedules` — operator-direct schedule create:
`{ targets, body, first_fire_at_unix, interval_seconds?, description? }`.
Agent-initiated schedules go through the approval queue instead
(via the `request_schedule_prompt` MCP tool).
- `PATCH /api/schedules/{id}` — partial edit. JSON body
`{ body?, description?, interval_seconds?, next_fire_at_unix?,
targets_add?, targets_remove? }`.
Missing key = "leave alone"; explicit `null` on
`description` / `interval_seconds` clears the field (so a
recurring schedule flips to one-shot when the caller sends
`interval_seconds` as `null`). `targets_add` is replace-on-conflict:
re-adding a previously cancelled target drops the tombstone
and the target starts fresh (operator intent on re-add =
"this target is active again"). `targets_remove` delegates
to the same path as `cancel_targets` — tombstones preserve
audit, parent schedule autocancels when no active targets
remain. Refuses cancelled rows; returns the updated
`WireSchedule` on success.
- `POST /api/schedules/{id}/cancel` — cancel a schedule. Body
`{ targets?: ["name", …] }` cancels just those recipients;
absent or empty body cancels the whole schedule.
- `POST /api/schedules/{id}/fire-now` — out-of-band manual
pulse. Fires the schedule body once immediately to
every active target. Recurring schedules: `next_fire_at_unix`
is untouched; the regular cadence continues. One-shots: the
manual fan-out consumes the schedule (cancels it).
The endpoint annotates per-target `last_result` as a manual fire so
the audit trail distinguishes scheduled fires from operator-
triggered ones.
- `POST /api/schedules/{id}/pause` — pause a recurring or
one-shot schedule. A paused schedule doesn't fire regardless
of `next_fire_at`; the row gains a `⏸ paused` badge.
- `POST /api/schedules/{id}/resume` — resume a paused schedule.
Clears the pause flag without adjusting `next_fire_at`.
- `GET /api/schedules` — list every schedule row left in the hive's
store (cancelled ones included) for the read-only SCH3DUL3S tab.
Targets naming an agent that no longer exists are left out.
- `POST /api/meta-update` — `nix flake update` the selected
`meta/flake.lock` inputs, then rebuild the affected agents.
- `GET /api/dashboard/stream` — unified live event channel:
@ -1133,10 +1046,9 @@ payload):
rows with a `↳ reply` tag that scroll-highlights the parent
row on selection. Used by the message-flow terminal renderer and
the operator-inbox derived state.
- `approval_added` (id, agent, approval_kind, sha_short, diff,
description) / `approval_resolved` (id, agent, approval_kind,
sha_short, status, resolved_at, note, description) — pending
queue + history mutations. Client mutates a derived store and
- `approval_resolved` (id, agent, approval_kind, status,
resolved_at, note, description) — moves a row from the pending
queue to history. Client mutates a derived store and
re-renders only the approvals section.
- `transient_set` (name, transient_kind, since_unix) /
`transient_cleared` (name) — lifecycle action spinners. The
@ -1158,16 +1070,6 @@ payload):
terminal-history trim). Unlike the snapshot events below it ships
no state at all: the client re-fetches `GET /api/jobq/graph`, which
is where it reads the queue from cold too.
- `schedules_changed` (seq, schedules: `Vec<WireSchedule>`) —
full snapshot of all scheduled prompts. Emitted after every
operator mutation via the `/api/schedules` surface (new /
edit / cancel / fire-now) and after the worker fires or
rearms a row. Same snapshot-shape rationale as
`tombstones_changed` / `meta_inputs_changed` (small list, no
add/remove races). The SCH3DUL3S tab subscribes and
re-renders `schedulesState` on receipt; tab activation still
re-fetches as a safety net for approval-path inserts and
disconnect windows.
- `reminders_changed` (seq, reminders: `Vec<PendingReminder>`) —
full snapshot of all pending reminders. Emitted after every
reminder mutation: agent `remind` calls (`agent_server`),