Skip to content

Main - #871

Open
lucaandrea wants to merge 130 commits into
sleepypod:mainfrom
lucaandrea:main
Open

Main#871
lucaandrea wants to merge 130 commits into
sleepypod:mainfrom
lucaandrea:main

Conversation

@lucaandrea

Copy link
Copy Markdown

No description provided.

Require owner authorization across API routes and sensor streaming, add expiring
browser sessions, and disable raw actuator/MCP access by default. Handle legacy
Pod 4 capacitance with calibration, quality and timestamp checks. Restore saved
Autopilot opt-in before starting its timer and default new installations to off.

Add five primary destinations, shared blue/navy design tokens, explicit demo
labels and honest Home Assistant connection states. Retain AGPL attribution and
upgrade Next.js to 16.4.3 following the official security update.

```mermaid
flowchart LR
  Apps[Web and native apps] --> Auth[Owner access]
  Auth --> Core[Pod controller]
  Sensors[Validated Pod 4 measurements] --> Core
  Core --> Hardware[Single hardware authority]
```

Validation: 521 targeted tests passed in 19 files; changed TypeScript passes
ESLint; production build passed with isolated pre-migrated SQLite databases.
Browser checks verified invalid-key rejection, sign-in and sign-out. Initial
fresh-file build encountered SQLite WAL initialization contention, documented
in the implementation record. Personal comfort port, native compatibility,
data importer, home setup and physical/overnight gates remain pending.
Return disabled from kill-switch, status and diagnostic reads when device
settings are absent, matching startup behavior. Keep device children unmounted
in unauthenticated server markup, supply an authenticated request in the fake
stream transport, and freeze the dated Apple Watch fixture's coverage clock.

Validation: all 177 tests in the five previously affected suites passed after
creating the piezo processor's environment from its locked uv dependencies.
Port the deterministic comfort learner and guard checks, and add isolated
passive policy leases to the sole temperature controller. Rule refreshes
preserve other producers; failed guards revoke leases and cannot replay
stale proposals or power an inactive side on.

```mermaid
flowchart LR
  Feedback --> Comfort[Bounded comfort policy]
  Comfort --> Authority[Shared temperature authority]
  Rules --> Authority
  Manual --> Authority
  Authority --> Hardware
```

Validation: 184 targeted tests, TypeScript and changed-file ESLint passed.
Production scheduling, persistence and sensor adapters remain unconnected;
no Pod hardware or overnight sleep outcomes were tested by this change.
Give native, web and bedside clients a versioned discovery contract that
separates implemented routes, current runtime evidence and unverified
physical behavior. Observe existing DAC, base and MQTT state without
starting hardware connections. Keep Stop independent of position freshness.

```mermaid
flowchart LR
  Client --> OwnerAuth
  OwnerAuth --> Capabilities
  ExistingRuntime --> Capabilities
  Capabilities --> Evidence[Readiness and qualification]
```

Include REST/tRPC/OpenAPI parity, private no-store responses and explicit
unavailable states for native compatibility, personal comfort runtime,
room context and music vibration. Current controls do not claim durable
receipts, expiry envelopes or physically verified outcomes.

Add regression coverage for authentication, expired/future/malformed data,
disconnects, Stop availability, passive discovery and build metadata.
No live Pod deployment or hardware action is included.
Describe the future compatibility prefix as a nullable API path and receipt
support as booleans instead of constants. Current responses remain null/false;
generated clients can adopt supported features without a model-type break.

```mermaid
flowchart LR
  Schema --> ClientDecoder
  RuntimeEvidence --> ClientDecoder
```
Connect the bounded comfort learner to live Pod observations and actual
schedule events, with SQLite check-ins, learning cursors, observation history
and a web Autopilot panel. Expose owner-authenticated versioned status,
configuration and feedback APIs. Distinguish Preview from active capability.

Persist a six-hour personal-policy pause for manual temperature, power,
resume, gesture, HomeKit and priming controls. Keep scheduled events separate
and allow manual shutdown when the journal is unavailable.

```mermaid
flowchart LR
  Sensors[Fresh sensors and routines] --> Preview[Comfort Preview]
  Checkins[Comfort check-ins] --> Preview
  Manual[Manual intent] --> Pause[Durable pause]
  Pause --> Preview
  Preview --> Journal[SQLite observations]
  Journal --> Clients[Web and authenticated API]
```

Validation: 564 targeted tests; TypeScript, full ESLint and both Drizzle
schema checks passed. Includes DST, ambiguous routines, SQLite rollback and
reopen, manual intent, sensor guards, feedback cursors, API and UI behavior.

Active personal control, Core vital/phase adapters, native compatibility,
physical qualification and seven observed Preview nights remain gated.
No physical Pod deployment or actuator qualification is claimed.
Keep the global Autopilot switch unavailable until its saved status arrives,
instead of briefly showing enabled during loading. Pin the three new comfort
schema tables and exercise Preview startup through the lifecycle test harness.

Flow: pending status -> confirmed settings -> enabled user control.

Validation: updated only the three intended table snapshots; schema tests
and 35 lifecycle/UI checks pass. No hardware or sleep-night qualification.
Require healthy recent DAC status and finite, non-future biometric and
capacitance observations. Window expressions no longer reuse history when
the current source is missing, and live policies release ownership between
triggers when an action or trigger input becomes unavailable.

Preserve explicit one-shot expiry and routine-relative action baselines.
Add regressions for invalid observations, sensor loss and recovery.

```mermaid
flowchart LR
  Sensors --> Validity[Freshness and numeric checks]
  Validity --> Policies[Live policy evaluation]
  Policies --> Authority[Shared temperature authority]
  Missing[Missing inputs] --> Withdrawal[Policy withdrawal]
  Withdrawal --> Authority
```

Validation: 226 focused tests across 12 files passed. The prior Preview
milestone passed its 3,124-test push gate; no Pod deployment is included.
Handle the new comfort panel in the demo transport without pretending to
save feedback, run a policy or record observed sleep nights. Return the
real status contract with an explicit live-Pod requirement and reject writes.

Validation: demo handler coverage, response-schema and write-rejection tests.
feat: add authenticated Pod 4 control and personal comfort Preview
@coderabbitai

coderabbitai Bot commented Oct 25, 2026 •

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: defaults
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 8d3a58b8-3b11-4d82-85b7-62d8b66bfe01

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • Trigger review
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

Share

Stage a new offline Core candidate from a verified Free Sleep backup without
changing the Pod or replacing the source. Preserve original metrics, journal,
private recovery materials, learning cursors and manual pauses. Start comfort
Off and keep imported occupancy calibration pending qualification.

Add explicit next-day power-off scheduling so an overnight Free Sleep routine
retains its weekday behavior. Existing Core rows keep their calendar-day default;
REST, tRPC, demo and Preview preserve the offset through partial updates.

```mermaid
flowchart LR
  Backup[Verified backup] --> Candidate[Offline Core candidate]
  Backup --> Recovery[Original data and private recovery archive]
  Candidate --> Review[Compatibility and hardware qualification]
```

Validation: 14 offline importer tests and 398 scheduler/API/Preview/schema tests;
TypeScript, full ESLint, both Drizzle checks and isolated production build pass.
The owner's saved backup staged successfully with unchanged source hashes.

This is not a controller cutover. Full-installation rollback, overnight editor
compatibility, alarm behavior review, historical API support, hardware tests and
seven actual Preview nights remain gates before activation.
Copy the explicit power-off weekday offset in the web calendar-day copy flow.
Previously a copied overnight row defaulted to shutdown on its start weekday.
Keep missing offsets at the existing calendar-day default and preserve disabled
rows. Temperature and alarm rows retain their calendar weekdays.

```mermaid
flowchart LR
  Source[Monday start and next-day stop] --> Copy[Copy calendar-day rows]
  Copy --> Target[Saturday start and Sunday stop]
```

Validation: 154 focused hook/time tests passed, including next-day, same-day and
missing-offset regressions across the week boundary. The separate bedtime-based
curve editor, live cutover and physical acceptance remain pending.
feat: stage verified Free Sleep migrations with overnight schedules
Keep imported power times, morning phases and wake alarms together when a
routine is edited, copied or moved. Add a versioned routine contract with
atomic revision checks, ownership validation and separate scheduler status.

Protect managed rows from partial calendar edits, preserve power-only and
disabled routines, and add an editor using the existing SleepyPod components.
Update the offline importer and keep existing calendar-only sides unchanged.

```mermaid
flowchart LR
  Backup --> Routine[Complete bedtime routine]
  Editor --> Revision[Compare every original revision]
  Revision --> Transaction[Atomic week update]
  Routine --> Transaction
  Transaction --> Calendar[Owned calendar scheduler rows]
```

Validation: production build; TypeScript and full ESLint; 106 focused router
and editor tests; 16 offline importer tests; all six isolated production
browser tests, including authentication, persistence and concurrent edits.
A private offline rehearsal verified 14 source routines without changing the
Pod. Native adoption, controller cutover, hardware qualification and seven
actual Preview nights remain separate gates.
Extend the exhaustive table export and schema snapshot assertions with the
reviewed bedtime ownership table and its unique side/day index. The generated
migration and existing table contracts remain unchanged.

Validation: all 19 schema tests pass. The independent demo-link rerun passed
all five tests after the broader parallel run hit its existing startup timeout.
…rites

A lost response can leave clients unable to tell whether a Pod command ran.
Add authenticated versioned control requests with durable unique IDs, expiry
at the DAC/GATT write boundary, and explicit unknown/partial outcomes.

Reuse the existing command authority and side locks. Never implicitly replay
hardware write callbacks on socket failure; allow retries only for explicitly
read-only callbacks. Keep acknowledgment separate from physical verification
and detach long-lived scheduler jobs from a request's dispatch deadline.

```mermaid
flowchart LR
  Client[Authenticated request] --> Receipt[Durable claim]
  Receipt --> Guard[Expiry and existing authority]
  Guard --> Hardware[DAC or Bluetooth]
  Hardware --> Outcome[Acknowledged or unknown]
```

Validation: TypeScript, full ESLint, production build, 250 focused controller
checks and seven isolated production browser tests. SQLite restart, duplicate,
expiry, partial dispatch, persistence failure and transport queue tests use
simulated hardware; no Pod settings or hardware commands were changed.
feat: preserve complete overnight bedtime routines
feat: persist expiring control requests without replaying uncertain writes
Integrate upstream alarm duration and taper with web controls, tap gestures,
HomeKit and restart persistence. Preserve imported bedtime ownership and reject
older-client replacements that would erase custom settings.

Serialize snooze writes, invalidate cancelled or replaced callbacks after side
lock waits, and keep deliberate future alarms outside immediate request expiry.
Advertise snooze support explicitly while the owned curve library remains pending.

```mermaid
flowchart LR
  Alarm[Saved alarm] --> Snooze[Tap or HomeKit snooze]
  Snooze --> State[Persist configuration and repeat count]
  State --> Check[Side lock and cancellation checks]
  Check --> Restart[Restart same alarm]
```

Validation: production build; 17 offline importer tests; focused behavioral
tests; seven isolated browser scenarios across the initial run and corrected
routine locator rerun. The real private upgrade rehearsal preserved all 14
owned routines, one enabled power routine and zero enabled alarms, with original
database hashes unchanged. Mandatory pre-push checks run before publication.
No live controller migration or physical vibration qualification is claimed.
…ines

Integrate upstream named calendar curves with per-side weekday ownership,
atomic day moves, activation, and one-time adoption of compatible schedules.
Keep imported bedtime routines in their complete-night editor and reject
calendar rewrites before changing either side. Preserve paused settings.

Return scheduler registration status separately from committed saves and
re-read current rows after scheduler startup to avoid reviving stale jobs.
Keep web, demo and MCP responses aligned; MCP remains disabled by default.

```mermaid
flowchart LR
  Review[Review curve and days] --> Guard[Check overnight ownership]
  Guard --> Save[Atomic claims and rows]
  Save --> Register[Register current scheduler rows]
  Register --> Result[Saved state plus schedulerApplied]
```

Validation includes migration retry, two-side rollback, delayed scheduler
startup, paused-row edits, real REST/browser workflows and a private offline
upgrade preserving all 14 imported routines. No live Pod cutover or physical
qualification is claimed. See docs/SCHEDULE_LIBRARY.md for contract limits.
Add authenticated reference-sample reads and writes, generated biometrics
migration 0031, and Health-export import counts for breathing rate and SDNN.
Keep samples separate from Pod vitals, link normalized provenance atomically,
and delete linked samples with their import. Repeated imports are idempotent.

Exclude known SleepyPod and Free Sleep sources from reference exports, convert
recognized units, and retain gaps and metric definitions. Adapt reviewed
upstream import/read contracts without enabling personal-model execution.

```mermaid
flowchart LR
  Export[Local Health export] --> Filter[Source and unit checks]
  Filter --> References[Watch references with provenance]
  References --> Compare[Read and compare distinct metrics]
  Pod[Original Pod readings] --> Compare
```

Validation: focused router/import/provenance tests, 57 Python parser tests,
production build, isolated upload/reload browser workflow, and an offline
upgrade preserving existing configuration/biometrics and source hashes.
Hardware, owner Watch-history import and sleep-outcome validation remain open.
Restore the original neutral theme and SleepyPod branding. Match the native
Temp, Schedule and Sleep phone destinations while keeping secondary controls,
owner sign-out and system warnings accessible through Settings.

Load the reviewed local 3D renderer without CDN requests; preserve readable
light-mode fallback controls and prevent bed/control drags from navigating.

```mermaid
flowchart LR
  Phone[Temp / Schedule / Sleep] --> Settings[Secondary controls and owner session]
  Desktop[SleepyPod rail] --> Features[Original and custom features]
  Pod[Local renderer] --> Bed[3D bed or accessible 2D controls]
```

Validation: production build, 271 focused tests, 37 subsequent renderer tests,
ten browser workflows plus two final navigation/rendering checks passed.
Reviewed 390px light/dark and desktop screenshots. Browser fixtures use isolated
synthetic data; no hardware or controller migration is implied.
Package a clean committed standalone build with fresh locked Linux dependencies,
verified Node 24.22.1 and SQLite prebuilds, source/license and file manifests.
Reject local databases, credentials, host-native binaries and unsafe archives.
Add an inert target probe that exercises SQLite and image encoding without
importing the app or starting hardware services.

```mermaid
flowchart LR
  Source[Committed source and matching build] --> Bundle[Verified ARM64 bundle]
  Bundle --> Stage[New private Pod staging directory]
  Stage --> Probe[In-memory dependency probe]
  Probe --> Gate[Separate attended cutover and rollback]
```

Validation: eight packaging boundary tests and installer shell syntax passed.
Full package creation and the target probe are recorded separately from live
controller deployment; the working Free Sleep installation remains in place.
feat: preserve per-alarm snooze settings across overnight routines
feat: add a schedule library while preserving imported overnight routines
feat: import Apple Watch breathing and SDNN as separate references
feat: align the web shell with SleepyPod and render the bed offline
fix: improve sleep totals, MQTT reliability and contextual comfort learning
Include explicit power-on targets and calendar shutdown boundaries in the Autopilot and temperature timelines, so a 70 F hold with no intermediate phases is visible. Keep shutdown markers out of upcoming temperature changes and label the base schedule separately from wake warming.

Flow: saved power routine -> calendar projection -> Tonight and 3D timelines.

Validation: 332 component/calendar tests, including DST, disabled and ambiguous windows, and shutdown boundary behavior; TypeScript and ESLint pass. No controller or saved routine changes.
…ne-display

fix: show constant bedtime routines in schedule timelines
Clip rule and model epochs to recording boundaries and prevent same-stage
blocks from spanning sensor gaps. Apply the same limits to rule previews
and candidate comparisons, and version the corrected algorithm contract.

Recorded intervals -> bounded epochs -> stage charts and comparisons

Validation: 8,329 unit checks passed in the full run; the remaining four
checks passed in a 60-test serial rerun after regenerating the browser
worker identity. The three subprocess timeouts passed at their unchanged
5-second limit. Algorithm registry and boundary regression checks: 27 passed.
TypeScript and focused ESLint passed. No actuator behavior changes.
fix: keep sleep-stage estimates within recorded time
Update the native night-view documentation to include all recording segments
and preserved gaps. Separate Watch stage validation from thermal-context learning
and retain the physical qualification and reviewed-night requirements.
Correct the agent guide to describe the existing owner-authenticated API.

```mermaid
flowchart LR
  Watch[Aligned Watch and Pod stages] --> Stage[Stage evaluation]
  Room[Pod and room context plus comfort feedback] --> Thermal[Thermal evaluation]
  Physical[Owner observations and reviewed nights] --> Activation[Activation review]
```

Validation: checked against native stage aggregation, Core learning and owner
contracts, and the OpenAPI security definition; git diff --check passed.
Documentation only; no runtime or hardware behavior changes.
…idence-docs

fix(docs): clarify sleep-learning validation requirements
Schema publishing was polling an owner-authenticated endpoint without a
credential and timing out even though the server had started. Generate a
masked, job-local credential, bind the export server to loopback, and
verify authenticated export plus anonymous rejection.

Validation: isolated production-server probe exported all 220 paths and
returned HTTP 401 anonymously. Existing owner credentials are never used.

Flow: temporary CI credential -> local server -> authenticated schema
artifact; unauthenticated requests -> HTTP 401.
* fix(comfort): preserve qualification across bounded baseline drift

The detector republishes adaptive capacitance means every 15 minutes.
Hashing those means as calibration identity invalidated attended checks
and made seven matching Preview nights impossible even during ordinary
drift.

Persist an anchored calibration epoch across publications and restarts.
Keep current live means for occupancy; rotate the epoch on recalibration,
reseed, changed parameters or cumulative L1 drift beyond one quarter of
the entry threshold. Malformed/out-of-budget metadata cannot qualify.
Existing observations retain their original identity and build.

```mermaid
flowchart LR
  Baseline[Adaptive baseline] --> Epoch[Persisted anchor]
  Epoch --> Within[Bounded drift retains identity]
  Epoch --> Changed[Material change requires new qualification]
```

Validation: 139 detector tests, 64 shared-calibration tests, 89 Node
occupancy/owner-activation tests, TypeScript and targeted lint passed.
Physical deployment and new-build qualification are separate gates.

* fix(deploy): switch verified sensor source with controller releases

Stage sensor source from the release's verified archive while reusing only
unchanged locked dependencies. Validate the source and environment links
before stopping services; switch and restore sensor units with Core.

```mermaid
flowchart LR
  Archive[Verified release source] --> Stage[Separate sensor tree]
  Stage --> Check[Source and lock checks]
  Check --> Upgrade[Quiesced controller and sensor switch]
  Upgrade --> Recovery[Previous units and data on failure]
```

Validation: 155 deployment tests passed, including source tampering,
archive traversal, environment links, dependency changes and rollback.
`Analyze & Release` currently reaches tag publication and fails because its repository pre-push hook invokes `uv`, which the release runner has not installed. Install Python 3.10, uv, and the locked piezo runtime used by the normal CI integration checks so release hooks can complete.

Create that host-only environment after the deployment archive is packaged. Runner-specific wheels and interpreter paths therefore stay out of the Pod artifact. Repository hooks and their validation remain enabled.

```mermaid
flowchart LR
  Build --> Package[Pod archive]
  Package --> Runtime[Locked host test runtime]
  Runtime --> Hooks[Release push validation]
  Hooks --> Publish
```

Validation: workflow YAML and step ordering checked; full local pre-push checks passed, including 6,692 unit tests, 155 deployment tests, migration tests, typecheck, lint and both schema checks. An initial parallel test run hit timeouts; the affected 24 tests and full unmodified suite passed on rerun. The workflow-only follow-up also runs the normal push gates. Hosted checks and actual post-merge release publication must complete before this publishing repair is considered verified.
Prepare short attended offline tests without changing the qualified Pod controller, calibration or saved routine. A root-owned helper keeps one direct LAN recovery peer available, covers IPv4 and IPv6, and arms an independent recovery timer before installing temporary isolation rules.

```mermaid
flowchart LR
  Preflight --> RecoveryTimer --> TemporaryIsolation --> ExistingRoutine
  RecoveryTimer --> RestoreOwnedRules
  ExistingRoutine --> OwnerObservation
```

The helper records intent before changes, rejects duplicate trials and non-LAN recovery paths, restores partial failures, and preserves foreign rules. A recovery-only rehearsal installs no isolation rules. The documented workflow keeps physical observations separate from acknowledgments and never enables Active comfort.

Validation:
- Full initial pre-push validation: TypeScript, ESLint, migrations and 6,692 related tests passed (17 skipped). Final pre-push checks passed again after the timer reconciliation change.
- Local deployment suite: 171 tests, 170 passed and the opt-in Linux packet test skipped on macOS.
- Actual Pod: read-only preflight and independent ten-second recovery rehearsal passed; IPv4/IPv6 rule digests unchanged, Core 51678cf remained active, all five physical qualifications retained, MQTT remained connected. No network isolation or actuator command was issued.
- CI runs real IPv4/IPv6 probes inside disposable network namespaces, including recovery-peer access, blocked phone/broker traffic, and restoration without changing the runner host firewall.
- Attended scheduled warming, wake vibration and cancellation remain planned for October 30; this PR does not establish those physical results.
* feat: prepare private household accounts and onboarding

Prepare separate owner and partner accounts with revocable device keys,
expiring invitations, private preferences and weekly routine drafts. Keep
physical assignment, active controls, history and Health import unavailable
until their separate migration and qualification gates are complete.

Protect personal endpoints from legacy owner access and prevent browser
account-switch races with persisted session scope, signed v2 owner sessions,
scope revisions and stale-editor identity checks. Restrict whole-database
downloads and private household table inspection.

Add an offline interactive guide for Marissa and a researched home-automation
plan covering bedtime lighting, Endel/AirPlay and one-morning alarm coordination.

```mermaid
flowchart LR
  Device[Personal device] --> Account[Private sleeper account]
  Account --> Drafts[Preferences and routine drafts]
  Drafts --> Review[Future reviewed bed assignment]
```

Validation includes two-browser account isolation, delayed login response
reordering, revocation, conflicting writes, inert routine drafts and mobile
guide interactions. No household code or new house automation is deployed.

* fix: keep household preparation limited to private drafts

Reject scheduled routine responses in the browser preparation workspace so
a later controller upgrade cannot silently turn its draft editor into an
active scheduler. Cover the transition with the real authenticated browser.

```mermaid
flowchart LR
  Response[Personal routines] --> Draft[Draft: allow preparation]
  Response --> Active[Scheduled: require updated personal app]
```

Validation: both household browser scenarios pass, including the new
scheduled-response gate and complete guide interactions.
Keep sleep records attached to a stable sleeper when that person moves sides.
Add reviewed source intervals and immutable person-record identities, with
credential-derived reads, revision checks and signed bounded pagination.
Withhold transition-spanning or unknown observations, prevent duplicate
presence duration and quarantine changed source records.

```mermaid
flowchart LR
  Source[Complete source observation] --> Epoch[Reviewed dated assignment]
  Epoch --> Record[Stable person record]
  Credential[Current personal credential] --> Query[Self-only history query]
  Record --> Query
```

This is an internal integration foundation. Signup does not claim old history;
no HTTP mutation, collector, hardware assignment, live capability or Health
operation is enabled by it.

Validation: 53 household/schema tests, TypeScript and focused ESLint pass.
Tests cover solo-to-two-sleeper reassignment, foreign record IDs/cursors,
revocation, source corrections, boundary intervals and rollback.
The recording services merge both zones for a sole sleeper, while live comfort
evaluation previously inspected only the selected side. Resolve logical sleeper
presence from either zone and require both fresh calibrated sources before
using the combined observation. Keep two-sleeper and physical-zone views separate.

```mermaid
flowchart LR
  Left[Calibrated Left] --> Presence[One logical sleeper]
  Right[Calibrated Right] --> Presence
  Presence --> Preview[Bounded comfort Preview]
```

Bind qualification to both calibration identities and the logical source side.
Withhold missing, stale, future or mixed-frame evidence; residual movement cannot
create a fresh entry. Routines and temperature limits are unchanged.

Validation: 21 focused presence and live-adapter tests, TypeScript and ESLint pass.
Physical left/right/middle qualification and Pod deployment remain separate.
* feat(controls): bind personal commands to sleeper assignments

Add an internal person-scoped command service with isolated durable receipts.
Resolve physical zones from current authority, recheck credentials and bed
configuration at dispatch, and never replay interrupted or moved-side requests.

Thermal operations now validate the current request before persisting manual
intent, so an expired or superseded command cannot leave a new hold or pause.
No personal HTTP route, assignment activation or live capability is enabled.

```mermaid
flowchart LR
  PersonalKey --> Sleeper
  Sleeper --> CurrentAssignment
  CurrentAssignment --> GuardedCommand
  GuardedCommand --> PrivateReceipt
  GuardedCommand --> AuthorizedZones
```

Validation: 115 focused household, thermal, command and schema tests; TypeScript
and scoped ESLint. Hosted and mandatory pre-push checks are recorded on the PR.

* docs: handle an unscheduled weekend wake explicitly

Keep disabled weekend alarms separate from the following Monday occurrence. Plan a reviewed dated one-time alarm only after a dedicated API is implemented and qualified.
Record the merged account, history and command foundations separately from
live Pod state and the remaining two-person integration and physical checks.
Clarify that thermal following does not mirror the scheduled vibration alarm.

Validation: documentation links and git diff --check; existing software test
results are cited per exact PR, with skipped tests and the timeout retry noted.
No runtime, routine, credential or automation changes.

```mermaid
flowchart LR
  Solo[Luca solo] --> Review[Reviewed assignments]
  Review --> Shared[Marissa Left / Luca Right]
```
* feat: add scoped personal bed controls and atomic routine storage

Expose a disabled-by-default personal bed and command API that resolves current
sleeper authority from the database and rejects stale browser, device, assignment
and hardware-configuration contexts before writes and private responses.

Preserve durable request receipts, distinguish requested/reported/physical state,
and report partial two-zone dispatch as unknown. Move complete routines for both
zones in one SQLite transaction while retaining compiled-row, CAS and snooze checks.

```mermaid
flowchart LR
  Person[Personal session] --> Scope[Current sleeper and configuration]
  Scope --> Read[Filtered bed reading]
  Scope --> Receipt[Durable command receipt]
  Receipt --> Guard[Per-write authority check]
  Guard --> Hardware[Existing side locks and DAC FIFO]
```

Validation: 140 focused household, control, transaction and schema tests; TypeScript;
generated migration and schema snapshot. Full mandatory pre-push and hosted checks
will be recorded in the PR. No Pod deployment, profile activation, schedule change
or physical qualification is included. Routine publication and the complete
assignment/privacy coordinator remain separate release gates.

* fix: expose personal command POST route and exercise disabled runtime
Keep private routine drafts inert until their owner reviews the full live week
and confirms a scoped, expiring publication. Commit changed schedules and an
idempotent receipt together; report scheduler refresh separately from storage
and physical behavior. Preserve unchanged days and custom snooze settings.

```mermaid
flowchart LR
  Draft --> Review --> AtomicSave[Schedule and receipt transaction]
  AtomicSave --> Refresh[Scheduler refresh]
  LostResponse --> Lookup[Own receipt lookup]
```

Add account, revision, deadline, rollback, revocation and browser regressions,
plus frozen web/native fixtures. Publication defaults off; no Pod settings,
assignments, temperatures, alarms or TestFlight release are changed.

Validation: 151 focused SQLite/HTTP/contract tests, TypeScript and scoped lint.
Full pre-push, production build and built-route browser checks follow.
…ing (#70)

Personal accounts could prepare drafts but lacked an operational web interface. Add a separate personal workspace with authorized-zone temperature/power/Stop controls and a full weekly editor. Explicitly load the actual operating week, preserve all phase and alarm fields, compare every night including removals, then require both acknowledgments before publishing.

Reserve account-bound recovery references before one POST and use GET-only receipt recovery after lost replies, reloads or re-pairing. Keep reported, requested and measured values distinct; reject stale identity/routing and preempt unsent local actions when Stop is pressed. Preference saves cannot disable Stop. The personal bundle does not mount legacy owner clients.

Validation: 35 focused tests, six browser scenarios, and production build passed. Browser coverage distinguishes actual account isolation/disabled APIs from intercepted control responses and real IndexedDB recovery. Mandatory pre-push TypeScript, lint, schema, migration/deployment/bedroom and related-test checks are run without bypass. Existing household runtime flags remain off; this does not deploy to the Pod, activate a second sleeper, or release TestFlight.

Delayed draft/recovery reads cannot overwrite newer saved state or hide pending commands. Explicit draft reload/save temporarily disables editing; background bed polling does not.

```mermaid
flowchart LR
  Account[Personal account] --> Scope[Current permitted zones]
  Scope --> Saved[Durable recovery reference]
  Saved --> Request[Single explicit request]
  Request --> Receipt[Own receipt / GET recovery]
  Draft[Private weekly draft] --> Review[Whole-week review]
  Review --> Saved
```
Switching the browser to another account could leave an earlier owner response or sensor connection delivering data. Recheck current access after awaited API work, before and after each streamed read, and on every WebSocket input and output. RAW replay stops and closes its descriptor; revoked archive and database downloads cancel their producers and remove staging files.

```mermaid
flowchart LR
  Request[Original identity] --> Work[Await data]
  Work --> Check[Recheck current account]
  Check -->|valid| Deliver
  Check -->|changed| Cancel[Withhold and cancel]
```

Validation:
- 209 focused tests passed, including real response streams, real WebSocket connections, persisted account switching, delayed reads and archive cleanup.
- One existing socket-host test hit its five-second limit in a combined local run; it passed unchanged in isolation, and the complete 209-test set then passed unchanged with one worker. No timeout or assertion was relaxed.
- Six browser scenarios passed against the production build: illustrated guide, actual two-account API isolation, routine review, unknown-outcome recovery and storage isolation.
- Production build passed. Standard pre-push TypeScript, full lint, schema and Python/Node gates passed, with 6,903 related tests passed and 17 skipped before the final two cleanup regressions. The final cleanup delta then passed all the same mandatory gates and 28 related tests. These suites overlap and are not additive.

This change withholds further responses; it does not undo commands already dispatched or recall bytes already delivered. It does not change the frozen personal API contracts, enable household capabilities, restrict a still-valid owner's legacy scope, deploy to the Pod or release TestFlight. Persistent household privacy restrictions, person-scoped Health ingestion and reviewed side assignment remain separate activation requirements.
* feat: preserve personal privacy after household assignment

Persist a one-way privacy boundary with shared assignment and attribution so
legacy owner credentials cannot become a partner-history or RAW-data export.
Keep account preparation and unassigned drafts separate from activation.

Reject legacy APIs and streams after the boundary, direct browsers to their
personal workspace, interrupt superseded Watch uploads, and withhold shared
presence and biometrics. Preserve existing climate telemetry and HomeKit pairings.

```mermaid
flowchart LR
  Assignment[Reviewed shared arrangement] --> Boundary[Persistent privacy boundary]
  Boundary --> Personal[Person-scoped accounts]
  Boundary --> Legacy[Reject legacy owner data access]
  Boundary --> Shared[Withhold unconsented shared measurements]
```

Validate migration/backfill, rollback, account switching, in-flight output,
real socket closure, upload interruption and cached MQTT redaction with isolated
fixtures. Two-person activation, request-effect quiescence, person-bound Health
history and shared-actuator consent remain separate release gates. No live
controller deployment, settings changes or TestFlight release is included.

* fix: withdraw HomeKit presence after personal activation

Recheck the persisted privacy boundary for HomeKit reads and polling. Preserve accessory identity while returning unavailable and a fault, so shared occupancy cannot leak or trigger an empty-bed automation. Validated 144 focused HomeKit, MQTT, telemetry and privacy tests.
Preserve the current owner's actual operating week when preparing separate
sides. Each person sees and approves only their own preferences and routines;
changed settings, expired reviews and revoked approving devices invalidate it.

Add durable review storage, authenticated versioned routes and a private web
review with full-week summaries and GET-only recovery after lost replies.
Review flags default off. Approvals do not switch the bed or publish schedules.

```mermaid
flowchart LR
  Solo[Current solo bed] --> Review[Private proposed sides]
  Owner[Own operating week] --> Review
  Member[Own saved draft] --> Review
  Review --> Approval[Independent approvals]
  Approval --> Pending[Separate activation remains required]
```

Validation: 92 focused unit checks, production build, and nine distinct
household/personal browser scenarios passed. Final phone/tablet screenshots
were reviewed at large text sizes. No live Pod or TestFlight changes.
Personal activation closes the legacy owner API used by deployment health checks. This change adds a separate, read-only administrative status response containing only controller identity, freshness, aggregate thermal readiness and privacy-boundary availability. Browser sessions, personal credentials, selectors and actuator requests cannot use it. Deployment accepts the new validated contract; only a missing route (404) permits old-release compatibility.

Legacy recovery now refuses to overwrite or restart against personal household records, including preparation drafts. It checks before service changes, again after writers stop, and checks both current data and backups. Concurrent joins and failed-candidate personal writes are retained. Unknown/corrupt storage also holds recovery; if detected after quiescence, services remain stopped and the journal requires recovery. This is a conservative hold, not the final supported personal-account restore protocol. External durable recovery/version compatibility remains an activation gate.

```mermaid
flowchart LR
  Operator[Administrative bearer] --> Status[Aggregate status only]
  Restore[Legacy update or restore] --> Check{Personal records?}
  Check -->|yes or unknown| Hold[Preserve data and hold recovery]
  Check -->|no| Recheck[Stop writers and check again]
```

Validation before push:
- Production build and focused lint passed.
- 87 focused TypeScript tests passed, including personal-boundary, key rotation, abort, malformed/future/stale telemetry and restricted proxy behavior.
- Deployment suite: 192 passed, one skipped (193 total), including SQLite WAL, unassigned drafts, candidate failure, concurrent join, manual rollback and post-stop rechecks.
- Two built-server browser scenarios passed: the new GET/HEAD/405/auth contract and the existing maintenance UI recovery flow.

The working Pod, flags, accounts, routines, hardware and installed TestFlight build are unchanged. No physical or personal-recovery qualification is claimed. Mandatory push checks passed: 7,000 related TypeScript tests, 17 skipped, zero errors; full typecheck/lint, both schema checks, migration/deployment/bedroom checks also passed. Hosted results: all 14 checks passed on fc2c1e8; 8,660 unit tests passed, 19 skipped, and 42 browser scenarios passed. Both package builds, lint/typecheck, all seven Python module jobs, 21 offline migration checks, 193 deployment tests (one skipped), 11 bedroom tests and isolated network failure/recovery checks passed.

Two initial local hook runs were not accepted: different worker-start and wall-time test deadlines expired. The affected profile-history test passed unchanged in isolation. macOS power logs showed repeated system sleeps during the runs; CPU and memory were normal on inspection. The complete unchanged hook subsequently passed under a command-scoped system-sleep assertion (163-second test run). No test deadline or hook has been relaxed.
Expose bounded, credential-owned Pod recordings without legacy side fallback.
Keep complete overlapping intervals so date filters do not silently discard
an overnight recording, and preserve presence, movement and HRV semantics.

Recheck account authority and selected records immediately before response
delivery. Add strict shared web/native schemas and fixtures; keep the feature
disabled by default. Ingestion, Health and account activation remain separate.

Validation: 60 focused tests, three built-server browser scenarios, production
build, typecheck and focused lint. No live Pod or TestFlight changes.

```mermaid
flowchart LR
  Credential[Personal credential] --> Self[Resolve self]
  Self --> Records[Attributed recordings]
  Records --> Guard[Recheck before delivery]
  Guard --> Client[Private history]
```
Personal sleepers can now browse their attributed presence, vitals and movement recordings from the private web workspace. Previously the API existed but the web workspace offered no history view. The reader keeps complete recording intervals and historical side attribution, renders unavailable measurements explicitly, and labels bed presence separately from sleep.

```mermaid
flowchart LR
  Session[Personal session] --> Scope[Validated sleeper scope]
  Scope --> History[Ephemeral paginated history]
  Session --> Stop[Independent Stop control]
```

The reader validates the frozen v1 envelope, query echo and attribution before rendering, rejects repeated cursors or record identities, and clears private results when the page is hidden or session access changes. History requests never block Stop. No private history or cursors are saved to browser storage; the rollout flags remain unchanged.

Validation:
- 75 focused unit tests passed.
- 13 production-bundle browser checks passed, including phone/tablet large text, pagination, revoked access and concurrent Stop.
- Production build, TypeScript, lint and migration checks passed.
- Mandatory pre-push regression: 7,063 tests passed; 17 skipped.

No Pod deployment, personal ingestion activation or physical-device claim is included.
Allow fresh, quiet thermal observations to reach the personal comfort learner during Preview even while HR readiness is withheld. Keep control eligibility unchanged, attribute water measurements to the occupied physical zone, and require exact-time coverage with consistent source identities.

```mermaid
flowchart LR
  Observations[Fresh occupied thermal observations] --> Research[Research-only receipts]
  Research --> Nights[Comparable complete-night data]
  Nights --> Model[Held-out comfort learning]
```

Validation: 7,089 tests passed before the boundary refinement; 3,018 affected tests and all required local checks passed on the final head. Live deployment and adaptive activation remain separate.
Add Tonight and Signals views over the existing MQTT entities and link to
Core's authenticated controls and routine editor. Document why the legacy
free-sleep-ha component is not installed and how Homebridge room data and
native HomeKit fit the existing architecture.

Validation: YAML structure and 19 entity mappings checked; both views and
history rendered live in Home Assistant; authenticated routine link verified.
MQTT writes, hardware settings and routines remain unchanged.

```mermaid
flowchart LR
  Homebridge --> Core
  Core -->|MQTT| Dashboard
  Core <-->|HomeKit| AppleHome
```
* feat(comfort): train local models from complete reviewed nights

Reject partial, sparse, ambiguous and wake-warming recordings before thermal
learning. Fit a persistent on-Pod ridge model with source-bound reviews and
chronological holdout comparisons; keep model inference advisory.

Add authenticated readiness/training endpoints and a responsive model card.
Document the evidence, model limits and the separate causal-control milestones.

Flow: qualified readings + reviewed feedback -> complete nights -> local fit
      -> unseen-night baseline comparison -> research preview

Validation: 275 comfort tests, TypeScript, ESLint, production build and the
authenticated browser readiness test passed. No thermal model was fitted to
owner data and no actuator setting or controller service was changed.

* fix(comfort): complete model demo and schema contracts
Learn conditional 15- and 30-minute water-temperature forecasts from complete,
owner-reviewed Pod and room recordings. Compare later nights with persistence
and a fitted simple target-response baseline, retain provenance and empirical
error bands, and withhold unsupported or invalidated predictions.

Expose authenticated explicit fitting and read-only forecast cards. This model
does not estimate body temperature, establish the effect of changing targets,
or issue actuator commands. Existing routines and comfort modes remain intact.

```mermaid
flowchart LR
  Records[Reviewed full-night recordings] --> Fit[Earlier nights fit model]
  Records --> Check[Separate calibration and later evaluation]
  Fit --> Preview[Water forecast or abstention]
  Check --> Preview
  Preview --> UI[Read-only web cards]
```

Validation: 8,780 tests pass, 19 skipped; 192 deployment/recovery tests pass,
one skipped; two authenticated browser tests pass at desktop and mobile widths;
lint, TypeScript and production build pass. Real SQLite audit-to-fit tests use
explicit synthetic fixtures, never installed personal weights. Personal forecast
accuracy and sleep benefit still require qualified real recordings.
…se-forecast

feat: add reviewed-night water response forecasting

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant