Skip to content

v2.6.0

Latest

Choose a tag to compare

@github-actions github-actions released this 06 Sep 08:23
54bd15a

2.6.0 (2026-09-06)

✨ Features

  • cut v2.6.0 — NATS frame readers, pump-stall guard hardening, startup perf (#696) (54bd15a), closes #664 #685 #694 #693 #670 #683 #681
  • hardware: rehydrate pump stall guard from persisted alerts at startup (55291fe)
  • nats: add Python NATS frame source alongside the .RAW path (a530dce)
  • scripts: NATS raw.> capture probe for new-firmware discovery (fdebfad)
  • sp-status: firmware-variant + NATS JetStream diagnostics (6662e16)
  • sp-status: surface firmware sensor drop logs (e49016b)
  • status: surface active pump alerts with per-row dismiss (47daf10)
  • streaming: NATS frame readers + pump-stall false-trip hardening (#685) (84e82fe), closes #670
  • streaming: read sensor frames from NATS on new-firmware pods (0d3d7a5)

🐛 Bug fixes

  • automation: reset the anti-thrash baseline when a manual override registers (83e23db)
  • hardware: anchor stall dwell to the frame-arrival clock so bursts and stream gaps cannot satisfy it (7b983ff)
  • hardware: enforce pump-stall guard at every energizing ingress (c8aded1)
  • hardware: enforce pump-stall guard at every energizing ingress (#672) (572df01), closes #669
  • hardware: fold #685's bilateral dwell + frame-arrival clock into the pump-stall guard (43f6ff0), closes #677
  • hardware: hold simultaneous both-side zero-RPM runs to an extended dwell before dual-tripping (d835982)
  • hardware: ignore normal no-countdown session stops (4db993b)
  • hardware: keep auto-recover from overwriting a newer power-off and mirror state inside the side lock (595ed63)
  • hardware: keep processing frames for a blocked side so cutoff retries and auto-recovery can run (1a2fee6)
  • hardware: pump-stall recovery — remaining-session restore, stale-alert rehydration hardening, alert history UI (#677) (8977182)
  • hardware: restore only the remaining session on pump-stall recovery (d81a0dc), closes #663
  • hardware: retain observed session expiry across zero countdowns (4c38f54)
  • hardware: retry pump cutoff on later frames when the trip power-off fails (1f35583)
  • hardware: stop pump-stall restore loops (e0b40b7)
  • hardware: stop stale pump-stall alerts from re-blocking healthy sides at boot (a49b351)
  • homekit: gate sideController power-on and temp writes on the pump stall guard (#670) (7041c5d)
  • homekit: keep AUTO-on from falling back to off (#681) (e917b0e)
  • install: write the SSH key where sshd actually reads it (#683) (022e80f)
  • nats: harden firmware transition diagnostics (e475bd4)
  • nats: harden frame-reader rollout (3e19d7b)
  • network: make updater firewall restore fail closed (1d47aac)
  • scheduler: make reboot sudoers OTA repair reliable (9f5d3df)
  • scheduler: run the away-start power-off under the side lock with the DB marked off first (c282717)
  • scheduler: self-heal the reboot sudoers rule on update via sp-maintenance (6a8c2bb), closes #670
  • scheduler: sudo the scheduled reboot so it runs as the sleepypod user (8fa4da7)
  • server: acknowledge restart-orphaned pump alerts by falling back to the newest active row (820765e)
  • server: acknowledge restart-orphaned pump alerts by falling back to the newest active row (#669) (0536ce9)
  • server: correlate pump-alert ack and dismiss by client-provided alert id (2a58cde)
  • server: gate raw execute's energizing opcodes on the pump-stall guard (6afd2d6)
  • server: keep rejected device commands side-effect free and surface guard errors (ccc54f6)
  • server: re-check pump-stall guard at the write in runOnce.start and lock the away-return power-on (18dd941)
  • server: replay the persisted restore snapshot for restart-orphaned pump alerts (1033afd)
  • server: skip orphaned-alert fallback when the stall guard kept its restore snapshot (f76699c)
  • server: stamp pump-alert acknowledgement only after the restore succeeds and re-arm on failure (e0e1c84)
  • server: validate run-once duration before cancelling and power off on insert failure (b040268)
  • services: serialize the temperature keepalive through withSideLock (51da9f7)
  • sleep-detector: read capSense2 presence as ref-compensated raw deviation, matching Node occupancy (394ee6b)
  • sp-update: gate biometrics-archiver skip on NATS, not frank.sh (3909424), closes #588
  • sp-update: log nats-server + jetstream state when skipping helper (858db55)
  • sp-update: skip biometrics-archiver setup when frank.sh absent (342702a)
  • streaming: address NATS lifecycle and validation review feedback (e2c45c8)
  • streaming: include pump-stall notices in WebSocket status frames (#671) (792fc94), closes #669
  • ui: lock both stall-banner actions while either mutation is pending and expose it as an alert (f8c7d19)

📝 Documentation

  • nats: frame-readers design spec from field capture (2822344)
  • nats: resolve spec review — robust source selection, status handling, sp-status log surfacing, fixture clearance (6ef8e49)
  • nats: statusCounts column on cap_sense_frames windows; flag Node streaming as second RAW consumer (0afbac2)

⚡ Performance improvements

  • shorten startup and remove blocking API diagnostics (#694) (2e13b79)
  • web: reduce status latency and defer diagnostics charts (#693) (dd5c425)

🧪 Tests

  • cover mutation-run regressions (#695) (a66c0ec)
  • db: cover residual retention mutation contracts (f3f5615)
  • db: cover runtime mutation branches (f9f3182)
  • db: pin complete schema contracts (c2db4d3)
  • hardware-lib: cover residual mutation contracts (0c67622)
  • hardware,server: kill dacTransport framing and device lock-routing mutants (#591 hit list) (#688) (0fd45be)
  • hardware: cover mutation survivor paths (20d4ec1)
  • hardware: cover prolonged firmware timeout pump spin-down (ed315f1)
  • hardware: cover residual transport contracts (f8e6cec)
  • hardware: kill empirical residual mutants (6d93c3c)
  • hardware: kill types.ts surviving mutants (#591 hit list) (#679) (b10d1ca)
  • hardware: pin gesture writes against a trip landing while queued on the side lock (fdacebf)
  • homekit,streaming: pin identity derivation, bridge teardown, and frame normalization contracts (e0fb11a)
  • homekit: kill residual bridge mutants (5433541)
  • homekit: pin the side-specific guard refusal message in the per-side gating test (33f1bf2)
  • homekit: remove redundant flaky HAP setter case (b516ffd)
  • hooks: isolate i18n mock calls (7b0451e)
  • hooks: kill empirical residual mutants (61bca19)
  • hooks: kill mutation survivors (42be7af)
  • hooks: preserve later time range resolvers (ff654d7)
  • isolate mutation regression suites (b9dc4bd)
  • keep catalog imports analyzable under mutation (c8dd42f)
  • kill empirical server streaming and lib mutants (d2b282e)
  • kill latest mutation-run survivors (#686) (0836125), closes #591
  • kill mutation survivors from run 29636626335 (#668) (05711ee)
  • kill pod and HomeKit mutation survivors (#682) (ba7cf5a)
  • kill scheduler and service mutants (bcdf3fb)
  • kill streaming and HomeKit mutants (9bb775c)
  • lib: attribute catalog initialization mutants (bcc6c39)
  • lib: cover hottest gradient stop (7565d28)
  • lib: cover residual parsing and HR filters (0d9db27)
  • lib: kill mutation survivors (315bc9e)
  • make server-only stub portable to Stryker sandboxes (c476f9a)
  • nats: cover source lifecycle branches (23b7951)
  • scheduler: cover residual mutation contracts (78e0603)
  • scheduler: kill empirical residual mutants (5175d38)
  • scheduler: pin scheduler, auto-off and keepalive behaviour against mutation survivors (3fc7fe3)
  • server: assert the vitals baseline averages each squared vital (e91d613)
  • server: cover both device power sync states (b954182)
  • server: cover error passthrough and query construction in the core routers (5bcb79c)
  • server: cover non-Error rejection branch of orphaned-alert lookup warning (877060f)
  • server: cover residual mutation contracts (7d8d7a6)
  • server: fail loudly on unexpected DB calls in the pump-alerts harness (0649261)
  • server: kill mutation survivors (ee5f5e6)
  • server: kill validation schema mutation survivors (#678) (559b266)
  • server: make recent-date assertion timezone-safe (634b48f)
  • server: pin automation AST depth/node budgets at their exact boundaries (6b5b55a)
  • streaming: cover residual guard contracts (c7d7ce4)
  • streaming: cover zero-client broadcast guard (a5aaeb3)
  • streaming: kill piezoStream serialization and seek-read mutants (d7d7da3)
  • streaming: pin mqtt payload BOM trim and probe clientId suffix (d35140f)
  • streaming: reconcile dev contract suites with the NATS source selection and statusCounts column (cb7abe1)
  • streaming: serialize MQTT command assertions (8228aa9)
  • streaming: type serialization spy calls (cbd2c8d)

🔧 Chores

  • deps: Update @base-ui/react all non-major dependencies (#684) (d4bd493)
  • deps: Update @eslint/js all non-major dependencies (#667) (a2850f3)
  • deps: Update @formatjs/intl-localematcher all non-major dependencies (#673) (b4d4358)
  • deps: Update @tanstack/react-query all non-major dependencies (#676) (279cbff)
  • deps: Update @tanstack/react-query all non-major dependencies (#689) (10eab0d)
  • deps: Update @tanstack/react-query all non-major dependencies (#692) (3ce5e62)
  • deps: Update @types/negotiator all non-major dependencies (#687) (07f3856)
  • deps: Update @types/react all non-major dependencies (#680) (35d2782)
  • tooling: exclude .codex worktrees from vitest discovery and eslint (20b4c19)