-
Notifications
You must be signed in to change notification settings - Fork 7
chore: make the repo cloneable, add CI, drop the dead TypeScript port #28
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
4 commits
Select commit
Hold shift + click to select a range
cfec831
chore: make the repo cloneable, add CI, drop the dead TypeScript port
abdulsaheel bca815a
chore: address CodeRabbit review — CI hardening, honest privacy wording
abdulsaheel 49604f9
ci: actually test the declared minimum SDK
abdulsaheel 308a75b
test: suppress deliberate deprecation notices so 3.5.0 passes
abdulsaheel File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| # GitHub funding config only accepts URLs, not raw wallet addresses. | ||
| custom: | ||
| - https://github.com/OpenStrap/edge/blob/main/DONATE.md |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,46 @@ | ||
| name: test | ||
|
|
||
| on: | ||
| push: | ||
| branches: [main] | ||
| pull_request: | ||
| workflow_dispatch: | ||
|
|
||
| # Read-only: this job only builds and tests. Nothing here needs write access, | ||
| # and it executes code from pull requests. | ||
| permissions: | ||
| contents: read | ||
|
|
||
| jobs: | ||
| test: | ||
| runs-on: ubuntu-latest | ||
| strategy: | ||
| fail-fast: false | ||
| matrix: | ||
| # pubspec declares `sdk: ^3.5.0`, so 3.5.0 is a claim this package makes | ||
| # to anyone depending on it. Test it, rather than only testing whatever | ||
| # `stable` happens to be — otherwise the lower bound is a guess. | ||
| sdk: ['3.5.0', 'stable'] | ||
| name: test (Dart ${{ matrix.sdk }}) | ||
| steps: | ||
| - uses: actions/checkout@v4 | ||
| with: | ||
| # Don't leave GITHUB_TOKEN in .git/config where PR-authored test code | ||
| # could read it. Nothing in this job pushes back to the repo. | ||
| persist-credentials: false | ||
| - uses: dart-lang/setup-dart@v1 | ||
| with: | ||
| sdk: ${{ matrix.sdk }} | ||
|
|
||
| - name: Install dependencies | ||
| run: dart pub get | ||
|
|
||
| - name: Analyze | ||
| run: dart analyze --fatal-infos | ||
|
|
||
| # The golden capture (whoop_hist.jsonl) is a real band recording kept | ||
| # beside the repo rather than committed to it. The handful of tests that | ||
| # replay it SKIP here (they call markTestSkipped) and run locally; every | ||
| # synthetic-input and property test runs on each PR. | ||
| - name: Test | ||
| run: dart test --reporter=expanded | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,92 @@ | ||
| # Contributing | ||
|
|
||
| This package is the math: 1 Hz records in, metrics out. **Pure Dart, zero runtime | ||
| dependencies, no I/O, no randomness, no clock.** Same input, same output, every | ||
| time. It runs on-device, inside an isolate, on a phone — so it also has to be | ||
| cheap. | ||
|
|
||
| ## What belongs here (and what doesn't) | ||
|
|
||
| | Your change | Repo | | ||
| |---|---| | ||
| | A metric, or how an existing number is computed | **here** | | ||
| | A record type, opcode, event, anything byte-level | [protocol](https://github.com/OpenStrap/protocol) | | ||
| | Storage, sync, Bluetooth, UI, when things get computed | [edge](https://github.com/OpenStrap/edge) | | ||
|
|
||
| ## The two rules that matter | ||
|
|
||
| **1. Cite the method.** Everything in here implements a published, | ||
| peer-reviewed algorithm, with the citation in a comment next to the code and a | ||
| row in [`ALGORITHMS.md`](ALGORITHMS.md). The point is that you can go read the | ||
| paper and decide for yourself whether to trust the number. | ||
|
|
||
| If nothing in the literature fits, that's allowed — mark it `ESTIMATE`, give it | ||
| low confidence, and say so plainly. What's not allowed is inventing constants | ||
| and presenting them as science, or reverse-engineering WHOOP's scores by | ||
| fitting to their output. | ||
|
|
||
| **2. Never fabricate a value.** If an input isn't there, return a `Metric` with | ||
| a `null` value. Not a default, not a last-known-good, not an interpolation | ||
| that'll look plausible on a chart. Cold start returns | ||
| `need_baseline:have=H,need=N` and that's the correct behaviour, not a bug to | ||
| paper over. | ||
|
|
||
| ```dart | ||
| class Metric<T> { | ||
| final T? value; // null when the inputs weren't there | ||
| final double confidence; // 0..1 | ||
| final String tier; // AUTH | HIGH | ESTIMATE | RELATIVE | ||
| ... | ||
| } | ||
| ``` | ||
|
|
||
| ## Honest ceilings — please don't "fix" these | ||
|
|
||
| These are properties of what a WHOOP 4.0 actually hands over, not defects: | ||
|
|
||
| - **HRV is PRV**, derived from 1 Hz beat timing. It is not ECG-grade. | ||
| - **Deep sleep is a low-confidence HR-flatness overlay.** The band gives no | ||
| signal that distinguishes NREM stages properly. | ||
| - **SpO₂ and skin temperature are relative ADC values.** There is no calibration | ||
| to absolute units and there won't be. `absolute_spo2:false` is deliberate. | ||
| - **Cole–Kripke coefficients on 1 Hz data** are a documented bounded exception, | ||
| used for the wake spine only and corrected downstream. Read the comment in | ||
| `cardio_stager.dart` before touching it. | ||
|
|
||
| Making any of these *look* more confident than the underlying signal supports is | ||
| the one change guaranteed to be rejected. | ||
|
|
||
| ## Structure | ||
|
|
||
| Each family is a subdirectory under `lib/src/onehz/` with its own sub-barrel: | ||
| `foundations`, `clinical`, `sleep`, `respiration`, `motion`, `workout`, | ||
| `wellness`, `human`. Put new work with its siblings and export it through the | ||
| barrel. | ||
|
|
||
| There is **one** sleep source (`segmentSleep`) and **one** headline readiness | ||
| (`readinessComposite`). Don't add a second of either — extend the existing one. | ||
|
|
||
| ## Tests | ||
|
|
||
| ```bash | ||
| dart pub get | ||
| dart analyze | ||
| dart test | ||
| ``` | ||
|
|
||
| Everything runs on synthetic and property-based inputs in CI. A handful of tests | ||
| replay `whoop_hist.jsonl`, a real band capture kept *beside* the repo rather | ||
| than committed to it; those skip automatically when it's absent. | ||
|
|
||
| Any change to a metric needs a test that pins the behaviour, and — because | ||
| stored results are versioned and immutable — a note in the PR saying so, since | ||
| it means `kAlgoVersion` has to be bumped over in edge. If that bump doesn't | ||
| happen, devices keep serving the old numbers. | ||
|
|
||
| ## Pull requests | ||
|
|
||
| - Branch off `main`, one logical change per PR. | ||
| - Name the paper you implemented, with enough detail to find it. | ||
| - Say whether the output of any existing metric changes. This is the single most | ||
| important line in the PR. | ||
| - No `Co-Authored-By` trailers. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,59 @@ | ||
| # Security Policy | ||
|
|
||
| ## Reporting a vulnerability | ||
|
|
||
| Please **don't** open a public issue for a security problem. | ||
|
|
||
| Use GitHub's private reporting instead: | ||
| [**Report a vulnerability →**](https://github.com/OpenStrap/analytics/security/advisories/new) | ||
|
|
||
| That goes straight to the maintainer and stays private until there's a fix. | ||
|
|
||
| Rough expectations, set honestly — this is a one-maintainer project, not a | ||
| company with an on-call rota: | ||
|
|
||
| - Acknowledgement within about a week. | ||
| - An assessment, and a fix or a clear "won't fix and here's why", within 30 days | ||
| for anything that puts user data at risk. | ||
| - Credit in the release notes if you want it. | ||
|
|
||
| ## What's in scope | ||
|
|
||
| - Anything that discloses a user's health data off their device. | ||
| - Anything that lets a third party read, write to, or hijack the Bluetooth | ||
| session with someone's band. | ||
| - Local data-at-rest problems: the database, exports, the App Group container, | ||
| widget snapshots. | ||
| - The optional companion worker in | ||
| [backend](https://github.com/OpenStrap/backend): auth, the import endpoints, | ||
| the opt-in telemetry and health-upload paths. | ||
| - Anything that causes the app to send data anywhere the user did not agree to. | ||
|
|
||
| ## What's out of scope | ||
|
|
||
| - The band's own firmware. We don't ship it, can't patch it, and won't publish | ||
| attacks against it. | ||
| - WHOOP's own apps and services. Please report those to WHOOP. | ||
| - The fact that sideloaded builds are unsigned, or that a rooted/jailbroken | ||
| device can read app storage. Both are known properties of the distribution | ||
| model, documented in the README. | ||
| - Metric accuracy. Wrong numbers are bugs — open a normal issue. | ||
|
|
||
| ## Where your data actually is | ||
|
|
||
| Worth knowing before you go looking: OpenStrap computes and stores your health | ||
| data on-device, and there's no account or server holding it. Two qualifications, | ||
| so the boundary is exact: | ||
|
|
||
| - **Anonymous diagnostics** (Firebase crash/performance, never health data) are | ||
| **on by default in GitHub release builds** and absent from App Store / Play | ||
| Store builds. Switchable off in-app. | ||
| - **Health-data contribution** uploads the local database, but is opt-in, off by | ||
| default, and compiled out of store builds entirely. | ||
|
|
||
| Everything else the companion worker does — legacy import, an update pointer — | ||
| is optional and carries no health data. See [edge's PRIVACY.md](https://github.com/OpenStrap/edge/blob/main/PRIVACY.md). | ||
|
|
||
| That means the realistic attack surface is the phone, the Bluetooth link, and | ||
| the local database — not a cloud backend. Reports focused there are the most | ||
| useful. |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.