128 lines
7.4 KiB
Markdown
128 lines
7.4 KiB
Markdown
# Full-generation sync rollout readiness
|
|
|
|
## 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 desktop generation path remains disabled unless trusted local configuration
|
|
authorizes a specific persisted Android peer. Android foreground synchronization
|
|
uses its generation coordinator by default; the request artifact is a correlated
|
|
admission signal, not a switch back to standalone V3. Configuration absence on
|
|
desktop preserves the strict V3 compatibility fallback. The Web coordinator owns
|
|
a fixed worker, 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 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 authorizes an unconfigured desktop.
|
|
|
|
### Candidate, backup and recovery
|
|
|
|
1. Build and validate one revision, then run `python3
|
|
tools/package_sync_candidate.py --output <new-private-directory>`. Its
|
|
inventory records hashes, schemas, protocols, entry points and dependencies.
|
|
The relocatable bundle includes `trainlog`, `trainlog-sync-once`,
|
|
`trainlog-syncd`, the production generation MTP adapter and their matching
|
|
Python codecs. User units must point only into one versioned bundle; they
|
|
must not combine a packaged binary with helpers from a live checkout.
|
|
Stable user-bin symlinks are supported: each launcher resolves the link to
|
|
its physical bundle before locating `libexec` and `tools`.
|
|
Packaging validation imports the production orchestrator and peer worker
|
|
from the staged `tools` directory so their complete local module closure is
|
|
present before installation.
|
|
2. `assembleDebug` is development evidence only. Rollout requires the existing
|
|
release signing identity, verification of its public certificate and a valid
|
|
increasing `versionCode`. A bounded `TRAINLOG_ANDROID_VERSION_CODE` build
|
|
override may establish an update-only private rollout chain without changing
|
|
the product version, schema or protocol. The bridge recipe also produces a
|
|
signed release variant for installation; debug APKs remain test evidence.
|
|
3. Quiesce old writers only during an authorized rollout. Desktop backup uses
|
|
`backup_trainlog_sqlite.py` and SQLite's backup API, then integrity and
|
|
foreign-key checks.
|
|
4. V3 is not an Android backup. At the original September 2026 rollout, the
|
|
installed schema-v17 phone required a pinned bridge candidate, verified
|
|
signing/version continuity, and a complete retained user backup before the
|
|
newer Android package. That is historical procedure evidence, not a claim
|
|
about the currently installed phone schema or an instruction to repeat the
|
|
bridge. A new rollout must inspect its actual versions and backups first.
|
|
5. Replacing a binary does not roll back a schema. Before any exchange, a
|
|
mutually compatible captured pair may be restored. After causal writes or
|
|
ACKs, never restore only one peer: stop synchronization, preserve both stores
|
|
and all artifacts, and use an explicit paired recovery plan.
|
|
6. Per-peer retained-generation ceilings are admission gates: the audited
|
|
desktop `sync_generation_exchange.py` permits 16 active outgoing entries;
|
|
Android `SyncGenerationService` permits eight. Exhaustion preserves pending
|
|
generations, tombstones, finalizations and ACK ledgers; it never triggers
|
|
hidden eviction. These counts are not a bound on all transient staging or
|
|
transport objects.
|
|
|
|
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 software-only candidate recorded for the original rollout was rebuilt under the private root
|
|
`/home/fy59/.cache/trainlog/sync-rollout-candidate-v1.NEoMDx` from source commit
|
|
`dd8c91a946a9c836965818d8cc35b8f8bce74658`. Its desktop inventory records every
|
|
packaged file digest plus schemas, protocols, entry points and runtime
|
|
dependencies; the inventory file SHA-256 is
|
|
`800034b409824a68cef45e5251dd4d94f00bd9e13b3387a1a302b8e2e1136839`. The current
|
|
debug APK SHA-256 is
|
|
`aca2f499ee9ff53ba5913a76a2a0117274e3e5545967ce361f6f126a6af497e1`; the
|
|
non-installed bridge APK SHA-256 is
|
|
`0a28d81cbb0818cdf2fee72d5024a4b706fcfda39f1182c682c12f000a026cb4`; and its
|
|
synthetic schema-v17 backup SHA-256 is
|
|
`06eb3999c6f3ce2fd8f551b38727a0a67fe6b48dde4c3244b3d50357afa7e6a3`.
|
|
These are unsigned development evidence, not deployment authorization.
|
|
|
|
## Compatible set for the original rollout
|
|
|
|
- desktop binary containing schema v21, the Web API and the generation worker;
|
|
- `sync_generation_exchange.py` and all matching transaction-neutral codecs;
|
|
- Android schema v20 with `SyncGenerationService`;
|
|
- peers advertising manifest V1, ACK V1, causal deletion V1, history V4 and
|
|
execution draft V1 under their stable `peer_<uuid-v4>` identities;
|
|
- a trusted local orchestrator configuration referencing the packaged peer/MTP
|
|
helper with fixed arguments.
|
|
|
|
## Controlled sequence
|
|
|
|
1. Back up both SQLite stores independently and record their schema versions.
|
|
2. Stop the user services only during the separately authorized deployment.
|
|
3. Install the mutually compatible desktop helper, binary and Android APK.
|
|
4. Migrate synthetic copies first; migration rollback means restoring a backup,
|
|
not merely replacing the binary.
|
|
5. Verify peer identities and advertised capabilities without pairing by name.
|
|
6. Perform one non-destructive foreground Android publication and desktop run.
|
|
7. Verify both manifest digests, both durable ACK records, lineage and readers.
|
|
8. Keep V3 selectable until the controlled full-generation smoke is accepted.
|
|
|
|
## Recovery limits
|
|
|
|
Do not delete an unacknowledged generation, the last acknowledged generation,
|
|
its previous valid generation, or causal evidence. An ACK timeout is unresolved,
|
|
not rollback. Sixteen retained outgoing generations exhaust admission and require
|
|
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.
|
|
|
|
The audited MTP peer worker has a 90-second per-operation budget, further
|
|
limited by the remaining conversation deadline. It is a timeout bound, not a
|
|
success guarantee or proof that an interruption cause has disappeared.
|
|
|
|
The recorded private installation completed physical MTP, service coordination
|
|
and APK/desktop deployment. Actual Drive configuration remains untested; the
|
|
Android eight-generation admission bound and foreground-phone requirement
|
|
remain; the audited desktop limit is 16.
|