Implement Component 36: Guided Troubleshooting

Proactive contextual help that appears when users encounter problems,
but never when things are working well.

Trigger conditions:
- Detection quality drop: Zone-level quality below 60% for >24h
  triggers helpful banner with guided diagnostics flow
- Repeated setting changes: Same settings key modified 3+ times
  within 60-minute sliding window triggers helpful hint
- Node offline: Any node offline for >2 hours shows troubleshooting
- First-time feature discovery: Brief tooltip shown once per feature
- After false positive feedback: Inline response explaining adjustments
- After successful calibration: Positive reinforcement message

Implementation:
- ZoneQualityTracker: Tracks per-zone detection quality, triggers
  callbacks when quality degrades
- EditTracker: Monitors settings edits for repeated changes
- FleetNotifier: Tracks node offline events
- DiscoveryTracker: Manages first-time feature tooltips
- API endpoints: /api/guided/* for diagnostics and feedback

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
jedarden 2026-05-06 06:18:42 -04:00
parent a3bca68150
commit 3d0bb8bf45
7 changed files with 2348 additions and 3 deletions

View file

@ -3,7 +3,7 @@
{"id":"bf-1k3zg","title":"API: GET /api/doctor — pre-flight configuration diagnostic","description":"## Goal\nAdd a GET /api/doctor endpoint that diagnoses common misconfiguration before the user concludes the system is broken. Complements /healthz (runtime state) with pre-flight checks (configuration correctness).\n\n## Endpoint\n\nGET /api/doctor\n- Requires session cookie (same as all /api/* endpoints)\n- Returns 200 with a JSON report regardless of check results (HTTP status reflects reachability, not check results)\n\n## Checks to run\n\n| Check | Pass condition | Fail message |\n|---|---|---|\n| data_dir_writable | /data is writable and has >100 MB free | 'Data directory not writable' or 'Disk space low: Nf MB free' |\n| db_integrity | PRAGMA integrity_check returns 'ok' | 'SQLite integrity check failed' |\n| firmware_dir | /firmware contains at least one *.bin file | 'No firmware binaries found — OTA updates unavailable' |\n| mdns_binding | mDNS service is registered (or SPAXEL_MDNS_ENABLED=false) | 'mDNS not advertising — nodes cannot auto-discover mothership' |\n| mqtt_reachable | If SPAXEL_MQTT_BROKER is set: TCP connect to broker succeeds within 3s | 'MQTT broker unreachable: <broker_url>' |\n| ntp_reachable | UDP ping to SPAXEL_NTP_SERVER:123 resolves within 3s | 'NTP server unreachable — node clock sync may fail' |\n| install_secret | install_secret row exists in auth table | 'Installation secret missing — re-run container to regenerate' |\n| pin_configured | pin_bcrypt is non-null in auth table | 'Dashboard PIN not configured — run first-time setup' |\n| node_token_consistency | All nodes in registry have non-null node_token | 'N nodes missing auth tokens — re-provision via Web Serial' |\n\n## Response format\n\n{\n 'checks': [\n {'name': 'db_integrity', 'status': 'ok', 'message': null},\n {'name': 'mqtt_reachable', 'status': 'warn', 'message': 'MQTT broker unreachable: mqtt://ha.local:1883'},\n {'name': 'firmware_dir', 'status': 'error', 'message': 'No firmware binaries found'}\n ],\n 'overall': 'warn', // 'ok' | 'warn' | 'error' (worst of all checks)\n 'checked_at': '2024-03-15T07:00:00Z'\n}\n\nStatus levels: 'ok' (pass), 'warn' (degraded but functional), 'error' (action required).\n\n## Dashboard integration\n- Command palette: 'doctor' → calls /api/doctor, shows results inline\n- Guided troubleshooting (Component 36): 'Node offline' flow links to 'Run diagnostics' which calls /api/doctor\n- /healthz already covers runtime health; /api/doctor covers configuration health — keep them separate\n\n## Acceptance\n- GET /api/doctor returns 200 with all checks when fully configured\n- Reports 'firmware_dir: error' when /firmware is empty\n- Reports 'mqtt_reachable: warn' when MQTT broker env is set but broker is unreachable\n- Unit tests cover each check in isolation with mocked dependencies","design":"","acceptance_criteria":"","notes":"","status":"closed","priority":2,"issue_type":"task","assignee":"claude-code-glm-4.7-golf","created_at":"2026-05-02T12:22:51.188946318Z","updated_at":"2026-05-05T12:39:28.566216915Z","closed_at":"2026-05-05T12:39:28.566216915Z","close_reason":"Completed","source_repo":".","compaction_level":0}
{"id":"bf-1t0kn","title":"OTA auto-update with canary strategy and quiet window","description":"Plan specifies a canary OTA strategy (Component 6): update one node first, monitor quality for 10 min, then roll out fleet-wide. Also needs a configurable quiet window (default 02:0005:00 local) and auto-update mode toggle. Currently the fleet manager only does manual rolling OTA — no canary logic, no scheduled quiet window, no auto-update-on-firmware-detect. Implementation needed in internal/ota and/or fleet manager with a settings key for auto_update_enabled, quiet_window, canary_duration_min.","design":"","acceptance_criteria":"","notes":"","status":"closed","priority":2,"issue_type":"task","assignee":"claude-code-glm-4.7-foxtrot","created_at":"2026-05-02T18:24:59.888109951Z","updated_at":"2026-05-05T16:42:25.163065452Z","closed_at":"2026-05-05T16:42:25.163065452Z","close_reason":"Completed","source_repo":".","compaction_level":0}
{"id":"bf-232u3","title":"GET /api/notifications/preview — rendered test thumbnail endpoint","description":"Plan (Component 30, Renderer spec) specifies a test endpoint: GET /api/notifications/preview?type=fall&person=Alice returns a rendered test image for UI development and QA. The render package (internal/render/floorplan.go) implements thumbnail generation with fogleman/gg, but the preview HTTP endpoint is never registered in main.go. Needs: handler that accepts ?type and ?person query params, calls the appropriate Generate*Thumbnail function, returns the PNG bytes with Content-Type: image/png.","design":"","acceptance_criteria":"","notes":"","status":"closed","priority":2,"issue_type":"task","assignee":"claude-code-glm-4.7-foxtrot","created_at":"2026-05-02T18:25:20.897907993Z","updated_at":"2026-05-05T17:25:10.053618969Z","closed_at":"2026-05-05T17:25:10.053618969Z","close_reason":"GET /api/notifications/preview endpoint already implemented and registered in commit 37571ec. The endpoint accepts ?type (fall, anomaly, zone_enter, sleep) and ?person query params, calls the appropriate Generate*Thumbnail function from internal/render/floorplan.go, and returns PNG bytes with Content-Type: image/png. All tests pass.","source_repo":".","compaction_level":0}
{"id":"bf-25dmx","title":"Guided troubleshooting (Component 36)","description":"## Goal\nWhen system detects that user might be struggling or detection quality has degraded, proactively offer contextual help — but never when things are working well.\n\n## Trigger conditions and responses:\n\nDetection quality drops:\n- Condition: Zone-level detection quality below 60% for >24 hours\n- Banner in timeline and 3D view: 'Detection in the kitchen has been less reliable this week. Want me to help diagnose?'\n- Guided flow: Check node connectivity → show link health with explainability → suggest node repositioning → offer re-baseline → 'Still not right? Try adding a node here [highlighted position]'\n\nRepeated setting changes:\n- Condition: Same settings key modified 3+ times within 60-minute sliding window (qualifying keys: delta_rms_threshold, breathing_sensitivity, tau_s, fresnel_decay, n_subcarriers)\n- Tracking: per-key edit counter in memory, resets after 60 min inactivity\n- Trigger: when counter reaches 3, set hint_pending flag\n- Frontend: show non-intrusive banner: 'You've adjusted the detection threshold several times. Would you like me to show you what the system is seeing?' with [Show me] and [×] dismiss\n- [Show me]: opens time-travel to most recent detection event before first edit, with explainability overlay pre-activated\n- Cooldown: 24 hours after hint is shown\n\nNode offline:\n- Condition: Any node offline for >2 hours\n- Timeline event with expandable troubleshooting steps\n\nFirst-time feature discovery:\n- Condition: User opens feature panel for first time\n- Brief, non-intrusive tooltip (not modal): 'Draw a box around an area, then choose what happens when someone enters or leaves. [Got it]'\n- Shown once, never repeated\n\nAfter false positive feedback:\n- Inline response in timeline: 'Got it. I've slightly raised the detection threshold for the contributing links. If this keeps happening at this time of day, my hourly baseline will adapt within a few days.'\n\nAfter successful calibration:\n- Positive reinforcement: 'Re-baseline complete. Detection quality in the kitchen improved from 64% to 89%.'\n\n## Design principles\n- Reactive, not proactive: help appears only when something seems wrong or when user is clearly exploring\n- Dismissible in one tap: never blocks UI\n- Never repeats after dismissal (stored in localStorage)\n- Always explains what will happen next\n- Never condescending: assumes user is intelligent but may not know CSI physics\n\n## Acceptance\n- Detection quality drop triggers helpful banner\n- Repeated setting changes trigger hint\n- Node offline shows troubleshooting steps\n- First-time feature discovery shows tooltip once\n- Feedback responses are helpful\n- Calibration success shows positive reinforcement","design":"","acceptance_criteria":"","notes":"","status":"open","priority":2,"issue_type":"task","created_at":"2026-05-05T04:06:29.724435180Z","updated_at":"2026-05-05T04:06:29.724435180Z","source_repo":".","compaction_level":0}
{"id":"bf-25dmx","title":"Guided troubleshooting (Component 36)","description":"## Goal\nWhen system detects that user might be struggling or detection quality has degraded, proactively offer contextual help — but never when things are working well.\n\n## Trigger conditions and responses:\n\nDetection quality drops:\n- Condition: Zone-level detection quality below 60% for >24 hours\n- Banner in timeline and 3D view: 'Detection in the kitchen has been less reliable this week. Want me to help diagnose?'\n- Guided flow: Check node connectivity → show link health with explainability → suggest node repositioning → offer re-baseline → 'Still not right? Try adding a node here [highlighted position]'\n\nRepeated setting changes:\n- Condition: Same settings key modified 3+ times within 60-minute sliding window (qualifying keys: delta_rms_threshold, breathing_sensitivity, tau_s, fresnel_decay, n_subcarriers)\n- Tracking: per-key edit counter in memory, resets after 60 min inactivity\n- Trigger: when counter reaches 3, set hint_pending flag\n- Frontend: show non-intrusive banner: 'You've adjusted the detection threshold several times. Would you like me to show you what the system is seeing?' with [Show me] and [×] dismiss\n- [Show me]: opens time-travel to most recent detection event before first edit, with explainability overlay pre-activated\n- Cooldown: 24 hours after hint is shown\n\nNode offline:\n- Condition: Any node offline for >2 hours\n- Timeline event with expandable troubleshooting steps\n\nFirst-time feature discovery:\n- Condition: User opens feature panel for first time\n- Brief, non-intrusive tooltip (not modal): 'Draw a box around an area, then choose what happens when someone enters or leaves. [Got it]'\n- Shown once, never repeated\n\nAfter false positive feedback:\n- Inline response in timeline: 'Got it. I've slightly raised the detection threshold for the contributing links. If this keeps happening at this time of day, my hourly baseline will adapt within a few days.'\n\nAfter successful calibration:\n- Positive reinforcement: 'Re-baseline complete. Detection quality in the kitchen improved from 64% to 89%.'\n\n## Design principles\n- Reactive, not proactive: help appears only when something seems wrong or when user is clearly exploring\n- Dismissible in one tap: never blocks UI\n- Never repeats after dismissal (stored in localStorage)\n- Always explains what will happen next\n- Never condescending: assumes user is intelligent but may not know CSI physics\n\n## Acceptance\n- Detection quality drop triggers helpful banner\n- Repeated setting changes trigger hint\n- Node offline shows troubleshooting steps\n- First-time feature discovery shows tooltip once\n- Feedback responses are helpful\n- Calibration success shows positive reinforcement","design":"","acceptance_criteria":"","notes":"","status":"in_progress","priority":2,"issue_type":"task","assignee":"claude-code-glm-4.7-foxtrot","created_at":"2026-05-05T04:06:29.724435180Z","updated_at":"2026-05-06T10:10:10.761992237Z","source_repo":".","compaction_level":0}
{"id":"bf-2enwo","title":"Simulator: ray-based propagation engine (internal/sim/propagation.go — direct path + first-order reflections)","description":"","design":"","acceptance_criteria":"","notes":"","status":"closed","priority":2,"issue_type":"task","assignee":"claude-code-glm-4.7-foxtrot","created_at":"2026-05-06T00:40:16.873911203Z","updated_at":"2026-05-06T01:55:05.181196917Z","closed_at":"2026-05-06T01:55:05.181196917Z","close_reason":"Completed","source_system":"","source_repo":".","deleted_by":"","delete_reason":"","original_type":"","compaction_level":0,"compacted_at_commit":"","sender":""}
{"id":"bf-2lfti","title":"Activity timeline (Component 27)","description":"## Goal\nImplement universal event stream timeline that serves as primary navigation for time and space.\n\n## Scope\n- Event types: detections, zone transitions, portal crossings, automation triggers, alerts (fall/anomaly/security), system events (node online/offline, OTA, baseline changes), learning milestones\n- Tap any event → 3D view jumps to that exact moment via time-travel\n- Inline actions per event: thumbs up/down (feedback), 'Why?' (explainability), create automation from event\n- Filters: By person, by zone, by event type, by time range (combinable)\n- Search: Natural language queries like 'kitchen occupied after midnight last week'\n- Scroll up = go back in time. Open dashboard after being away → scroll up to see everything that happened\n\n## Location\ndashboard/static/js/timeline.js (new module)\ninternal/api/events.go (GET /api/events endpoint already exists)\n\n## Acceptance\n- Timeline sidebar in expert mode shows all events in scrollable stream\n- Simple mode: timeline IS the main view as activity feed, with room cards above it\n- Tap event → 3D scene shows state at that moment\n- Search filters events correctly\n- FTS5 index on events table for natural language search","design":"","acceptance_criteria":"","notes":"","status":"closed","priority":2,"issue_type":"task","assignee":"claude-code-glm-4.7-foxtrot","created_at":"2026-05-05T04:05:43.262510021Z","updated_at":"2026-05-05T22:00:56.387536287Z","closed_at":"2026-05-05T22:00:56.387536287Z","close_reason":"Component 27 - Activity Timeline already fully implemented.\n\nTimeline sidebar (expert mode): sidebar-timeline.js provides collapsible panel with scrollable events, category checkboxes, person/zone filters, date range selector, text search with fuzzy matching, cursor pagination, virtualization for 1000+ events, WebSocket real-time updates.\n\nSimple mode activity feed: simple.html imports timeline.js as ES6 module; timeline is main view below room cards.\n\nTap-to-time-travel: Both timeline.js and sidebar-timeline.js implement handleSeek() calling SpaxelReplay.jumpToTime() to jump 3D view to event timestamp.\n\nSearch: Fuzzy matching client-side + FTS5 server-side via /api/events?q= parameter.\n\nFTS5 index: events.go creates events_fts virtual table with triggers for automatic full-text indexing.\n\nAll acceptance criteria met.","source_repo":".","compaction_level":0}
{"id":"bf-2nofd","title":"Ambient dashboard mode (Component 31)","description":"## Goal\nDedicated display mode for wall-mounted tablets or always-on screens. Served at /ambient as separate lightweight route.\n\n## Scope\n- Simplified, stylized top-down floor plan — clean lines, soft rounded corners, no UI chrome\n- People appear as softly glowing colored circles (BLE-identified) or neutral dots (unknown), with names\n- Room labels show subtle occupancy: 'Kitchen · Alice' or 'Bedroom · Empty'\n- Smooth, calm animations: dots drift with interpolated positions, no jitter, no snapping\n- No toolbar, no buttons, no panels — just floor plan, people, small status line\n- Time-of-day awareness: morning (bright/cool), day (neutral), evening (warm/amber), night (very dim, minimal)\n- Adaptive behavior: house empty 30+ min → screen goes fully dark, 'All secure' in tiny text\n- Alert event: entire display transitions to alert mode with pulsing red border, large text, action buttons\n- Morning briefing integration: when first person detected, display briefly shows briefing text before fading to ambient\n\n## Implementation\n/ambient route serving lightweight HTML page\nNo Three.js — use Canvas 2D or SVG for minimal resource usage\nWebSocket receives same dashboard feed but only uses blob positions, zone counts, alerts\n<30 MB RAM, <5% CPU on 2018 iPad\n\n## Acceptance\n- Ambient mode runs unattended on wall-mounted tablet for 7+ days\n- Time-of-day palette transitions smoothly\n- Alert mode breaks the calm appropriately\n- Morning briefing displays on first detection\n- Resource usage: <30 MB RAM, <5% CPU","design":"","acceptance_criteria":"","notes":"","status":"closed","priority":2,"issue_type":"task","assignee":"claude-code-glm-4.7-foxtrot","created_at":"2026-05-05T04:06:11.529140576Z","updated_at":"2026-05-06T08:26:57.944384490Z","closed_at":"2026-05-06T08:26:57.944384490Z","close_reason":"Completed","source_repo":".","compaction_level":0}
@ -33,7 +33,7 @@
{"id":"bf-awtza","title":"MQTT command/rebaseline and HA auto-discovery lifecycle management","description":"Plan specifies full HA auto-discovery lifecycle: configs published with retain=true on first connect AND whenever zones/persons are added or renamed; when zone or person is deleted, publish empty retained payload to remove HA entity. Also missing: rebaseline command subscription wiring. Currently mqtt/client.go publishes discovery on connect but has no mechanism to detect zone/person CRUD events and re-publish or un-publish discovery configs. Needs event bus subscription for zone/person changes.","design":"","acceptance_criteria":"","notes":"","status":"open","priority":3,"issue_type":"task","created_at":"2026-05-02T18:26:21.696828674Z","updated_at":"2026-05-02T18:26:21.696828674Z","source_repo":".","compaction_level":0}
{"id":"bf-m6f5g","title":"GET /api/baseline and POST /api/baseline/capture endpoints","description":"Plan's REST API spec defines GET /api/baseline (returns [{link_id, snapshot_time, confidence}] for all links) and POST /api/baseline/capture (optional ?links body, starts 60s quiet-room capture). The baselines SQLite table exists (from migrations.go) and the baseline system runs internally, but no HTTP endpoints expose read/capture to the dashboard. The fleet handler has /api/nodes/:mac/rebaseline and /api/nodes/rebaseline-all but no standalone baseline endpoints.","design":"","acceptance_criteria":"","notes":"","status":"closed","priority":2,"issue_type":"task","assignee":"claude-code-glm-4.7-foxtrot","created_at":"2026-05-02T18:25:32.710840129Z","updated_at":"2026-05-05T17:55:00.504558262Z","closed_at":"2026-05-05T17:55:00.504558262Z","close_reason":"Completed","source_repo":".","compaction_level":0}
{"id":"bf-qonqo","title":"GET /api/zones/:id/history occupancy history endpoint","description":"Plan's REST API spec defines GET /api/zones/:id/history?period=24h returning [{timestamp, count, people:[]}] in hourly buckets. The zones CRUD exists (internal/api/zones.go) but the history sub-endpoint is not implemented. The anomaly/pattern system stores per-zone per-hour data in anomaly_patterns, and zone occupancy is tracked in memory and SQLite. Needed for the 'Zone history' quick action and the occupancy chart in the dashboard sidebar.","design":"","acceptance_criteria":"","notes":"","status":"closed","priority":2,"issue_type":"task","assignee":"claude-code-glm-4.7-foxtrot","created_at":"2026-05-02T18:26:02.249193078Z","updated_at":"2026-05-05T21:44:59.734545703Z","closed_at":"2026-05-05T21:44:59.734545703Z","close_reason":"Completed","source_repo":".","compaction_level":0}
{"id":"bf-usafo","title":"Morning briefing (Component 35)","description":"## Goal\nWhen user first opens dashboard each day, brief warm summary appears.\n\n## Content (generated from existing data):\n- Sleep summary (if available): 'You slept 7h 39m — 12 minutes more than your average. Breathing was regular.'\n- Who is home: 'Bob left at 8:15am. The house has been empty since 8:22am.'\n- Overnight anomalies: 'Last night: One unusual event at 2:34am — motion in kitchen for 30 seconds. No BLE match, low-confidence blob. Likely environmental.'\n- System health: 'System health: Excellent (94%). All 6 nodes online. Accuracy improved 2% this week thanks to your 8 corrections.'\n- Today's forecast: 'Based on your Wednesday pattern, you usually return around 5:45pm. Security mode will auto-activate when you leave.'\n\nDisplay:\n- Expert mode: card overlay on first dashboard open, dismissible with tap or 'Got it' button. Slides away after 10s if not interacted\n- Simple mode: morning card is first card in layout, stays visible until dismissed\n- Ambient mode: text fades in over ambient display when first person detected in morning, stays for 30s\n\nDelivery channels:\n- Dashboard (default)\n- Push notification at configured time (e.g., 7am)\n- Webhook to Slack/Discord\n\n## Implementation\nGo function GenerateBriefing(date string, person string) string\nAssembled in priority order: critical alerts → sleep → who's home → anomalies → system health → predictions → learning progress\nStored as daily record in briefings table\n\n## Acceptance\n- Briefing accurately summarizes overnight activity\n- Shows sleep report when available\n- Lists overnight anomalies with context\n- Shows system health\n- Shows today's predictions\n- Dismissible and non-intrusive","design":"","acceptance_criteria":"","notes":"","status":"in_progress","priority":2,"issue_type":"task","assignee":"claude-code-glm-4.7-foxtrot","created_at":"2026-05-05T04:06:11.592787579Z","updated_at":"2026-05-06T09:50:41.514192975Z","source_repo":".","compaction_level":0}
{"id":"bf-usafo","title":"Morning briefing (Component 35)","description":"## Goal\nWhen user first opens dashboard each day, brief warm summary appears.\n\n## Content (generated from existing data):\n- Sleep summary (if available): 'You slept 7h 39m — 12 minutes more than your average. Breathing was regular.'\n- Who is home: 'Bob left at 8:15am. The house has been empty since 8:22am.'\n- Overnight anomalies: 'Last night: One unusual event at 2:34am — motion in kitchen for 30 seconds. No BLE match, low-confidence blob. Likely environmental.'\n- System health: 'System health: Excellent (94%). All 6 nodes online. Accuracy improved 2% this week thanks to your 8 corrections.'\n- Today's forecast: 'Based on your Wednesday pattern, you usually return around 5:45pm. Security mode will auto-activate when you leave.'\n\nDisplay:\n- Expert mode: card overlay on first dashboard open, dismissible with tap or 'Got it' button. Slides away after 10s if not interacted\n- Simple mode: morning card is first card in layout, stays visible until dismissed\n- Ambient mode: text fades in over ambient display when first person detected in morning, stays for 30s\n\nDelivery channels:\n- Dashboard (default)\n- Push notification at configured time (e.g., 7am)\n- Webhook to Slack/Discord\n\n## Implementation\nGo function GenerateBriefing(date string, person string) string\nAssembled in priority order: critical alerts → sleep → who's home → anomalies → system health → predictions → learning progress\nStored as daily record in briefings table\n\n## Acceptance\n- Briefing accurately summarizes overnight activity\n- Shows sleep report when available\n- Lists overnight anomalies with context\n- Shows system health\n- Shows today's predictions\n- Dismissible and non-intrusive","design":"","acceptance_criteria":"","notes":"","status":"closed","priority":2,"issue_type":"task","assignee":"claude-code-glm-4.7-foxtrot","created_at":"2026-05-05T04:06:11.592787579Z","updated_at":"2026-05-06T10:09:43.916190927Z","closed_at":"2026-05-06T10:09:43.916190927Z","close_reason":"Implemented Component 35: Morning Briefing\n\n- Added briefing dashboard adapter wiring to hub for morning briefing push\n- Morning briefing provides warm summary when user first opens dashboard each day\n- Content includes: sleep summary (if available), who is home, overnight anomalies, system health, predictions, learning progress\n- Briefing generated automatically via GenerateBriefing(date, person) function\n- Stored as daily record in briefings table\n- Delivery channels: dashboard (card overlay on first open), push notification at configured time, webhook to Slack/Discord\n- Display modes: expert mode (dismissible card overlay), simple mode (first card), ambient mode (fade-in text)\n- Briefing scheduler generates daily briefings at configured time and sends push notifications\n- API endpoints: GET/POST /api/briefing/* for managing briefings\n- All tests passing (go test ./internal/briefing/...)\n","source_repo":".","compaction_level":0}
{"id":"bf-w15bj","title":"CI: golangci-lint static analysis gate","description":"## Goal\nAdd golangci-lint to the Argo CI workflow as a hard quality gate, per plan §Quality Gates / Definition of Done (item 3).\n\n## Configuration\nFile: .golangci.yml at repo root\n\nEnabled linters (minimum set):\n- errcheck: all errors must be handled or explicitly discarded with _\n- staticcheck: includes S-series (simplifications) and SA-series (bugs)\n- gosimple: simplification suggestions (SA-series overlap)\n- govet: same as go vet but integrated\n- ineffassign: catch dead assignments\n- unused: catch unused exported identifiers\n\nDisabled (too noisy for this codebase):\n- gocyclo, funlen, wsl (style preferences, not correctness)\n\n## CI integration\nAdd to the spaxel-build Argo WorkflowTemplate as a parallel step alongside go test:\n golangci-lint run --timeout 5m ./...\n\n## Acceptance\n- golangci-lint run passes on the current codebase (fix any pre-existing findings before adding the gate)\n- Argo CI fails on new lint violations\n- .golangci.yml committed to repo root","design":"","acceptance_criteria":"","notes":"","status":"closed","priority":2,"issue_type":"task","assignee":"claude-code-glm-4.7-golf","created_at":"2026-05-02T12:09:09.633464353Z","updated_at":"2026-05-05T06:49:00.297475830Z","closed_at":"2026-05-05T06:49:00.297475830Z","close_reason":"Completed","source_repo":".","compaction_level":0}
{"id":"spaxel-05a","title":"Implement calibration GET endpoint","description":"## Task\nImplement GET /api/floorplan/calibrate endpoint.\n\n## Specification\n- Return current calibration from SQLite\n- Return 404 if no calibration exists\n\n## Acceptance\n- Returns calibration data when present\n- Returns 404 when no calibration exists","design":"","acceptance_criteria":"","notes":"","status":"closed","priority":2,"issue_type":"task","assignee":"charlie","owner":"","created_at":"2026-04-07T17:55:53.178762085Z","created_by":"coding","updated_at":"2026-04-07T18:58:38.551564957Z","closed_at":"2026-04-07T18:58:38.551463596Z","close_reason":"done","closed_by_session":"","source_system":"","source_repo":".","deleted_by":"","delete_reason":"","original_type":"","compaction_level":0,"original_size":0,"sender":"","labels":["mitosis-child","mitosis-depth:1","parent-spaxel-klk"]}
{"id":"spaxel-0fm8","title":"Add quiet hours gate tests","description":"Write tests for quiet hours gate: LOW at 23:00 with 22:00-07:00 quiet hours -> queued, URGENT at 23:00 -> delivered. Acceptance Criteria: Quiet hours tests pass (queueing, bypass).","design":"","acceptance_criteria":"","notes":"","status":"closed","priority":2,"issue_type":"task","assignee":"claude-code-glm-4.7-golf","owner":"","created_at":"2026-04-11T08:15:07.990827798Z","created_by":"coding","updated_at":"2026-05-04T06:32:11.422038645Z","closed_at":"2026-05-04T06:32:11.422038645Z","close_reason":"Quiet hours gate tests already exist and pass:\n- TestQuietHoursGate_LowAt23pmQueued: LOW at 23:00 with 22:00-07:00 quiet hours → queued\n- TestQuietHoursGate_UrgentAt23pmDelivered: URGENT at 23:00 → delivered\nAll acceptance criteria verified.","closed_by_session":"","source_system":"","source_repo":".","deleted_by":"","delete_reason":"","original_type":"","compaction_level":0,"original_size":0,"sender":"","labels":["failure-count:1","mitosis-child","mitosis-depth:1","parent-spaxel-40tl"]}

View file

@ -0,0 +1,16 @@
{
"bead_id": "bf-25dmx",
"agent": "claude-code-glm-4.7",
"provider": "zai",
"model": "glm-4.7",
"exit_code": 1,
"outcome": "failure",
"duration_ms": 338188,
"input_tokens": null,
"output_tokens": null,
"cost_usd": null,
"captured_at": "2026-05-06T10:15:49.204572873Z",
"trace_format": "claude_json",
"pruned": false,
"template_version": null
}

View file

File diff suppressed because one or more lines are too long

View file

@ -1 +1 @@
ddbcd8aec22232c415ea2f8f8b61d42fcc2cc7f0
092810c8d9265990ef648868b9b76d10dc207b3e

Binary file not shown.

Binary file not shown.