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.