Commit graph hyperhive/docs
Author SHA1 Message Date
iris
803ea9d7f6 docs: fix swarm.md — peer list reaches agents via HYPERHIVE_PEERS env, not get_agent_meta 2026-05-31 23:51:31 +02:00
iris
b79ef005b5 docs: add swarm.md — multi-hive peer config guide 2026-05-31 23:51:31 +02:00
iris
b6c5dcc397 docs: update P33RS tab wiring to match domain-as-key reshape 2026-05-31 23:36:32 +02:00
iris
2fb1b9eb5a docs: fix P33RS tab — correct nix option name and peer card icon 2026-05-31 23:30:56 +02:00
iris
8ba1947c3f docs: add P33RS tab to dashboard layout docs 2026-05-31 23:27:52 +02:00
iris
8a97277f20 fix(#540): pin weston socket + inject WAYLAND_DISPLAY globally
Services started by systemd in a gui-enabled container didn't have
WAYLAND_DISPLAY set, so Wayland clients couldn't find the compositor.
libwayland would fall back to a headless display or error out, leaving
apps running invisibly while the VNC session showed a blank weston
desktop (the double-screen problem).

Fix in weston-vnc.nix:
- Pass --socket=wayland-0 to weston so the socket name is
  deterministic (weston normally picks any free wayland-N name).
- Set WAYLAND_DISPLAY=wayland-0 and XDG_RUNTIME_DIR=/run/user/0 as
  global environment.variables gated on hyperhive.gui.enable, so
  every service in the container inherits them automatically.
- Update gui.json to include wayland_display for tooling that reads it.

Update docs/gotchas.md with the rationale and pointer to #540.
2026-05-31 22:59:46 +02:00
atlas
01d7c37af2 gateway: fix nginx reload — trigger from host via systemd-run (#889)
The #872 path-unit approach was silently broken: IN_MOVED_TO from an
atomic rename on the host does not propagate across the nspawn
mount-namespace boundary into the container, so the watcher inside
the gateway container never fired.

Fix: after each agents.conf write, c0re calls
`systemd-run --machine=hive-gateway -- nginx -s reload` from the host.
The reload is best-effort (logged on failure, not fatal).

Remove the now-unused `hive-gateway-agents-conf.path` +
`hive-gateway-nginx-reload.service` from the gateway container config.
Update docs/gateway.md + comments to reflect the host-side approach.
2026-05-31 22:42:52 +02:00
iris
61b9c23613 fix(#886 follow-up): restore docs/web-ui.md to thin index
The #886 merge accidentally reverted the #727/#885 split —
web-ui.md went from the 40-line index back to the 1344-line
monolithic file. The split files (docs/web-ui/{shape,dashboard,
agent}.md) are correct in main; only web-ui.md needs restoring.
2026-05-31 21:54:52 +02:00
iris
050e130eba build-logs: SSE live streaming + raw download (#726 phase 4)
Backend (hive-c0re):
- build_logs.rs: add tokio::sync::broadcast::Sender<i64> to BuildLogs;
  append() and finish() notify subscribers after each sqlite write.
  Add BuildLogProgress struct and get_progress(id, stdout_cursor,
  stderr_cursor) for incremental delta reads.
- dashboard.rs: two new endpoints —
    GET /api/build-logs/id/{id}/stream  SSE; streams BuildLogFrame
      {stdout_append, stderr_append, status?, done} deltas until the
      build finishes or the browser disconnects. Backed by an mpsc
      channel task that watches the per-build broadcast notifications.
    GET /api/build-logs/id/{id}/raw    text/plain download with
      Content-Disposition: attachment; filename build-log-{agent}-{id}.txt

Frontend (dashboard):
- tabs.js: running builds (status === null) connect an EventSource to
  /stream and append lines live; "live" badge pulses amber while active,
  flips to ok/fail on done. Finished builds still use the JSON fetch path.
  Collapsing a running panel closes the EventSource; re-expanding
  reconnects. Adds a "⬇ raw" download link to every expanded row.
- dashboard.css: .build-logs-dl inline download link; .build-logs-live
  live pulse @keyframes animation.

Docs: web-ui.md updated for all three new endpoints + behaviour.
2026-05-31 21:48:31 +02:00
iris
cc6227ccb5 dashboard: build-log side-panel viewer in agent card (#726 phase 3)
Adds a `↳ build logs · {agent}` drill-in to every agent card that
opens the side panel and fetches the last 10 build-log headers from
GET /api/build-logs/{agent}. Each row shows a status chip (ok/fail/
running), kind, age, and truncated cmdline. Clicking a row lazily
fetches the full stdout+stderr from GET /api/build-logs/id/{id} and
expands it inline as a scrollable pre.

CSS additions: .build-logs-{panel,toolbar,list,item,row-btn,...} plus
.badge-ok/.badge-fail/.badge-running status chips shared with future
uses. docs/web-ui.md updated with the new drill-in and the new badge
classes.
2026-05-31 21:48:31 +02:00
iris
c7360cf0bb docs(#727): split docs/web-ui.md into shape / dashboard / agent
docs/web-ui.md (1315 lines) split into three sub-files:
- docs/web-ui/shape.md   — shared SPA skeleton, SSE multiplexing,
  Worker-death self-heal, terminal pane, listener bind, relative
  paths, atomic repaint, side panel
- docs/web-ui/dashboard.md — SW4RM/Y3R/SYST3M/SCH3DUL3S/S3TT1NGS
  tabs, container row, topology tree, selection bar, approval card,
  dashboard endpoints + event channel
- docs/web-ui/agent.md   — header, terminal, composer, inbox, live
  view, slash commands, per-agent endpoints, stats page

docs/web-ui.md replaced with a thin index linking all three.

Section anchors in docs (gateway.md, gotchas.md), Rust doc comments
(hive-ag3nt/src/web_ui.rs), and nix/templates/weston-vnc.nix updated
to point at the correct sub-file. README and CLAUDE.md file-map
updated with sub-file links. Inline // comments in frontend source
left unchanged (they reference the index which redirects to the right
sub-file).
2026-05-31 21:37:04 +02:00
damocles
36c683138d feat(#704): add <children> recipient sentinel — fan-out to direct descendants 2026-05-31 20:59:20 +02:00
damocles
fce1f49f6a refactor(#838): consolidate harness state files into hyperhive-harness.json 2026-05-31 20:32:13 +02:00
iris
f6b3145349 dashboard: add GET /api/build-logs/{agent} + /id/{id} endpoints (#726 phase 2)
Wires the Phase 1 sqlite store into the dashboard HTTP layer so the
frontend can surface full build logs without hitting journald.

Two new read endpoints:
- GET /api/build-logs/{agent}?limit=N  — Vec<BuildLogHeader> JSON,
  newest first, default limit 10, server-side cap at 50.
- GET /api/build-logs/id/{id}          — BuildLogFull JSON (header +
  stdout + stderr), HTTP 404 on vacuum-reaped / unknown ids.

Agent-name validated ([a-z0-9_-], 1-63 chars) before the sqlite call.
Both handlers reach coord.build_logs (Arc<BuildLogs>) introduced in
the Phase 1 commit. Docs updated in docs/web-ui.md.
2026-05-31 20:31:07 +02:00
atlas
07434e8f50 gateway: hot-reload agents.conf at runtime (#869)
Replace eval-time per-agent nginx location baking with a runtime
include file. c0re writes /var/lib/hyperhive/agents.conf (nginx
location blocks, UDS or TCP per agent) on every topology change and
on the 10s marker poll. The gateway container bind-mounts
/var/lib/hyperhive/ at /run/hive-state/ and nginx includes
/run/hive-state/agents.conf. A systemd path unit inside the container
watches the file for changes and fires `nginx -s reload` on each
atomic rename from c0re — no nixos-rebuild switch needed when agents
start, stop, or flip useUnixSocket.

  - new hive-c0re/src/gateway_nginx.rs: write() + render()
  - lib.rs + meta.rs + agent_sockets::spawn_poll: hook in write()
  - hive-gateway.nix: drop agentPortsTable/agentSocketsTable/
    agentUpstreamFor/lib.mapAttrs', add /run/hive-state bind-mount,
    include directive, systemd path unit + reload service, tmpfiles
    for /var/lib/hyperhive + agents.conf seed
  - docs/gateway.md: update vhost table + Per-agent UDS section
2026-05-31 20:29:56 +02:00
iris
6cf169d324 dashboard: new S3TT1NGS tab housing the notification toggle (closes #763)
Adds a fifth tab (◆ S3TT1NGS ◆) at the end of the dashboard tab
strip; moves the browser-notification controls out of the chrome
header into the new pane.

### Why

The chrome was carrying the notification controls as 'always-on
ergonomics' but the surface they belong on is operator preferences,
not navigation. With #589 / #701 likely adding more per-browser
preferences later (theme / density / etc.), having a dedicated
S3TT1NGS pane gives them a home so the chrome strip doesn't keep
accreting controls.

### Shape

- index.html: new `#tab-pane-settings` section with H2 + intro +
  H3 'browser notifications' group; same notif-row DOM (same IDs)
  migrated from the chrome
- flow.html: drops the duplicated notif-row from its chrome (FL0W
  reused the dashboard's strip); adds a `◆ S3TT1NGS ◆ →`
  cross-page link to `/#settings`. Notifications still fire on
  FL0W when enabled — NOTIF.show() reads
  Notification.permission + the hyperhive.notify.muted localStorage
  key directly, no buttons needed in the page DOM.
- tabs.js: adds 'settings' to TABS array so hash routing activates
  the pane
- dashboard.css: drops the chrome-anchoring `.tabbar #notif-row`
  rule and the flow-page reuse comment, both obsolete; the general
  `.notif-row` styling stays
- docs/web-ui.md: new `### S3TT1NGS tab` section; Chrome-header
  bullet drops 'Notification controls' + adds S3TT1NGS; Browser
  notifications section pointers at the new pane

### No JS or backend changes

Same IDs (notif-row, notif-enable, notif-mute, notif-unmute,
notif-status) so `NOTIF.bind()` in common.js wires the new pane
unchanged. NOTIF.show() dispatch is DOM-independent.

### Validation

`npm run --workspace @hive/dashboard build` clean (tabs.js 167.8kb,
flow.js 37.4kb, dashboard.css 50.2kb).
2026-05-31 17:55:30 +02:00
iris
6bdfe52386 docs: scrub #NNN self-references (closes #719)
Last pass of the docs-from-code → docs/ epic (#708). Drops every
attribution cookie from docs/ + README.md + CLAUDE.md so the
source-tree files no longer reference the issue tracker. Issue
threads + commit history retain the references — those are the
canonical record.

- README.md: drop #701 / #660×2 / #551 from matrix + display-name
  sections, rephrase to convey the semantics directly
- CLAUDE.md: scrub 18 cookies from the file map (#655, #15, #784,
  #832, #444, #425, #361, #548, #598, #539, #544, #589, #701,
  #658, #280, #660, #551, #764, #772, #793, #14, #805)
- docs/agent-hierarchy.md: drop #658 ×3 (per-agent user is the
  current shape, not a transition)
- docs/conventions.md: drop #571 (replaced with a docs xref to
  persistence.md::matrix-avatar-sync)
- docs/gateway.md: scrub vhost-map table cookies + Sub-domain
  rationale + Per-agent unix-socket upstream + Self-signed TLS +
  Firewall posture + HIVE_FORGE_URL + Per-agent error pages
  sections; drop the trailing 'Sequencing history' issue list +
  the 'Next-up' issue-link footnote
- docs/matrix.md: scrub serverName/gatewayHost + Default-closed
  firewall + Provisioning flow + Initial rollout + Assertion
  rationale + fluffychat-web build fixes; drop the trailing
  'Sequencing history' issue list
- docs/network.md: drop 'Why ship before #14' #805 quote +
  Container shape #805 attribution + trailing 'Sequencing history'
  + Cross-references issue links; rename v2 column to 'after netns
  isolation'
- docs/web-ui.md: drop #784 from Container row, replace with a
  docs xref to docs/gateway.md::Per-agent unix-socket upstream

Only remaining #NNN in docs/ is the literal markdown-heading
example in docs/forge.md (`#tag`, `#123`, `#!/bin/bash`)
which demonstrates the renderer's behaviour — not an attribution
cookie.
2026-05-31 17:47:21 +02:00
iris
55716be8fc hive-ag3nt + docs: extract web_ui prose (#716 batch 6)
docs/web-ui.md:
- New `### Listener bind` subsection — uncapped TCP retry rationale
  (replaces stale "12 tries" claim that contradicted the code) +
  pointer to gateway.md for unix-socket transition
- Expand `/api/logout` bullet with three-step teardown rationale
  (SIGINT race, selective cred-file wipe preserves --continue,
  wait_for_login resumption path)

hive-ag3nt/src/web_ui.rs:
- serve / bind_unix / bind_with_retry rustdocs trimmed to docs
  pointers (binding modes, .bound marker, retry budget all live in
  the prose now)
- AgentLink / StateSnapshot.links / agent_links rustdocs trimmed
  to single-line summaries
- post_logout / CRED_FILE_NAMES rustdocs reference docs/web-ui.md
- 13 → 0 cookies
2026-05-31 17:25:27 +02:00
iris
94c110fd5f hive-ag3nt + docs: extract harness binary shape prose (#716 batch 5)
`bin/hive.rs` carries ~15 attribution cookies (#598, #676, #692,
#693, #778, #788, #682, #688) plus structural prose about the
single-binary architecture (role-from-env), the `Surface` trait
pattern (zero-sized type tags + generic dispatch), boot wiring
(label fallback, plugin install → send_to_parent failure routing),
and turn-outcome branching (ack / requeue / wait_for_login / parent
notify).

Migrated to a new `docs/turn-loop.md::Harness binary shape`
subsection covering:

- Single-binary rationale (server-side privilege boundary on the
  broker socket means no escalation risk in shipping both wire
  surfaces in the same process).
- Three subcommands (`serve` / `mcp` / `wake`).
- Surface trait + zero-sized type tags (AgentSurface,
  ManagerSurface) — picks per-role FLAVOR / FORGE_IS_MANAGER and
  exposes the broker wire ops behind trait methods so the turn
  loop is written once.
- Boot wiring (HIVE_PORT, HIVE_LABEL fallback, plugin failures
  routed via send_to_parent, web_ui + forge_notify spawn).
- Turn outcomes table (Ok/Compacted/RateLimited/AuthFailed/Failed)
  + continue-sentinel pickup.

In-code rustdocs reduced to 1-line summaries + doc pointers;
inline cookies stripped from boot wiring + plugin install +
sentinel cleanup paths.

15 → 0 cookies in bin/hive.rs; cargo check -p hive-ag3nt passes.
2026-05-31 17:18:22 +02:00
damocles
2ce8bb5b77 scheduled_prompts: address argus 🟡 on #849 — submit paths section + persistence.md anchor fix 2026-05-31 17:18:15 +02:00
damocles
50879cea5a hive-c0re + docs: extract scheduled_prompts prose (#715 batch 2) 2026-05-31 17:18:15 +02:00
damocles
314f1774d8 hive-gateway: self-signed TLS for matrix-client well-known fetch (closes #837) 2026-05-31 17:17:58 +02:00
iris
76d3267b55 hive-ag3nt + docs: extract forge_notify prose (#716 batch 4)
forge_notify.rs is the biggest remaining #716 hotspot: ~22 attribution
cookies (#110 #230 #231 #253 #256 #455 #518 #539 #544) plus a thick
module-level docstring + per-function rationale blocks for the
notification pipeline. The substantive prose lives in a new
`docs/forge.md` covering the wider forge integration story:

- Per-agent forge accounts + agent-configs mirror (was implicit
  across `hive-c0re/src/forge.rs` rustdocs).
- Notification poller: activation gates, self-notification filtering,
  body excerpt + truncation + ATX heading escape pipeline, wrapper
  formats (comment / review / new-item / state-change) with shape
  table, meta suffix shape, review-request override, reason
  drop-list rationale (drop vs allow), auto-unsubscribe on broad
  watches.

In-code rustdocs reduced to 1-line semantic summaries + doc
pointers; inline cookie comments scrubbed. Net diff is ~150 lines
removed from the .rs file. All 16 forge_notify unit tests pass.

CLAUDE.md gets a new `docs/forge.md` file-map entry + reading-path
question entry. The existing `src/forge_notify.rs` file-map blurb
keeps its `(#539 / #544)` cookie — consistent with the rest of
CLAUDE.md's lineage attributions.
2026-05-31 17:17:24 +02:00
iris
fbc41d42a6 dashboard: build same-origin /agent/<name>/ links when gateway is up (closes #842)
When `services.hyperhive.gateway.enable` is on (default), the c0re
NixOS module now sets `HIVE_GATEWAY_ENABLED=1` on the service env.
`/api/state` exposes the flag as `gateway_enabled`; the SW4RM tab's
container-row renderer flips three link sites (primary agent-name
link, favicon fetch, `container`-kind nav-strip links) from the
legacy `http://<host>:<port>/` direct TCP shape to same-origin
`/agent/<name>/` URLs — the gateway proxies them to the per-agent
harness via `agent-ports.json` or `agent-sockets.json` (#784 / #815).
Gateway-off deploys keep the direct TCP fallback so local-dev /
operator opt-out keeps working.

`forge`-kind nav-strip links still resolve against `:3000` (separate
sub-domain transition, tracked by `forge.behindGateway`);
`external`-kind links are already absolute.

Mirrors the `HIVE_MATRIX_GUI_ENABLED` env→snapshot-flag pattern.
Docs updated: `docs/web-ui.md::Container row` + new
`docs/gateway.md::Dashboard link shape` section.
2026-05-31 17:16:53 +02:00
atlas
ed3b9d853e nix/hive-network: bridge + dnsmasq resolver, opt-in (#805 v1)
Stand up the host-side bridge interface + per-agent DNS resolver
ahead of #14 (netns isolation). Mara on #805#11541: "we need it
before #14 so nothing breaks when we switch over". v1 ships the
endpoint live but containers stay on shared host netns — when #14
flips them to private netns the DNS contract is already there.

Shape:

- new `nix/modules/hive-network.nix` with `services.hyperhive.network.*`
  options (enable + bridgeName + bridgeIp + bridgePrefixLength +
  upstreamDns). Default off. Imported from `hive-c0re.nix`.
- bridge interface via `networking.bridges` (no slave NICs at v1;
  per-agent veth pairs attach once #14 lands).
- bridge IP assigned via `networking.interfaces`.
- `networking.firewall.interfaces.<bridge>.allowed{UDP,TCP}Ports =
  [ 53 ]` opens the resolver on the bridge interface only —
  other interfaces stay closed.
- dnsmasq config added to the existing `hive-gateway` container
  (mara on #805:10957: "put the resolver into the gateway container").
  Listens only on `bridgeName` + `lo`; authoritative for
  `<hive-domain>`, `forge.<hive>`, `matrix.<hive>` answering with
  the bridge IP; forwards everything else to upstream.
  `resolveLocalQueries = false` keeps the gateway container's own
  resolver untouched.

Asserts `services.hyperhive.domain != null` + `gateway.enable =
true` — both required for the resolver to be meaningful.

Docs: new `docs/network.md` covering v1 vs v2 split, container shape
rationale, default addressing, resolver behaviour, firewall posture.

`nix flake check` clean.
2026-05-31 16:56:59 +02:00
iris
84f3fe5f69 hive-ag3nt + docs: extract prompt-rendering prose (#716 batch 3) 2026-05-31 16:46:00 +02:00
iris
2bb8f2a3f7 hive-ag3nt + docs: extract identity prose (#716 batch 1) 2026-05-31 16:41:24 +02:00
atlas
4821f1a36e docs/gateway.md: drop duplicate 'Per-agent UDS upstream' section
mara/damocles wrote a fuller version of the same section at line 70
(`Per-agent unix-socket upstream (#784)`) as part of #832 — covers
the 4-step rollout flow including the .bound marker filter that
landed in #832. The atlas-side section at line 207 was the pre-#832
version with the eval-time path-exists gate notes; superseded.

Net effect: one canonical section on the unix-socket upstream story
rather than two with overlapping content.
2026-05-31 16:35:26 +02:00
damocles
90c72d9131 docs/gateway.md: section on the #784 unix-socket upstream chain (mara on #832) 2026-05-31 16:28:36 +02:00
iris
777d26812a hive-sh4re + docs: extract AgentMeta wire-shape prose (#717 batch 8) 2026-05-31 16:25:10 +02:00
iris
29fda64866 docs/approvals.md: split sha vs tag scoping per argus on #833 2026-05-31 16:25:03 +02:00
iris
f3fefe7f7e hive-sh4re + docs: extract HelperEvent prose (#717 batch 7) 2026-05-31 16:25:03 +02:00
iris
a12c097044 hive-sh4re + docs: extract Ask/Answer routing prose (#717 batch 2) 2026-05-31 16:18:01 +02:00
atlas
a043c61828 docs: extract best-effort oneshot service contract + matrix-avatar (#718 batch 6)
Two new sections housing rationale that was inline in
`harness-base.nix`:

- `docs/conventions.md::Best-effort oneshot services` — shape
  contract shared by `tea-login`, `forge-avatar-sync`, and
  `matrix-avatar-sync`: always exit 0, no `set -e`, skip silently
  on missing prerequisites, wired to multi-user.target,
  re-runnable. Plus the artefact-under-agent-home + service-stays-
  root posture and the operator-visible-via-journalctl trade-off.

- `docs/persistence.md::matrix-avatar-sync` — the two-step `media
  upload` → `set avatar_url` matrix-spec dance + why
  `RemainAfterExit = false` (so the `.path` watcher's re-fire on
  token appearance actually re-executes the unit).

In-code comments trim to one-liner purpose + pointers; the script
bodies stay (they're the actual implementation) but their inline
`#` rationale comments collapse where the docs cover them.

`description = ''…''` blocks (operator-facing options docs)
preserved per iris #718.

`nix flake check` clean; `nix fmt` clean.
2026-05-31 16:14:38 +02:00
iris
18d0fbfecb hive-sh4re + docs: extract Wake-injection prose (#717 batch 5) 2026-05-31 16:14:07 +02:00
atlas
3a29aee001 nix/hive-gateway: UDS upstream for /agent/<name>/ (#784 phase 2 step 3)
Switch per-agent gateway upstreams from TCP loopback to unix-domain
socket when the agent has opted in via `hyperhive.web.useUnixSocket`
(#822). Coexists with the TCP path during rollout.

Changes:

- New `agentSocketsFile` option (default
  `/var/lib/hyperhive/agent-sockets.json`) — c0re writes the map
  there via `hive_c0re::agent_sockets::write` (#809).
- `agentSocketsTable = lib.importJSON ...` (graceful empty when
  file missing).
- `agentUpstreamFor name port` picks `http://unix:<path>:/` when the
  socket has a JSON entry AND the file exists at eval time; else
  `http://127.0.0.1:<port>/`. Path-exists gate guards against
  c0re's blanket-emit shape during the canary window (agents in
  `agent-sockets.json` who haven't actually flipped have no
  bound socket on disk → fall back to TCP). Damocles will ship a
  `.bound` marker filter on the c0re side (#784 step 2d
  follow-up); once that's in, the path-exists check is redundant
  but harmless. Step 4 drops it entirely along with the TCP
  fallback.
- `containers.hive-gateway.bindMounts."/run/hive-agent"` —
  read-only, unconditional. Inert when no agents have opted in.
  Required so nginx inside the gateway container can `connect(2)`
  to the per-agent sockets damocles's #813 bind-mounts into agent
  containers at the same paths.

Docs:

- `docs/gateway.md::Per-agent UDS upstream (#784)` — full rollout
  flow, subdir-bind rationale (damocles #813), eval-time gate
  explainer, step 4 drop plan.

`nix flake check` clean; `nix fmt` clean.

Canary plan: once #822 (`useUnixSocket` option) lands + this PR
merges, manager flips atlas's agent.nix to `useUnixSocket = true`
via the config-update flow. End-to-end validation against atlas
before broader rollout.
2026-05-31 16:14:02 +02:00
iris
22b3e542c5 hive-sh4re + docs: extract LooseEnd wire-shape prose (#717 batch 4) 2026-05-31 16:13:24 +02:00
iris
a0b15ed6a4 hive-sh4re + docs: extract Approval lifecycle prose (#717 batch 3) 2026-05-31 16:12:36 +02:00
iris
a443108be5 hive-sh4re + docs: extract broker delivery/ack/requeue prose (#717 batch 1) 2026-05-31 15:53:00 +02:00
iris
7bb55bca43 docs/agent-hierarchy.md: scrub self-ref cookies (#719 batch 5) 2026-05-31 15:49:37 +02:00
iris
bd6b48a883 docs/persistence.md: scrub self-ref cookies (#719 batch 4) 2026-05-31 15:49:32 +02:00
iris
680d13b9e9 docs/gotchas.md: scrub self-ref cookies (#719 batch 3) 2026-05-31 15:46:02 +02:00
atlas
8a50f36c0c docs/agent-hierarchy.md: extract harness systemd unit shape (#718 batch 4)
Move the harness systemd unit rationale (role-driven unit name,
manager-only forge defaults, PATH wrapper-dir trick, env vars,
standalone-eval fallbacks, RuntimeDirectory + User= reasoning)
from `nix/templates/harness-base.nix` to a new
`docs/agent-hierarchy.md::Harness systemd unit shape (per-role)`
section.

In-code comments trim to short purpose statements + pointers; the
PATH /bin auto-append behaviour is already documented in
docs/gotchas.md, so the harness file just cross-refs both.

`description = ''…''` blocks (operator-facing options docs)
preserved per iris #718.

`nix flake check` clean; `nix fmt` clean (after formatter pass).
2026-05-31 15:44:41 +02:00
iris
5ca96b8c85 docs: scrub self-ref cookies across 5 files (#719 batch 2)
All five files scrubbed to 0 issue-ref cookies. Most refs were
'(closes #NNN)' style attribution after closed work landed.

- docs/turn-loop.md: 6 → 0 (#598 unified binary, #419 auth-fail,
  #542 mtime resumption, #519 role markers, #442 spawn path,
  #474/#478 partial edit)
- docs/approvals.md: 5 → 0 (#317 flake validation, #250 withdraw,
  #441 rebuild-queue dispatch, #753 manager port hash, #425
  crash-watch grace)
- docs/terminal-rendering.md: 2 → 0 (#666 ask-operator inline)
- docs/conventions.md: 3 → 0 (#753 port hash, #692 parent
  sentinel, #486 reparenting)
- docs/security.md: 4 → 0 (#240 + #658 ×2 + #673/#678 attribution)

Combined with PR #810 (docs/web-ui.md 14→0), this PR closes the
small / medium files. Remaining: agent-hierarchy.md (13),
gotchas.md (13), persistence.md (13). gateway.md is atlas's lane.
2026-05-31 15:39:09 +02:00
atlas
a8d8159038 docs/matrix.md: extract hive-matrix prose (#718 batch 5)
New top-level matrix doc covering everything that doesn't fit
elsewhere:

- Container shape (nixos-container, shared host netns, name choice,
  state persistence) — sibling to gateway.md::hive-forge container shape.
- Identity vs API listener: serverName vs gatewayHost split with the
  #660 breaking change.
- Default-closed firewall + federation port 8448 caveat.
- Provisioning flow: registration token activation, bind-mount,
  LoadCredential, hive-c0re's per-agent register + access_token
  persistence. Captures #565 first-boot race + #644 / iris 8043
  ownership shape.
- Assertion rationale (serverName, gatewayHost == "").
- fluffychat-web build fixes (#685): Imaging.{js,wasm} emscripten
  derivation + dart compile worker fixup, build-CWD path lesson
  from #685 / #733.
- Sequencing history.

In-code # comments trim to short purpose statements + docs pointers.
description = '' blocks (operator-facing options docs) preserved per
iris #718. ~140 lines removed from hive-matrix.nix.

`nix flake check` clean; `nix fmt` clean.
2026-05-31 15:38:43 +02:00
iris
ac83404f1c docs/web-ui.md: scrub self-ref cookies (#719 batch 1)
14 issue-ref cookies removed from docs/web-ui.md. Most were
attribution refs to closed issues that landed the feature being
described — the prose around them already describes the current
behaviour, the cookie was just a 'this was issue NNN' breadcrumb.

Scrubbed:
- #753 (manager port hash 8100-8999)
- #233 (linkify XSS)
- #448 (SSE multiplexing SharedWorker)
- #515 (worker-death self-heal)
- #451 (side-panel drag-to-resize)
- #635 (matrix.gui.enable defaults)
- #609 + #15 (gateway re-root) → 'lives in docs/gateway.md'
- #66 (ctx badge thresholds)
- #541 (journald panel-body column-flex)
- #447 (rebuild-queue cancel)
- #559 (mark all read)
- #474 (schedules PATCH partial edit)
- #467 (schedules fire-now)
- #589 (hive-qualified label phase A)

docs/web-ui.md: 14 → 0 issue-ref cookies. Self-contained read.
2026-05-31 15:38:28 +02:00
atlas
db2a48cde6 docs/gotchas.md: extract nix/{assets,docs,templates/weston-vnc} prose (#718 batch 3)
- assets.nix: cargo-cache-invalidation rationale → "Split asset
  derivations away from the rust workspace" section.
- templates/weston-vnc.nix: port allocation, weston bind-address
  quirk, PAM service name, Type=simple choice, idle-time=0 →
  "Weston VNC compositor (per-agent hyperhive.gui.enable)" section.
- docs/default.nix: rendering pipeline + subtree-pick + output-tree
  history → "Nix options reference" section.

In-code comments trimmed to short purpose statements + docs pointers.
description = '' blocks (operator-facing options docs) preserved per
iris #718.

`nix flake check` + `nix build .#docs` clean.
2026-05-31 15:24:39 +02:00
iris
f60a90d752 shared terminal + docs: migrate sticky-scroll + backfill prose (#714 batch 1)
Substantial prose migration from @hive/shared/terminal.js (the
shared HiveTerminal factory backing #msgflow + #live across both
dashboard and per-agent UIs) into a new docs subsection.

Added to docs/web-ui.md as a new ### Shared terminal pane
subsection under ## Shape (shared by both) — ~78 lines of new
substantive prose:

- **api shape**: row / details / detailsDiff factory contract
- **Sticky-bottom + snap animation**: stickToBottom semantics +
  140ms ease-out vs 500ms browser default + 24px short-circuit;
  per-frame target re-eval extends destination through
  mid-animation mutations
- **Mid-animation scroll-event guard**: smoothScrollingUntil
  timestamp swallows the rAF-driven scroll events so the eased
  positions don't flip stickToBottom false partway
- **Post-append MutationObserver**: catches renderer mutations
  after api.row returns (badges, multi-line bodies, tool panes)
  + why programmatic scrollTop writes don't feedback-loop
- **Backfill + SSE**: history/stream envelope shape (seq, events),
  kind-aware seq dedupe at the boundary, .no-anim during replay,
  optional streamFactory for SharedWorker integration
- **linkify**: text-node-only autolink, XSS-safe by construction,
  trailing-punctuation strip

Collapsed in terminal.js (cookies en passant):
- #400 (snap animation timing — closed) × 3 → docs pointers
- #393 (post-append MutationObserver — closed) × 1 → docs pointer
- #375 (pre-append nearBottom snapshot — closed) × 1 → docs pointer
- #448 (streamFactory SharedWorker hook — closed) × 1 → docs pointer
- #163 (seq dedupe + onStreamOpen resync — closed) × 2 → drop
  cookies; substance lives in docs
- #233 (linkify) × 1 → docs pointer + terminal.css cookie scrub

terminal.js: 8 → 0 #NNN cookies (100% reduction).
terminal.css: 1 → 0 issue-ref cookies (remaining 1 match is a
hex color literal).
Net effect: ~50 lines of substantive WHY-prose moved out of
shared frontend into docs/web-ui.md, where it documents the
factory's contract for both consumer pages.
2026-05-31 15:18:31 +02:00
iris
6c9b28903f dashboard.css + docs: migrate MESS4GE FL0W body layout + final cookie scrub (#712 batch 13)
Second dashboard.css batch — scrubs all remaining #NNN cookies
(post-batch-12 dashboard.css went from 51 → 36 raw matches, mostly
hex colors). This batch zeroes out the actual issue refs.

Moved to docs/web-ui.md::FL0W page:
- **MESS4GE FL0W (extended)**: msgrow flex-wrap row + body
  flex-basis: 100% + min-width: 0 rationale (~10 lines new prose).
  Without flex-basis: 100% the body sat inline eating whatever the
  chips left, starting ~30ch in on long timestamps + agent names
  and wrapping awkwardly. Pushing it to its own line lets the body
  use the full row width.

Collapsed in dashboard.css (en passant cookie scrubs across many
small comments):
- #485 msgrow body flex (→ FL0W docs pointer)
- #450 inbox max-height (→ inline rationale only, cookie dropped)
- #451 side-panel drag-to-resize × 2 (→ Side panel docs pointer)
- #369 dashboard chrome (→ Tab strip pointer)
- #416 full-width layout (→ inline rationale, cookie dropped)
- #389 slug banner footer (→ inline rationale, cookie dropped)
- #369#issuecomment-3437 + #362 + #383 + #383 + #362 flow.html
  section (→ FL0W page pointer + per-agent header pills pointer)
- #375 tail pill stacking context (→ Per-agent page Terminal-wrap
  pointer to existing docs)
- #66 ctx badge thresholds (→ Container row Line 1 pointer)
- #541 panel-body column flex × 2 (→ inline rationale, cookie dropped)
- #188 / #192 image preview (→ Side panel pointer)
- #275 bulk select × 2 (→ inline, cookies dropped)
- #259 background meta-update (→ inline, cookie dropped)
- #474 inline edit button + form (→ inline, cookies dropped)
- #466 interval composer (→ inline, cookie dropped)
- #535 schedules-as-table × 2 (→ SCH3DUL3S tab pointer + inline)
- #564 inline create row (→ inline, cookie dropped)
- #443 selection bar (→ Selection bar pointer)
- #486 M0V3 → <pick> (→ Selection bar pointer)
- #459 scheduled prompts tab section (→ SCH3DUL3S tab pointer)

dashboard.css: ~20 issue refs scrubbed in this batch + ~10 lines
substantive prose migrated to MESS4GE FL0W. Total dashboard.css
across batches 12 + 13: 51 raw matches → 0 issue-ref cookies
(only hex colors remain).
2026-05-31 15:09:54 +02:00
atlas
24775845a3 nix/hive-gateway: static not-found + unreachable pages for /agent/<name>/ (#755)
mara on #755: "e.g. /agent/name should show an error page stating
that the agent could not be found if missing in json or that it is
not reachable if we get a connection error. we dont want a fully
generic fallback, only for routes already special cased in the
nginx config."

Adds two static HTML pages built at deploy time via
`pkgs.runCommand "hyperhive-agent-error-pages"`:

- **not-found.html** — served when `/agent/<unknown>/...` hits the
  bare `/agent/` catch-all. The catch-all `return 404`s, and
  `error_page 404 = /__hive_agent_not_found` rewrites to the static
  page.
- **unreachable.html** — served when `/agent/<known>/...` proxy_pass
  to the harness returns 502 / 503 / 504. `proxy_intercept_errors
  on` + `error_page 502 503 504 = /__hive_agent_unreachable` on each
  per-agent location block rewrites to the static page.

Mechanics:

- `agentErrorPagesDir` (in the `let` block) is a `runCommand` that
  emits two HTML files using a `<<EOF` heredoc — no template engine
  needed.
- Two `internal` nginx locations (`= /__hive_agent_not_found`,
  `= /__hive_agent_unreachable`) `alias` the exact files. `internal`
  keeps the URIs unreachable from direct operator request — only
  nginx's own error-handling can hit them.
- Per-agent location blocks pick up the `error_page` directive
  through the existing `lib.mapAttrs'` over `agentPortsTable`. No
  per-agent generated content; same static page for all.
- `/agent/` catch-all generates from a tiny optionalAttrs alongside
  the per-agent block — both are no-op when the agent table is
  empty (matches the pre-#15 shape).

Pages: minimal inline CSS, catppuccin palette matching the
dashboard (`#1e1e2e` bg, `#cdd6f4` text, `#cba6f7` not-found heading,
`#f9e2af` unreachable heading). No frontend-dist dependency — render
even when hive-c0re is down. Both link back to `/`.

Per mara's "only for routes already special cased" — scope stays
narrow. Forge / matrix / fluffychat keep nginx defaults; extending
the custom-error pattern to other vhosts is a separate follow-up
if/when needed.

Verified:
- nginx location attrset has `["/", "/agent/", "= /__hive_agent_not_found", "= /__hive_agent_unreachable"]`
- container toplevel builds clean (`nixos-system-hive-gateway-26.05pre-git`)
- `docs/gateway.md::Per-agent error pages` section captures the
  design + rationale + intentional narrowness

Closes #755.
2026-05-31 15:04:54 +02:00