Skip to content

feat(biometrics): add calibration UI, browser tests and docs - #831

Merged
ng merged 7 commits into
devfrom
feat/bio-cal-4-ui
Oct 14, 2026
Merged

ng merged 7 commits into
devfrom
feat/bio-cal-4-ui

Conversation

@ng

@ng ng commented Oct 13, 2026 •

Copy link
Copy Markdown
Contributor

Part 4 of 4 splitting #824 (reference snapshot 7b9ac5d3) into reviewable stacked PRs. #824 stays open as the umbrella and is not merged; the four parts reproduce its tree exactly (the tree of feat/bio-cal-4-ui is identical to the tree of 7b9ac5d3).

Stack, merge in order:

  1. feat/bio-cal-1-foundation → dev: versioned calibration profiles, references, DB schema and migrations, shared Python runtime
  2. feat/bio-cal-2-backtest → part 1: retained backtest replay engine and isolated package experiments
  3. feat/bio-cal-3-shadow-api → part 2: prospective shadow runtime, isolated coordinator host, calibration API and MCP, demo handlers
  4. feat/bio-cal-4-ui → part 3: calibration UI, i18n catalogs, browser tests and docs

This part

  • Calibration UI (src/components/biometrics): profile editing and revisions, reference imports and corrections, dataset freezing, backtest submission and monitoring, report review, replay traces, shadow planning and prospective observations.
  • Settings integration for sleep-stage rules and Watch imports with calibration profiles.
  • Spanish, English and pseudo catalogs for the new messages.
  • Playwright browser tests (tests/browser), the test:browser script and the Browser Tests CI job.
  • Review follow-ups on this slice: signal_replay experiments are labelled in the experiment list, CSV formula prefixes behind leading line breaks are neutralized, the correction and measurement panels in the reference library use distinct React keys, and the calibration components gained unit cases for their error, loading, paging and toggle paths so the per-PR patch-coverage gate holds without the browser suite.
  • Calibration docs: API, datasets, reference imports, backtest jobs, runtime activation, replay benchmark and readiness map.
  • Second coverage pass: CandidateStageFields and CalibrationOverview gained tests and the remaining Calibration components' branches are driven; estimated patch coverage is about 92% (remaining misses are i18n locale fallbacks and guards unreachable from the DOM).

Test plan

  • tsc --noEmit clean at this slice
  • eslint on the changed TS/TSX files clean
  • Full vitest run green at this slice (507 files, 7,164 tests) (the only failure under full-suite load was the pre-existing, unrelated scripts/tests/diagnosticCli.test.ts timing test, which passes in isolation)
  • CI: Typecheck, Lint, Unit Tests, Python modules, Build & Package
  • CodeRabbit review via the mirror proxy addressed

🤖 Generated with Claude Code

🛏️ Beam this PR onto a sleepypod ✨

Pick the snippet that matches your pod. Already-installed pods can't use the curl bootstraps below — sleepypod's egress firewall DROPs github.com, and the script that knows how to unblock WAN is the very file curl is trying to fetch. Use sp-update instead; it's on disk and opens WAN as its first step.

🔄 Already on a sleepypod (most common — review a PR on a running pod):

sudo sp-update feat/bio-cal-4-ui

🚀 Fresh pod / first install — bootstraps from GitHub, rebuilds every push:

curl -fsSL https://raw.githubusercontent.com/sleepypod/core/feat/bio-cal-4-ui/scripts/install \
  | sudo bash -s -- --branch feat/bio-cal-4-ui

🎯 Pin to this exact build (run 38524545463 · d71688c) — fresh-pod path, locked to one CI artifact for reproducible review:

curl -fsSL https://raw.githubusercontent.com/sleepypod/core/d71688cc42c52dc7bc9107f8929907d1f60d38ce/scripts/install \
  | sudo bash -s -- \
      --branch feat/bio-cal-4-ui \
      --artifact-url 'https://nightly.link/sleepypod/core/actions/runs/38524545463/sleepypod-core.zip'

🧊 Artifact: sleepypod-core · self-destructs in 30 days 💥

@vercel

vercel Bot commented Oct 13, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated
sleepypod-demo Ignored Ignored Preview Oct 14, 2026 6:50am UTC

@coderabbitai

coderabbitai Bot commented Oct 13, 2026 •

Copy link
Copy Markdown

Important

Review skipped

Too many files!

This PR contains 109 files, which is 9 over the limit of 100.

To get a review, reduce the PR to 100 files or fewer by splitting it into smaller PRs or changing its base branch.

Upgrade to a paid plan to raise the limit.

This review couldn't start because sufficient usage credits or metered capacity aren't available. Add credits or update usage-based reviews in the billing tab, then retry.

⚙️ Run configuration
  • Configuration used: defaults
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: d16e7565-89cb-43c2-ab27-c6bb56d77936
📥 Commits

Reviewing files that changed from the base of the PR and between d5dd2dd and d71688c.

📒 Files selected for processing: 109
  • .github/workflows/test.yml
  • docs/biometrics-backtest-jobs.md
  • docs/biometrics-calibration-api.md
  • docs/biometrics-calibration-readiness.md
  • docs/biometrics-datasets.md
  • docs/biometrics-reference-imports.md
  • docs/biometrics-replay-benchmark.md
  • docs/biometrics-runtime-activation.md
  • docs/performance/biometrics-replay-2026-10-13/deployment-policy.json
  • docs/performance/biometrics-replay-2026-10-13/deployment-verification.json
  • docs/performance/biometrics-replay-2026-10-13/fullnight-db52f1da.json
  • docs/performance/biometrics-replay-2026-10-13/live-shadow-operational.json
  • docs/performance/biometrics-replay-2026-10-13/shadow-4ee74c25.json
  • docs/performance/biometrics-replay-2026-10-13/smoke-4453c0a5.json
  • package.json
  • src/components/Settings/SettingsScreen.tsx
  • src/components/Settings/SleepStageRules.tsx
  • src/components/Settings/sections.ts
  • src/components/Settings/tests/SleepStageRules.test.tsx
  • src/components/Settings/tests/sections.test.ts
  • src/components/biometrics/BiometricsPage.tsx
  • src/components/biometrics/Calibration/BacktestJobs.tsx
  • src/components/biometrics/Calibration/BacktestReport.tsx
  • src/components/biometrics/Calibration/BacktestSubmission.tsx
  • src/components/biometrics/Calibration/BiometricCalibration.tsx
  • src/components/biometrics/Calibration/CalibrationBacktests.tsx
  • src/components/biometrics/Calibration/CalibrationHistory.tsx
  • src/components/biometrics/Calibration/CalibrationOverview.tsx
  • src/components/biometrics/Calibration/CalibrationReferences.tsx
  • src/components/biometrics/Calibration/CandidateStageFields.tsx
  • src/components/biometrics/Calibration/DatasetBuilder.tsx
  • src/components/biometrics/Calibration/DatasetLibrary.tsx
  • src/components/biometrics/Calibration/ExperimentBuilder.tsx
  • src/components/biometrics/Calibration/ExperimentLibrary.tsx
  • src/components/biometrics/Calibration/ManualProfileActivation.tsx
  • src/components/biometrics/Calibration/NumericReport.tsx
  • src/components/biometrics/Calibration/NumericTrace.tsx
  • src/components/biometrics/Calibration/ObjectiveThresholds.tsx
  • src/components/biometrics/Calibration/ProfileCandidateEditor.tsx
  • src/components/biometrics/Calibration/ProfileComparison.tsx
  • src/components/biometrics/Calibration/ProfileLibrary.tsx
  • src/components/biometrics/Calibration/ProfileRecovery.tsx
  • src/components/biometrics/Calibration/ReferenceLibrary.tsx
  • src/components/biometrics/Calibration/ReferenceOverlay.tsx
  • src/components/biometrics/Calibration/ReferenceTimeSpan.tsx
  • src/components/biometrics/Calibration/ReplayResources.tsx
  • src/components/biometrics/Calibration/ReplaySessionPicker.tsx
  • src/components/biometrics/Calibration/ShadowComparison.tsx
  • src/components/biometrics/Calibration/ShadowReport.tsx
  • src/components/biometrics/Calibration/ShadowRuns.tsx
  • src/components/biometrics/Calibration/ShadowSchedule.tsx
  • src/components/biometrics/Calibration/StageReport.tsx
  • src/components/biometrics/Calibration/StageTrace.tsx
  • src/components/biometrics/Calibration/ValidatedProfileActivation.tsx
  • src/components/biometrics/Calibration/WaveformDatasetBuilder.tsx
  • src/components/biometrics/Calibration/report-view.ts
  • src/components/biometrics/Calibration/shadow-schedule-recovery.ts
  • src/components/biometrics/Calibration/tests/BacktestJobs.test.tsx
  • src/components/biometrics/Calibration/tests/BacktestReport.test.tsx
  • src/components/biometrics/Calibration/tests/BacktestSubmission.test.tsx
  • src/components/biometrics/Calibration/tests/BiometricCalibration.test.tsx
  • src/components/biometrics/Calibration/tests/CalibrationOverview.test.tsx
  • src/components/biometrics/Calibration/tests/CalibrationReferences.test.tsx
  • src/components/biometrics/Calibration/tests/CandidateStageFields.test.tsx
  • src/components/biometrics/Calibration/tests/DatasetBuilder.test.tsx
  • src/components/biometrics/Calibration/tests/DatasetLibrary.test.tsx
  • src/components/biometrics/Calibration/tests/ExperimentBuilder.test.tsx
  • src/components/biometrics/Calibration/tests/ExperimentLibrary.test.tsx
  • src/components/biometrics/Calibration/tests/ManualProfileActivation.test.tsx
  • src/components/biometrics/Calibration/tests/NumericReport.test.tsx
  • src/components/biometrics/Calibration/tests/NumericTrace.test.tsx
  • src/components/biometrics/Calibration/tests/ProfileCandidateEditor.test.tsx
  • src/components/biometrics/Calibration/tests/ProfileComparison.test.tsx
  • src/components/biometrics/Calibration/tests/ProfileLibrary.test.tsx
  • src/components/biometrics/Calibration/tests/ProfileRecovery.test.tsx
  • src/components/biometrics/Calibration/tests/ReferenceLibrary.test.tsx
  • src/components/biometrics/Calibration/tests/ReferenceOverlay.test.tsx
  • src/components/biometrics/Calibration/tests/ReferenceTimeSpan.test.tsx
  • src/components/biometrics/Calibration/tests/ReplayResources.test.tsx
  • src/components/biometrics/Calibration/tests/ReplaySessionPicker.test.tsx
  • src/components/biometrics/Calibration/tests/ShadowComparison.test.tsx
  • src/components/biometrics/Calibration/tests/ShadowRuns.test.tsx
  • src/components/biometrics/Calibration/tests/ShadowSchedule.test.tsx
  • src/components/biometrics/Calibration/tests/StageReport.test.tsx
  • src/components/biometrics/Calibration/tests/StageTrace.test.tsx
  • src/components/biometrics/Calibration/tests/ValidatedProfileActivation.test.tsx
  • src/components/biometrics/Calibration/tests/WaveformDatasetBuilder.test.tsx
  • src/components/biometrics/Calibration/tests/report-view.test.ts
  • src/components/biometrics/Calibration/tests/shadow-schedule-recovery.test.ts
  • src/components/biometrics/RawDataButton.tsx
  • src/components/biometrics/biometricsLogic.ts
  • src/components/biometrics/tests/BiometricsPage.test.tsx
  • src/components/biometrics/tests/biometricsLogic.test.ts
  • src/components/biometrics/tests/vitals-csv.test.ts
  • src/components/biometrics/vitals-csv.ts
  • src/lib/i18n/locales/en.js
  • src/lib/i18n/locales/en.po
  • src/lib/i18n/locales/es.js
  • src/lib/i18n/locales/es.po
  • src/lib/i18n/locales/pseudo.js
  • src/lib/i18n/locales/pseudo.po
  • src/server/routers/tests/biometricTuning.test.ts
  • tests/browser/README.md
  • tests/browser/calibration.e2e.ts
  • tests/browser/fixture.ts
  • tests/browser/playwright.config.ts
  • tests/browser/provenance.e2e.ts
  • tests/browser/run.mjs
  • tests/browser/workflow.e2e.ts

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

  • 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

Comment @coderabbitai help to get the list of available commands.

@ng ng changed the title feat(biometrics): add calibration UI, demo simulation, browser tests and docs feat(biometrics): add calibration UI, browser tests and docs Oct 13, 2026
@ng
ng force-pushed the feat/bio-cal-4-ui branch from 5adb0ff to e5672b8 Compare October 13, 2026 23:35
@ng
ng force-pushed the feat/bio-cal-3-shadow-api branch from 9ac5c2f to 6992227 Compare October 13, 2026 23:35
@ng
ng force-pushed the feat/bio-cal-3-shadow-api branch from 6992227 to 94d2ea9 Compare October 13, 2026 23:56
@ng
ng force-pushed the feat/bio-cal-4-ui branch from e5672b8 to b15bcf9 Compare October 14, 2026 00:00
@ng
ng force-pushed the feat/bio-cal-3-shadow-api branch from 94d2ea9 to 2eed4dc Compare October 14, 2026 00:58
@ng
ng force-pushed the feat/bio-cal-4-ui branch from b15bcf9 to 3fd83bd Compare October 14, 2026 00:58
@ng
ng force-pushed the feat/bio-cal-3-shadow-api branch from 2eed4dc to 95042a8 Compare October 14, 2026 01:04
@ng
ng force-pushed the feat/bio-cal-4-ui branch from 3fd83bd to a9d6e75 Compare October 14, 2026 01:04
@ng
ng force-pushed the feat/bio-cal-3-shadow-api branch from 95042a8 to a08f64a Compare October 14, 2026 02:37
@ng
ng force-pushed the feat/bio-cal-4-ui branch 2 times, most recently from 67b3ce6 to 1639835 Compare October 14, 2026 02:51
@ng
ng force-pushed the feat/bio-cal-3-shadow-api branch from a08f64a to f67e89e Compare October 14, 2026 02:51
@ng
ng force-pushed the feat/bio-cal-4-ui branch from 1639835 to d34c58b Compare October 14, 2026 03:34
@ng
ng force-pushed the feat/bio-cal-3-shadow-api branch 2 times, most recently from 1cfde00 to a6fb67c Compare October 14, 2026 05:11
@ng
ng force-pushed the feat/bio-cal-4-ui branch from d34c58b to 27b8a4b Compare October 14, 2026 05:11
@ng
ng force-pushed the feat/bio-cal-3-shadow-api branch from a6fb67c to 13d60df Compare October 14, 2026 05:45
@ng
ng force-pushed the feat/bio-cal-4-ui branch 2 times, most recently from 00dba78 to 7ffe551 Compare October 14, 2026 05:57
@ng
ng force-pushed the feat/bio-cal-3-shadow-api branch from 13d60df to 143a346 Compare October 14, 2026 05:57
@ng
ng force-pushed the feat/bio-cal-4-ui branch from 7ffe551 to dcfa45e Compare October 14, 2026 06:12
@ng
ng force-pushed the feat/bio-cal-3-shadow-api branch from 143a346 to 338aabe Compare October 14, 2026 06:12
@ng
ng force-pushed the feat/bio-cal-4-ui branch from dcfa45e to fd60d23 Compare October 14, 2026 06:44
Base automatically changed from feat/bio-cal-3-shadow-api to dev October 14, 2026 06:48
@ng
ng force-pushed the feat/bio-cal-4-ui branch from fd60d23 to d71688c Compare October 14, 2026 06:49
@ng
ng enabled auto-merge October 14, 2026 06:50
@ng
ng added this pull request to the merge queue Oct 14, 2026
Merged via the queue into dev with commit f905a77 Oct 14, 2026
10 checks passed
@ng
ng deleted the feat/bio-cal-4-ui branch October 14, 2026 07:06
ng added a commit that referenced this pull request Oct 14, 2026
…ibration, saved curves and presence auto-on (#820)

Promotes `dev` to `main` with Apple Watch reference data, configurable sleep-stage classification, biometrics calibration, saved and annotated curves, experimental presence auto-on, and Host/Origin hardening for the pod API.

## Changes
- Import Apple Watch sleep stages and heart rate, overlay reference heart rate on the vitals chart, explore vitals, and build datasets for classifier calibration (#802, #803, #814, #821, #826).
- Add per-side sleep-stage rules, written as sentences with quick adjust, preview and a change log, and respect piezo calibration quality, including unknown calibration in the week view (#815, #816, #817, #822).
- Add biometrics calibration: versioned profiles and references, a shared Python runtime, a retained backtest replay engine, a prospective shadow runtime with a calibration API, and the calibration UI (#828–#831).
- MCP tools to inspect, preview and apply sleep-stage rules against the Watch reference, and to build and save a sleep curve from pod data (#823, #825).
- Save named curves on the pod and add optional notes to curves (#827, #832).
- Experimental per-side presence auto-on with person-vs-pet occupancy classification; auto-off now ignores light loads such as pets (#810).
- Reject unknown Host headers so DNS-rebinding pages cannot reach the unauthenticated pod API, and apply the same Host/Origin allowlist to the sensor WebSocket handshake (#833, #834).
- Improve session endings, movement scoring during Pod 5 pump operation, and vitals continuity for quiet sleepers (#804, #813).
- Add away-mode toggles to the side card and Stage panel, move Settings to per-section side tabs, improve the scheduled label contrast, and prevent premature stalled-pipeline banners (#805–#808).
- Update dependencies and pin Babel runtime to fix the Turbopack MQTT build (#811, #812, #818, #819).

## Migrations
- Configuration DB: side stage classifier, stage classifier changes, curve templates, schedule notes and presence auto-on columns (0022–0027).
- Biometrics DB: Watch reference stages and vitals, and calibration tables (0017–0030).

## Test plan
- [x] GitHub checks on the `dev` head: build, lint, typecheck, unit tests, browser tests and all Python test jobs.
- [ ] After merge, wait for "Analyze & Release" on the `main` merge commit, then `sudo sp-update main` once on a pod and confirm the service starts and migrations apply.
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