📄 wadsworth-dashboard-brief.md 6,823 bytes Apr 29, 2026 📋 Raw

Wadsworth — Dashboard Operations Brief

From: Daedalus 🎨
Date: 2026-04-28
Purpose: Routing, config, and monitoring for the Family Dashboard


1. Architecture Overview

family.hoffdesk.com
  ↓ Cloudflare Tunnel
  ↓ (Host: family.hoffdesk.com)
  ↓
titanium-butler:8000 ← main_v2.py (Starlette host routing)
  ├── family_app (when Host: family.hoffdesk.com)
  │   ├── SessionAuthMiddleware ← all routes except /login, /static/
  │   ├── auth_router  →  GET /login, POST /login, GET /me, POST /logout
  │   ├── dashboard_router → GET / (dash HTML), GET /family/login/, GET /api/today
  │   ├── family_router → /admin/... (family automation)
  │   ├── imap_router → IMAP proxy dashboard
  │   └── WebSocket endpoints (future)
  │
  └── blog app (all other hosts)

There is also a second server on port 8001:

titanium-butler:8001 ← Icarus staging API (icarus.core.api)
  ├── /api/today ← calendar + weather + health JSON
  ├── /api/event_graph/... ← Event Graph CRUD
  ├── /system/state ← System state dashboard HTML
  └── Jinja2 templates ← index.html.j2 (HTMX version)

Current state: The family.hoffdesk.com app (port 8000) serves a static index.html without the Event Graph cards. The Icarus server (port 8001) has the Jinja2 template with HTMX wiring but lacks auth middleware and isn't behind the tunnel.


2. Routes & Endpoints

Auth (family_app, port 8000)

Method Path Purpose Status
GET /family/login/ Login page ✅ Live
POST /login Login handler (JSON body) ✅ Live
GET /me Session check ✅ Live
POST /logout Clear session ✅ Live

Credentials (from .env):
- matt / hoffdesk-matt-2026 — roles: admin, editor
- aundrea / hoffdesk-aundrea-2026 — roles: family

Dashboard (family_app, port 8000)

Method Path Purpose Status
GET / Dashboard (requires auth) ✅ Live
GET /api/today JSON: calendar+weather+health ✅ Live

Icarus API (port 8001, internal)

Method Path Purpose Status
GET /api/today Calendar + weather + health JSON ✅ Live
GET /api/event_graph/stats Event Graph aggregate stats ✅ Live
GET /api/event_graph/recent Recent events from graph ✅ Live
GET /api/event_graph/coordination Coordination items ✅ Live
GET /system/state System state dashboard HTML ✅ Live
GET / or /family/ Dashboard HTML (Jinja2, HTMX) ✅ Live
GET /family/login/ Login page ✅ Live

Running the Icarus Server

cd /home/hoffmann_admin/.openclaw/workspace/services/icarus
ICARUS_ENV=staging \
PYTHONPATH=/home/hoffmann_admin/.openclaw/workspace/services:$PYTHONPATH \
nohup uvicorn icarus.core.api:app --host 0.0.0.0 --port 8001 --log-level info > /tmp/icarus-api.log 2>&1 &

3. What's Working (Daedalus ✅)

  • Family dashboard served at family.hoffdesk.com with auth
  • Login flow: page → POST /login → session cookie → redirect to dashboard
  • /api/today returns calendar (Radicale), weather (wttr.in), health (live pings)
  • Static assets served at /static/ (style.css, favicon.svg, system-state.css)
  • Event Graph API endpoints on port 8001
  • CSS polish: Event Graph cards, IMAP proxy, iPad responsive (shared/project-docs/dashboard/static/style.css)

4. What Needs Routing / Config (Wadsworth)

Critical

  • [ ] Monitor the Icarus server process on port 8001 — start it on boot, restart if it dies
  • [ ] ICARUS_ENV must be staging for the assert in api.py line 11
  • [ ] PYTHONPATH must include /home/hoffmann_admin/.openclaw/workspace/services for the icarus package to resolve

Config Management

  • [ ] HOFFDESK_USERS env var in .env contains the credential map — do NOT expose in logs
  • [ ] SESSION_SECRET_KEY should be set for production (currently defaults to dev-secret)
  • [ ] RADICALE_HOST/PORT/USER/PASS — used by dashboard router for calendar data
  • [ ] Cloudflare tunnel routes family.hoffdesk.com to localhost:8000

Dashboard Template Path (important)

The dashboard router on port 8000 reads templates from:

/home/hoffmann_admin/.openclaw/shared/project-docs/dashboard/templates/

This is a shared path — if I update templates, they're live immediately. Don't move them.

Event Graph

The Event Graph API runs on port 8002 and feeds into the dashboard. If 8002 is down, /api/today returns empty events gracefully (no crash).


5. Monitoring

Health Check Endpoints

GET http://localhost:8000/health        → blog API health
GET http://localhost:8001/api/today     → Icarus health (check status fields)
GET http://localhost:8002/health        → Event Graph health
GET http://localhost:5232/              → Radicale CalDAV health

What to Watch

  1. Port 8001 — Icarus API dies if PYTHONPATH is wrong
  2. Port 8002 — Event Graph API (needs separate startup)
  3. Radicale on 5232 — calendar source; dashboard degrades gracefully but quietly
  4. Cloudflare tunnel — if it drops, family.hoffdesk.com is unreachable

Model Health Watchdog

See shared/processes/model-health-watchdog.md for the model ping spec. Not yet implemented.


6. Quick Commands

# Check dashboard is alive
curl -s -H "Host: family.hoffdesk.com" -o /dev/null -w "%{http_code}" http://localhost:8000/

# Check API response
curl -s -H "Host: family.hoffdesk.com" http://localhost:8000/api/today | python3 -m json.tool

# Restart Icarus API
kill $(lsof -t -i:8001)
sleep 2
cd /home/hoffmann_admin/.openclaw/workspace/services/icarus && \
ICARUS_ENV=staging PYTHONPATH=/home/hoffmann_admin/.openclaw/workspace/services:$PYTHONPATH \
nohup uvicorn icarus.core.api:app --host 0.0.0.0 --port 8001 --log-level info > /tmp/icarus-api.log 2>&1 &

# Check logs
tail -20 /tmp/icarus-api.log

# Test auth flow
curl -s -c /tmp/hcookie.txt -X POST http://localhost:8000/login \
  -H "Content-Type: application/json" \
  -d '{"username":"matt","password":"hoffdesk-matt-2026"}'
curl -s -b /tmp/hcookie.txt -H "Host: family.hoffdesk.com" http://localhost:8000/

7. URLs

URL Destination Auth
https://family.hoffdesk.com/ Family dashboard Session cookie
https://family.hoffdesk.com/family/login/ Login page None
https://hoffdesk.com/ Blog (public) None
https://hook.hoffdesk.com/ Webhooks Token

Questions? Ping @Daedalus89Bot on Telegram or drop a note in shared/project-docs/