Document Web Sessions withdrawal rollout

This commit is contained in:
fy59 2026-09-18 15:29:02 +02:00
parent 4573fe9a42
commit 679ed6184a
4 changed files with 167 additions and 20 deletions

View file

@ -2,6 +2,21 @@
## Unreleased — 0.1.2
- Completed the controlled Web Sessions presentation/withdrawal rollout on the
paired private installation. Desktop migrated from schema v23 to v24 and
Android from v22 to v23 without clearing application data. The requested
validation preparation was withdrawn once; Android reported
`execution_preserved` because its delivery had already started. Two
post-withdrawal direct-MTP generations around component restart proved no
resurrection or duplication while preserving the source proposal and all
actual workout data.
- Fixed a rollout-discovered stale peer-advertisement failure in the
full-generation MTP worker. Each MTP run now requires one successful pull
from the expected phone before validating peer identity and capabilities, so
a retained pre-upgrade advertisement cannot reject a compatible upgraded
Android peer.
- Corrected Web Sessions presentation with one descending cross-type order,
strict civil-date and zoned-timestamp formatting, contextual French states,
readable persisted proposal provenance, and an installation-local versioned

View file

@ -315,7 +315,7 @@ not contain cloud credentials and does not run `rclone`.
## Current status
As of 2026-09-17:
As of 2026-09-18:
- `TRAINLOG_FORMAT_V1=PASS/FROZEN`;
- desktop SQLite schema v24 and Android SQLite schema v23;
@ -334,9 +334,9 @@ As of 2026-09-17:
Analyse, Programmes, and Exercises remain placeholders;
- `TRAINLOG_WEB_V1=CONTRACT_FROZEN / IMPLEMENTATION_STARTED`;
- `TRAINLOG_SYNC_GENERATION_ACK_V1=PASS/FROZEN` through explicit staged
services; automatic synchronization still selects V3. The opt-in grouped Web
path is validated in isolation; the next boundary is
`TRAINLOG_SYNC_DEPLOYMENT_READINESS_V1`, not an authorized deployment.
services; automatic synchronization still selects V3. The trusted local
opt-in path is deployed on the paired private installation and has completed
real direct-MTP restart/replay validation; it is not a public rollout.
The latest executable result belongs in
[current state](docs/current_state.md), not in multiple README narratives.

View file

@ -3,11 +3,13 @@
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.
persistent peer identities. The latest controlled rollout verified real
backups and restoration, desktop schema v23 to v24 and Android schema v22 to
v23 migration, signing-preserving Android replacement, the requested durable
preparation withdrawal, two complete post-withdrawal 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
@ -19,7 +21,7 @@ The rollout packager now keeps the legacy request daemon and one-shot helper in
the same relocatable, hashed bundle as the Web generation coordinator, avoiding
mixed-checkout user-service execution during the controlled rollout.
Snapshot date: **2026-09-17**.
Snapshot date: **2026-09-18**.
`TRAINLOG_CODE_READABILITY_V1` normalizes the recent generation-MTP,
generation/ACK, Android-backup, Web Dashboard serialization, tests, doubles and
@ -240,11 +242,14 @@ preparation** action; withdrawn rows remain technically inspectable but cannot
be edited or delivered.
The controlled deployment preserved the installed Android signing identity and
advanced its private `versionCode` without uninstalling or clearing data. The
validation preparation derived from the six-occurrence proposal remained a
separate pending Android preparation across application and service restart.
Two correlated generation conversations completed without a duplicate,
performed fact, or active-draft replacement.
advanced its private `versionCode` from 13 to 14 without uninstalling or
clearing data. The requested six-occurrence validation preparation was already
`started` on Android at preflight, so withdrawal retained its immutable
delivery and returned `execution_preserved`; it did not delete or complete the
reserved execution. The source proposal retained its identity, `archived`
state, content and publication timestamp. Two correlated post-withdrawal
generation conversations, separated by component restart, completed without
resurrection, duplicate withdrawal, performed fact, or draft mutation.
The Next Session tile no longer treats the frozen Dashboard
`next_session.available` placeholder as a durable inventory. A separate bounded
@ -264,7 +269,9 @@ orders revisions per `run_id`, and rejects stale responses from older runs.
The reciprocal MTP read is bounded to the Android peer advertisement, current
generation reference and consumption ACK, plus the single Android generation
named by that reference. Historical generations and other retained evidence
are neither traversed nor deleted during polling.
are neither traversed nor deleted during polling. Before peer validation, MTP
mode now requires one successful current-device pull; a retained pre-upgrade
advertisement can no longer cause a false missing-capability failure.
## Data semantics
@ -369,10 +376,13 @@ 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 is not automated. The controlled real-device rollout
validated two consecutive full-generation exchanges around a Trainlog-service
restart. The expected AI proposal was verified in the persistent Android store
and the read-only Web proposal projection with its original identity and
content; no proposal-to-execution-draft conversion was performed.
validated two consecutive post-withdrawal full-generation exchanges around a
Trainlog component restart. Android retained exactly one withdrawal result as
`execution_preserved`, retained the linked delivery as `started`, and exposed
no active preparation or start action after replay. Desktop retained exactly
one acknowledged withdrawal and no active preparation. The source AI proposal
was verified with its original identity, state, entry content and publication
timestamp; no proposal-to-execution-draft conversion was performed.
## Active limitations

View file

@ -0,0 +1,122 @@
# Web Sessions presentation and preparation withdrawal V1 evidence
Date: 2026-09-18
This record covers the corrective presentation tranche, the durable
preparation-withdrawal implementation, and its controlled private deployment.
It does not open the Exercises route, publish a release, or change
`TRAINLOG_FORMAT_V1`.
## Delivered behavior
- Preparation merges manual preparations and AI proposals in descending valid
planned-date order, followed by factual sort timestamp, kind and stable
identity. Resume uses Core-owned draft recency; History uses the real session
start instant. Undated or invalidly dated records remain visible after valid
records.
- French civil dates and 24-hour times are the default. A persisted local Web
preference selects ISO dates without entering business SQLite or
synchronization artifacts. Civil dates are never timezone-shifted.
- Contextual French state labels preserve their distinct stored enums.
Proposal provenance comes from the persisted source identity and title; no
title heuristic is used.
- **Delete preparation** performs a revision-guarded, idempotent logical
withdrawal. Desktop schema v24 retains revisions, deliveries and one
immutable withdrawal. `trainlog-session-preparations` V2 transports the
operation; Android schema v23 cancels only pending deliveries and permanently
rejects older delivery replay.
## Controlled deployment
The desktop bundle installed from commit `4573fe9a4240b7ff233da29c1facd5666462659a`
contains one hashed 47-file inventory and coordinated Core, Web, sync daemon,
generation adapter and Python helpers. It was tested outside the checkout with
private HOME/XDG roots before installation. The prior versioned installation
was retained.
The desktop database was backed up consistently at schema v23, passed integrity
and foreign-key checks, and migrated on a copy before the live v24 migration.
All 39 historical tables and 784 rows compared exactly on the migration copy.
The Android `.tlbackup` archive was verified by the production backup service;
restoration of a test-owned copy preserved every historical value while
migrating schema v22 to v23.
The installed Android package advanced from private `versionCode` 13 to 14
with the exact certificate identity already installed. That existing private
identity is an Android Debug certificate despite older deployment prose that
described it as a release identity. A separately built APK with a different
release certificate was retained as evidence and was not installed. No
uninstall, data clear, downgrade or package-identity change occurred.
## Requested real withdrawal
Preflight resolved the exact target by stable identity, not title:
- preparation: `sp_0b6e748d-5acd-4b3a-b17b-90bf513fe3c1`;
- current revision: `spr_6aebc873-5214-4c37-914f-c8ac35aad2d6`;
- delivery: `spd_d0ddf01a-aa9c-4667-9fde-7804afc9c826`;
- source proposal retained: `aid_4b14b098-a567-4631-82af-cfb7dfb7b960`.
The Android delivery had changed since the earlier report: it was already
`started`. The protected Core/API command therefore created exactly one
withdrawal, removed the preparation from active desktop readers, and requested
Android propagation without deleting the delivery or any execution identity.
Android consumed that exact operation as `execution_preserved`. The linked
delivery remained `started`; no completed session exists under its reserved
session identity and no active draft or workout fact was removed.
The first full-generation attempt exposed a retained pre-upgrade peer
advertisement in the desktop transport cache. It failed before generation
consumption. The worker was corrected and regression-tested to require a fresh
successful MTP pull before peer validation. The retained failed run was not
deleted. The retry completed with a correlated Android ACK, and a second full
generation after Web, daemon and application restart also completed with zero
sessions reconciled.
After replay:
- desktop and Android each retain exactly one withdrawal with the same stable
identity and `execution_preserved` result;
- the active Web preparation list is empty and its deep link reports
`withdrawn` with the Android acknowledgement;
- the Android Sessions reader exposes neither the target nor a start action;
- the linked delivery remains `started` and its payload is unchanged;
- workout, draft, execution, proposal and delivery table groups on Android are
byte-for-byte logically unchanged across the second exchange;
- desktop workout, preparation-content and delivery table groups match their
pre-withdrawal digests;
- the source proposal keeps its ID, `archived` state, entries and
`published_at`. The legacy V3 inbox re-copied the same Drive archive and
refreshed only its operational `archived_at` timestamp, as designed by that
existing helper.
No generation, archive, causal proof, old installation or backup was removed.
## Validation evidence
- Web TypeScript typecheck, production build, and 91 tests in 14 files passed.
- Civil-date tests passed under `Pacific/Honolulu` and `Pacific/Kiritimati`.
- The strict GCC Meson suite passed 86/86 tests.
- A strict Clang 22 ASan/UBSan build passed the nine directly affected native
tests, including the C17 public-header syntax check.
- Android debug assembly and unit tests passed: 226 tests, zero failures or
errors, with five optional fixture skips.
- JSON, import-contract and training-knowledge validators passed.
- Firefox exercised the production embedded C server and Core on a synthetic
database, including a real delete click, V2 export, desktop layout, and an
exact 390×844 viewport. The mobile footer overlap discovered by that run was
fixed and the browser test then passed.
- The rollout-specific stale-peer regression and the generation/deployment
suites passed before the corrected package was installed.
## Captures
- [Sessions list, desktop](evidence/web-sessions-list-desktop.png)
- [Preparation editor, 390×844](evidence/web-sessions-editor-mobile.png)
- [Preparation detail, desktop](evidence/web-sessions-detail-desktop.png)
- [Withdrawal confirmation, 390×844](evidence/web-sessions-delete-confirmation-mobile.png)
- [Withdrawn preparation detail, desktop](evidence/web-sessions-withdrawn-detail-desktop.png)
The captures use isolated synthetic data. The real withdrawal evidence is the
correlated persistent desktop/Android state described above; no private device
identifier, peer identifier, user-data payload or signing digest is committed.