docs(sync): document Android conversation ownership
This commit is contained in:
parent
38d304d014
commit
eb6d70fb62
4 changed files with 67 additions and 21 deletions
11
CHANGELOG.md
11
CHANGELOG.md
|
|
@ -4,6 +4,17 @@
|
|||
|
||||
Development opened after the stable v0.1.2 release.
|
||||
|
||||
- Made explicit Android synchronization intent authoritative over automatic
|
||||
background resumption. A process-wide conversation arbiter now yields an
|
||||
older background wait before the foreground publishes its fresh request
|
||||
UUID, and `NEW_EXPLICIT` ignores the request/run that existed before the
|
||||
click. Background USB and Drive workers classify new requests, new
|
||||
correlated remote evidence, legitimate handoff, and stale resumable state;
|
||||
terminal runs are no longer retried every five seconds without new proof.
|
||||
Durable generations are retained across yield and handoff, and desktop
|
||||
request-ID deduplication remains strict. No schema, protocol, causal rule or
|
||||
exchange format changed.
|
||||
|
||||
- Hardened direct-MTP full-generation conversations after a private Android
|
||||
run was frozen before generation capture. Android now emits bounded
|
||||
run/phase metadata, refreshes the user-enabled background listener before a
|
||||
|
|
|
|||
|
|
@ -1077,11 +1077,24 @@ Manifest/reference remain the commit markers; scanning does not change their
|
|||
bytes or protocol meaning. Production logging records only `run_id`, phase,
|
||||
artifact name, generation ID and result.
|
||||
|
||||
When background synchronization is enabled, an explicit UI request refreshes
|
||||
the foreground listener before starting the UI-owned conversation. The shared
|
||||
process lock prevents a second run while the UI coordinator is alive; if the
|
||||
activity is frozen or destroyed, the listener can validate and resume the
|
||||
durable request without inventing another generation.
|
||||
When background synchronization is enabled, an explicit UI request announces
|
||||
foreground ownership before refreshing the foreground listener. Service
|
||||
liveness and conversation ownership are separate: the service may keep the
|
||||
process alive, but it cannot acquire automatic ownership while explicit intent
|
||||
is pending. The process-wide arbiter gives `NEW_EXPLICIT` priority over
|
||||
`RESUME_BACKGROUND`; a background waiter observes cooperative yield, returns a
|
||||
typed superseded result, and releases ownership before the foreground emits a
|
||||
fresh request UUID. The explicit coordinator baselines the existing desktop
|
||||
run and accepts only a different run after that trigger, so it cannot attach
|
||||
the click to a stale `request-v1.json`.
|
||||
|
||||
An interrupted explicit conversation leaves captured/published generations
|
||||
durable. The listener may resume that same run without recapture or a second
|
||||
generation. Automatic actionability separately classifies a new request, new
|
||||
correlated desktop ACK/reference evidence, a legitimate active handoff, and a
|
||||
stale resumable generation. A locally terminal run is suppressed until its
|
||||
run ID changes or its correlated remote evidence advances; mere presence of a
|
||||
resumable generation does not schedule the same run every five seconds.
|
||||
|
||||
The Mensurations grid uses two 140 dp compact fields plus a 10 dp gutter at
|
||||
normal phone widths. The deployed 1080 px/480 dpi phone supplies approximately
|
||||
|
|
|
|||
|
|
@ -7,7 +7,14 @@ basis without rolling back USB. Both transports move the same generation/ACK
|
|||
bytes; neither transports SQLite. Android has an explicitly enabled foreground
|
||||
USB listener with mandatory notification and a private-folder Drive grant with
|
||||
bounded WorkManager checks. Both use the same concurrency-guarded generation
|
||||
coordinator as SyncScreen.
|
||||
coordinator as SyncScreen. That coordinator has one process-wide ownership
|
||||
arbiter: explicit foreground intent has priority over automatic background
|
||||
resumption, while the foreground service may remain alive without owning the
|
||||
conversation. An automatic run yields cooperatively at safe boundaries; its
|
||||
durable generation is retained for a correlated handoff rather than deleted.
|
||||
Background actionability distinguishes a new request or new correlated remote
|
||||
evidence from a merely stale resumable generation, preventing five-second
|
||||
terminal retry loops.
|
||||
|
||||
Direct-MTP publication now has an explicit Android visibility boundary.
|
||||
Durable immutable generation files are submitted to MediaProvider and all scan
|
||||
|
|
@ -20,13 +27,18 @@ individual adapter budget is distinct from the overall conversation deadline,
|
|||
so an absent correlated generation reports a protocol wait timeout while an
|
||||
actually blocked adapter reports `transport_timeout`.
|
||||
|
||||
The failed private run `sy_9639f06e-58ba-4bc0-ab1b-1488aefe011c` received its
|
||||
desktop request and archive-ACK files on the Android filesystem, but created no
|
||||
Android generation row/reference/object. System evidence shows the activity
|
||||
was moved to Android's file-access settings and frozen before capture. The
|
||||
retained Android generation reference and MTP bytes both belonged to an older
|
||||
run; no hidden new generation was found. No causal or business mutation
|
||||
occurred.
|
||||
The resumed private run `sy_9639f06e-58ba-4bc0-ab1b-1488aefe011c` received its
|
||||
desktop request and archive-ACK files, captured generation
|
||||
`gen_532da95e-713f-4163-acc1-d838673c33bf`, and published its immutable objects
|
||||
and reference with manifest SHA-256
|
||||
`170b55ad5bf3e44501fb506107cd26ab807d0179c95a5f1bf73f8251ea1a14e8`.
|
||||
Filesystem and MTP exposed the same bytes. It then waited for a desktop ACK
|
||||
that could not arrive because the daemon correctly refused to create another
|
||||
conversation for the already-consumed request UUID. No causal or business
|
||||
mutation occurred. The remaining defect was Android ownership: an automatic
|
||||
resume could hold the old run while the explicit foreground attempt failed
|
||||
before publishing a fresh request UUID. The arbiter and explicit run baseline
|
||||
now prevent that state.
|
||||
|
||||
Existing preparation rows expose separate editing and Android-delivery states
|
||||
and an accessible send action. Draft/local advances the same preparation to a
|
||||
|
|
|
|||
|
|
@ -1555,14 +1555,24 @@ the measured 312 dp phone content width as two columns, a true 280 dp narrow
|
|||
layout as one column, 1.5 font-scale fallback, long French labels and `kg`/`cm`
|
||||
suffixes.
|
||||
|
||||
Read-only forensics for failed run
|
||||
`sy_9639f06e-58ba-4bc0-ab1b-1488aefe011c` found the correlated desktop request
|
||||
and archive acknowledgements on Android, but no correlated generation
|
||||
reference, immutable directory or error record. The direct filesystem and MTP
|
||||
views contained identical bytes for the retained older Android reference.
|
||||
Logcat showed Android moving Trainlog behind the file-access settings surface
|
||||
and freezing it before capture. The post-v19 backup predates this run and is
|
||||
not presented as SQLite evidence for it.
|
||||
Android conversation-ownership regressions reproduce the production race: an
|
||||
automatic owner waiting on an old resumable run yields to explicit foreground
|
||||
intent, the click publishes a fresh request UUID, the explicit coordinator
|
||||
ignores the pre-click desktop run, and exactly one generation is captured for
|
||||
the new run. Additional fixtures cover typed cancellation and durable handoff,
|
||||
terminal-run suppression across five scheduling cycles, reactivation by new
|
||||
correlated desktop evidence, and exclusive ownership. Desktop routing tests
|
||||
retain the complementary invariant that an already-consumed Android request
|
||||
UUID cannot create a second daemon run.
|
||||
|
||||
The resumed run `sy_9639f06e-58ba-4bc0-ab1b-1488aefe011c` subsequently proved
|
||||
the MTP publication path: Android captured
|
||||
`gen_532da95e-713f-4163-acc1-d838673c33bf`, published the immutable objects and
|
||||
reference, and exposed bytes identical to the filesystem through MTP. It
|
||||
stopped after `generation_reference_published` because no ACK could be created
|
||||
for the daemon-deduplicated old request UUID. This evidence supersedes the
|
||||
earlier pre-resume forensic snapshot without rewriting or deleting the
|
||||
incomplete generation.
|
||||
|
||||
The authorized 2026-09-17 rollout added regression coverage for production
|
||||
failures found only after installation: feedback import under `sqlite3.Row`,
|
||||
|
|
|
|||
Loading…
Reference in a new issue