diff --git a/docs/web-ui/dashboard.md b/docs/web-ui/dashboard.md index 0918dab6..639bbdec 100644 --- a/docs/web-ui/dashboard.md +++ b/docs/web-ui/dashboard.md @@ -231,20 +231,37 @@ read from `GET /api/matrix-accounts?agent=` → `{ accounts: [ { name, homeserver, token_present, live, user_id } ], as_of_unix }`. `token_present` is whether a token is **stored**; `live`, `homeserver`, and `user_id` are backfilled from the matrix daemon's -`matrix-accounts.json` snapshot — a host-visible file the daemon writes at -startup after its sessions restore (an account with a token but absent -from the snapshot reports `live: false`). `as_of_unix` is the snapshot's -mtime (null when absent), so the dot can show "live as of N ago". The -snapshot is rewritten each daemon (re)start, so an old `as_of_unix` is -ambiguous (stable uptime vs dead daemon) — the live-status dot rendering -(3-state + snapshot-age tooltip, cross-referencing container-running -state) is the dashboard-side follow-up. +`matrix-accounts.json` snapshot — a host-visible file the daemon +**force-rewrites every ~30s** (a heartbeat), so `as_of_unix` (the +snapshot mtime) advances while the daemon is alive and a *stalled* value +genuinely means "stopped publishing", not just "old snapshot". An account +with a token but absent from the snapshot reports `live: false`. + +The status dot renders these states: + +- **green** — `live` and the container is running: online. +- **dim green** — `live` but `as_of_unix` hasn't advanced in > ~90s (3 + missed heartbeats) while the container is *not* down: the daemon stopped + publishing, so the snapshot's `live` is no longer trustworthy (likely + dead/wedged). Labelled "online · no heartbeat". +- **amber** — `live` but the container is **down** (a stopped container + ⟹ a dead daemon, so the snapshot is stale); also the `token_present && + !live` "provisioned but offline" case. +- **grey** — no token (not provisioned). + +The container-down cross-reference (`/api/state`) takes precedence over +the age check. `as_of_unix` is tooltipped ("live as of N ago") throughout +so freshness is always legible. When `live` is absent (an older backend +without the snapshot) the dot falls back to a token-present rendering. The provision form (account name, homeserver, login method) posts -`POST /matrix-account-login` (`x-www-form-urlencoded`, operator-auth): +`POST /api/matrix-account-login` (`x-www-form-urlencoded`, operator-auth): fields `agent, account, homeserver, mode=password|token, user_id?, -password?, token?` → `2xx { ok, user_id }` on success or -`4xx { error }` on failure. The host coordinator performs the login +password?, token?` → `200 { ok, user_id }` on success. Failures come back +as RFC 9457 `application/problem+json` (`{ type, title, status, detail }`) +with the human-readable message in `detail` and the status code reflecting +the cause (400 for a validation error, 500 for a login / `whoami` / +internal failure); the page reads `detail` for display. The host coordinator performs the login (password) or validates the token (`whoami`) and writes the bearer to the agent's `matrixAccounts..tokenFile` via the same privileged write path as the hive-internal `matrix-token`; the token is