Inspect frontend recovery implementations and refine operation lifecycles

Assistant: codex
Assistant-Model: gpt-6-astra
Assistant-Session: 01a0cffe-206f-7323-89d3-b20ca4cf4bf9
This commit is contained in:
tegwick 2026-09-25 10:41:59 +02:00
parent 96d11431dc
commit d7b2ea49ce
22 changed files with 1048 additions and 2 deletions

View file

@ -102,3 +102,23 @@ uncertainty or turning the application into a local-authoritative editor.
Next: inspect real frontend recovery implementations and review this case alongside
[VC-02](VC02-OfflineFieldNotes.md). No canonical admission or M1 completion follows
from completing a synthetic narrative.
## Recovery lifecycle clarification — 2026-09-25
Retain the submitted payload in an operation record before clearing or reusing the
composer. This is a logical handoff in this page-session design, not a durability
claim. R01–R05 in the [implementation review](../reviews/FrontendRecoveryImplementations.md)
show why recoverable intent need not stay in the original input box.
For step 9, tag reads with a local request generation. Confirming z advances the
generation and invalidates outstanding reads issued before that acceptance. Such an
old response cannot replace the current observation. A post-acceptance read must
meet a documented read-after-write consistency contract (or provide a comparable
server revision); request generation alone cannot repair stale replicas. Unequal
opaque versions do not reveal which is newer. Without that server contract, show
freshness as unresolved. Preserve newer typing independently of read generations.
Correlate every acknowledgement, server event and error to its original operation.
Once authoritative evidence confirms z, a late transport error cannot regress it to
unknown; a receipt for z cannot clear a new draft or mark a later operation accepted.
A status label such as failed_request is not itself rejection evidence.

View file

@ -61,9 +61,9 @@ ordering: quality/recovery requirements influence step 1, not only step 5.
| 3 | A restarts while offline | Reconstruct a1 and opA from storage | Same local-save and pending-sync states survive restart |
| 4 | B independently commits r0→b1, then uploads | Receiver acknowledges b1; A still has a1 | B has receiver confirmation only; A cannot yet know b1 |
| 5 | A reconnects | Ancestry shows a1 and b1 diverge from r0 | Do not mark divergence semantically resolved |
| 6 | A preserves a1 and selects b1 as active | One recoverable transaction stores conflict K, active b1 and unresolved marker | Conflict needs review; remote selection does not establish remote semantic authority |
| 6 | A preserves a1 and selects b1 as active | One recoverable transaction stores conflict K, active b1, unresolved marker and blocks opA from automatic upload | Conflict needs review; remote selection does not establish remote semantic authority |
| 7 | A restarts again | K and unresolved marker remain | Both versions discoverable, keyboard review available |
| 8 | User reconciles to c1 | Commit c1 with parents a1/b1 and pending opC; retain recovery history | Resolved locally; synchronization still pending |
| 8 | User reconciles to c1 | Commit c1 with parents a1/b1 and pending opC; supersede blocked opA atomically; retain history | Resolved locally; synchronization still pending |
| 9 | Receiver accepts opC, response is lost | c1 may be stored remotely; A still has pending opC | Do not claim failure or global success from timeout alone |
| 10 | A retries opC | Receiver deduplicates and confirms c1; A stores receipt | Synced to receiver at c1; other-device delivery and backup are separate |
@ -124,3 +124,18 @@ justify separate retrieval/use. This is development evidence, not a held-out eva
These are owned by FEP-WP-0002-T02 (specific evidence) and T03 (walkthrough/corpus).
Broad source collection, more self-critique and additional provider calls would not
answer them without selecting an implementation or a comparison protocol.
## Recovery lifecycle clarification — 2026-09-25
opA is a durable pending-upload record with an immutable identity and payload for a1.
Conflict detection blocks its automatic retry; it is not acknowledged as synchronized.
The step 8 transaction marks opA superseded while recording c1 and opC. A delayed
receipt for opA updates only its history, never the current revision or opC status.
The receiver must enforce ancestry/preconditions on delayed submissions too; otherwise
an in-flight opA could overwrite c1 despite local queue retirement. This strengthens
an explicit protocol requirement; it is not an observed Joplin/Obsidian guarantee.
The crash before that transaction leaves opA blocked and the conflict unresolved;
a crash after it leaves opC pending and opA superseded.
See [recovery review](../reviews/RecoveryWalkthroughReview.md). These lifecycle rules
are design corrections, still awaiting implementation and fault-test evidence.