arizuko › components › dashd
dashd is the operator dashboard: an HTMX server that renders pages over messages.db and allow-listed memory files. Reads are the default; the only write paths are PUT and DELETE on a fixed list of markdown files under each group’s folder.
Routes live at /dash/*. The portal at /dash/ links to status, tasks, activity, groups, memory, and profile pages, each rendered server-side as one HTML page plus HTMX partials for live sub-views.
Without dashd, operators inspect an arizuko instance through sqlite3 messages.db, journalctl -u arizuko_<inst>, and the arizuko CLI. That works but does not scale to non-engineers and does not give a one-screen answer to “what is this instance doing right now”.
dashd owns no tables of its own. It is an aggregator: it reads from groups, routes, scheduled_tasks, messages, sessions, channels, and auth_users — tables owned by gated, timed, and onbod — and renders them. The plan in specs/5/5-uniform-mcp-rest.md is to migrate those direct reads onto the sibling daemons’ /v1/* APIs; dashd becomes pure client.
operator browser
|
v /dash/...
|
proxyd requireAuth: JWT or refresh-token cookie
| stamp X-User-Sub, X-User-Groups, HMAC sig
v
dashd render HTML / HTMX partial
| read: messages.db (today)
| write: PUT|DELETE /dash/memory/{folder}/{rel}
v
filesystem: <groups>/<folder>/MEMORY.md, diary/*.md, ...
dashd reads identity from signed headers set by proxyd’s requireAuth. Write verbs go further: every TIER 1 mutation runs requireAdmin, which calls auth.Authorize with action admin against the caller’s groups, plus a same-origin CSRF guard. Read views still depend on proxyd alone for the front gate.
Two write surfaces today. Memory editor accepts MEMORY.md, .claude/CLAUDE.md, and flat *.md under diary/, facts/, users/, episodes/; reads capped at 1 MiB; path joiner blocks symlink escape. TIER 1 admin — routes editor, groups CRUD, per-user secrets — gated by the admin check above.
dashd needs a SQLite file and a port. The TIER 1 write surface refuses requests without a signed admin identity; read views still need proxyd’s front gate to be safe on the public internet.
export DATA_DIR=/srv/data/arizuko_demo
export DASH_PORT=:8080
export INSTANCE_NAME=demo
./dashd
# browse http://localhost:8080/dash/
DATA_DIR resolves the database at $DATA_DIR/store/messages.db and the groups tree at $DATA_DIR/groups/. Set DB_PATH to override the database location independently. INSTANCE_NAME appears in the portal header.
Health: GET /health returns 200 when the database is reachable. Exposing dashd directly on the public internet skips the auth gate — do not do this.
Read views (each one HTML the browser renders directly):
/dash/ — portal index linking the other pages./dash/status/ — groups, sessions, channels at a glance./dash/activity/ — the last 50 messages across all groups./dash/tasks/ — scheduled tasks from scheduled_tasks./dash/groups/ — group folders with their channel routes./dash/memory/ — the editable markdown view per group./dash/profile/ — the calling user’s auth_users row.HTMX partials (tasks/x/list, activity/x/recent) feed live sub-views.
TIER 1 admin surfaces (admin auth + CSRF):
/dash/routes/ — routes editor: list, create, edit, delete rules./dash/groups/new + /dash/groups/{folder}/settings — group create / settings / delete./dash/me/secrets — per-user secret set, list, delete./dash/channels/whatsapp/pair — self-service WhatsApp re-pair page. Requires the ** operator super-grant. Calls whapd /v1/pair/start; the pairing code is returned once, expires in 60s, rate-limited to 5/hr. Every start writes an audit row in messages.Today every page queries SQLite directly. The plan is to swap each read for a call to the sibling daemon that owns the table:
/dash/groups/ → gated/v1/groups + gated/v1/routes./dash/tasks/ → timed/v1/tasks (with a form POST for create)./dash/activity/ → gated/v1/messages?limit=50&order=desc./dash/profile/ → onbod/v1/users/{sub}.After the migration dashd holds an operator session token (issued by proxyd at OAuth login), forwards it as Authorization: Bearer ... on every /v1/* call, and stops touching messages.db at all.
dashd does not send messages, schedule tasks, mint tokens, or admit users — those belong to gated, timed, proxyd, and onbod. Writes are scoped to the surfaces listed above: memory editor and TIER 1 admin. Everything else is a view.
specs/5/5-uniform-mcp-rest.md — the /v1/* migration plan.specs/4/Q-dash-memory.md — memory view and edit surface.