{"id":"09ab3469-52bf-48c3-8ae0-53924a4ff812","slug":"ath","kind":"skill","name":"ath","summary":"An open, local-first file format for an athlete's training and recovery data, built for AI agents to read. Device measurements and self-reported notes stay separate.","owner":"mwhitham","repoUrl":"https://github.com/mwhitham/ath","license":"MIT","licenseTier":"permissive","trust":"community","stars":3,"match":null,"fewStars":true,"format":"skill","createdAt":"2026-08-29T22:42:33.000Z","addedAt":"2026-10-22T01:44:56.730Z","logoUrl":"https://avatars.githubusercontent.com/u/2522959?v=4","linkOnly":false,"collection":null,"skillPath":null,"categories":["data-analytics","files-documents","productivity"],"tags":["ai-agents","crossfit","fitness","hrv","hyrox","json-schema","local-first","training-data"],"runtime":"node","local":true,"cloudCapable":false,"cloudCapability":"unknown","cloudReadyOnPlatform":false,"needsApiKey":false,"reviewed":false,"syncedAt":"2026-10-22T01:45:16.143Z","sample":false,"url":"https://conduits.dev/tools/ath","language":"TypeScript","transports":["stdio"],"install":{"npm":"athleticstandard"},"requirements":{"env":[],"upstreamMayCharge":false},"tools":null,"readme":"# Athletic Standard\n\nAthletic Standard is an open, local-first record for training and recovery data.\nThe live record is one SQLite database:\n\n```text\nathlete.ath.sqlite\n```\n\nThe `ath` command reads and writes that database. Local use needs no account,\nnetwork connection, subscription, or hosted service.\n\nAthletic Standard keeps measured records separate from athlete reports. A measured\nrecord must name its source. An athlete report cannot name one. Sources also remain\nseparate when two devices measure the same quantity.\n\nNot an app, not a coach, not medical advice.\n\n## Security\n\nThe database contains sensitive health and training data. Athletic Standard creates\nlocal files with owner-only permissions where the operating system supports them,\nbut it does not encrypt the database itself. Use operating-system disk encryption.\nAnyone who can read the database file can read the athlete record.\n\n## Install\n\nAthletic Standard needs Node.js 20 or newer.\n\n```sh\nnpm install -g athleticstandard\n```\n\nThis installs the `ath` command. `npx athleticstandard` can be used instead of a\nglobal install.\n\nRun `ath --update` to update the package. Run `ath skill install` to refresh the\nlocal agent skill without updating the package.\n\nTypeScript and JavaScript callers can import the public parts directly:\n\n```ts\nimport { AthleticStandardPackage } from \"athleticstandard/schema\";\nimport { openDatabase, queryMeasurements } from \"athleticstandard/database\";\n```\n\nThe JSON schemas are exported as `athleticstandard/json-schema`,\n`athleticstandard/json-schema/export-manifest`, and\n`athleticstandard/json-schema/measurement-series`. The Agent Skill is exported as\n`athleticstandard/skill`. The retired prerelease JSON runtime is not part of the v1\npackage API.\n\n## Create a database\n\n```sh\nmkdir training-record\ncd training-record\nath init\n```\n\n`ath init` asks for optional profile fields and creates\n`athlete.ath.sqlite`. It also adds a manual source and the standard benchmark\ndefinitions. Pass `--timezone America/Chicago` to set the default IANA timezone for\ncalendar calculations.\n\nThe command installs the agent skill into `.agents/skills/` and supported agent\nfolders already present. Pass `--no-skill` to skip that step.\n\nUse an empty database only as the destination for a complete v1 restore:\n\n```sh\nath init --empty -y\nath import ./saved-package\nath import ./saved-package --yes\n```\n\nAthletic Standard v1 does not import prerelease `0.x` Athletic Standard documents.\nThe old npm package remains available for reading those files.\n\n## Import provider data\n\n`ath import` reads Apple Health, WHOOP, Oura, and complete Athletic Standard v1\npackages. The first run is always a preview:\n\n```sh\nath import ~/Downloads/apple_health_export.zip\n```\n\nProvider previews report new, matching, changed, skipped, and conflicting records.\nPackage previews report new, matching, changed, conflicting, unrepresentable, and\nunknown records. Unknown or unrepresentable content blocks the write. No option\nsilently discards it. Apply a conflict-free preview with a second command:\n\n```sh\nath import ~/Downloads/apple_health_export.zip --yes\n```\n\nProvider rows use route-specific import keys. Importing unchanged data reports a\nmatch. Changed data with the same key creates a new revision of the existing\nrecord. It does not create a second record.\n\nWhen a v1 package conflicts with local history, the preview creates a temporary\nconflict set:\n\n```sh\nath conflicts show\nath conflicts resolve <record-id> --choice local\nath conflicts resolve <record-id> --choice imported\nath conflicts resolve <record-id> --choice corrected --data '<complete-data-json>'\nath import ./saved-package --yes\n```\n\nThe conflict commands do not change athlete data. The final import writes the\nnon-conflicting records and every chosen resolution in one transaction. A changed\npackage or database makes the choices stale.\n\nApple Health, WHOOP, and Oura routes remain separate sources. Records from two\ndevices also remain separate. A manual source never enters a device baseline.\n\n## Log records\n\n`ath log` is the general creation command. It is also the only command that enters a\nbenchmark result.\n\nPlain text covers common entries:\n\n```sh\nath log RMSSD 61 ms\nath log sore quads 4/5\nath log Fran in 4:41 rx\nath log Meal photo --attachment ./receipt.png\n```\n\nSay `RMSSD` or `SDNN`. They are different statistics and never share a baseline.\n\nStructured input is one v1 object or an array of v1 objects. Every item has\n`record_type` and `data`. Prediction-result links and grades are tool-managed and\ncannot be supplied this way:\n\n```sh\nath log '{\n  \"record_type\": \"athlete_report\",\n  \"data\": {\n    \"report_type\": \"note\",\n    \"reported_at\": \"2026-10-13T04:00:00.000Z\",\n    \"input_reported_at\": {\n      \"timestamp_text\": \"2026-10-13T04:00:00.000Z\",\n      \"utc_offset_text\": \"Z\",\n      \"utc_offset_meaning\": \"documented_recording_offset\",\n      \"timestamp_basis\": \"source_instant\"\n    },\n    \"reported_via\": \"text\",\n    \"note\": \"Easy session; no soreness.\"\n  }\n}'\n```\n\n`record_id` and `created_at` may be supplied beside `record_type`. When omitted,\n`ath` creates a UUIDv7 record ID and uses the current time. A structured array is\nvalidated and written in one transaction.\n\n`--attachment` accepts PNG, JPEG, WebP, and PDF files up to 25 MiB. Pass it more\nthan once for several files. The log batch must contain exactly one athlete report\nor nutrition entry to own them. The file hashes, attachment records, links, and\nowner-only stored files are written together after confirmation.\n\nThe command shows a preview before writing. `--json` returns the preview and never\nacts as confirmation. After review, run the command without `--json` and confirm in\nthe terminal, or pass `--yes`.\n\nWhen a new benchmark result matches exactly one open prediction, the same\ntransaction also creates a prediction-result link and a grade. It does not guess\nwhen no prediction or several predictions match.\n\n## Read and change records\n\nUse the fixed overview first:\n\n```sh\nath stats\nath check\n```\n\nUse stable record IDs for revisions and links:\n\n```sh\nath records list\nath records list --type prediction\nath records show <record-id> --history --links\n```\n\n`ath records list` shows current records in stable order. `ath records show` can\nshow one retained revision, the full revision history, and incoming or outgoing\nlinks.\n\nCorrections keep the record ID and retain the prior complete state:\n\n```sh\nath correct <record-id> --revision 2 --data '<complete-data-json>' --json\nath correct <record-id> --revision 2 --data '<complete-data-json>' --yes\n```\n\n`--revision` prevents an old preview from overwriting a newer change.\n\n`ath link <result-id> <session-id> --revision <current-revision>` links a benchmark\nresult to a workout session. The link is stored as a new revision of the benchmark\nresult. A stale revision is refused.\n\nNormal deletion and privacy erasure are different operations:\n\n```sh\nath delete <record-id> --revision 2 --json\nath erase <record-id> --revision 2 --json\n```\n\n`ath delete` hides the current record and keeps its revisions. `ath erase` removes\nthe record's values, value-bearing revisions, dependent records, and attachment\nfiles. The preview records the database revision and complete dependency set. The\nwrite is refused if either changes before confirmation. Interactive use asks for\nnormal confirmation and then requires the exact record ID. Non-interactive use\nneeds both flags:\n\n```sh\nath erase <record-id> --revision 2 --reason athlete_request --yes \\\n  --confirm-erasure <record-id>\n```\n\n`--json` never performs erasure. Erasure cannot remove copies already present in\nexports, backups, filesystem\nsnapshots, SQLite journals, or storage-device history.\n\n## Read samples and calculate results\n\nDense samples live in SQLite. There are no separate live sample files.\n\n```sh\nath series heart_rate\nath series heart_rate --raw --from 2026-10-01 --to 2026-10-07\n```\n\n`ath calculate` runs named operations without writing athlete data:\n\n```sh\nath calculate baseline hrv_rmssd --from 2026-07-01 --to 2026-09-30\nath calculate summary steps --group day --timezone America/Chicago\nath calculate compare-sources resting_heart_rate \\\n  --source <source-id> --compare-source <other-source-id>\nath calculate baseline recovery --record-kind provider-score\nath calculate provider-period-summary readiness \\\n  --record-kind provider-score --period-type oura_day_unspecified\n```\n\nThe operations are `summary`, `baseline`, `trend`, `coverage`,\n`compare-sources`, `correlation`, `workout-drift`, and\n`provider-period-summary`. Record kinds are `measurement`, `provider-score`,\n`provider-summary`, and `session-summary`. Measurements are the default. Naming the\nkind prevents a provider score or reported total from being mixed with a sensor\nmeasurement that has a similar name.\n\n`provider-period-summary` requires `--period-type`. It groups by the exact Oura day,\nWHOOP cycle, or Apple activity-summary day stored on each record. It never relabels\nthat period as a midnight-to-midnight calendar day.\n\nResults name their method, sources, input revisions, exclusions, range, and timezone\nor provider period when one was used. A receipt lists at most 1,000 input revisions\nand says when that list was shortened. Arithmetic refuses more than 100,000 inputs\nuntil the request is narrowed. It never calculates from a silently shortened input\nset. Sources are not pooled. Manual sources are excluded.\n\n## Export a complete package\n\n```sh\nath export ./athlete-backup\n```\n\nSQLite remains the sole live local record. The export is a complete portable\nsnapshot. It does not stay synchronized with the database.\n\nAn exported directory contains:\n\n```text\nathlete-backup/\n  athlete.ath.json\n  series/\n    <source-id>-<quantity>.ath-series.json\n  attachments/\n    <stored attachment files>\n  export-manifest.json\n```\n\n`athlete.ath.json` contains every current non-sample record, every retained\nnon-sample revision, normal deletions, erasure markers, provider import keys, and\nreferences to generated sample files. Each generated sample file contains current\nsample records and their history. The manifest lists file hashes, byte counts,\nrecord counts, the source database ID, and the database revision.\n\nThe export time is absent by default. Two exports from the same database revision\nwith the same options are byte-identical. Pass a fixed `--exported-at` value only\nwhen the manifest needs one.\n\nImporting an exported package is explicit and uses the same preview-then-`--yes`\nworkflow as a provider import.\n\n## Predict and grade\n\nInside an agent harness, ask the database for prediction evidence:\n\n```sh\nath predict fran --json\n```\n\nThis returns evidence, not a prediction. The agent writes a `prediction` record\nthrough structured `ath log`.\n\nIn a terminal, bare `ath predict fran` can call a selected model and save its\nprediction after confirmation. That optional model call needs a Vercel or OpenRouter\nkey in the operating-system password store. Local database use does not need that\nkey or a network connection.\n\nResults are entered with `ath log`. Explicit grading only joins two records that\nalready exist:\n\n```sh\nath records list --type prediction\nath records list --type benchmark_result\nath grade <prediction-id> --result <result-id> --json\nath grade <prediction-id> --result <result-id> --yes\n```\n\n`ath grade` never logs a result. It creates a UUIDv7 prediction-result link when one\ndoes not exist. A corrected result revises the existing link, so older grades retain\ntheir exact link revision. The command saves deterministic grade arithmetic against\nthe current link revision.\n\nA prediction error analysis is a separate authored record written through\nstructured `ath log`.\n\n`ath backtest` replays historical results and writes a report beside the database.\nIt does not change athlete data.\n\n## Record model\n\nEvery logical record has a stable UUIDv7 ID and numbered revisions. A correction\nkeeps the ID. Evidence names both the record ID and revision.\n\nThe format defines 23 record types for profile data, sources, measurements,\nsessions, athlete reports, nutrition, attachments, benchmarks, predictions, plans,\ngoals, and saved authored work. [`SPEC.md`](SPEC.md) is the public field reference.\nThe generated v1 JSON Schemas are in [`schema/1.0.0/`](schema/1.0.0/).\n\nProvider data research is in\n[`docs/connections.md`](docs/connections.md). The installed agent instructions are\nin [`skill/`](skill/).\n\n## License\n\nMIT License. See [LICENSE](LICENSE). Copyright 2026 Athletic Standard contributors.\n"}