From 3d5f9a2bef947173e8053704e7340a3fbba81838 Mon Sep 17 00:00:00 2001 From: fy59 Date: Sat, 5 Sep 2026 19:28:26 +0200 Subject: [PATCH] Freeze Trainlog exchange format v1 --- CHANGELOG.md | 4 +- docs/exchange_format.md | 15 ++++--- docs/reviews/gate1_closure.md | 75 +++++++++++++++++++++++++++++++++++ docs/roadmap.md | 28 ++++++++----- format/README.md | 7 ++-- 5 files changed, 110 insertions(+), 19 deletions(-) create mode 100644 docs/reviews/gate1_closure.md diff --git a/CHANGELOG.md b/CHANGELOG.md index a31226c..69bcad1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,11 +26,11 @@ The project uses a simple pre-release changelog during early development. ### Changed - 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. - Planned exercises may contain zero actual sets. - Top-level exercise metadata must exactly match session exercise references. - Assistance kilograms have distinct semantics from external resistance. - Different exercise IDs with equivalent normalized names are hard import conflicts. - 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. diff --git a/docs/exchange_format.md b/docs/exchange_format.md index 5142458..d30364d 100644 --- a/docs/exchange_format.md +++ b/docs/exchange_format.md @@ -4,9 +4,10 @@ ```text GATE_0=PASS -GATE_1_REVIEW_01=IMPLEMENTED -GATE_1=VALIDATION_PENDING -TRAINLOG_FORMAT_V1=DRAFT +GATE_1_REVIEW_01=PASS +GATE_1_REVIEW_02=PASS +GATE_1=PASS +TRAINLOG_FORMAT_V1=FROZEN ``` 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 reviewed commit is pushed and mirrored. -Until then: +Gate 1 validation and mirrored review completed successfully. + +The exchange format is now frozen: ```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 The wire format treats `exercise_id` and `session_id` as opaque identifiers satisfying their defined syntax. diff --git a/docs/reviews/gate1_closure.md b/docs/reviews/gate1_closure.md new file mode 100644 index 0000000..22cfdd0 --- /dev/null +++ b/docs/reviews/gate1_closure.md @@ -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. diff --git a/docs/roadmap.md b/docs/roadmap.md index 9241f39..425c8d8 100644 --- a/docs/roadmap.md +++ b/docs/roadmap.md @@ -25,15 +25,22 @@ ebd4316ed68c58598a471e567edf13455d00f92b ## Gate 1 — Exchange format v1 freeze -Status: VALIDATION PENDING — REVIEW #2 +Status: PASS -Canonical state: +Canonical result: ```text -GATE_1_REVIEW_01=IMPLEMENTED -GATE_1_REVIEW_02=IMPLEMENTED -GATE_1=VALIDATION_PENDING -TRAINLOG_FORMAT_V1=DRAFT +GATE_1_REVIEW_01=PASS +GATE_1_REVIEW_02=PASS +GATE_1=PASS +TRAINLOG_FORMAT_V1=FROZEN +``` + +Reviewed commits: + +```text +9d9a9223a0c46df72f5c3ab208107c0ac6698438 +dfd6717cb7978d009670f1a49029c62c9154af55 ``` Review #1 defined: @@ -55,7 +62,7 @@ Review #2 closes: - different-ID/same-name anti-duplicate conflicts; - atomic catalog reconciliation. -Exit criteria: +Exit criteria satisfied before closure: - `python tools/validate_json.py` passes; - `python tools/validate_import_contract.py` passes; @@ -63,8 +70,11 @@ Exit criteria: - Android documentation aligned; - TUI documentation aligned; - both review commits pushed to Forgejo and GitHub; -- mirrored review passes; -- closure sets `TRAINLOG_FORMAT_V1=FROZEN`. +- GitHub mirror read back and reviewed. + +Gate 1 is closed. + +Gate 2 is now the active gate. ## Gate 2 — TUI persistence core diff --git a/format/README.md b/format/README.md index 75e21eb..f6430b6 100644 --- a/format/README.md +++ b/format/README.md @@ -6,9 +6,10 @@ Current canonical state: ```text GATE_0=PASS -GATE_1_REVIEW_01=IMPLEMENTED -GATE_1=VALIDATION_PENDING -TRAINLOG_FORMAT_V1=DRAFT +GATE_1_REVIEW_01=PASS +GATE_1_REVIEW_02=PASS +GATE_1=PASS +TRAINLOG_FORMAT_V1=FROZEN ``` Files: