docs(sync): record operational private rollout
This commit is contained in:
parent
e64ea836f7
commit
56ac1cdfd2
9 changed files with 165 additions and 30 deletions
12
CHANGELOG.md
12
CHANGELOG.md
|
|
@ -2,6 +2,18 @@
|
|||
|
||||
## Unreleased — 0.1.2
|
||||
|
||||
- Completed the authorized private full-generation rollout over production
|
||||
direct MTP: verified Android and desktop backups, signing-preserving Android
|
||||
updates, schema migrations, persistent peer pairing, bidirectional durable
|
||||
ACKs, restart and idempotent replay. This did not publish a release or modify
|
||||
v0.1.1.
|
||||
|
||||
- Fixed rollout-discovered feedback idempotence across SQLite row modes,
|
||||
packaged the complete generation exporter closure, ignored stale Android
|
||||
coordination objects until their run/generation correlation matches, and
|
||||
made the Android screen report completed generation conversations instead of
|
||||
waiting for a legacy receipt.
|
||||
|
||||
- Packaged `trainlog-sync-once` and `trainlog-syncd` with the relocatable sync
|
||||
candidate so user services cannot mix a versioned install with live-checkout
|
||||
helpers during rollout.
|
||||
|
|
|
|||
10
README.md
10
README.md
|
|
@ -91,6 +91,16 @@ Android and the TUI in each stable release share the same Trainlog product
|
|||
version on both mirrors. Database schemas and JSON protocol versions are
|
||||
independent.
|
||||
|
||||
### Daily synchronization on an opted-in installation
|
||||
|
||||
Connect and unlock the paired phone, keep Trainlog's Synchronization screen in
|
||||
the foreground, then select **Synchronize** in the local Web Dashboard and
|
||||
**Synchronize now** on Android. Wait until Web reports completion and Android
|
||||
shows that synchronization completed on both Android and PC. A failure remains
|
||||
durable and should be diagnosed before retrying; do not delete generation,
|
||||
ACK, database, or backup files. Full-generation mode is a trusted local opt-in;
|
||||
other installations continue to use the established V3 request/receipt path.
|
||||
|
||||
### Build from source
|
||||
|
||||
Desktop:
|
||||
|
|
|
|||
|
|
@ -956,3 +956,11 @@ The installed schema-v17 release has no backup UI. The reproducible
|
|||
adds only the backup surface, assigns a higher candidate version code and
|
||||
builds/tests an APK without installing it. Its synthetic v17 archive is also
|
||||
restored by current code and migrated through the normal v17-to-v20 path.
|
||||
|
||||
The authorized private rollout used the bridge only to add the backup surface
|
||||
without clearing package data, verified the resulting plaintext archive, then
|
||||
installed the current signed release variant through a strictly increasing
|
||||
version-code chain. The final installed private candidate retains product
|
||||
version 0.1.2 and schema v20. Its full-generation foreground coordinator waits
|
||||
for correlated objects, tolerates stale objects left by interrupted runs, and
|
||||
shows completion only after both durable peer acknowledgements.
|
||||
|
|
|
|||
|
|
@ -1,12 +1,13 @@
|
|||
# Current implementation state
|
||||
|
||||
The development branch has opt-in full-generation coordination with durable Web
|
||||
progress and a foreground Android conversation. Its production generation MTP
|
||||
adapter is integrated and tested through an object-I/O boundary double. Android
|
||||
also has a complete same-installation backup/verify/restore container, and a
|
||||
non-installed schema-v17 bridge candidate is reproducibly built and tested.
|
||||
Physical-device MTP, release signing, real user backup/restore, main integration
|
||||
and deployment are not complete.
|
||||
The opt-in full-generation path is operational on the private daily
|
||||
installation. The loopback Web control and foreground Android coordinator use
|
||||
the production direct-libmtp adapter, correlated manifest/ACK V1 objects, and
|
||||
persistent peer identities. The controlled rollout verified real backups, the
|
||||
schema-v17 to v20 Android update chain, desktop v18 to v21 migration, three
|
||||
complete hardware conversations, restart, and idempotent replay. Drive was not
|
||||
configured and remains outside this local MTP result. This is a private 0.1.2
|
||||
development deployment, not a public release; v0.1.1 is unchanged.
|
||||
|
||||
`TRAINLOG_NATIVE_BUILD_AND_CANDIDATE_V1` closes the native warning gate. Strict
|
||||
GCC 16.2.1 and Clang 22.1.8 builds now pass the same 81-test inventory, and the
|
||||
|
|
@ -75,6 +76,7 @@ parallel implementation of its rules.
|
|||
| Web sync API V1 | `TRAINLOG_WEB_SYNC_API_V1=PASS/FROZEN` |
|
||||
| Web sync button V1 | `TRAINLOG_WEB_SYNC_BUTTON_V1=PASS/FROZEN` |
|
||||
| Sync Web end-to-end wrapper | `TRAINLOG_SYNC_WEB_END_TO_END_V1=PASS/FROZEN` (isolated) |
|
||||
| Private full-generation rollout | `TRAINLOG_SYNC_FINALIZATION_AND_ROLLOUT_V1=PASS` (direct MTP, one authorized phone) |
|
||||
| Local Web | `TRAINLOG_WEB_V1=CONTRACT_FROZEN / IMPLEMENTATION_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` |
|
||||
|
|
|
|||
67
docs/reviews/sync_rollout_v1_deployment.md
Normal file
67
docs/reviews/sync_rollout_v1_deployment.md
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
# Full-generation synchronization V1 private deployment record
|
||||
|
||||
Date: 2026-09-17
|
||||
|
||||
Status: `TRAINLOG_SYNC_FINALIZATION_AND_ROLLOUT_V1=PASS`
|
||||
|
||||
This record deliberately omits phone serials, peer IDs, generation IDs,
|
||||
credential locations, user content, and private backup hashes. Complete causal
|
||||
evidence is retained in the private rollout journal.
|
||||
|
||||
## Installed set
|
||||
|
||||
- Trainlog 0.1.2 development; desktop schema v21 and Android schema v20.
|
||||
- Versioned relocatable desktop bundle behind stable user-bin symlinks.
|
||||
- Android release-variant APK installed only through compatible signed updates;
|
||||
the final private rollout version code is 6.
|
||||
- Production direct-libmtp generation adapter with one explicitly paired peer.
|
||||
- Loopback Web service and the user-session request daemon are active from the
|
||||
same versioned installation. No live-checkout runtime helper is used.
|
||||
|
||||
## Data and migration evidence
|
||||
|
||||
- The original Android schema-v17 store was backed up through the signed bridge
|
||||
UI and verified for manifest, digests, SQLite integrity, foreign keys and an
|
||||
exact semantic match to the pre-update store. The real archive migrated on a
|
||||
copy before live installation.
|
||||
- A post-migration Android backup was also verified. The real source contained
|
||||
no active draft, so draft restoration was correctly not applicable; no
|
||||
synthetic draft was inserted.
|
||||
- The desktop schema-v18 store was copied with SQLite's backup API, validated,
|
||||
and migrated on an isolated copy before the live schema-v21 open. Historical
|
||||
table values were preserved.
|
||||
- Backups, failed generations, rejection ACKs and successful generation/ACK
|
||||
evidence remain retained. No one-sided rollback was performed after causal
|
||||
writes began.
|
||||
|
||||
## Operational evidence
|
||||
|
||||
- The actual foreground Android advertisement exposed the required persistent
|
||||
identity and all five capabilities.
|
||||
- Production libudev/libmtp discovery and object transfer completed on the
|
||||
selected unlocked phone.
|
||||
- Three final bidirectional conversations completed with a durable consumed ACK
|
||||
on each peer and all eight required domains reported successful.
|
||||
- A service/application restart and a second non-destructive exchange produced
|
||||
no duplicate business data. Logical hashes for 23 desktop business tables
|
||||
and 540 rows were identical before and after replay; integrity and foreign-key
|
||||
checks passed.
|
||||
- Android visibly returned to an enabled action and displayed synchronization
|
||||
completion for both Android and PC.
|
||||
|
||||
## Rollout repairs
|
||||
|
||||
The real rollout exposed and closed four bounded defects: feedback idempotence
|
||||
depended on the SQLite row representation; the desktop package omitted several
|
||||
runtime exporters; Android accepted stale coordination filenames without
|
||||
run/generation correlation; and its UI waited for a legacy receipt after the
|
||||
generation coordinator had already completed. Regression tests cover each
|
||||
affected boundary.
|
||||
|
||||
## Remaining limits
|
||||
|
||||
The phone must be connected, unlocked and in the foreground synchronization
|
||||
flow. Retained outgoing generations remain subject to the explicit capacity of
|
||||
eight per peer; evidence is never silently evicted. Drive was not configured or
|
||||
tested. This private deployment does not publish 0.1.2, create a tag or release,
|
||||
or alter the existing v0.1.1 release.
|
||||
|
|
@ -1,9 +1,9 @@
|
|||
# Roadmap
|
||||
|
||||
Before controlled rollout, complete and validate the physical libmtp generation
|
||||
adapter, establish a legitimate installed-Android backup path, verify release
|
||||
signing continuity and obtain explicit rollout approval. Do not enable generation
|
||||
mode or advance `main` before those gates.
|
||||
The controlled private rollout is complete for the paired daily installation:
|
||||
physical libmtp, verified backups, signing continuity, migrations, correlated
|
||||
ACKs, restart, and idempotent replay passed. Generation mode remains an
|
||||
explicit per-installation opt-in; Drive is still unconfigured and unvalidated.
|
||||
|
||||
This document owns future work. The implemented baseline is summarized in
|
||||
[current_state.md](current_state.md); completed narratives and evidence belong
|
||||
|
|
@ -38,7 +38,7 @@ visualizations are implemented; the other four Web routes remain placeholders.
|
|||
## Current cursor
|
||||
|
||||
```text
|
||||
CURRENT_OPERATIONAL_CURSOR=TRAINLOG_SYNC_DEPLOYMENT_READINESS_V1
|
||||
CURRENT_OPERATIONAL_CURSOR=TRAINLOG_WEB_V1_NEXT_CONTRACT
|
||||
```
|
||||
|
||||
The focused `TRAINLOG_SYNC_CAUSAL_DELETE_V1_CLOSEOUT` is complete before this
|
||||
|
|
@ -47,9 +47,10 @@ cross-platform draft revision identity and resource-bound admission are closed.
|
|||
`TRAINLOG_SYNC_GENERATION_ACK_V1=PASS/FROZEN`: both platforms expose explicit
|
||||
coherent capture, immutable manifest publication, whole-generation
|
||||
transactional consumption, durable correlated ACK and restart/replay entry
|
||||
points. The orchestrator, Web API and Web control are now complete behind an
|
||||
explicit trusted opt-in. Automatic V3 selection remains unchanged. The next
|
||||
boundary is deployment readiness; no rollout starts here.
|
||||
points. The orchestrator, Web API and Web control are complete behind an
|
||||
explicit trusted opt-in. The authorized private direct-MTP rollout passed on
|
||||
real hardware; automatic V3 selection remains unchanged without that opt-in.
|
||||
The next work returns to separately contracted Web surfaces.
|
||||
|
||||
`TRAINLOG_SYNC_GAP_CONTRACT_V1=CONTRACT_FROZEN / IMPLEMENTATION_IN_PROGRESS`
|
||||
defines the complete-sync target and its bounded dependency order.
|
||||
|
|
|
|||
|
|
@ -776,6 +776,19 @@ idempotently. Causal V1 operation bytes remain unchanged across first emission
|
|||
and retransmission because generation membership lives only in
|
||||
`sync_causal_publications`.
|
||||
|
||||
The foreground Android coordinator correlates both durable desktop ACKs and
|
||||
desktop generation references by the active run (and the Android generation
|
||||
for its ACK). Objects retained from an interrupted conversation are ignored
|
||||
until atomically replaced by matching objects. After both peer ACKs, Android
|
||||
reports completion directly; it does not enter the legacy receipt wait state.
|
||||
|
||||
The 2026-09-17 private rollout exercised this path with the production libmtp
|
||||
adapter on one paired Samsung phone. Three complete bidirectional conversations
|
||||
passed, including service/application restart and an idempotent replay whose
|
||||
23 desktop business tables and 540 rows retained identical logical hashes.
|
||||
Rejected pre-fix generations and their ACKs were retained as causal evidence.
|
||||
No Drive transport was configured or claimed by this validation.
|
||||
|
||||
The generation MTP adapter resolves `Documents/Trainlog` through libudev and
|
||||
libmtp, selects one exact advertised peer/capability set across bounded devices
|
||||
and storages, and mirrors only bounded regular object names. It downloads to
|
||||
|
|
|
|||
|
|
@ -1,6 +1,17 @@
|
|||
# Full-generation sync rollout readiness
|
||||
|
||||
## Deployment-readiness candidate
|
||||
## Operational rollout status
|
||||
|
||||
`TRAINLOG_SYNC_FINALIZATION_AND_ROLLOUT_V1=PASS` on 2026-09-17 for the
|
||||
authorized private daily installation. Verified real Android and desktop
|
||||
backups were retained, migration copies passed before live updates, the signing
|
||||
identity and increasing Android version-code chain were verified, and the
|
||||
production libmtp adapter completed bidirectional manifest/ACK conversations.
|
||||
Restart and idempotent replay also passed. Drive was not configured. No public
|
||||
release or tag was created, and v0.1.1 was not modified. The sanitized evidence
|
||||
record is [sync rollout V1 deployment](reviews/sync_rollout_v1_deployment.md).
|
||||
|
||||
## Deployment-readiness contract
|
||||
|
||||
The generation path remains disabled unless desktop configuration authorizes a
|
||||
specific persisted Android peer and Android contains the strict opt-in document
|
||||
|
|
@ -10,12 +21,10 @@ bounded typed progress and its descendant process group. The foreground Android
|
|||
coordinator advertises its real peer identity, publishes manifest-last bytes,
|
||||
consumes the return generation and emits a durable correlated ACK.
|
||||
|
||||
The integrated proof uses the production generation adapter with only its
|
||||
typed libudev/libmtp I/O callbacks replaced by an object-store double. This is
|
||||
software evidence for selection, bounds, publication ordering and the complete
|
||||
conversation, but not evidence for a particular phone's physical libmtp
|
||||
behavior. Generation mode must remain disabled until that hardware gate and
|
||||
the separately authorized rollout are complete.
|
||||
The isolated proof still uses the production generation adapter with only its
|
||||
typed libudev/libmtp I/O callbacks replaced by an object-store double. The
|
||||
separate deployment record owns the physical-phone evidence; neither proof
|
||||
generalizes pairing to another phone or enables generation mode by default.
|
||||
|
||||
### Candidate, backup and recovery
|
||||
|
||||
|
|
@ -54,12 +63,10 @@ the separately authorized rollout are complete.
|
|||
preserve pending generations, tombstones, finalizations and ACK ledgers; it
|
||||
must never trigger hidden eviction.
|
||||
|
||||
Actual rollout needs one separate approval for the signed APK, desktop bundle,
|
||||
verified user backups, coordinated service quiescence, pairing, synthetic smoke
|
||||
and non-destructive hardware smoke. Drive remains separate and untested here.
|
||||
|
||||
This is a non-executed rollout checklist. The development branch implements the
|
||||
path; the daily installation still uses V3.
|
||||
The grouped rollout approval covered the signed APK, desktop bundle, verified
|
||||
user backups, coordinated service quiescence, pairing, synthetic smoke and
|
||||
non-destructive hardware smoke. Those steps are complete for the recorded
|
||||
private installation. Drive remains separate and untested.
|
||||
|
||||
The latest software-only candidate set was rebuilt under the private root
|
||||
`/home/fy59/.cache/trainlog/sync-rollout-candidate-v1.NEoMDx` from source commit
|
||||
|
|
@ -106,5 +113,6 @@ operator diagnosis; this tranche adds no tombstone or evidence garbage
|
|||
collection. A migrated database is recovered from its verified backup, never by
|
||||
assuming an older binary reverses its migration.
|
||||
|
||||
Physical MTP, actual Drive configuration, service coordination, installed APK,
|
||||
main merge and deployment are intentionally not performed here.
|
||||
The recorded private installation completed physical MTP, service coordination
|
||||
and APK/desktop deployment. Actual Drive configuration remains untested; the
|
||||
eight-generation admission bound and foreground-phone requirement remain.
|
||||
|
|
|
|||
|
|
@ -1361,3 +1361,17 @@ SQLite value type and value before restore, migrates through the production
|
|||
repository owner, and compares that complete historical shape afterward. The
|
||||
draft assertion follows the archived state instead of requiring the synthetic
|
||||
fixture's sample draft.
|
||||
|
||||
## Private full-generation rollout validation
|
||||
|
||||
The authorized 2026-09-17 rollout added regression coverage for production
|
||||
failures found only after installation: feedback import under `sqlite3.Row`,
|
||||
the complete exporter inventory of the relocatable package, stale Android ACK
|
||||
and generation-reference correlation, and the completed-generation UI state.
|
||||
The real direct-libmtp smoke then completed three bidirectional conversations
|
||||
on the paired phone. Restart and replay preserved identical logical hashes for
|
||||
23 desktop business tables and 540 rows; SQLite integrity and foreign-key
|
||||
checks passed, both outgoing desktop generations were acknowledged, and the
|
||||
Android UI displayed completion. The private journal retains exact IDs and
|
||||
hashes. Drive and `connectedDebugAndroidTest` were not run; the personal phone
|
||||
was used only for non-destructive install, backup and manual sync validation.
|
||||
|
|
|
|||
Loading…
Reference in a new issue