✅ System State View — Wired and Tested
Endpoint: GET /system/state
Status: Complete ✅
Date: 2026-04-26
What's Live
API Endpoints
| Endpoint | Response | Status |
|---|---|---|
GET /system/state |
HTML dashboard with HTMX polling | ✅ 200 |
GET /system/state?format=json |
JSON schema | ✅ 200 |
GET /static/system-state.css |
Stylesheet | ✅ 200 |
Files Added/Modified
API (core/api.py):
- Added system_state() endpoint (lines ~160-240)
- Added Jinja2 template rendering
- Added static file serving (/static/)
- Added custom format_time filter
Templates (templates/):
- base.html.j2 — Base template with HTMX, CSS links
- system-state.html.j2 — Dashboard (from Daedalus' handoff)
Static (static/):
- system-state.css — Bar charts, member colors, layout (from Daedalus)
JSON Schema
{
"family": {
"family_id": "hoffmann",
"member_count": 4,
"rule_count": 7
},
"members": [
{
"id": "sullivan",
"name": "Sullivan",
"nickname": "Sully",
"current_grade": "1st",
"school": "",
"teacher": "",
"calendar_color": "blue",
"stats": {"documents_routed": 0, "avg_confidence": 0.9}
}
],
"rules": [
{
"id": "rule_001",
"description": "...",
"pattern": "(?i)\\b(sullivan|sully)\\b",
"assign_to": ["sullivan"],
"confidence": 0.9,
"status": "active",
"last_triggered": "2026-04-26T14:30:00Z",
"trigger_count": 0
}
],
"routing_decisions": [],
"telemetry": {
"total_documents": 0,
"auto_routed": 0,
"user_asked": 0,
"errors": 0,
"avg_processing_time_ms": 0,
"confidence_distribution": {"high": 0, "medium": 0, "low": 0}
}
}
HTML Dashboard Sections
- Header — Family name, member count, rule count
- Stats Row — Total docs, auto-routed %, asked-user %
- Members — Color-coded avatars, grade/teacher, docs routed, confidence bars
- Active Rules — ID, description, regex pattern, target members, trigger count
- Confidence Distribution — CSS bar chart (high/medium/low)
- Recent Routing Decisions — Last 10 with status icons
HTMX Polling: hx-trigger="load, every 30s"
TODOs for Production
Telemetry (High Priority)
- [ ] Wire
documents_routedto actual ingress spooler counts - [ ] Wire
avg_confidenceto LLM confidence scores - [ ] Wire
auto_routed/user_askedcounters - [ ] Wire
last_triggeredtimestamps per rule - [ ] Wire
trigger_countper rule
Routing Decisions (High Priority)
- [ ] Connect to ingress spooler decision log
- [ ] Store last N decisions in SQLite
- [ ] Add decision status (auto/asked/error)
Performance (Medium Priority)
- [ ] Cache family config (reload on file change)
- [ ] Cache telemetry (30s TTL)
- [ ] Add request timing metrics
Security (Medium Priority)
- [ ] Add auth middleware (API key or session)
- [ ] Rate limiting on polling endpoint
- [ ] Audit log for dashboard access
Design Compliance
✅ Contract-First: API spec written first, UI built against it
✅ Read-Only: No forms, no mutations
✅ HTMX Polling: 30s auto-refresh
✅ Zero Frontend Code: Daedalus owns CSS/templates, Socrates owns data
✅ Family Colors: blue/pink/purple/green from hoffmann.yaml
Testing
# JSON
curl http://localhost:8000/system/state?format=json
# HTML
curl http://localhost:8000/system/state
# CSS
curl http://localhost:8000/static/system-state.css
Test results: All passing ✅
Next Steps
- Telemetry wiring — Connect to ingress spooler when Phase 4 is complete
- Auth — Add CF Access headers or API key middleware
- Performance — Add caching layer for family config
- Real data — Replace placeholders with actual metrics
Handoff: Ready for Daedalus review. CSS and templates are in his domain if tweaks needed.