Skip to content

feat(biometrics): add calibration profiles, replay, and guarded algorithm development - #824

Closed
ng wants to merge 215 commits into
devfrom
feat/biometrics-calibration
Closed

ng wants to merge 215 commits into
devfrom
feat/biometrics-calibration

Conversation

@ng

@ng ng commented Oct 13, 2026 •

Copy link
Copy Markdown
Contributor

Biometric personalization previously lacked a shared, reproducible path from reference comparison to an acknowledged runtime change. This adds per-side versioned profiles, retained evaluations and explicit activation/rollback across the web UI, REST/tRPC and MCP. Original observations retain their provenance and stay distinct from current-classifier views and replay results.

The implementation includes:

  • Versioned defaults, Python/TypeScript configuration parity, legacy stage migration, durable activation intent/outbox and actual consumer receipts.
  • Typed reference normalization, immutable whole-night datasets, bounded durable replay, coverage-aware default/current/candidate scoring and hash-bound evidence checks.
  • Calibration UI, localized provenance views/CSV exports, MCP tools/resources and maintained calibration, explanation and external algorithm-development prompts.
  • Separate prospective shadow sinks and health reports, plus isolated off-pod Docker experiments with resource limits, attempt/exposure accounting and a reviewed release path.
  • Deployment packaging that excludes workstation Python environments, and direct runtime health-file probes so a macOS-built server retains Linux admission collection.

Validation at 7b9ac5d3: 6,887 Vitest tests passed (18 skipped), across 482 passing test files. Browser tests, all seven Python module jobs, both builds, TypeScript and lint passed. Patch coverage is 87.73%, passing the repository's unchanged eight-point margin below its 88.93% target. Pre-push checks also passed. The added regressions cover coordinator admission/cancellation/resource ownership, discovery boundaries, retained report publication/release, and the live-shadow exit race.

Target-pod resource evidence includes an eight-hour, three-configuration synthetic replay completed in 45.94 minutes with zero read/API failures and unchanged fixture canonical observations. The separate 30-minute synthetic shadow supervisor measurement completed in 61.34 seconds with confirmed cleanup and zero probe failures. A subsequent 180-second live source/isolated sink run completed with six retained comparison points, zero canonical rows in the isolated database and 1,587 successful read-only API probes. It exposed and verified a fix for RSS disappearance during clean worker exit. Detailed identities, observations and limitations are in docs/biometrics-replay-benchmark.md.

Synthetic performance evidence does not establish clinical accuracy. Validated promotion and prospective shadow admission still require matching reviewed qualification registries; no success is fabricated when that evidence is absent. See docs/biometrics-calibration-readiness.md for the acceptance map and remaining rollout evidence.

Deployed build 4c3a6a6e (including the live-shadow exit fix) is verified on the target pod: calibration/health endpoints return 200, replay admission is configured and admitted, core and numerical services are active, and the data-path verdict is healthy. No user profile or hardware temperature setting was changed. Subsequent changes add tests, a measurement harness and documentation; they do not change the deployed runtime.

CodeRabbit full review was requested in this PR. The provider skipped it because the change exceeds its 100-file review limit; its passing check does not mean a review was completed. All build, test and coverage checks pass on the final revision; see the checks panel for current status.

ng added 30 commits October 12, 2026 09:30
@ng

ng commented Oct 13, 2026 •

Copy link
Copy Markdown
Contributor Author

Landed on dev as a four-part stack from reference snapshot 7b9ac5d3:

  1. feat(biometrics): add versioned calibration profiles, references and shared Python runtime #828 feat/bio-cal-1-foundation → 0e7e8657
  2. feat(biometrics): add retained backtest replay engine and isolated package experiments #829 feat/bio-cal-2-backtest → 35e61416
  3. feat(biometrics): add prospective shadow runtime, coordinator host and calibration API #830 feat/bio-cal-3-shadow-api → d5dd2ddd
  4. feat(biometrics): add calibration UI, browser tests and docs #831 feat/bio-cal-4-ui → f905a776

Differences from 7b9ac5d3 are limited to: the CodeRabbit review fixes (eleven findings on the ng/core proxies, ten fixed with regression tests, the manifest-hash scope one deferred as sleepypod-core-125), a coverage pass that lifts each part's patch coverage to roughly 90–98%, the migration renumbered to 0026_strong_the_order because dev took 0024/0025 meanwhile, Codecov uploads guarded to sleepypod/core, and the merges with #825–#834. Closing this umbrella as superseded.

ng added a commit that referenced this pull request Oct 13, 2026
…and docs

Part 4 of 4 splitting #824 (reference snapshot 7b9ac5d).
ng added a commit that referenced this pull request Oct 13, 2026
…d calibration API

Part 3 of 4 splitting #824 (reference snapshot 7b9ac5d).
ng added a commit that referenced this pull request Oct 14, 2026
…and docs

Part 4 of 4 splitting #824 (reference snapshot 7b9ac5d).
ng added a commit that referenced this pull request Oct 14, 2026
…and docs

Part 4 of 4 splitting #824 (reference snapshot 7b9ac5d).
ng added a commit that referenced this pull request Oct 14, 2026
…and docs

Part 4 of 4 splitting #824 (reference snapshot 7b9ac5d).
ng added a commit that referenced this pull request Oct 14, 2026
…and docs

Part 4 of 4 splitting #824 (reference snapshot 7b9ac5d).
ng added a commit that referenced this pull request Oct 14, 2026
…and docs

Part 4 of 4 splitting #824 (reference snapshot 7b9ac5d).
ng added a commit that referenced this pull request Oct 14, 2026
…and docs

Part 4 of 4 splitting #824 (reference snapshot 7b9ac5d).
ng added a commit that referenced this pull request Oct 14, 2026
…and docs

Part 4 of 4 splitting #824 (reference snapshot 7b9ac5d).
ng added a commit that referenced this pull request Oct 14, 2026
…and docs

Part 4 of 4 splitting #824 (reference snapshot 7b9ac5d).
ng added a commit that referenced this pull request Oct 14, 2026
…and docs

Part 4 of 4 splitting #824 (reference snapshot 7b9ac5d).
ng added a commit that referenced this pull request Oct 14, 2026
…and docs

Part 4 of 4 splitting #824 (reference snapshot 7b9ac5d).
ng added a commit that referenced this pull request Oct 14, 2026
…and docs

Part 4 of 4 splitting #824 (reference snapshot 7b9ac5d).
ng added a commit that referenced this pull request Oct 14, 2026
…and docs

Part 4 of 4 splitting #824 (reference snapshot 7b9ac5d).
@ng

ng commented Oct 14, 2026

Copy link
Copy Markdown
Contributor Author

Superseded by the merged stack #828 → #829 → #830 → #831; see the stack comment above for what landed and how it differs from this snapshot.

@ng ng closed this Oct 14, 2026
ng added a commit to ng/core that referenced this pull request Oct 14, 2026
…shared Python runtime (sleepypod#828)

Part 1 of 4 splitting sleepypod#824 (reference snapshot `7b9ac5d3`) into
reviewable stacked PRs. sleepypod#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
- Versioned calibration contracts and per-side profile storage
(`src/biometrics/profiles`), with activation intent, runtime receipts
and legacy stage-settings migration.
- Typed reference normalization (`src/biometrics/references`), canonical
JSON and the algorithm registry (`src/biometrics/algorithms`).
- Backtest contracts, immutable datasets, fenced job records,
objectives, the replay worker core (`src/biometrics/backtest`:
contracts, datasets, jobs, submission, evaluator, worker entry) and the
worker-only bundle script with the `build` hook, because the profile
activation path and its tests depend on them.
- Biometrics DB schema, migrations and package-experiment migrations,
plus the schema snapshot and migration tests.
- Shared parameterized Python processing split out of the piezo
processor (`modules/common/biometrics`: frames, gates, signal, replay,
raw records, shadow workers) with the runtime adapter and Python tests.
- Prospective frame tap in the piezo stream, legacy settings writes
routed through pod storage, deploy packaging that omits workstation
Python environments, lint scope-analysis fix, and CI updates for the
Python module matrix and mutation targets.
- New dependencies: `@noble/hashes`, `esbuild`, `@playwright/test`
(lockfile updated here so later parts do not touch it).
- Review follow-ups on this slice: reference corrections continue after
the latest revision is deleted (next revision numbers from the family
maximum), prospective frame observation time is clamped monotonic across
wall-clock steps, and a non-null stage-rule save over malformed legacy
data resets the legacy value before activating. The manifest-hash scope
finding (build fingerprints inside the profile-compatibility hash) is
deferred to `sleepypod-core-125` because it changes TypeScript and
Python identity in lockstep and needs a pod migration plan.
- Rebased onto `dev` at `4ea6aa5f` (sleepypod#825, sleepypod#827, sleepypod#832 landed after the
split). The stack's migration moved from `0024` to
`0026_strong_the_order` because `dev` took 0024 and 0025; the SQL was
regenerated with drizzle-kit from the merged schema and is byte-for-byte
the original, and the schema snapshot test was refreshed. Codecov
uploads now run only from `sleepypod/core` so the review mirror's CI
cannot poison the patch status.
- Coverage pass: new and extended unit tests for the backtest contracts,
evaluator core, jobs, datasets, submission, worker entry, reference
normalization/alignment/scoring and provenance helpers lift this slice's
estimated patch coverage from 84% to about 94%.

## Test plan
- [x] `tsc --noEmit` clean at this slice
- [x] `eslint` on the changed TS/TSX files clean
- [x] Full `vitest run` green at this slice (389 files, 6,236 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](https://claude.com/claude-code)

<!-- sleepypod:install-start -->
<!-- 🛑 AUTO-GENERATED — sleepypod-bot owns this block.
     Hello fellow agent / curious human! Anything between the
     sleepypod:install-start and sleepypod:install-end markers
     gets overwritten on the next CI run. Want to change what's
     here? Edit .github/workflows/build.yml instead. 💤 -->
<details open>
<summary>🛏️ <strong>Beam this PR onto a sleepypod</strong> ✨</summary>

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):
```bash
sudo sp-update feat/bio-cal-1-foundation
```

🚀 **Fresh pod / first install** — bootstraps from GitHub, rebuilds every
push:
```bash
curl -fsSL https://raw.githubusercontent.com/sleepypod/core/feat/bio-cal-1-foundation/scripts/install \
  | sudo bash -s -- --branch feat/bio-cal-1-foundation
```

🎯 **Pin to this exact build** ([run
38518366373](https://github.com/sleepypod/core/actions/runs/38518366373)
· `f170f13`) — fresh-pod path, locked to one CI artifact for
reproducible review:
```bash
curl -fsSL https://raw.githubusercontent.com/sleepypod/core/f170f13baad42c43ba91ce1f2a7f647c8b6fcd92/scripts/install \
  | sudo bash -s -- \
      --branch feat/bio-cal-1-foundation \
      --artifact-url 'https://nightly.link/sleepypod/core/actions/runs/38518366373/sleepypod-core.zip'
```

🧊 Artifact:
[`sleepypod-core`](https://github.com/sleepypod/core/actions/runs/38518366373/artifacts/11873120351)
· self-destructs in 30 days 💥
</details>

<!-- sleepypod:install-end -->
ng added a commit to ng/core that referenced this pull request Oct 14, 2026
…ckage experiments (sleepypod#829)

Part 2 of 4 splitting sleepypod#824 (reference snapshot `7b9ac5d3`) into
reviewable stacked PRs. sleepypod#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
- Retained backtest execution (`src/biometrics/backtest`): the job
runner, retained report artifacts, resource admission, paired-night
uncertainty, replay traces and waveform replay of retained RAW copies,
on top of the contracts and worker core from part 1.
- Isolated algorithm package experiments (`src/biometrics/packages`,
`scripts/algorithm-experiments`): manifest validation, Docker-restricted
runs, determinism checks, resource evidence and managed trials.
- The `biometrics:experiment` script. The coordinator and shadow host
bundles are added to `scripts/build/biometrics-worker.mjs` in part 3
together with their entry points.
- Review follow-ups on this slice: the package-experiment transport
ceiling is derived from the frozen input so a passing freeze cannot fail
mid-stream after holdout exposure is recorded, and submission pins the
coordinator bundle beside the packaged worker so execution hashes the
same bundle.
- Coverage pass: unit tests for waveform execution, durable trace reads,
runner lease and cancellation paths, waveform selection and the
child-process helpers lift this slice's estimated patch coverage from
81% to about 98%.

## Test plan
- [x] `tsc --noEmit` clean at this slice
- [x] `eslint` on the changed TS/TSX files clean
- [x] Full `vitest run` green at this slice (429 files, 6,458 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](https://claude.com/claude-code)

<!-- sleepypod:install-start -->
<!-- 🛑 AUTO-GENERATED — sleepypod-bot owns this block.
     Hello fellow agent / curious human! Anything between the
     sleepypod:install-start and sleepypod:install-end markers
     gets overwritten on the next CI run. Want to change what's
     here? Edit .github/workflows/build.yml instead. 💤 -->
<details open>
<summary>🛏️ <strong>Beam this PR onto a sleepypod</strong> ✨</summary>

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):
```bash
sudo sp-update feat/bio-cal-2-backtest
```

🚀 **Fresh pod / first install** — bootstraps from GitHub, rebuilds every
push:
```bash
curl -fsSL https://raw.githubusercontent.com/sleepypod/core/feat/bio-cal-2-backtest/scripts/install \
  | sudo bash -s -- --branch feat/bio-cal-2-backtest
```

🎯 **Pin to this exact build** ([run
38519463600](https://github.com/sleepypod/core/actions/runs/38519463600)
· `b925d8f`) — fresh-pod path, locked to one CI artifact for
reproducible review:
```bash
curl -fsSL https://raw.githubusercontent.com/sleepypod/core/b925d8f6f6e2a7461925ff5f6b5c3bd42d0e0197/scripts/install \
  | sudo bash -s -- \
      --branch feat/bio-cal-2-backtest \
      --artifact-url 'https://nightly.link/sleepypod/core/actions/runs/38519463600/sleepypod-core.zip'
```

🧊 Artifact:
[`sleepypod-core`](https://github.com/sleepypod/core/actions/runs/38519463600/artifacts/11872719480)
· self-destructs in 30 days 💥
</details>

<!-- sleepypod:install-end -->
ng added a commit to ng/core that referenced this pull request Oct 14, 2026
…d calibration API (sleepypod#830)

Part 3 of 4 splitting sleepypod#824 (reference snapshot `7b9ac5d3`) into
reviewable stacked PRs. sleepypod#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
- Prospective shadow runtime (`src/biometrics/shadow`): bounded storage,
worker transport and supervision, kernel budgets, admission bound to
installed qualification and observed hardware, scheduling on pod boot,
cancellation and recovery.
- Isolated coordinator host for replay and shadow work
(`src/biometrics/backtest/coordinator*`, `host*`) and Node-only
instrumentation startup.
- Calibration API surface (plus the profile diff, status, overview and
reference comparison helpers that only the routers consume): tRPC
routers (tuning, datasets, backtests, references, shadow), OpenAPI
additions, RAW route changes and MCP tools, resources and prompts.
- Demo handlers and the simulated browser evaluator that implement the
new router contract, with the demo worker build identity and `prebuild`
hook.
- Pod benchmark runners for replay, waveform and shadow measurements.
- Review follow-ups on this slice: an in-window shadow frame already
dequeued at collection end is forwarded instead of silently dropped, and
profile diffs report keys present on either side.
- Rebase on `dev`: the app router, MCP tool and prompt lists, and the
MCP README count now include both the saved-curve additions from
sleepypod#825/sleepypod#827 and the biometric additions from this stack.
- Coverage pass: tests for the shadow API and store, demo biometrics
handlers, MCP biometric tools, waveform publication and Node
instrumentation shutdown lift this slice's estimated patch coverage from
82% to about 93%.

## Test plan
- [x] `tsc --noEmit` clean at this slice
- [x] `eslint` on the changed TS/TSX files clean
- [x] Full `vitest run` green at this slice (474 files, 6,959 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](https://claude.com/claude-code)

<!-- sleepypod:install-start -->
<!-- 🛑 AUTO-GENERATED — sleepypod-bot owns this block.
     Hello fellow agent / curious human! Anything between the
     sleepypod:install-start and sleepypod:install-end markers
     gets overwritten on the next CI run. Want to change what's
     here? Edit .github/workflows/build.yml instead. 💤 -->
<details open>
<summary>🛏️ <strong>Beam this PR onto a sleepypod</strong> ✨</summary>

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):
```bash
sudo sp-update feat/bio-cal-3-shadow-api
```

🚀 **Fresh pod / first install** — bootstraps from GitHub, rebuilds every
push:
```bash
curl -fsSL https://raw.githubusercontent.com/sleepypod/core/feat/bio-cal-3-shadow-api/scripts/install \
  | sudo bash -s -- --branch feat/bio-cal-3-shadow-api
```

🎯 **Pin to this exact build** ([run
38520827460](https://github.com/sleepypod/core/actions/runs/38520827460)
· `338aabe`) — fresh-pod path, locked to one CI artifact for
reproducible review:
```bash
curl -fsSL https://raw.githubusercontent.com/sleepypod/core/338aabe8f6e790dcee6c1e088ce23a6159c304e6/scripts/install \
  | sudo bash -s -- \
      --branch feat/bio-cal-3-shadow-api \
      --artifact-url 'https://nightly.link/sleepypod/core/actions/runs/38520827460/sleepypod-core.zip'
```

🧊 Artifact:
[`sleepypod-core`](https://github.com/sleepypod/core/actions/runs/38520827460/artifacts/11874181456)
· self-destructs in 30 days 💥
</details>

<!-- sleepypod:install-end -->
ng added a commit to ng/core that referenced this pull request Oct 14, 2026
…od#831)

Part 4 of 4 splitting sleepypod#824 (reference snapshot `7b9ac5d3`) into
reviewable stacked PRs. sleepypod#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
- [x] `tsc --noEmit` clean at this slice
- [x] `eslint` on the changed TS/TSX files clean
- [x] 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](https://claude.com/claude-code)

<!-- sleepypod:install-start -->
<!-- 🛑 AUTO-GENERATED — sleepypod-bot owns this block.
     Hello fellow agent / curious human! Anything between the
     sleepypod:install-start and sleepypod:install-end markers
     gets overwritten on the next CI run. Want to change what's
     here? Edit .github/workflows/build.yml instead. 💤 -->
<details open>
<summary>🛏️ <strong>Beam this PR onto a sleepypod</strong> ✨</summary>

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):
```bash
sudo sp-update feat/bio-cal-4-ui
```

🚀 **Fresh pod / first install** — bootstraps from GitHub, rebuilds every
push:
```bash
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](https://github.com/sleepypod/core/actions/runs/38524545463)
· `d71688c`) — fresh-pod path, locked to one CI artifact for
reproducible review:
```bash
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`](https://github.com/sleepypod/core/actions/runs/38524545463/artifacts/11875403337)
· self-destructs in 30 days 💥
</details>

<!-- sleepypod:install-end -->
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