Releases: tsubotti63/garmin-running-data-normalizer
Release list
v1.2.0
Garmin Running Data Normalizer v1.2.0
v1.2.0 adds an opt-in, private local Snapshot Accumulation lifecycle while
preserving the existing v1.1.1 one-shot Run-All interface and stable 1.x
output contract.
Highlights
- An immutable, account-bounded Snapshot Store preserves explicitly confirmed
complete Garmin Export observations and validated archive members by content. missing_is_not_deleteprevents later absence from silently deleting earlier
evidence.- Family-specific merge policies distinguish entity upsert, event union,
immutable FIT content union, and regenerated derived datasets. - Historical backfill can be inserted deterministically; all 24 registration
order permutations produce the same canonical result. - Repeat registration of identical content is idempotent.
- Seven-state missing-value semantics keep absence, explicit null, empty,
malformed, unsupported, retained, and promoted states auditable. - Cumulative unique FIT materialization deduplicates content aliases before
parsing, then regenerates Activity–FIT relationships under the existing
evidence-qualified contract. - Incremental canonical output matches a fresh full rebuild from the same
approved Snapshot set. - All 13 required failure and recovery scenarios pass.
Correctness and contract improvements
- Runtime schema validation agrees with the generated schema catalog,
including integer identifiers. - Invalid FIT enum sentinels, including the raw sport sentinel, normalize to
JSON null with deterministic audit counts. - Multi-session FIT is normalized only when declared lap allocation is complete
and unambiguous. Conflicting files remain visible in FIT audit and are
excluded from normalized sessions/laps and relationship eligibility. - Activity-side, FIT-session-side, eligible, and structurally excluded
populations are reported separately; relationship coverage is an evidence
boundary, not a success score. - Full local output can retain memo text and email-shaped source filenames.
Those fields remain private-local and are removed from the optional
external-safe pack. - The Product Quick Start now documents the stable Snapshot commands, directory
input contract, ZIP-inside-directory support, and private-store handling.
Verification
Public synthetic validation covers registration, merge, determinism,
full-rebuild equivalence, FIT deduplication, relationship regeneration,
failure/recovery behavior, package installation, and privacy scanning.
Public-safe aggregate evidence from four repeated Garmin Account Data Export
snapshots from the same account confirms cumulative behavior without publishing
private dates, paths, tokens, filenames, hashes, identifiers, rows, or record
values.
Backward compatibility
The existing run-all --input DIRECTORY --output DIRECTORY workflow remains
supported. Dataset names, grain, stable keys, fixed one-shot output paths,
Python 3.11+ support, and the standard-library runtime dependency boundary do
not change. Snapshot adoption is optional; no migration is required for
one-shot users.
Direct ZIP input remains unsupported and fails with INPUT_NOT_DIRECTORY.
Supported ZIP assets are inspected only when found inside the supplied input
directory.
Upgrade guidance
After package-index publication has completed, upgrade normally from PyPI.
One-shot users can keep their existing commands. Snapshot users should read the
v1.2 migration guide,
retain each complete Export until registration and verification succeed, use
one opaque account boundary per store, and back up only a verified store.
Known limitations
- Snapshot deletion, tombstones, automatic garbage collection, and automatic
deletion inference are not provided. - Explicit null/empty values and unsupported fields can require review rather
than automatic promotion. - Snapshot Stores are private, local, and user-managed; backup and restore must
be verified explicitly. - Windows manual environment characterization remains pending.
- Sleep, HRV, and Health Status remain library-level and are not promoted into
Snapshot Run-All output.
Privacy boundary
Snapshot Stores, approved inputs, and full outputs contain private local data
and must not be committed or shared. Public examples use synthetic fixtures.
The optional external-safe pack is allowlist-only and excludes identifiers,
provenance, memo text, exact timestamps, coordinates, and unneeded health or
performance detail. It still requires Human review before transfer.
Garmin Running Data Normalizer v1.1.1
Garmin Running Data Normalizer v1.1.1
v1.1.1 is the stable Production package candidate for the reviewed v1.1
implementation. It strengthens FIT integrity and turns Run-All output into a
standalone, privacy-aware analysis handoff.
Release identity
The published v1.1.0 tag and GitHub Release remain immutable. Their exact
source declares package version 1.1.0rc1, so the TestPyPI rehearsal artifacts
are not renamed or reused as stable Production files. v1.1.1 finalizes package,
module, CLI, generated-output, test, and release metadata consistently without
changing runtime behavior or the stable 1.x interface.
Highlights
- FIT file and optional header CRC validation with fail-closed audit states.
- Multi-session FIT identity through
fit_session_keyandfit_lap_key. - Null normalization and per-field audit counts for FIT protocol invalid
sentinels, including enum fields. - Evidence-qualified Activity/FIT links with explicit eligibility, exclusion,
ambiguity, duplicate, and coverage evidence. - Relationship Coverage in
START_HERE.md,ANALYSIS_HANDOFF.md, and
ANALYSIS_CONTEXT.jsonfor every explicit relationship, with unresolved
records retained and inference explicitly prohibited. - Fail-closed explicit relationships for Activity/Gear, Personal
Record/Activity, and FIT Lap/Session. - Deterministic human guidance (
START_HERE.md,DATASET_INVENTORY.md,
ANALYSIS_HANDOFF.md) and machine context (ANALYSIS_CONTEXT.json,
SCHEMA_CATALOG.json,artifact_inventory.json). - An explicit
integer|stringschema contract for source identifiers whose
Garmin representation or deterministic fallback can use either JSON type. - Optional allowlist-only external-safe Analysis Pack with no automatic upload.
Compatibility
Existing 1.x CLI commands and output paths remain available. v1.1 adds new
paths and datasets. fit_file_id and lap_index remain compatible fields;
fit_session_key and fit_lap_key are the v1.1 FIT stable keys.
Privacy and boundaries
Full Run-All output is a local/trusted handoff and can contain personal metrics,
identifiers, provenance, hashes, exact timestamps, memo text, and
source-relative filenames that may contain email-shaped personal identifiers.
The opt-in external-safe pack is limited to month-level activity volume/count
and removes identifiers, keys, paths, hashes, memo text, coordinates, exact
dates/times, heart rate, power, cadence, training effect/load, and other
unneeded health or performance detail. It still requires review before
transfer. Run-All never uploads data.
Sleep, HRV, and Health Status remain library-only. Hosted processing,
authentication, weather integration, automatic upload, and medical/coaching
interpretation remain outside this release.
Publication
The wheel and source distribution must be built from the reviewed v1.1.1
version-finalization commit and pass tests, validators, strict metadata checks,
isolated installation, installed Run-All validation, and CI. Tag creation,
GitHub Release publication, TestPyPI upload, and Production PyPI upload remain
separate Human Approval Boundaries.
Garmin Running Data Normalizer v1.1.0
Garmin Running Data Normalizer v1.1.0
v1.1.0 strengthens FIT integrity and turns Run-All output into a standalone,
privacy-aware analysis handoff.
Highlights
- FIT file and optional header CRC validation with fail-closed audit states.
- Multi-session FIT identity through
fit_session_keyandfit_lap_key. - Null normalization and per-field audit counts for FIT protocol invalid
sentinels, including enum fields. - Evidence-qualified Activity/FIT links with explicit eligibility, exclusion,
ambiguity, duplicate, and coverage evidence. - Relationship Coverage in
START_HERE.md,ANALYSIS_HANDOFF.md, and
ANALYSIS_CONTEXT.jsonfor every explicit relationship, with unresolved
records retained and inference explicitly prohibited. - Fail-closed explicit relationships for Activity/Gear, Personal
Record/Activity, and FIT Lap/Session. - Deterministic human guidance (
START_HERE.md,DATASET_INVENTORY.md,
ANALYSIS_HANDOFF.md) and machine context (ANALYSIS_CONTEXT.json,
SCHEMA_CATALOG.json,artifact_inventory.json). - An explicit
integer|stringschema contract for source identifiers whose
Garmin representation or deterministic fallback can use either JSON type. - Optional allowlist-only external-safe Analysis Pack with no automatic upload.
Compatibility
Existing 1.x CLI commands and output paths remain available. v1.1 adds new
paths and datasets. fit_file_id and lap_index remain compatible fields;
fit_session_key and fit_lap_key are the v1.1 FIT stable keys.
Privacy and boundaries
Full Run-All output is a local/trusted handoff and can contain personal metrics,
identifiers, provenance, hashes, exact timestamps, memo text, and
source-relative filenames that may contain email-shaped personal identifiers.
The opt-in external-safe pack is limited to month-level activity volume/count
and removes identifiers, keys, paths, hashes, memo text, coordinates, exact
dates/times, heart rate, power, cadence, training effect/load, and other
unneeded health or performance detail. It still requires review before
transfer. Run-All never uploads data.
Sleep, HRV, and Health Status remain library-only. Hosted processing,
authentication, weather integration, automatic upload, and medical/coaching
interpretation remain outside this release.
Installation and publication
The wheel and source distribution are validated from the reviewed release
candidate. Git tag creation, GitHub Release publication, TestPyPI upload, and
Production PyPI upload are separate Human Approval Boundaries.
Garmin Running Data Normalizer v1.0.1
Garmin Running Data Normalizer v1.0.1
v1.0.1 is a packaging-only patch release prepared for the initial
package-index publication of Garmin Running Data Normalizer. It preserves the
v1.0.0 runtime behavior, public CLI, Run-All output contract, dependency
boundary, and supported Garmin dataset scope.
Packaging and publication
- Advances the Python distribution version to
1.0.1. - Includes the PyPI-safe README and repeatable wheel/source-distribution gate.
- Includes the manual-only, build-only-by-default publication workflow.
- Requires exact source and version validation, target-specific approval,
protected GitHub Environments, and Trusted Publishing through OIDC before
either index upload. - Verifies wheel and source-distribution installation before upload and checks
the exact installed version after publication.
Compatibility
This patch does not change the stable 1.x CLI or versioned Run-All output
contract. It does not add runtime dependencies, hosted processing, Garmin
authentication, or new data families to Run-All.
Security and privacy
Only synthetic fixtures are public. Real Garmin exports and generated personal
results remain local and must not be uploaded as package, Release, or CI
artifacts.
Publication boundary
The annotated tag, GitHub Release, protected GitHub Environments, approval
variables, and Trusted Publisher configuration were explicitly authorized for
this release. TestPyPI and PyPI uploads remain separately gated and require
explicit Human approval immediately before each upload.
v1.0.0
Garmin Running Data Normalizer v1.0.0
v1.0.0 is the first stable release of the local-first Garmin Account Export
normalization workflow. It keeps source data local, produces deterministic
outputs with provenance and QA, and uses only Python's standard library at
runtime.
Highlights
- Stable activities-only Golden Path and multi-family Run-All CLI.
- Required Activities plus optional Gear, Personal Records, and bounded FIT
session/lap normalization. - Fixed Run-All output layout, explicit exit statuses, completion marker,
deterministic digests, provenance, and privacy-safe console errors. - Library-level Sleep, HRV, and Health Status normalization backed by synthetic
tests without expanding the Run-All output contract. - Apache-2.0 licensing, synthetic public examples, Analysis Handoff guidance,
and a reproducible case study.
Install and run
git clone https://github.com/tsubotti63/garmin-running-data-normalizer.git
cd garmin-running-data-normalizer
python3 -m venv .venv
source .venv/bin/activate
python -m pip install -e .
python -m garmin_running_data_normalizer --version
python -m garmin_running_data_normalizer run-all \
--input examples/synthetic/garmin_export \
--output workspace/run-allCompatibility boundary
The documented CLI and versioned Run-All output contract are stable for 1.x.
Sleep, HRV, Health Status, and Analysis Pack remain library-level interfaces and
are not Run-All outputs in this release.
Security and privacy
Real Garmin exports and generated results contain personal data and must remain
in ignored local storage. No real export, identifier, coordinate, private path,
or generated personal artifact is included in the repository or Release assets.
Known limitations
Complete FIT CRC validation, multi-session FIT identity, PyPI publication,
hosted processing, Open-Meteo, and Parquet output are not included. See the
tag-pinned limitations
and
supported datasets.
No binary assets are attached to the GitHub Release. The source archives are
generated by GitHub from the reviewed tag.
v0.1.0-rc.2
v0.1.0-rc.2
Release summary
This prerelease expands Garmin Running Data Normalizer from the RC1
activities-only Golden Path to a bounded multi-family Run-All workflow and a
reproducible analysis handoff. It remains a Release Candidate, does not claim a
stable third-party Python API, and is not published to PyPI.
The Git tag is v0.1.0-rc.2; the Python package version is 0.1.0rc2.
Included
- Activities-required Run-All with optional Gear, Personal Records, and bounded
FIT sessions/laps - Fixed deterministic output layout, QA, provenance manifest, completion
summary, and explicit partial-success behavior - Bounded large-archive compatibility with traversal, link, encryption, count,
size, total-size, and compression-ratio controls retained - Private public-safe real-export execution evidence without publishing private
rows, paths, identifiers, counts, or fingerprints - Analysis Handoff, reusable prompt, public synthetic usage example, three
key-free Analysis Examples, and a Primary Case Study
Quick Start
Follow the tag-pinned
Product Quick Start.
Run the synthetic Activities Golden Path:
python -m garmin_running_data_normalizer normalize-activities \
--input examples/synthetic/garmin_export \
--output workspace/golden-pathRun the minimum multi-family workflow:
python -m garmin_running_data_normalizer run-all \
--input examples/synthetic/garmin_export \
--output workspace/run-allAnalysis and case study
Calculated facts in the synthetic examples are reproducible. Generative wording
is not claimed to be byte-identical.
Reproducibility and validation
The exact release commit passed:
- 39 standard-library unit tests and 39 pytest tests
- Bootstrap Validation
- Static Policy
- Platform Alignment
- Public History validation
- Synthetic Golden Result comparison and byte-identical repeat execution
- Minimum Run-All and byte-identical repeat execution
- Existing-output rejection with exit code 2
- Public-contract, privacy, documentation-link, and clean-clone review
GitHub Actions run
29896162447
completed successfully for commit
0996c4889ae807be0082ae83a26319a860f62c96.
Safety and privacy
Public reproduction uses synthetic fixtures only. Real Garmin exports and
generated output remain local and must not be committed or attached to CI or a
Release.
The Activities CSV has no separate activity_id column, but its
garmin_activity_key may incorporate a source activity ID. Remove that key
from externally shared derivatives and review date/time granularity before
transfer.
Known limitations
- Activities are required; optional families use the documented exact filename
rules. - FIT support covers selected session/lap fields and does not implement complete
CRC or invalid-sentinel handling. - Weather, Sleep, HRV, Parquet, dashboards, notebooks, automatic Analysis Pack
generation, stable API guarantees, stable release, and PyPI publication are
absent. - Analysis examples are descriptive and do not provide medical or coaching
conclusions.
License and feedback
The project is available under the
Apache License 2.0.
Report reproducible problems through
GitHub Issues.
v0.1.0-rc.1
v0.1.0-rc.1
Release summary
This is the first Release Candidate of Garmin Running Data Normalizer. It is for
users who want to evaluate a local, activities-only synthetic Golden Path before
a stable release. It reads a Garmin-shaped export directory and writes
deterministic normalized activities, QA, and provenance metadata without using
a hosted service.
The Git tag is v0.1.0-rc.1; the corresponding Python package version is
0.1.0rc1 to follow Python version syntax.
Included
- A formal module command for the activities-only synthetic Golden Path
- One visibly synthetic Garmin-shaped input fixture
- Deterministic
normalized_activities.json,qa_summary.json, and
run_manifest.jsonoutputs - Activity-grain records keyed by
garmin_activity_key - Source-relative provenance, source/output SHA-256 values, and a deterministic
records digest - Fail-closed input and archive checks and non-destructive input handling
- A reviewed Golden Result, Product Quick Start, automated tests, validators,
and GitHub Actions workflow
Supported scope
The formal CLI supports summarizedActivities.json activity normalization only.
Library components also exist for Garmin gear and activity-gear links, personal
records, bounded FIT sessions/laps, dataset policy inspection, deterministic QA,
and allowlist-only Analysis Pack creation. Those components are not exposed as
a combined Run-All command.
Known limitations
- This is a Release Candidate; the Python API may change before a stable release.
- The formal CLI supports a limited activities dataset, not every Garmin export
dataset. - There is no complete Run-All workflow.
- Validation uses synthetic fixtures and does not guarantee compatibility with
every real Garmin Account Export shape. - Open-Meteo and Parquet output are not implemented.
- FIT parsing is limited to selected session and lap fields and does not provide
complete CRC or invalid-sentinel handling. - The project is not published to PyPI.
Safety and privacy
The workflow is local-first and does not modify its input. Only wholly synthetic
fixtures are committed. Do not commit real Garmin exports, generated personal
outputs, account or activity identifiers, coordinates, health data, credentials,
or host-specific paths.
Quick Start
Follow the Product Quick Start.
The formal command is:
python -m garmin_running_data_normalizer normalize-activities \
--input examples/synthetic/garmin_export \
--output workspace/golden-pathVerification
The candidate is covered by 29 synthetic tests, Golden Result comparison,
deterministic repeat-run checks, input immutability checks, Bootstrap Validation,
Static Policy, Platform Alignment, Public History validation in CI, and the
bootstrap-ci GitHub Actions workflow. The release commit must pass that
workflow before the tag and GitHub prerelease are created.
Feedback
Report reproducible problems through
GitHub Issues.