Freeze Trainlog exchange format v1

This commit is contained in:
fy59 2026-09-05 19:28:26 +02:00
parent dfd6717cb7
commit 3d5f9a2bef
5 changed files with 110 additions and 19 deletions

View file

@ -26,11 +26,11 @@ The project uses a simple pre-release changelog during early development.
### Changed ### Changed
- Gate 0 project contract is complete. - Gate 0 project contract is complete.
- Gate 1 remains active pending review #2 validation. - Gate 1 completed and Trainlog exchange format v1 frozen.
- Actual repetition count may be zero for a failed attempt. - Actual repetition count may be zero for a failed attempt.
- Planned exercises may contain zero actual sets. - Planned exercises may contain zero actual sets.
- Top-level exercise metadata must exactly match session exercise references. - Top-level exercise metadata must exactly match session exercise references.
- Assistance kilograms have distinct semantics from external resistance. - Assistance kilograms have distinct semantics from external resistance.
- Different exercise IDs with equivalent normalized names are hard import conflicts. - Different exercise IDs with equivalent normalized names are hard import conflicts.
- Same exercise ID with incompatible tracking mode is a hard import conflict. - Same exercise ID with incompatible tracking mode is a hard import conflict.
- `TRAINLOG_FORMAT_V1` remains draft pending Gate 1 closure. - `TRAINLOG_FORMAT_V1=FROZEN`; incompatible changes require a new format version.

View file

@ -4,9 +4,10 @@
```text ```text
GATE_0=PASS GATE_0=PASS
GATE_1_REVIEW_01=IMPLEMENTED GATE_1_REVIEW_01=PASS
GATE_1=VALIDATION_PENDING GATE_1_REVIEW_02=PASS
TRAINLOG_FORMAT_V1=DRAFT GATE_1=PASS
TRAINLOG_FORMAT_V1=FROZEN
``` ```
This document defines the proposed final Trainlog v1 exchange contract. This document defines the proposed final Trainlog v1 exchange contract.
@ -475,11 +476,15 @@ Gate 1 may freeze v1 only after:
- the schema and semantic contract contain no known ambiguity; - the schema and semantic contract contain no known ambiguity;
- the reviewed commit is pushed and mirrored. - the reviewed commit is pushed and mirrored.
Until then: Gate 1 validation and mirrored review completed successfully.
The exchange format is now frozen:
```text ```text
TRAINLOG_FORMAT_V1=DRAFT TRAINLOG_FORMAT_V1=FROZEN
``` ```
Any incompatible semantic or structural change requires a new exchange-format version.
## 23. Generated identifier policy ## 23. Generated identifier policy
The wire format treats `exercise_id` and `session_id` as opaque identifiers satisfying their defined syntax. The wire format treats `exercise_id` and `session_id` as opaque identifiers satisfying their defined syntax.

View file

@ -0,0 +1,75 @@
# Gate 1 Closure — Trainlog Exchange Format v1
## Status
```text
GATE_1_REVIEW_01=PASS
GATE_1_REVIEW_02=PASS
GATE_1=PASS
TRAINLOG_FORMAT_V1=FROZEN
```
## Reviewed commits
Gate 1 review #1:
```text
9d9a9223a0c46df72f5c3ab208107c0ac6698438
Define Trainlog v1 freeze candidate
```
Gate 1 review #2:
```text
dfd6717cb7978d009670f1a49029c62c9154af55
Define Trainlog v1 catalog identity rules
```
Both commits were pushed and observed on the GitHub mirror.
## Required closure validation
The canonical working tree must pass immediately before this closure commit:
```bash
python tools/validate_json.py
python tools/validate_import_contract.py
git diff --check
```
The closure commit must not be created if any command fails.
## Frozen v1 contract
Trainlog v1 now freezes:
- strict JSON structure;
- stable exercise identifiers;
- UUIDv4 generation policy for new official identifiers;
- exercise `tracking_mode`;
- repetition and duration representations;
- load modes: `none`, `external`, `assistance`;
- planned and actual set separation;
- planned rest representation;
- body weight and named measurements;
- optional bounded notes;
- active/incomplete-session representation;
- catalog completeness rules;
- normalized display-name duplicate prevention;
- local catalog reconciliation;
- atomic import conflict handling;
- session import idempotency contract.
## Compatibility rule
After this closure, an incompatible structural or semantic change requires a new exchange-format version.
Trainlog v1 may receive only changes that preserve the frozen contract.
## Next gate
```text
GATE_2=TUI_PERSISTENCE_CORE
```
Gate 2 may now implement the frozen format in C17 and SQLite.

View file

@ -25,15 +25,22 @@ ebd4316ed68c58598a471e567edf13455d00f92b
## Gate 1 — Exchange format v1 freeze ## Gate 1 — Exchange format v1 freeze
Status: VALIDATION PENDING — REVIEW #2 Status: PASS
Canonical state: Canonical result:
```text ```text
GATE_1_REVIEW_01=IMPLEMENTED GATE_1_REVIEW_01=PASS
GATE_1_REVIEW_02=IMPLEMENTED GATE_1_REVIEW_02=PASS
GATE_1=VALIDATION_PENDING GATE_1=PASS
TRAINLOG_FORMAT_V1=DRAFT TRAINLOG_FORMAT_V1=FROZEN
```
Reviewed commits:
```text
9d9a9223a0c46df72f5c3ab208107c0ac6698438
dfd6717cb7978d009670f1a49029c62c9154af55
``` ```
Review #1 defined: Review #1 defined:
@ -55,7 +62,7 @@ Review #2 closes:
- different-ID/same-name anti-duplicate conflicts; - different-ID/same-name anti-duplicate conflicts;
- atomic catalog reconciliation. - atomic catalog reconciliation.
Exit criteria: Exit criteria satisfied before closure:
- `python tools/validate_json.py` passes; - `python tools/validate_json.py` passes;
- `python tools/validate_import_contract.py` passes; - `python tools/validate_import_contract.py` passes;
@ -63,8 +70,11 @@ Exit criteria:
- Android documentation aligned; - Android documentation aligned;
- TUI documentation aligned; - TUI documentation aligned;
- both review commits pushed to Forgejo and GitHub; - both review commits pushed to Forgejo and GitHub;
- mirrored review passes; - GitHub mirror read back and reviewed.
- closure sets `TRAINLOG_FORMAT_V1=FROZEN`.
Gate 1 is closed.
Gate 2 is now the active gate.
## Gate 2 — TUI persistence core ## Gate 2 — TUI persistence core

View file

@ -6,9 +6,10 @@ Current canonical state:
```text ```text
GATE_0=PASS GATE_0=PASS
GATE_1_REVIEW_01=IMPLEMENTED GATE_1_REVIEW_01=PASS
GATE_1=VALIDATION_PENDING GATE_1_REVIEW_02=PASS
TRAINLOG_FORMAT_V1=DRAFT GATE_1=PASS
TRAINLOG_FORMAT_V1=FROZEN
``` ```
Files: Files: