3.9 KiB
Bidirectional synchronization checkpoint
Validated status
ANDROID_LOCAL_WORKFLOWS=PASS
ANDROID_TO_PC_MTP=PASS
DESKTOP_MOBILE_IMPORT_V1=PASS
DESKTOP_MOBILE_IMPORT_IDEMPOTENT=PASS
PC_CATALOG_EXPORT_V1=PASS
PC_TO_ANDROID_MTP_PUBLISH=PASS
ANDROID_SAF_FOLDER_SELECTION=PASS
ANDROID_SAF_FOLDER_CHANGE=PASS
This checkpoint represents the validated synchronization foundation on the physical Samsung device.
Android → PC
Android produces:
Download/Trainlog/trainlog-mobile-export-v1.json
The desktop retrieves it through direct libmtp.
No GVFS/FUSE mount is used.
The desktop importer:
tools/import_mobile_export.py
is:
strict
transactional
idempotent by stable IDs
profile-aware
Validated behavior:
first import:
new exercise/session/body observation imported
second import:
no duplicates
existing stable IDs skipped
PC → Android
The desktop produces:
/tmp/trainlog-pc-catalog-v1.json
with:
format = trainlog-pc-catalog
version = 1
The catalog is published by direct MTP to:
Download/Trainlog/trainlog-pc-catalog-v1.json
Physical-device publication has been validated.
The Android application accesses the PC-created file through one persistent Storage Access Framework grant.
The selected folder must be:
Download/Trainlog
The Sync screen must always allow changing this folder because a wrong persisted SAF grant must be recoverable without clearing application data.
Important semantics
The synchronization layer exchanges versioned Trainlog domain artifacts.
It does not synchronize SQLite files.
The frozen legacy session format remains:
TRAINLOG_FORMAT_V1=FROZEN
Profile-aware synchronization uses separate explicit synchronization artifacts.
Current TUI state
The existing desktop Sync action can:
Android → PC import
PC → Android catalog publication
The current status/count-oriented Sync presentation is temporary.
A snapshot file remaining on Android is not a pending queue item. Therefore labels such as:
1 JSON candidate
must not be considered a final synchronization UX.
Next synchronization UX
The TUI Sync page must become a persistent synchronization history, similar to:
git log
Example:
06/09/2026 16:00 ✓ Android +1 session · PC catalog 3 exercises
06/09/2026 15:42 ✓ no changes
06/09/2026 15:31 ! device disconnected
A synchronization entry must be selectable.
Enter opens a detailed view analogous to:
git show
The detail must include:
sync ID
trigger
start/end local time
status
Android → PC
exercises imported/reconciled/skipped
sessions imported/skipped
body observations imported/skipped
PC → Android
catalog exercises published
Android catalog apply result when available
transport/artifact diagnostics
Android-triggered synchronization
The final Android Sync UX must not require:
Prepare export
then use the PC manually
Target behavior:
Android data change
-> mobile snapshot maintained automatically
Android "Synchronize now"
-> synchronization request
PC trainlog-syncd
-> detects request over direct MTP
-> runs the same bidirectional sync engine
-> writes synchronization receipt
Android
-> reads receipt
-> applies PC catalog
-> displays final synchronization result
MTP remains host-initiated. Therefore Android-triggered synchronization needs a small PC-side agent; it cannot directly command libmtp operations on the PC.
Display normalization
User-facing session history must use local presentation:
DD/MM/YYYY HH:MM
Canonical RFC3339 timestamps remain unchanged in persistence and exchange.
Next cursor
SYNC_HISTORY_GIT_LIKE=NEXT
COMMON_SYNC_ENGINE=NEXT
TRAINLOG_SYNCD=NEXT
ANDROID_SYNC_REQUEST_RECEIPT=AFTER
ANDROID_AUTO_OUTBOX=AFTER_AGENT_FOUNDATION