9.4 KiB
Current implementation state
Snapshot date: 2026-09-16.
This document owns the current implemented state. Historical checkpoints and closed incidents belong in reviews and the changelog.
Product boundary
Android is the field companion: it captures training and body data, preserves the active draft, receives AI proposals, triggers synchronization, and shows quick summaries. The C17/Notcurses TUI is the administration, inspection, maintenance, import/export, and technical-tooling surface. The documented but not yet implemented local Web sibling will own analysis, visualization, and program/session preparation through Trainlog Core.
Trainlog Core owns business truth. The desktop SQLite database remains the canonical local source of truth and long-term history; no interface owns a parallel implementation of its rules.
Versions and compatibility
| 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 terminal backend | Notcurses only |
| Trainlog product version | 0.1.1 stable, synchronized across Android and desktop (no independent interface versions) |
| Interface language | TRAINLOG_I18N_V0_1_1=PASS: French default; English selectable in Settings → Language on both surfaces |
| AI history export | TRAINLOG_AI_EXPORT_V1 active |
| AI session proposals | TRAINLOG_AI_SESSION_DRAFT_V1=VALIDATION_PENDING |
| Training knowledge | TRAINING_KNOWLEDGE_V1=PASS |
| Session generator | SESSION_GENERATOR_V1=PASS, hidden pending V2 |
| Application shell | APP_SHELL_V1=IMPLEMENTED_AWAITING_VISUAL_REVIEW_2 |
| Statistics | STATS_V1=IMPLEMENTED |
| Local Web | TRAINLOG_WEB_V1=CONTRACT_FROZEN / IMPLEMENTATION_NOT_STARTED |
Desktop and Android schema numbers are independent. Neither changes the frozen Trainlog JSON V1 contract.
Language is device-local presentation state. Android keeps it in dedicated
SharedPreferences; desktop keeps it in the XDG configuration file
trainlog/presentation.conf. A successful selection updates the UI
immediately. It does not enter either SQLite database, training data, stable
IDs, schemas, exchange artifacts, synchronization protocols, AI proposals,
MAX, or feedback. User-defined exercise and catalogue names are never
automatically translated. Where a recognized stable body-zone ID has a local
presentation label, only that label is localized; unknown IDs retain their
catalogue label. Numbers, dates, and other visible formatting are owned by the
selected presentation language.
Synchronization remains a protocol boundary: core, receipt, and persisted history summaries stay opaque operational bytes. Android and the TUI render 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.
Storage and synchronization
- Android stores capture data in its private SQLite database.
- Android reads and writes exchange artifacts only in
/storage/emulated/0/Documents/Trainlogafter the user grants all-files access through system settings. - The old SAF/tree-URI path and
Download/Trainlogare historical recovery boundaries, not active storage choices. - Desktop synchronization uses direct libudev/libmtp discovery and object access. No GVFS/FUSE mount is required.
trainlog_sync_run()is shared by the TUI andtrainlog-syncd.- The desktop imports Android snapshots, publishes catalog/profile/feedback/AI companions, and returns a receipt. Stable IDs and tombstones make defined replay paths idempotent.
- SQLite database files are never synchronized.
- The desktop AI flow uses external
rclonefor Drive inbox/archive and read-only history export. Android owns no Drive credentials.
Android
Android currently provides:
- metadata-driven SETS+REPS, SETS+DURATION, and CONTINUOUS+DURATION capture;
- actual per-set values, optional occurrence equipment, and explicit MAX rows;
- exactly one durable active session draft with identity-preserving continuous multi-position drag reorder, resume, confirmed discard, and atomic completion;
- completed-session consultation, transient drag reorder, and atomic factual or order correction while retaining session/occurrence/feedback identities for synchronization;
- exercise catalogue editing with stable
exercise_idand referenced-profile protection; - supplied/custom equipment and machine-exercise metadata;
- body measurements and recent BODY ZONES summaries;
- immediate exercise feedback, immutable wording revisions, and J+1/session follow-ups;
- pending AI proposal collection, explicit start/delete, and durable tombstones;
- 7/30/90-day, year, and all-history quick statistics;
- direct-storage snapshot publication, sync triggering, locally rendered typed receipt status/counters, and companion application.
- French-default/English-selectable presentation from Settings → Language, applied immediately without changing repository or synchronization state.
Android does not own canonical long-term analytics. The V1 session generator is implemented but intentionally hidden from normal navigation pending V2.
Desktop TUI
The desktop is a strict C17 application using Notcurses. It currently provides:
- a keyboard-first seven-section shell, semantic true-color roles, UTF-8 input, resize recovery, and a 72x20 minimum-terminal fallback;
- session creation, history, detail, and transactional correction;
- exercise and equipment catalogue management;
- explicit measured-MAX consultation and working-load calculations;
- body observation history, correction, derived analytics, and longitudinal graphs;
- statistics derived from canonical occurrence-owned actual work, including exact calendar-week/month buckets, performance, body, frequency, exercise, and BODY ZONES views;
- detailed locally rendered typed synchronization status/history through the shared engine.
- French-default/English-selectable presentation from Settings → Language, including selected-language formatting without changing canonical data.
Rendering is not permitted to own SQL or business rules. Statistics are
read-only projections; they are not persisted as facts. The current TUI
Dashboard still has a known exception: its direct SQLite/
database_internal.h fact projection must be characterized, extracted into a
typed Core read model, and consumed by the TUI before any Web Dashboard
endpoint is created. This is an incremental extraction, not authorization for
a global tui.c refactor.
Local Web
TRAINLOG_WEB_V1 architecture, API independence, local-network boundary,
browser shell, Dashboard, layout ownership, build/runtime separation, and
security invariants are now canonical. No Web server, frontend, CLI option,
HTTP endpoint, embedded asset, or layout persistence is implemented yet.
Data semantics
exercise_ididentifies a catalogue exercise;entry_ididentifies one ordered occurrence in a session.- Plans and performed work are distinct. A continuous activity is not a fake performed set, and actual repetitions may be heterogeneous.
- Explicit MAX results are occurrence-owned and distinct from ordinary best sets. Equipment/resistance/execution context remains relevant.
- BODY ZONES are a UX/business projection over explicit scientific knowledge, not a complete anatomical taxonomy.
- Feedback roots retain identity while append-only revisions preserve wording history. J+1/session follow-ups are session-owned.
- AI proposals contain target-only plans and never create performed work, history, MAX, or feedback until the user explicitly starts and completes a normal capture draft.
Validation status
The durable commands are owned by tests.md. On 2026-09-15 final
validation passed desktop compilation, 60/60 normal Meson tests and
60/60 ASan/UBSan Meson tests, Android debug assembly and 202 Android
tests (198 passed, 4 skipped, 0 failed), the JSON validator, and the
import-contract validator. The source-derived TUI
TRANSLATABLE_UI=0 check and Android resource parity also passed. Link and
diff safety checks pass in the final audit evidence.
TRAINLOG_I18N_V0_1_1=PASS is covered by desktop presentation, persistence,
formatting, layout-invariance and source-derived text-boundary tests, plus
Android resource-parity, language-owner, typed sync-presentation, and
stable-data presentation tests. A real-device/manual visual language-switch
smoke remains a manual validation; it does not change the validated status.
Hardware-dependent MTP and the final real Drive plus Android-triggered AI-draft
smoke test are not automated. The latter is why
TRAINLOG_AI_SESSION_DRAFT_V1 remains VALIDATION_PENDING.
Active limitations
TRAINLOG_WEB_V1is contract-only; its implementation starts with Dashboard characterization and Core extraction, not React or HTTP infrastructure.APP_SHELL_V1still awaits the recorded human visual/accessibility review.- AI proposal exchange still awaits one real Drive plus Android-triggered bidirectional smoke test.
- Session Generator V1 is hidden while V2 planning semantics are developed.
- Hardware MTP validation requires a connected unlocked Android device.
- Scientific knowledge is bounded to reviewed catalog entries; unknown custom exercises remain unclassified rather than inferred from names.