docs(sync): freeze data lifecycle slice

This commit is contained in:
fy59 2026-09-17 08:19:18 +02:00
parent 99f3f46d13
commit 3db84bbfb0
12 changed files with 80 additions and 19 deletions

View file

@ -166,7 +166,7 @@ It is not the canonical analytics store.
The Android UI is driven by exercise metadata, never by exercise-name
heuristics.
Android local SQLite schema v17 retains the exactly-one durable active-session
Android local SQLite schema v18 retains the exactly-one durable active-session
draft introduced in v4.
Every meaningful draft/form mutation is persisted by the repository. Back,
backgrounding and process death never delete the draft. Home offers explicit
@ -180,7 +180,7 @@ from actual occurrence data after the additive v10 -> v11 migration. Existing
rows retain `load_mode=none`, zero rest and NULL targets. Android v12 adds the
durable flattened exercise-alias mapping used to resolve retired creator IDs.
Desktop schema v12 owns the same alias compatibility boundary. Later additive
desktop migrations reach v18 and Android migrations reach v17 without changing
desktop migrations reach v19 and Android migrations reach v18 without changing
that identity contract. The active
completed-session exchange is the separate strict
`trainlog-mobile-export` V3; V1/V2 remain readable and `TRAINLOG_FORMAT_V1`
@ -237,7 +237,7 @@ Desktop SQLite schema is versioned with:
PRAGMA user_version;
```
The current desktop schema is v18. Schema v9 added an occurrence-owned explicit
The current desktop schema is v19. Schema v9 added an occurrence-owned explicit
maximum result; v10/v11 added body-zone and planning metadata; v12 added durable
flattened exercise aliases; v13-v18 add machine metadata, feedback and
revisions, occurrence tracking snapshots, causal profile state, and AI proposal

View file

@ -2,6 +2,14 @@
## Unreleased — 0.1.2
- Completed `TRAINLOG_SYNC_DATA_LIFECYCLE_V1` with desktop schema v19 and
Android schema v18. Added explicit staged V4 enriched-history codecs,
causal notes, body-observation session links, stable execution-draft
identities, bounded pending drafts, explicit activation and atomic,
idempotent finalization with stale-replay protection. Active synchronization
remains V3; no service, user database, phone, tag or release artifact was
changed or deployed.
- Completed `TRAINLOG_SYNC_CHARACTERIZATION_V1` without changing production
synchronization, schemas, or formats. Added a real Android V3 exporter →
desktop importer/exporter → fresh Android importer round trip, and completed

View file

@ -308,11 +308,12 @@ not contain cloud credentials and does not run `rclone`.
As of 2026-09-17:
- `TRAINLOG_FORMAT_V1=PASS/FROZEN`;
- desktop SQLite schema v18 and Android SQLite schema v17;
- desktop SQLite schema v19 and Android SQLite schema v18;
- Notcurses is the only active desktop terminal backend;
- direct storage is `/storage/emulated/0/Documents/Trainlog` under Android's
all-files access setting;
- mobile export V3 is active; V1/V2 remain readable legacy inputs;
- mobile export V3 is active; V1/V2 remain readable legacy inputs; explicit V4
history and execution-draft codecs are staged but not selected by transport;
- `STATS_V1=IMPLEMENTED`, `TRAINING_KNOWLEDGE_V1=PASS`, and
`SESSION_GENERATOR_V1=PASS` (the generator is hidden pending V2);
- `APP_SHELL_V1=IMPLEMENTED_AWAITING_VISUAL_REVIEW_2`;

View file

@ -90,6 +90,15 @@ so an unchanged companion replay is a skip and cannot resurrect a started or
deleted proposal. Neither action manufactures performed sets, completed history,
MAX, or feedback.
Android schema v18 additively gives the execution draft its future stable
`session_id`, revision ancestry and `started_at`; adds bounded pending draft,
revision and finalization storage; and adds causal note state plus optional
observation-to-session ownership. Finalization inserts the completed session
with the same stable identities and records its ledger in the transaction that
removes the active draft. Retrying finalization is idempotent, and a stale
draft replay cannot recreate the finalized draft. Raw partial form strings
remain local and are absent from the lifecycle artifact.
The manual synchronization action publishes one prepared Android→PC bundle
before it exposes `trainlog-sync-request-v1.json`. The bundle contains mobile
V3, mobile equipment definitions, equipment associations V2, exercise aliases

View file

@ -468,7 +468,9 @@ silently rendered as unclassified.
### Desktop
Desktop SQLite schema v18 is canonical long-term history. Its v15 -> v16
Desktop SQLite schema v19 is canonical long-term history. Its additive v18 ->
v19 migration stores causal notes and execution-draft lifecycle state without
activating a new transport. Its v15 -> v16
transactional rebuild adds the occurrence-owned `tracking_mode` snapshot; the
one-time backfill copies the linked catalogue mode without changing child rows
or stable identities. The additive v16 -> v17 migration adds deterministic

View file

@ -25,9 +25,9 @@ parallel implementation of its rules.
| Boundary | Current state |
|---|---|
| Frozen project exchange | `TRAINLOG_FORMAT_V1=PASS/FROZEN` |
| Desktop SQLite | schema v18 |
| Android SQLite | schema v17 |
| Mobile snapshot | V3 active; V1/V2 readable legacy inputs |
| Desktop SQLite | schema v19 |
| Android SQLite | schema v18 |
| Mobile snapshot | V3 active; V1/V2 readable legacy inputs; explicit V4 codec staged, not selected by transport |
| Desktop terminal backend | Notcurses only |
| Trainlog product version | `0.1.2` development, synchronized across Android and desktop; latest stable release: `v0.1.1` |
| Interface language | `TRAINLOG_I18N_V0_1_1=PASS`: French default; English selectable in Settings → Language on both surfaces |
@ -48,9 +48,10 @@ parallel implementation of its rules.
| Web Dashboard visualizations | `WEB_DASHBOARD_VISUALIZATIONS_V1=PASS/FROZEN` |
| Web Dashboard V1 | `WEB_DASHBOARD_V1=PASS/FROZEN` |
| Local Web | `TRAINLOG_WEB_V1=CONTRACT_FROZEN / IMPLEMENTATION_STARTED` |
| Complete synchronization gap contract | `TRAINLOG_SYNC_GAP_CONTRACT_V1=CONTRACT_FROZEN / IMPLEMENTATION_NOT_STARTED` |
| Complete synchronization gap contract | `TRAINLOG_SYNC_GAP_CONTRACT_V1=CONTRACT_FROZEN / IMPLEMENTATION_IN_PROGRESS` |
| Isolated synchronization test environment | `TRAINLOG_SYNC_TEST_ENV_V1=PASS/FROZEN` |
| Synchronization characterization | `TRAINLOG_SYNC_CHARACTERIZATION_V1=PASS/FROZEN` |
| Synchronization data/lifecycle slice | `TRAINLOG_SYNC_DATA_LIFECYCLE_V1=PASS/FROZEN` |
Desktop and Android schema numbers are independent. Neither changes the frozen
Trainlog JSON V1 contract.
@ -72,6 +73,13 @@ their current synchronization state from local typed status and counters; they
never inject a raw cross-device French summary into the visible interface. No
raw exchange or protocol format changed for interface language support.
Schema v19/v18 now persists enriched history (`ended_at`, causal session,
occurrence and observation notes, and observation-to-session links), stable
execution-draft identities, bounded pending drafts and finalization ledgers.
The explicit `trainlog-mobile-export` V4 and `trainlog-execution-drafts` V1
codecs are validation-stage entry points only. The active sync engine and
Android inbox/outbox still select V3 and do not move the draft artifact.
## Storage and synchronization
- Android stores capture data in its private SQLite database.

View file

@ -16,8 +16,8 @@ is a later, separately versioned migration.
## 1. Status
```text
TRAINLOG_DATABASE_SCHEMA_VERSION=18
DATABASE_SCHEMA_V18=IMPLEMENTED
TRAINLOG_DATABASE_SCHEMA_VERSION=19
DATABASE_SCHEMA_V19=IMPLEMENTED
TRAINLOG_FORMAT_V1=FROZEN
```
@ -36,7 +36,7 @@ PRAGMA user_version;
Current value:
```text
18
19
```
The independent actual-set loads documented in the current desktop, Android
@ -49,6 +49,12 @@ Supported historical databases are migrated explicitly through the implemented
migration chain. A database newer than the running binary understands is
rejected.
Version 19 additively stores causal note revisions/current state and staged
execution drafts, their immutable revisions, pending/active state and durable
finalization ledger. It changes no published V1 format and performs no user
database migration until a v19 binary is deliberately deployed and opens that
database.
Version 7 assigns `session_exercises.entry_id` to each stable occurrence.
`exercise_id` remains only the catalogue identity and may occur more than once
in a session. The v6 → v7 migration rebuilds the obsolete uniqueness

View file

@ -400,7 +400,7 @@ de fichiers Android anciens.
isolé reproductible ;
2. `TRAINLOG_SYNC_CHARACTERIZATION_V1` : compléter les preuves actuelles sur
toutes plateformes ;
3. `TRAINLOG_SYNC_DATA_LIFECYCLE_V1` : mobile V4, drafts et champs perdus ;
3. `TRAINLOG_SYNC_DATA_LIFECYCLE_V1`: mobile V4, drafts and previously lost fields — `PASS/FROZEN`;
4. `TRAINLOG_SYNC_CAUSAL_DELETE_V1` : opérations causales et tombstones ;
5. `TRAINLOG_SYNC_GENERATION_ACK_V1` : manifest, staging, publication,
consommation, reprise et ack ;

View file

@ -78,6 +78,13 @@ The active completed-session synchronization artifact is separately versioned
`trainlog-mobile-export` V3 and is documented in [Synchronization
exchange](sync_exchange.md). It does not redefine this frozen V1 schema.
An explicit staged `trainlog-mobile-export` V4 codec carries nullable
`ended_at`, causal note values/revisions and observation `session_id`. A
separate strict `trainlog-execution-drafts` V1 codec carries confirmed business
state, stable draft/session and occurrence identities, ancestry and pending
state; it never carries raw UI form strings. Neither staged codec changes
`TRAINLOG_FORMAT_V1` or is selected by the active synchronization transport.
## 2. Design goal
Trainlog v1 must represent the training patterns required by the initial applications without turning the Android recorder into a complex training platform.

View file

@ -19,7 +19,7 @@ distinction between measured values and estimates.
## Current baseline
Desktop schema v18, Android schema v17, Notcurses, direct
Desktop schema v19, Android schema v18, Notcurses, direct
`Documents/Trainlog` storage, mobile export V3, Training Knowledge V1, Body
Zones V1, Training Feedback V1/V2, STATS V1, and Session Generator V1 are
implemented. Session Generator V1 is hidden pending V2. AI session-draft
@ -33,7 +33,7 @@ visualizations are implemented; the other four Web routes remain placeholders.
## Current cursor
```text
CURRENT_OPERATIONAL_CURSOR=TRAINLOG_SYNC_DATA_LIFECYCLE_V1
CURRENT_OPERATIONAL_CURSOR=TRAINLOG_SYNC_CAUSAL_DELETE_V1
```
`TRAINLOG_SYNC_GAP_CONTRACT_V1=CONTRACT_FROZEN / IMPLEMENTATION_NOT_STARTED`
@ -123,8 +123,11 @@ it does not authorize silently implementing a page.
The frozen contract orders future bounded lots as environment/test,
characterization, data/lifecycles, causal deletion, generation/consumption/ack,
orchestrator/report, Web API, then button/refresh. The environment/test and
characterization lots are complete; no production synchronization
implementation lot is started.
characterization and data/lifecycle lots are complete. Enriched V4 history and
the separate execution-draft codec are implemented behind explicit entry
points, while active transport remains V3. Causal deletion,
generation/consumption acknowledgement, orchestration/reporting and Web sync
remain unimplemented.
`WEB_DASHBOARD_V1=PASS/FROZEN` remains closed and unchanged.
### Gym catalog V1

View file

@ -2,7 +2,7 @@
## Machine-exercise Phase 1 compatibility
Desktop schema v18 and Android schema v17 retain mobile export V3, readable V1/V2 imports,
Desktop schema v19 and Android schema v18 retain mobile export V3, readable V1/V2 imports,
equipment definitions V1, equipment associations V2, exercise aliases V1, and
the BODY ZONES companion without wire-format changes. Machine metadata is not
silently added to a frozen artifact: stable exercise IDs and canonical names
@ -44,6 +44,7 @@ SESSION_GENERATOR_V1=PASS
BODY_ZONE_SYNC_V1=PASS
BODY_ZONE_SYNC_V1_LIVE_DEVICE=PASS
TRAINLOG_AI_SESSION_DRAFT_V1=VALIDATION_PENDING
TRAINLOG_SYNC_DATA_LIFECYCLE_V1=PASS/FROZEN
TRAINLOG_FORMAT_V1=FROZEN_UNCHANGED
```
@ -59,6 +60,13 @@ general correction; its older resumed-MAX compatibility remains bounded.
Synchronization artifacts are separate from the frozen Trainlog session JSON
v1 format.
V4 history and execution-draft V1 are staged codecs with explicit repository
and command-line entry points. They are deliberately absent from
`trainlog_sync_run()`, request/receipt publication and the Android automatic
inbox/outbox. Deployment must stop the old user worker, replace the installed
binary/scripts as one unit, migrate only through the new binary, and restart
only after compatibility checks; this ticket performs none of those steps.
## 2. Exchange directory
Canonical Android shared-storage directory:

View file

@ -399,6 +399,15 @@ python3 tools/validate_sync_isolated.py --suite smoke
python3 tools/validate_sync_isolated.py --suite full --jdk /usr/lib/jvm/java-17-openjdk
```
`TRAINLOG_SYNC_DATA_LIFECYCLE_V1` adds schema v19/v18 migration assertions and
Android lifecycle coverage for confirmed-only serialization, persistent
pending state, occupied-singleton refusal, explicit activation, identity-
preserving idempotent finalization and stale replay. The full isolated run at
closure passed 73/73 normal native tests, 73/73 ASan/UBSan native tests and 205
Android tests (201 passed, four unchanged historical-fixture skips), plus both
Python validators and `assembleDebug`. These are artifact/repository proofs;
they do not claim transport activation or global synchronization atomicity.
Use `--jdk /absolute/jdk17/home` when auto-detection is unsuitable and
`--run-parent /absolute/private/parent` to select another parent outside the
problematic system `/tmp`. `--keep-run-dir` retains a successful run for