Commit graph

114 commits

Author SHA1 Message Date
Argo Workflows CI
431ec0e96f ci: auto-bump version to 0.1.35 2026-04-07 06:55:10 +00:00
jedarden
544dc39977 test: add breathing rate FFT and anomaly acceptance tests
Table-driven tests verifying FFT correctly identifies 0.25 Hz (15 bpm),
EMA smoothing convergence, anomaly threshold triggers at >25% above
personal average, breathing regularity CV labels, anomaly in sleep
reports, FFT out-of-range rejection, persistence round-trip, and
breathing samples JSON format.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-07 02:54:31 -04:00
Argo Workflows CI
3ca5d674e5 ci: auto-bump version to 0.1.34 2026-04-07 06:31:11 +00:00
jedarden
b99599c403 fix: resolve Phase 6 build integration issues
- Fix unclosed brace in main.go (if zonesMgr block swallowed 1831 lines)
- Add missing resolveBlobIdentity helper function
- Apply worker changes to zones, automation, sleep, briefing, ingestion, localization, db

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-07 02:31:02 -04:00
Argo Workflows CI
7e5755459e ci: auto-bump version to 0.1.33 2026-04-07 06:16:43 +00:00
jedarden
ad1e17ddf2 feat: implement SQLite Online Backup API streaming endpoint
Use modernc.org/sqlite's Online Backup API (NewBackup/Step/Commit)
with in-memory destination and Serialize for consistent hot backups
without temp files. Streams zip directly to HTTP response.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-07 02:15:51 -04:00
Argo Workflows CI
7fd05a3615 ci: auto-bump version to 0.1.32 2026-04-07 06:14:18 +00:00
jedarden
96ba7c75b6 feat: breathing rate FFT extraction and anomaly flagging for sleep monitoring
- FFT-based breathing rate estimator: 512-sample window at 20Hz, zero-padded to 1024,
  dominant peak detection in 0.1-0.5 Hz band (6-30 BPM), 60-second EMA smoothing
- Per-night statistics: breathing_rate_avg, breathing_regularity (CV), anomaly count
- Anomaly detection: 30-day personal average (EMA α=0.05), flags when >25% above baseline
- Morning briefing integration: elevated breathing rate warnings with BPM comparison
- SQLite: breathing_anomaly BOOL and breathing_samples_json columns on sleep_records
- API: GET /api/sleep includes breathing anomaly and personal average fields
- Table-driven tests for FFT accuracy, EMA convergence, anomaly thresholds, regularity

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-07 02:13:35 -04:00
jedarden
ee1caf6ed8 feat: dual-partition OTA rollback validation with 60s role timeout
Update partition layout to 4MB factory/ota_0/ota_1 partitions for larger
firmware images. Add a 60-second validation timer that starts after the
hello message is sent on boot from an OTA partition. The partition is only
marked valid (via esp_ota_mark_app_valid_cancel_rollback) after receiving
a role message from the mothership. If the timer expires without role
receipt, the partition stays unconfirmed and the bootloader rolls back to
the previous firmware on next reset.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-07 01:43:29 -04:00
Argo Workflows CI
5670b5794e ci: auto-bump version to 0.1.31 2026-04-07 05:15:55 +00:00
jedarden
b72f234154 feat: add breathing rate FFT extraction and anomaly flagging for sleep monitoring
- BreathingRateEstimator: FFT peak detection on 512-sample (25.6s) phase windows
  at 20Hz, zero-padded to 1024 points, 0.1-0.5 Hz band (6-30 BPM), 60s EMA smoothing
- BreathingAnomalyTracker: per-person 30-day rolling EMA (α=0.05), flags elevated
  breathing at >25% above personal average
- ComputeBreathingRegularity: coefficient of variation (std/mean) with regular/normal/irregular labels
- Migration 008: add breathing_anomaly BOOL and breathing_samples_json TEXT to sleep_records
- Integration: anomaly check in GenerateMorningReports, anomaly data in report/metrics/handler JSON
- Table-driven tests: synthetic 15/12/20 BPM signals, circular buffer, noise, EMA convergence,
  anomaly threshold boundary cases, JSON round-trip, regularity CV computation

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-07 01:15:34 -04:00
Argo Workflows CI
cdca106a76 ci: auto-bump version to 0.1.30 2026-04-07 04:59:10 +00:00
jedarden
d3778ee5e8 fix: resolve merge conflict debris in main.go portal routes
The Phase 5→6 merge left garbled duplicate portal API code and
missing closing braces. Fixed the zones PUT handler closure, added
missing zones DELETE handler, cleaned up duplicate portal code, and
replaced non-existent GetZoneName() calls with GetZone().Name lookups.

The phase6 build tag and Phase 5 main.go.bak were already removed
in prior work — this commit fixes the remaining compilation errors.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-07 00:58:41 -04:00
Argo Workflows CI
29325eca4f ci: auto-bump version to 0.1.29 2026-04-07 04:15:46 +00:00
jedarden
09aee3f558 fix: improve webhook fault tolerance tests
- Route test requests through chi router instead of calling handlers directly
- Fix weekday test to use correct day mapping
- Use context cancellation for timeout test instead of long sleep
- Move mockServer.Close() after assertions to prevent goroutine leak

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-07 00:15:11 -04:00
Argo Workflows CI
f469129849 ci: auto-bump version to 0.1.28 2026-04-07 03:42:56 +00:00
jedarden
35df775726 fix: timezone bug in occupancy reconciliation + test fixes
- Use time.Now().In(m.tz) instead of time.Now() in reconcileOccupancy
  to correctly compute midnight in the configured timezone
- Fix ReconcileTick to only mark reconciled on exact blob count match
  (diff==0), keeping diff==1 as uncertain per spec
- Fix timestamp units consistency (UnixNano → UnixMilli) in crossing
  event recording and retrieval
- Fix reconciliation query to use from_zone/to_zone columns
- Reset m.reconciled=false in tests that create uncertain occupancy
  after manager construction

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-06 23:42:30 -04:00
Argo Workflows CI
3a5a00e39b ci: auto-bump version to 0.1.27 2026-04-07 03:05:47 +00:00
jedarden
543d66b697 feat: implement webhook action firing & fault tolerance for automations
Backend:
- HTTP client with 5s timeout, fire-and-forget webhook delivery
- Payload schema: {trigger_id, trigger_name, condition, blob_id, person, position, zone, dwell_s, timestamp_ms}
- 4xx response: disable trigger, set error_message, push WS alert to dashboard
- 5xx/timeout: log warning, increment error_count, do NOT disable
- error_count resets on first 2xx response
- POST /api/triggers/{id}/test endpoint with synthetic payload
- POST /api/triggers/{id}/enable clears error state and re-enables
- GET /api/triggers/{id}/webhook-log for last N firings
- Audit log via webhook_log table (migration_007)

Dashboard:
- Error badge (ERR) on trigger cards when error_message is set
- Disabled badge when trigger disabled due to 4xx
- Warning badge for transient error_count > 0
- Test Webhook button with real-time response display
- Webhook Log button showing last N firings
- Re-enable button to clear error state

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-06 23:04:49 -04:00
Argo Workflows CI
437e1865f8 ci: auto-bump version to 0.1.26 2026-04-07 02:01:01 +00:00
jedarden
757d7240dc feat: implement snapshot-on-connect + incremental update protocol for dashboard WebSocket
- Hub sends full snapshot (type=snapshot) on new client connect before adding
  to broadcast list, preventing race with delta messages
- tickDelta at 10 Hz computes byte-level diffs of cached JSON fields, broadcasts
  only changed fields with no type field
- Dashboard sets awaitingSnapshot on WS open, drops incremental updates until
  snapshot received, rebuilds full state from snapshot
- Fix zone snapshot building (nil→ok check, SizeX fields)
- Remove unused broadcastBLEScan function
- Add drainSnapshot helper and fix TestHub_LinkEvents to account for snapshot
- Add TestHub_SnapshotOnConnect, TestHub_SnapshotBeforeDelta, TestHub_DeltaOmitsTypeField

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-06 22:00:36 -04:00
Argo Workflows CI
dbc18e2793 ci: auto-bump version to 0.1.25 2026-04-07 01:40:08 +00:00
jedarden
e74834a3bf feat: implement webhook action firing & fault tolerance for automations
Backend: HTTP client with 5s timeout, fire-and-forget webhook delivery,
4xx disables trigger with error message, 5xx/timeout increments error count,
test endpoint, enable/disable endpoints, webhook_log audit table,
WebSocket alert broadcasting on trigger errors.

Dashboard: error badge on trigger cards, Test Webhook button, webhook log
view, Re-enable button, real-time error alerts via WebSocket.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-06 21:39:51 -04:00
Argo Workflows CI
2d22782ba4 ci: auto-bump version to 0.1.24 2026-04-07 01:29:45 +00:00
jedarden
eb5b43f279 feat: add migration_007 for webhook_log, trigger_state tables and trigger error columns
Formalizes the webhook audit infrastructure (webhook_log table, trigger_state
persistence, error_message/error_count columns) that was previously created
via ALTER TABLE in Store.init(). All webhook action firing, fault tolerance,
test endpoint, enable/disable, and dashboard UI were already implemented
in prior commits.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-06 21:29:17 -04:00
Argo Workflows CI
61512fdb88 ci: auto-bump version to 0.1.23 2026-04-07 01:27:37 +00:00
jedarden
f7df7740bf feat: implement 7-day pattern learning algorithm for anomaly detection
Welford's online algorithm for per-zone, per-hour, per-day-of-week
occupancy modeling with cold start suppression, outlier protection,
security mode override, and SQLite persistence.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-06 21:27:10 -04:00
Argo Workflows CI
d6b1a902d2 ci: auto-bump version to 0.1.22 2026-04-07 00:58:46 +00:00
jedarden
7c0bea764f fix: resolve compilation and test failures in analytics anomaly tests
- Change testAlertHandler.mu from sync.Mutex to sync.RWMutex to match
  RLock/RUnlock calls in alertCount/webhookCount/escalationCount
- Add proper mutex locking in SendAlert/SendWebhook/SendEscalation
- Fix TestAnomaly_UnknownBLEDevice: use security mode so score (0.8)
  exceeds security threshold (0.4) instead of normal threshold (0.6)
- Fix TestAnomaly_UnusualDwell: use security mode for threshold check
- Fix TestAnomaly_SecurityModeThreshold: remove normal mode call that
  creates cooldown and prevents security mode detection
- Fix TestAnomaly_AlertChainNormalMode/SecurityMode: add waitForGoroutines()
  before checking alerts sent via goroutines

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-06 20:58:25 -04:00
Argo Workflows CI
491def9a2e ci: auto-bump version to 0.1.21 2026-04-07 00:30:23 +00:00
jedarden
22b745f274 feat: webhook action firing & fault tolerance for automations
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-06 20:29:53 -04:00
Argo Workflows CI
adfab41cfa ci: auto-bump version to 0.1.20 2026-04-07 00:14:57 +00:00
jedarden
3bb58c0aa2 feat: add 7-day pattern learning algorithm for anomaly detection
Implement Welford's online algorithm for per-zone, per-hour-of-day,
per-day-of-week occupancy modeling with SQLite persistence, cold start
suppression, outlier protection, and security mode override.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-06 20:14:33 -04:00
Argo Workflows CI
d68b9553cd ci: auto-bump version to 0.1.19 2026-04-06 22:47:18 +00:00
jedarden
9791cd3a4f fix: correct paho v1.5.0 API mismatches in mqtt/client.go
- SetCleanOnConnect → SetCleanSession
- OnDisconnect field + OnConnectionLost → SetConnectionLostHandler
- Remove redundant type assertions in type switch cases

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-06 18:47:11 -04:00
jedarden
32bde5c743 fix: remove unused imports and variables in falldetect/detector.go
Remove unused "math" import, unused startZ/endZ variables, and fix
Position struct json tags to pass go vet.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-06 18:47:11 -04:00
Argo Workflows CI
07db05202f ci: auto-bump version to 0.1.18 2026-04-06 22:40:19 +00:00
jedarden
ae20b4ace6 fix: type-assert result["metrics"] before indexing in sleep/handler.go 2026-04-06 18:39:56 -04:00
Argo Workflows CI
eb04b87a21 ci: auto-bump version to 0.1.17 2026-04-06 22:36:08 +00:00
jedarden
622f8eaa49 fix: rename shadowed color variable to clr in notify/service.go
The local variable `color` shadowed the `image/color` package import,
causing compilation failures on lines that referenced `color.RGBA`
after the variable was declared.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-06 18:35:42 -04:00
Argo Workflows CI
c208a7d222 ci: auto-bump version to 0.1.16 2026-04-06 22:35:02 +00:00
jedarden
0a8a3288c0 fix: replace unused linkID with blank identifier in spatial_weights.go
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-06 18:34:53 -04:00
Argo Workflows CI
80db6c6026 ci: auto-bump version to 0.1.15 2026-04-06 22:31:55 +00:00
jedarden
7c7b9266fc fix: correct oui import path in apdetector
github.com/jedarden/spaxel → github.com/spaxel/mothership

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-06 18:31:49 -04:00
Argo Workflows CI
99b9062516 ci: auto-bump version to 0.1.14 2026-04-06 22:06:56 +00:00
jedarden
4595eafab0 feat: implement install secret generation with one-time print
Auto-generate 256-bit installation secret on first run using crypto/rand,
print it exactly once to stdout, and store in SQLite for subsequent startups.
Support SPAXEL_INSTALL_SECRET env var override. Expose via GET /api/auth/install-secret
endpoint (admin session or first-run state). Derive per-node provisioning tokens
via HMAC-SHA256(install_secret, node_mac).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-06 18:06:33 -04:00
Argo Workflows CI
835301ce58 ci: auto-bump version to 0.1.13 2026-04-06 19:21:26 +00:00
jedarden
3781ab7f86 feat: implement BLE device discovery & registration dashboard panel
Implements a comprehensive 'People & Devices' panel for BLE device management:

Frontend (dashboard/js/ble-panel.js, dashboard/css/ble-panel.css):
- Device list sorted by sighting frequency (rssi_count)
- Registration modal with label, person assignment, color picker, device type
- Auto-type hints with icons (iPhone, Apple Watch, Fitbit, Tile, AirTag)
- Pre-registration form for manual MAC address entry
- Unregistered count badge on panel toggle
- Device details modal with sighting history

Backend (mothership/internal/ble/handler.go):
- GET /api/ble/devices with registered/discovered filters and hours parameter
- PUT /api/ble/devices/{mac} for updates (label, device_type, person_id)
- GET /api/ble/devices/{mac}/history for sighting timeline
- POST /api/ble/devices/preregister for manual device entry
- GET /api/people and POST /api/people for person management

Database (mothership/internal/ble/registry.go):
- Enhanced ble_devices table with person_id, device_type, manufacturer fields
- ble_device_sightings table for history timeline
- Auto-detection of device types from manufacturer data (Apple, Fitbit, Garmin, Tile)
- RSSI tracking and averaging

Integration (dashboard/index.html, mothership/cmd/mothership/main.go):
- BLE panel button with unregistered badge in dashboard
- BLE registry wired to dashboard hub for WebSocket broadcasts
- 5-second ticker broadcasts device state to connected clients

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-06 15:21:11 -04:00
Argo Workflows CI
d2e0ea2111 ci: auto-bump version to 0.1.12 2026-04-06 18:33:39 +00:00
jedarden
374b61a559 feat: implement BLE address rotation detection & identity continuity
Backend (mothership/ble/):
- RotationDetector with manufacturer data fingerprinting, time+RSSI proximity
- ble_device_aliases table for tracking rotated MAC addresses
- Identity matcher integration with alias resolution for blob-to-device scoring
- 5-minute grace period fallback when rotation is unresolved
- REST API: GET /api/ble/devices/{mac}/aliases, POST /api/ble/merge, POST /api/ble/split

Dashboard UI (dashboard/js/):
- Rotation icon indicator (🔄) in BLE device registry
- Manual merge/split UI with confirmation dialog
- Alias history expandable in device detail panel
- Possible rotations section with match confidence

Acceptance:
- Identity continuity across address rotation with >90% precision
- No duplicate person tracks created on rotation event
- Alias history queryable via GET /api/ble/devices/{mac}/aliases

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-06 14:33:27 -04:00