Skip to content

description: chiptime architecture: four layers from wire frames to analytics, the monorepo, and the decision records.

Architecture

Four layers, each a strict refinement

 .fit bytes
 1  wire        iter_frames()      headers · definitions · data frames · CRCs
 2  messages    iter_messages()    decoded, unknown-tolerant, lossless
 3  semantic    parse()            sessions · streams · gaps · provenance
 4  analytics   metrics.analyze()  profiles · intervals · insights · load

Lower layers never depend on higher ones; the analytics package is optional and the core never imports it (test-enforced). Side doors: repair (salvage → re-encode) and validate (platform acceptance), both built on the same layers.

The monorepo

chiptime/
├── corpus/     the conformance contract — language-agnostic cases + tools
├── python/     the first implementation (zero runtime dependencies)
├── js/         the TypeScript twin (M3) — must match Python byte-for-byte
├── docs/       specs, implementation notes, ADRs, research, taxonomy
└── scripts/    profile generator, agent-docs generator, benchmarks

Design decisions with records

Non-obvious decisions get an Architecture Decision Record. Highlights:

ADR Decision
0002 Canonical JSON via RFC 8785; 64-bit integers as strings
0003 Defects as values; modes as one policy switch
0004 Profile: hand-authored verified core + generated breadth — never Garmin's files
0005 Timestamp ordering, timer state machine, gap classification
0007 Real-file corpus: private tier, PII rules
0008 Analytics: profiles as data, honest estimators, neutral names

Licensing stance

The Garmin FIT SDK ships under a restrictive license, so chiptime depends on none of it: profile tables are generated by our own script from a locally downloaded SDK, and only the generated output (our code shape) is committed. MIT throughout.