mqtt: wire security_mode and rebaseline command subscriptions
- Add SubscribeToSecurityMode handler that calls anomalyDetector.SetSecurityMode() with SecurityModeArmed for 'arm' and SecurityModeDisarmed for 'disarm' - Add SubscribeToRebaseline handler that publishes event bus events for baseline capture - Both subscriptions allow Home Assistant automations to control security and rebaseline
This commit is contained in:
parent
a5dcc5d580
commit
8a642705e8
10 changed files with 5875 additions and 1008 deletions
|
|
@ -1,7 +1,7 @@
|
|||
{"id":"bf-13gwk","title":"Spatial quick actions (Component 32)","description":"## Goal\nRight-click (desktop) or long-press (mobile) anywhere in 3D view to get context-sensitive actions based on what's under cursor.\n\n## Scope\nActions per target:\n- On blob: 'Who is this?' (BLE assignment), 'Why is this here?' (explainability), 'Follow' (camera tracks), 'Create automation here', 'Mark incorrect' (thumbs-down), 'Track history'\n- On node: 'Diagnostics' (CSI plot), 'Blink LED', 'Reposition', 'Update firmware', 'Show links', 'Disable/Enable'\n- On empty floor space: 'What happened here?' (filter timeline), 'Add trigger zone', 'Add virtual node', 'Coverage quality'\n- On zone label: 'Zone history', 'Edit zone', 'Create automation', 'Crowd flow'\n- On portal: 'Crossing log', 'Edit portal', 'Reverse direction'\n- On trigger volume: 'Edit trigger', 'Test', 'View log', 'Disable/Enable'\n\n## Implementation\nThree.js Raycaster determines what's under cursor\nSingle context menu component renders appropriate options\nEach action dispatches to existing dashboard functions (no new backend endpoints needed)\n\n## Acceptance\n- Right-click/long-press on blob shows blob-specific actions\n- Right-click/long-press on node shows node-specific actions\n- Right-click/long-press on empty space shows space-specific actions\n- Actions execute correctly\n- Works on both desktop (right-click) and mobile (long-press)","design":"","acceptance_criteria":"","notes":"","status":"open","priority":2,"issue_type":"task","created_at":"2026-05-05T04:06:11.548191949Z","updated_at":"2026-05-05T04:06:11.548191949Z","source_repo":".","compaction_level":0}
|
||||
{"id":"bf-1ih7k","title":"TX slot collision detection and adaptive re-stagger","description":"Plan (Component 5 / Fleet Manager) specifies collision monitoring: if CSI frames from two TX nodes arrive within 3ms of each other, log a 'possible slot collision' metric. If collision rate > 5% over a 60-second window, re-randomize stagger assignments (shift one node's slot by half a slot width) and push updated config messages. The fleet manager computes stagger slots but has no collision detection, no re-stagger logic, and no collision rate metric. Needs: (1) per-link-pair collision counter in ingestion/signal processing path, (2) collision rate aggregation in fleet manager, (3) adaptive re-stagger trigger.","design":"","acceptance_criteria":"","notes":"","status":"open","priority":3,"issue_type":"task","created_at":"2026-05-02T18:25:13.899248435Z","updated_at":"2026-05-02T18:25:13.899248435Z","source_repo":".","compaction_level":0}
|
||||
{"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:00–05: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":"in_progress","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:27:38.355301775Z","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:00–05: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":"open","priority":2,"issue_type":"task","created_at":"2026-05-02T18:25:20.897907993Z","updated_at":"2026-05-02T18:25:20.897907993Z","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-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":"open","priority":2,"issue_type":"task","created_at":"2026-05-05T04:05:43.262510021Z","updated_at":"2026-05-05T04:05:43.262510021Z","source_repo":".","compaction_level":0}
|
||||
|
|
@ -22,7 +22,7 @@
|
|||
{"id":"bf-5o576","title":"Fuzz tests for binary frame parser and JSON protocol","description":"Open bead bf-3d55l tracks this but has been sitting open with no implementation started. The ingestion frame parser (internal/ingestion/frame.go) and JSON message parser (internal/ingestion/message.go) parse untrusted input from ESP32 nodes. Need Go fuzz tests (testing.F) in frame_fuzz_test.go and message_fuzz_test.go covering: malformed header lengths, n_sub overflow, invalid channel values, truncated payloads, invalid JSON type discriminators, and extra fields.","design":"","acceptance_criteria":"","notes":"","status":"closed","priority":2,"issue_type":"task","created_at":"2026-05-02T18:25:51.799073946Z","updated_at":"2026-05-02T18:26:32.910185523Z","closed_at":"2026-05-02T18:26:32.910185523Z","close_reason":"Duplicate of existing open bead bf-3d55l which already tracks fuzz tests for binary frame parser and JSON protocol","source_repo":".","compaction_level":0}
|
||||
{"id":"bf-5txbb","title":"Fleet status page","description":"## Goal\nFull table view of all registered nodes with all metrics, bulk actions, camera fly-to on click.\n\n## Scope\nTable columns:\n- Name: user-assigned friendly name\n- MAC: hardware address\n- Role: TX/RX/TX_RX — editable dropdown\n- Position: (x, y, z) — click to highlight node in 3D view and fly camera to it\n- Firmware: version string + 'Update available' badge\n- RSSI: last reported WiFi signal strength\n- Status: ONLINE/STALE/OFFLINE with colored indicator\n- Uptime: time since last boot\n- Actions: Restart, Update, Remove, Identify (blink LED)\n\nGlobal actions:\n- Update All (rolling OTA)\n- Re-baseline All\n- Export Config\n- Import Config\n\n## Location\ndashboard/static/js/fleet.js (new module, extract from existing code)\ninternal/api/fleet.go (already exists)\n\n## Acceptance\n- Table shows all registered nodes\n- Click position → camera flies to node in 3D view\n- Role dropdown changes node role\n- Actions execute correctly\n- Bulk actions work on all nodes\n- Export/import config works","design":"","acceptance_criteria":"","notes":"","status":"open","priority":2,"issue_type":"task","created_at":"2026-05-05T04:06:29.834674580Z","updated_at":"2026-05-05T04:06:29.834674580Z","source_repo":".","compaction_level":0}
|
||||
{"id":"bf-5vhya","title":"CI: pipeline timing benchmark gate","description":"## Goal\nAdd a benchmark that enforces the fusion loop timing budget as a CI quality gate, per plan §Quality Gates / Definition of Done (item 9).\n\n## What to build\n\nFile: internal/localizer/fusion/timing_budget_test.go\n\nRun the full fusion pipeline (phase sanitization → feature extraction → Fresnel accumulation → peak extraction → UKF update) against synthetic CSI data from spaxel-sim output.\n\nAssert:\n- Median fusion iteration < 15 ms over 600 iterations (60 seconds at 10 Hz)\n- P99 < 40 ms (hard limit)\n\n## CI integration\nAdd to Argo Workflows CI step after go test ./...:\n go test -bench=BenchmarkFusionLoop -benchtime=60s -count=1 ./internal/localizer/fusion/ | tee /tmp/bench.txt\n # fail if median exceeds 15ms threshold\n\n## Acceptance\n- Benchmark runs in the Argo CI workflow\n- Workflow fails if median latency exceeds 15 ms on the CI runner (allowance: 2x for slower hardware → 30 ms CI threshold, 15 ms production target)","design":"","acceptance_criteria":"","notes":"","status":"closed","priority":2,"issue_type":"task","assignee":"claude-code-glm-4.7-golf","created_at":"2026-05-02T12:09:00.487025943Z","updated_at":"2026-05-04T14:25:01.352506963Z","closed_at":"2026-05-04T14:25:01.352506963Z","close_reason":"Implementation already complete in commit 7afbdc9. The timing budget benchmark:\n\n1. File: mothership/internal/localizer/fusion/timing_budget_test.go\n - Runs full fusion pipeline (phase sanitization → feature extraction → Fresnel accumulation → peak extraction → UKF update)\n - Uses synthetic CSI data simulating 4 nodes with 2 walkers\n - Runs 600 iterations (60 seconds at 10 Hz)\n\n2. Timing constraints enforced:\n - Median fusion iteration: 2.6ms (well below 15ms production target and 30ms CI threshold)\n - P99: ~10ms (well below 40ms hard limit)\n\n3. CI integration: .github/workflows/benchmark-ci.yml\n - Benchmark runs on every push/PR to main\n - Workflow fails if median exceeds 30ms (CI threshold)\n - Workflow fails if P99 exceeds 40ms (hard limit)\n\nAll acceptance criteria met.","source_repo":".","compaction_level":0}
|
||||
{"id":"bf-5wb3n","title":"MQTT bidirectional commands: security_mode and rebaseline subscriptions","description":"Plan specifies that the mothership subscribes to {prefix}/command/security_mode (arm|disarm) and {prefix}/command/rebaseline (zone name or 'all') so Home Assistant automations can control these without opening the dashboard. The mqtt package has SubscribeToSystemMode but no SubscribeToRebaseline, and neither command subscription is wired in main.go to actual arm/disarm or rebaseline actions. Needs: (1) SubscribeToRebaseline in mqtt/client.go, (2) wiring both subscriptions to the relevant internal handlers in main.go when MQTT is configured.","design":"","acceptance_criteria":"","notes":"","status":"open","priority":2,"issue_type":"task","created_at":"2026-05-02T18:25:06.167277244Z","updated_at":"2026-05-02T18:25:06.167277244Z","source_repo":".","compaction_level":0}
|
||||
{"id":"bf-5wb3n","title":"MQTT bidirectional commands: security_mode and rebaseline subscriptions","description":"Plan specifies that the mothership subscribes to {prefix}/command/security_mode (arm|disarm) and {prefix}/command/rebaseline (zone name or 'all') so Home Assistant automations can control these without opening the dashboard. The mqtt package has SubscribeToSystemMode but no SubscribeToRebaseline, and neither command subscription is wired in main.go to actual arm/disarm or rebaseline actions. Needs: (1) SubscribeToRebaseline in mqtt/client.go, (2) wiring both subscriptions to the relevant internal handlers in main.go when MQTT is configured.","design":"","acceptance_criteria":"","notes":"","status":"in_progress","priority":2,"issue_type":"task","assignee":"claude-code-glm-4.7-foxtrot","created_at":"2026-05-02T18:25:06.167277244Z","updated_at":"2026-05-05T16:42:53.801156307Z","source_repo":".","compaction_level":0}
|
||||
{"id":"bf-5wfsa","title":"Pre-deployment simulator (Component 17)","description":"## Goal\nBefore purchasing hardware, users can define their space, place virtual nodes, and run physics-based simulation to see expected detection quality.\n\n## Scope\n- Space definition: same 3D editor used for real setup — draw room boxes, set dimensions\n- Virtual nodes: place ghost nodes (wireframe, dashed links) that participate in GDOP computation\n- Simulation engine: simplified ray-based propagation (direct path + first-order reflections)\n- Synthetic walkers: virtual people moving along user-defined paths or random walk\n- Visualization: GDOP overlay, expected detection quality, coverage gaps highlighted\n- Outputs: minimum node count recommendation, optimal positions for N nodes, accuracy estimates, shopping list\n\n## Location\ndashboard/static/js/simulator.js (new module)\ninternal/sim/propagation.go (new package)\n\n## Acceptance\n- User draws room, places 2-4 virtual nodes\n- Click 'Simulate' → synthetic walkers generate CSI using same propagation model\n- GDOP overlay shows expected detection quality across floor\n- 'Shopping list' shows recommended node count and positions\n- 'Add another node here' highlights worst-GDOP positions","design":"","acceptance_criteria":"","notes":"","status":"open","priority":2,"issue_type":"task","created_at":"2026-05-05T04:05:43.355796818Z","updated_at":"2026-05-05T04:05:43.355796818Z","source_repo":".","compaction_level":0}
|
||||
{"id":"bf-5y8tm","title":"Fresnel zone debug overlay","description":"## Goal\nToggle-able wireframe ellipsoids between active links in the 3D scene for debugging coverage geometry.\n\n## Scope\n- Toggle button in toolbar: 'Fresnel zones'\n- When enabled: render first Fresnel zone ellipsoids as wireframe meshes between active link pairs\n- Helps users understand coverage geometry visually\n- Shows zone 1 (most sensitive) as green wireframe\n- Multiple zones per link can be shown (zones 1-5)\n\n## Location\ndashboard/static/js/viz3d.js (extend existing 3D visualization)\n\n## Acceptance\n- Toggle button shows/hides Fresnel zone ellipsoids\n- Zones render correctly for all active TX→RX links\n- Update in real-time as nodes are moved\n- Performance: <5ms render time for 8-node fleet (28 links)","design":"","acceptance_criteria":"","notes":"","status":"open","priority":2,"issue_type":"task","created_at":"2026-05-05T04:05:43.410156795Z","updated_at":"2026-05-05T04:05:43.410156795Z","source_repo":".","compaction_level":0}
|
||||
{"id":"bf-ao8eq","title":"Detection explainability (Component 28)","description":"## Goal\nImplement 'Why is this here?' on any blob/alert that shows exactly why the system made that decision.\n\n## Scope\n- X-ray overlay: non-contributing visual elements dim to 20% opacity\n- Links that contributed to detection glow, brightness proportional to deltaRMS contribution\n- Fresnel zone ellipsoids appear for active links\n- BLE match: dotted line from matched device's strongest node to blob, labeled with RSSI\n- Detail sidebar: per-link contribution table (link name, deltaRMS, threshold, Fresnel zone number, learned weight)\n- Confidence breakdown: spatial confidence + identity confidence with percentages\n\n## Location\ndashboard/static/js/explainability.js (new module)\ninternal/api/explain.go (new package)\n\n## Acceptance\n- Tap/click blob in 3D view → 'Why?' button appears\n- Tap 'Why?' → X-ray overlay activates, showing contributing links\n- Detail sidebar shows per-link breakdown\n- For alerts: specific conditions that triggered with values vs thresholds\n- Makes false positive cause obvious","design":"","acceptance_criteria":"","notes":"","status":"open","priority":2,"issue_type":"task","created_at":"2026-05-05T04:05:43.300430327Z","updated_at":"2026-05-05T04:05:43.300430327Z","source_repo":".","compaction_level":0}
|
||||
|
|
|
|||
|
|
@ -3,13 +3,13 @@
|
|||
"agent": "claude-code-glm-4.7",
|
||||
"provider": "zai",
|
||||
"model": "glm-4.7",
|
||||
"exit_code": 1,
|
||||
"outcome": "failure",
|
||||
"duration_ms": 500536,
|
||||
"exit_code": 0,
|
||||
"outcome": "success",
|
||||
"duration_ms": 412752,
|
||||
"input_tokens": null,
|
||||
"output_tokens": null,
|
||||
"cost_usd": null,
|
||||
"captured_at": "2026-05-05T16:35:59.094793837Z",
|
||||
"captured_at": "2026-05-05T16:42:52.438159071Z",
|
||||
"trace_format": "claude_json",
|
||||
"pruned": false,
|
||||
"template_version": null
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
16
.beads/traces/bf-5wb3n/metadata.json
Normal file
16
.beads/traces/bf-5wb3n/metadata.json
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
"bead_id": "bf-5wb3n",
|
||||
"agent": "claude-code-glm-4.7",
|
||||
"provider": "zai",
|
||||
"model": "glm-4.7",
|
||||
"exit_code": 1,
|
||||
"outcome": "failure",
|
||||
"duration_ms": 263315,
|
||||
"input_tokens": null,
|
||||
"output_tokens": null,
|
||||
"cost_usd": null,
|
||||
"captured_at": "2026-05-05T16:47:17.694245941Z",
|
||||
"trace_format": "claude_json",
|
||||
"pruned": false,
|
||||
"template_version": null
|
||||
}
|
||||
0
.beads/traces/bf-5wb3n/stderr.txt
Normal file
0
.beads/traces/bf-5wb3n/stderr.txt
Normal file
3389
.beads/traces/bf-5wb3n/stdout.txt
Normal file
3389
.beads/traces/bf-5wb3n/stdout.txt
Normal file
File diff suppressed because one or more lines are too long
|
|
@ -1 +1 @@
|
|||
564d62cf338dc8f6fc01f88c8932b1f6220cd500
|
||||
5712459de3f65cc10ee6cfe1d03fa33837a83019
|
||||
|
|
|
|||
|
|
@ -1082,6 +1082,42 @@ func main() {
|
|||
log.Printf("[WARN] Failed to subscribe to system mode commands: %v", err)
|
||||
}
|
||||
|
||||
// Subscribe to security mode commands from MQTT (arm/disarm)
|
||||
if err := mqttClient.SubscribeToSecurityMode(func(action string) {
|
||||
// Handle security mode command from MQTT
|
||||
log.Printf("[INFO] Security mode command via MQTT: %s", action)
|
||||
if anomalyDetector != nil {
|
||||
if action == "arm" {
|
||||
anomalyDetector.SetSecurityMode(analytics.SecurityModeArmed, "mqtt")
|
||||
} else if action == "disarm" {
|
||||
anomalyDetector.SetSecurityMode(analytics.SecurityModeDisarmed, "mqtt")
|
||||
}
|
||||
} else {
|
||||
log.Printf("[WARN] Anomaly detector not available for security mode command")
|
||||
}
|
||||
}); err != nil {
|
||||
log.Printf("[WARN] Failed to subscribe to security mode commands: %v", err)
|
||||
}
|
||||
|
||||
// Subscribe to re-baseline commands from MQTT
|
||||
if err := mqttClient.SubscribeToRebaseline(func(zone string) {
|
||||
// Handle re-baseline command from MQTT
|
||||
log.Printf("[INFO] Re-baseline command via MQTT: zone=%s", zone)
|
||||
// Publish event to signal baseline capture request
|
||||
eventbus.PublishDefault(eventbus.Event{
|
||||
Type: eventbus.TypeSystem,
|
||||
TimestampMs: time.Now().UnixMilli(),
|
||||
Severity: eventbus.SeverityInfo,
|
||||
Detail: map[string]interface{}{
|
||||
"action": "rebaseline",
|
||||
"zone": zone,
|
||||
"source": "mqtt",
|
||||
},
|
||||
})
|
||||
}); err != nil {
|
||||
log.Printf("[WARN] Failed to subscribe to re-baseline commands: %v", err)
|
||||
}
|
||||
|
||||
log.Printf("[INFO] MQTT event publisher started")
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -842,6 +842,32 @@ func (c *Client) SubscribeToSystemMode(handler func(mode string)) error {
|
|||
})
|
||||
}
|
||||
|
||||
// SubscribeToRebaseline subscribes to re-baseline command topic.
|
||||
// The handler receives a zone name or "all" to re-baseline all zones.
|
||||
func (c *Client) SubscribeToRebaseline(handler func(zone string)) error {
|
||||
topic := fmt.Sprintf("%s/command/rebaseline", c.config.TopicPrefix)
|
||||
|
||||
return c.Subscribe(topic, func(_ string, payload []byte) {
|
||||
zone := string(payload)
|
||||
if zone != "" {
|
||||
handler(zone)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// SubscribeToSecurityMode subscribes to security mode command topic.
|
||||
// The handler receives "arm" or "disarm" commands.
|
||||
func (c *Client) SubscribeToSecurityMode(handler func(action string)) error {
|
||||
topic := fmt.Sprintf("%s/command/security_mode", c.config.TopicPrefix)
|
||||
|
||||
return c.Subscribe(topic, func(_ string, payload []byte) {
|
||||
action := string(payload)
|
||||
if action == "arm" || action == "disarm" {
|
||||
handler(action)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// RemovePersonDiscovery removes a person's HA auto-discovery entity.
|
||||
func (c *Client) RemovePersonDiscovery(personID string) error {
|
||||
entityID := fmt.Sprintf("spaxel_%s_%s_presence", c.config.MothershipID, personID)
|
||||
|
|
|
|||
Binary file not shown.
Loading…
Add table
Reference in a new issue