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

12
TREE.md
View file

@ -264,11 +264,15 @@ research/plan/ResearchProtocol.md
research/plan/ValidationCases.md research/plan/ValidationCases.md
research/reviews/AuthorityPilot.md research/reviews/AuthorityPilot.md
research/reviews/CarniatoAdmissionRegression.json research/reviews/CarniatoAdmissionRegression.json
research/reviews/FrontendRecoveryImplementations.md
research/reviews/FrontendRecoverySources.json
research/reviews/JoplinConflictScreen.json research/reviews/JoplinConflictScreen.json
research/reviews/LLMConnectPilot.md research/reviews/LLMConnectPilot.md
research/reviews/LocalFirstAdmissionScreen.json research/reviews/LocalFirstAdmissionScreen.json
research/reviews/LocalFirstEvidenceExpansion.md research/reviews/LocalFirstEvidenceExpansion.md
research/reviews/ObsidianConflictScreen.json research/reviews/ObsidianConflictScreen.json
research/reviews/RecoveryReviewMetrics.json
research/reviews/RecoveryWalkthroughReview.md
research/reviews/ResearchOptimization.md research/reviews/ResearchOptimization.md
research/reviews/ResearchPipelineRefinement.md research/reviews/ResearchPipelineRefinement.md
research/reviews/SchemaAndSourcePreparation.md research/reviews/SchemaAndSourcePreparation.md
@ -276,6 +280,14 @@ research/reviews/TransactionalEvidenceExpansion.md
research/reviews/TransactionalLiveReview.yaml research/reviews/TransactionalLiveReview.yaml
research/reviews/TruncationDiagnosis.md research/reviews/TruncationDiagnosis.md
research/reviews/VC01-VC02-Comparison.md research/reviews/VC01-VC02-Comparison.md
research/reviews/recovery-review-01/inputs.json
research/reviews/recovery-review-01/prompt.md
research/reviews/recovery-review-01/receipt.json
research/reviews/recovery-review-01/rejected-response.md
research/reviews/recovery-review-02/inputs.json
research/reviews/recovery-review-02/prompt.md
research/reviews/recovery-review-02/receipt.json
research/reviews/recovery-review-02/response.md
research/walkthroughs/VC01-TransactionalAdministration.md research/walkthroughs/VC01-TransactionalAdministration.md
research/walkthroughs/VC02-OfflineFieldNotes.md research/walkthroughs/VC02-OfflineFieldNotes.md
scripts/research_admission.py scripts/research_admission.py

View file

@ -30,3 +30,5 @@ Execute bounded source investigations with the [research bench](bench/README.md)
Its checked-in fixture verifies the pipeline and is excluded from research evidence. Its checked-in fixture verifies the pipeline and is excluded from research evidence.
Current contrast: [VC-01 server-validated editing](walkthroughs/VC01-TransactionalAdministration.md), [VC-02 offline editing](walkthroughs/VC02-OfflineFieldNotes.md), and [cross-case assessment](reviews/VC01-VC02-Comparison.md). Current contrast: [VC-01 server-validated editing](walkthroughs/VC01-TransactionalAdministration.md), [VC-02 offline editing](walkthroughs/VC02-OfflineFieldNotes.md), and [cross-case assessment](reviews/VC01-VC02-Comparison.md).
Latest implementation evidence: [frontend recovery](reviews/FrontendRecoveryImplementations.md) and [walkthrough correction review](reviews/RecoveryWalkthroughReview.md).

View file

@ -31,3 +31,12 @@ Proposed connection: supports recovery from [Version-Checked Mutation](VersionCh
T01–T05 refer to [TransactionalEvidenceExpansion](../reviews/TransactionalEvidenceExpansion.md). T01–T05 refer to [TransactionalEvidenceExpansion](../reviews/TransactionalEvidenceExpansion.md).
Connections are research proposals, not admitted graph edges. Connections are research proposals, not admitted graph edges.
Reasoning exercise: [VC-01](../walkthroughs/VC01-TransactionalAdministration.md). Reasoning exercise: [VC-01](../walkthroughs/VC01-TransactionalAdministration.md).
## Implementation evidence update — 2026-09-25
[Frontend recovery review](../reviews/FrontendRecoveryImplementations.md) R01/R03
locates Zulip and Element draft storage/restoration at exact commits. These are two
partial known uses of unsent-intent separation, not confirmation of the entire
base/draft/current merge contract. Full-pattern recurrence remains unknown.
A composer may hand submitted content to a separate pending record. Preserve the
recoverable intent across that handoff; do not require the input box to stay filled.

View file

@ -35,3 +35,14 @@ be valid there while remote propagation remains unacknowledged.
T01–T05 refer to [TransactionalEvidenceExpansion](../reviews/TransactionalEvidenceExpansion.md). T01–T05 refer to [TransactionalEvidenceExpansion](../reviews/TransactionalEvidenceExpansion.md).
Connections are research proposals, not admitted graph edges. Connections are research proposals, not admitted graph edges.
Reasoning exercise: [VC-01](../walkthroughs/VC01-TransactionalAdministration.md). Reasoning exercise: [VC-01](../walkthroughs/VC01-TransactionalAdministration.md).
## Implementation evidence update — 2026-09-25
[Frontend recovery review](../reviews/FrontendRecoveryImplementations.md) R02/R04–R06
locates failed-send recovery and echo reconciliation in two frontend families.
These are partial uses, not verified implementations of all four proposed states.
NOT_SENT or failed_request may reflect missing confirmation, not proven rejection.
Correlation IDs, server deduplication and authoritative acceptance require separate
evidence. A later matching authoritative event can resolve uncertainty; stale errors
must not overwrite stronger evidence. Keep hypothesis maturity; assess whether this
is best retained as a shared review model rather than a standalone pattern.

View file

@ -62,3 +62,13 @@ execution evidence and limitations.
2026-09-25: local-first `-06` completed after replacing padded claim tables with 2026-09-25: local-first `-06` completed after replacing padded claim tables with
compact records. Its bounded negative result does not complete full-source review. compact records. Its bounded negative result does not complete full-source review.
Source state remains extracted; recurrence and independent implementations remain open. Source state remains extracted; recurrence and independent implementations remain open.
## Pinned frontend implementations — 2026-09-25
SRC-0013 Zulip, SRC-0014 Element Web, SRC-0015 Matrix JS SDK and SRC-0016 Matrix
client-server specification v1.15 are inspected in the
[frontend recovery review](../reviews/FrontendRecoveryImplementations.md).
The [manifest](../reviews/FrontendRecoverySources.json) records exact revisions,
file URLs and SHA-256 hashes. State: bounded static review; no runtime validation.
Element and its SDK are one implementation family. Complete-pattern recurrence
remains unproven despite two partial draft-preservation uses.

View file

@ -55,3 +55,5 @@ The failed provider runs are execution failures, not negative evidence for the m
## Transactional contrast — 2026-09-25 ## Transactional contrast — 2026-09-25
[VC-01/VC-02 assessment](../reviews/VC01-VC02-Comparison.md) sharpens Q02: local drafts do not imply local authority. Q03 lacks independent frontend uses; Q04 remains unknown despite two complete synthetic narratives. No question is closed by pattern count. [VC-01/VC-02 assessment](../reviews/VC01-VC02-Comparison.md) sharpens Q02: local drafts do not imply local authority. Q03 lacks independent frontend uses; Q04 remains unknown despite two complete synthetic narratives. No question is closed by pattern count.
2026-09-25 follow-up: [pinned frontend code](../reviews/FrontendRecoveryImplementations.md) supports two partial draft-separation uses, but not full-pattern recurrence. [Review attempt](../reviews/RecoveryWalkthroughReview.md) yielded no adopted model fixes; editorial lifecycle corrections do not resolve Q04 usefulness.

View file

@ -0,0 +1,100 @@
# Frontend recovery implementation review
Codex, 2026-09-25. Static source inspection at pinned commits, not runtime or fault
injection. Selection: two independently developed chat frontends with inspectable
draft and retry code. Chat sends broaden evidence for proposal lifecycles; they do
not validate transactional approval, version checking or offline note durability.
Exact file hashes and URLs: [source manifest](FrontendRecoverySources.json).
## Revisions and independence
- SRC-0013 Zulip: `5b06fa3d34f28fa01f459fbf3ba053e3c0858e9c`.
- SRC-0014 Element Web: `60b54fc8446ad1a88963660927cd7e1865905e63`.
- SRC-0015 Matrix JS SDK: `c0cf1015980b48a6f1332701cd731740d3f58272`.
- SRC-0016 [Matrix client-server specification v1.15](https://spec.matrix.org/v1.15/client-server-api/#transaction-identifiers), Transaction identifiers; accessed 2026-09-25.
Element's [package declaration](https://github.com/element-hq/element-web/blob/60b54fc8446ad1a88963660927cd7e1865905e63/apps/web/package.json#L84)
references SDK develop. The separately pinned SDK is an inspected mechanism snapshot,
not a verified lockfile resolution for this Element build. Element and its SDK count
as one implementation family, never two independent uses. No production release or
installed behavior is inferred from repository HEAD.
## Located observations
**R01 — Zulip drafts.** [compose_actions.hide_box](https://github.com/zulip/zulip/blob/5b06fa3d34f28fa01f459fbf3ba053e3c0858e9c/web/src/compose_actions.ts#L90)
saves the draft before hiding composition. [draft storage](https://github.com/zulip/zulip/blob/5b06fa3d34f28fa01f459fbf3ba053e3c0858e9c/web/src/drafts.ts#L207)
writes through its local-storage wrapper; [restore_message](https://github.com/zulip/zulip/blob/5b06fa3d34f28fa01f459fbf3ba053e3c0858e9c/web/src/drafts.ts#L388)
reconstructs compose arguments. This supports separating unsent intent from sent
messages. It does not prove crash durability or base/draft/current merge behavior.
**R02 — Zulip failed send and later evidence.** [resend_message](https://github.com/zulip/zulip/blob/5b06fa3d34f28fa01f459fbf3ba053e3c0858e9c/web/src/echo.ts#L162)
retains content, marks a resend, snapshots the request and submits again. Its
[event handling](https://github.com/zulip/zulip/blob/5b06fa3d34f28fa01f459fbf3ba053e3c0858e9c/web/src/echo.ts#L540) matches local IDs, replaces temporary identity,
and can clear a failure indication when the server event arrives. The
[error path](https://github.com/zulip/zulip/blob/5b06fa3d34f28fa01f459fbf3ba053e3c0858e9c/web/src/echo.ts#L641) sets failed_request; this client flag is not a proof
of server non-commit. [transmit](https://github.com/zulip/zulip/blob/5b06fa3d34f28fa01f459fbf3ba053e3c0858e9c/web/src/transmit.ts#L33) distinguishes acknowledgement
from later event receipt and restarts event polling if an acknowledged event is late.
These paths support asynchronous reconciliation, not a proven server deduplication
contract. No claim that Zulip duplicates messages or guarantees duplicate prevention
follows from these selected files.
**R03 — Element drafts and handoff.** [SendMessageComposer](https://github.com/element-hq/element-web/blob/60b54fc8446ad1a88963660927cd7e1865905e63/apps/web/src/components/views/rooms/SendMessageComposer.tsx#L514)
saves/restores editor state with a room/thread key using localStorage; unmount saves
state. Its [send path](https://github.com/element-hq/element-web/blob/60b54fc8446ad1a88963660927cd7e1865905e63/apps/web/src/components/views/rooms/SendMessageComposer.tsx#L479)
hands content to sendMessage and clears reply context while retry is delegated to
the queued message. Retaining recoverable intent need not mean retaining composer
text. Storage errors, crash windows and complete queue persistence were not tested.
**R04 — Element retry entry.** [Resend](https://github.com/element-hq/element-web/blob/60b54fc8446ad1a88963660927cd7e1865905e63/apps/web/src/Resend.ts#L16) selects NOT_SENT pending
events and passes the existing event to client.resendEvent. Its success branch
announces message_sent; its failure branch logs the failure. This is a real frontend
retry entry, but says nothing by itself about authoritative rejection.
**R05 — SDK identity and transport outcome.** [resendEvent](https://github.com/matrix-org/matrix-js-sdk/blob/c0cf1015980b48a6f1332701cd731740d3f58272/src/client.ts#L2528)
reuses the event and changes its local status. [sendEventHttpRequest](https://github.com/matrix-org/matrix-js-sdk/blob/c0cf1015980b48a6f1332701cd731740d3f58272/src/client.ts#L3120)
uses its existing transaction ID or assigns one, then places it in the ordinary
room-event PUT path. State-event paths differ: do not generalize this ID behavior to
all writes. The [send catch](https://github.com/matrix-org/matrix-js-sdk/blob/c0cf1015980b48a6f1332701cd731740d3f58272/src/client.ts#L3004) sets NOT_SENT after an error;
that label alone cannot distinguish rejection from a lost response.
[Room remote-echo handling](https://github.com/matrix-org/matrix-js-sdk/blob/c0cf1015980b48a6f1332701cd731740d3f58272/src/models/room.ts#L2916) merges the remote event into
the local event and removes transaction tracking. The SDK snapshot supports these
mechanisms, not the end-to-end correctness of a particular deployed client/server.
**R06 — Protocol contract.** Matrix v1.15 specifies that retransmissions with matching
transaction identity and request path should return the original response. Scope is
device and endpoint; a new device changes that scope. This supplies a protocol
basis for ordinary event retries, distinct from local-echo matching. It does not
establish a tested server implementation, indefinite result retention, payload-change
rules for our approval application, or full frontend recovery after restart.
## Synthesis and candidate decisions
Local Draft State has two independent partial code uses (R01/R03) for unsent intent
separation. Neither implements the full base/draft/current contract of VC-01 in the
inspected paths. Keep hypothesis maturity and separate core-mechanism recurrence from
complete-pattern recurrence.
Mutation Outcome Tracking has two partial recovery uses (R02/R04–R05). Neither proves
an explicit four-state model with unknown separated from rejected. Retain it as a
proposed review model for now, not an established implementation taxonomy. Add a
rule: preserve intent through a defined composer-to-pending handoff; classify states
by evidence rather than names in an enum. Idempotency, correlation and acceptance
must each have their own evidence.
No new pattern is needed. Version-Checked Mutation, Local Commit Boundary and offline
reconciliation gain no direct implementation confirmation here. Optimistic display
is visible in the inspected messaging mechanisms, but approval-specific safety and
independent full-pattern review remain missing; its standalone draft stays deferred.
## Review boundary and next experiment
A second-model critique of frozen walkthroughs ran through llm-connect; see
[its editorial disposition](RecoveryWalkthroughReview.md). It is a separate model
opinion, not independent human review, runtime evidence or a controlled usefulness
comparison. All original inputs and outputs are retained.
Next under FEP-WP-0002 T02: choose one exact client/SDK/server combination and replay
acceptance-with-lost-response plus delayed echo, checking operation identity and
content preservation across retry. Under T03: compare blinded, matched baseline and
pattern-guided decisions on new variants with an independent reviewer. The present
self-authored cases cannot establish that names improve decisions.

View file

@ -0,0 +1,83 @@
{
"accessed": "2026-09-25",
"method": "GitHub commit/tree API then raw file reads at pinned commits; static inspection only",
"files": [
{
"repository": "zulip/zulip",
"revision": "5b06fa3d34f28fa01f459fbf3ba053e3c0858e9c",
"path": "web/src/compose.ts",
"sha256": "f0f13db545e2e27a6d38fe3f1e49ee12a289e45f068eadc144a2f21536ff3534",
"url": "https://github.com/zulip/zulip/blob/5b06fa3d34f28fa01f459fbf3ba053e3c0858e9c/web/src/compose.ts#L1"
},
{
"repository": "zulip/zulip",
"revision": "5b06fa3d34f28fa01f459fbf3ba053e3c0858e9c",
"path": "web/src/compose_actions.ts",
"sha256": "a2cd35fd5512f8cca8f7a350ae1f273a91bf4c01a6408ed95e73934ff1e48d22",
"url": "https://github.com/zulip/zulip/blob/5b06fa3d34f28fa01f459fbf3ba053e3c0858e9c/web/src/compose_actions.ts#L1"
},
{
"repository": "zulip/zulip",
"revision": "5b06fa3d34f28fa01f459fbf3ba053e3c0858e9c",
"path": "web/src/drafts.ts",
"sha256": "c1b9b800b5a9f0ee8e1eb8c4db5056709e9588d67b589da7f6469b761bc51dae",
"url": "https://github.com/zulip/zulip/blob/5b06fa3d34f28fa01f459fbf3ba053e3c0858e9c/web/src/drafts.ts#L1"
},
{
"repository": "zulip/zulip",
"revision": "5b06fa3d34f28fa01f459fbf3ba053e3c0858e9c",
"path": "web/src/echo.ts",
"sha256": "2315ef455cd72c5d3584cd98cbcd6c3e641a43040aea627bf99cab655297d7ef",
"url": "https://github.com/zulip/zulip/blob/5b06fa3d34f28fa01f459fbf3ba053e3c0858e9c/web/src/echo.ts#L1"
},
{
"repository": "zulip/zulip",
"revision": "5b06fa3d34f28fa01f459fbf3ba053e3c0858e9c",
"path": "web/src/transmit.ts",
"sha256": "5d4901a4b4c010e6c4449770ba7471532bd199c8f17e987f259ff642c9d406dd",
"url": "https://github.com/zulip/zulip/blob/5b06fa3d34f28fa01f459fbf3ba053e3c0858e9c/web/src/transmit.ts#L1"
},
{
"repository": "element-hq/element-web",
"revision": "60b54fc8446ad1a88963660927cd7e1865905e63",
"path": "apps/web/package.json",
"sha256": "17799c032c71729832f68c024a82c86f5f65e59c57b9dcd31b0d06efc93c1b12",
"url": "https://github.com/element-hq/element-web/blob/60b54fc8446ad1a88963660927cd7e1865905e63/apps/web/package.json#L1"
},
{
"repository": "element-hq/element-web",
"revision": "60b54fc8446ad1a88963660927cd7e1865905e63",
"path": "apps/web/src/Resend.ts",
"sha256": "549928bf6268ace70eac3b0205a0abcd7fd2e95e33b75a7bad8fd53ae342e05a",
"url": "https://github.com/element-hq/element-web/blob/60b54fc8446ad1a88963660927cd7e1865905e63/apps/web/src/Resend.ts#L1"
},
{
"repository": "element-hq/element-web",
"revision": "60b54fc8446ad1a88963660927cd7e1865905e63",
"path": "apps/web/src/components/views/rooms/SendMessageComposer.tsx",
"sha256": "a23bd2620047b2cb964893adf67d23edb290bd9c50a0cba1c76e679702bd0d11",
"url": "https://github.com/element-hq/element-web/blob/60b54fc8446ad1a88963660927cd7e1865905e63/apps/web/src/components/views/rooms/SendMessageComposer.tsx#L1"
},
{
"repository": "matrix-org/matrix-js-sdk",
"revision": "c0cf1015980b48a6f1332701cd731740d3f58272",
"path": "src/client.ts",
"sha256": "dd226544aa6e0e99d39f9c25066be3fab52776bcc08c09d0e3e4c6c7d7206a5d",
"url": "https://github.com/matrix-org/matrix-js-sdk/blob/c0cf1015980b48a6f1332701cd731740d3f58272/src/client.ts#L1"
},
{
"repository": "matrix-org/matrix-js-sdk",
"revision": "c0cf1015980b48a6f1332701cd731740d3f58272",
"path": "src/models/event-status.ts",
"sha256": "b078fba2106c6124a93ff4940c6806af1571583a66a438e244ab558d7a1e7320",
"url": "https://github.com/matrix-org/matrix-js-sdk/blob/c0cf1015980b48a6f1332701cd731740d3f58272/src/models/event-status.ts#L1"
},
{
"repository": "matrix-org/matrix-js-sdk",
"revision": "c0cf1015980b48a6f1332701cd731740d3f58272",
"path": "src/models/room.ts",
"sha256": "aa22abe07579a78cab787d0b498db0248bd9843f64e3bfbc6b50ec615c198867",
"url": "https://github.com/matrix-org/matrix-js-sdk/blob/c0cf1015980b48a6f1332701cd731740d3f58272/src/models/room.ts#L1"
}
]
}

View file

@ -0,0 +1,26 @@
{
"reviewer": "Codex",
"reviewed_at": "2026-09-25",
"model_findings_reviewed": 2,
"model_findings_adopted": 0,
"editorial_corrections": [
"E01",
"E02",
"E03"
],
"disposition": "reject-model-fixes; retain-editorial-revisions",
"runs": [
{
"path": "research/reviews/recovery-review-01",
"receipt_sha256": "fd81e9851aaa213a1d051514acf1c4840f2d8cea6eb99fe72a99285f6112b20c",
"status": "failed"
},
{
"path": "research/reviews/recovery-review-02",
"receipt_sha256": "cf1596f44dd3ffd3fcf7b852bd96e25cb3e913e014c63a8bee6d80a1dfa82e65",
"status": "completed"
}
],
"reported_tokens": 10605,
"independent_human_review": false
}

View file

@ -0,0 +1,55 @@
# Recovery walkthrough review
Codex editorial review, 2026-09-25. Frozen inputs: repository `96d1143`, with
per-file and prompt hashes in the review runs. One separate model was asked to
challenge both cases through llm-connect. This is not independent human review or
an empirical comparison. The revised second prompt explicitly corrected errors in
the first response; this is not a blinded evaluation.
## Execution and disposition
[Attempt 01](recovery-review-01/receipt.json) exceeded its 2,500-token response cap.
The incomplete text is quarantined, never counted as a completed review. It confused
omniscient trace descriptions with client knowledge and treated intended idempotent
replay as problematic. Do not apply its proposed change from a write producing v12
to a write against v12: that changes the scenario incorrectly.
[Attempt 02](recovery-review-02/receipt.json) completed with a stricter prompt limiting
findings and total words. [Full response](recovery-review-02/response.md) is retained.
Across both attempts: two service calls, 10,605 reported tokens. No direct provider
calls, credential retrieval, or unrecorded retries.
1. Reject the proposed VC-01 freshness correction. An obsolete read cannot confirm
that a later write superseded it. Allowing it to update freshness markers would
weaken the intended invariant. Discard here means not applying obsolete data.
2. Reject the proposed VC-02 retry correction as a defect finding. The trace retries
the same immutable opC under an explicit deduplication assumption. Changed payload
would be a different proposal; it must not be smuggled into that retry. A new ID
while the original outcome is unresolved risks an extra transition. The response's
conditional same-payload clause is already covered by the trace's contract.
Two model findings reviewed, zero adopted. Its statement that baseline usefulness
is unknown is retained. This negative result is evidence about this review attempt,
not evidence that the walkthroughs are correct or that model reviews never help.
## Editorial corrections supported by local reasoning
E01: VC-02 steps 6/8 previously left opA's lifecycle unspecified. Block it on detected
conflict, atomically supersede it when opC is queued, and require the receiver to
reject stale delayed operations. Local queue retirement alone cannot stop an in-flight
write. Delayed opA receipts affect history only. These are proposed contracts, not
product guarantees.
E02: VC-01 step 9 lacked an operational rule for discarding obsolete reads. Add local
read generations plus an explicit read-after-write/server-version requirement.
Generation orders local requests, not opaque server revisions or replica freshness.
E03: Add operation-specific evidence handling: a late error cannot reverse confirmed
acceptance, and a previous operation's receipt cannot clear newer typing. Define
composer-to-pending handoff separately from storage durability, motivated by the
[pinned frontend code](FrontendRecoveryImplementations.md).
These are Codex editorial changes, not adopted model findings. They sharpen the
contract but remain synthetic reasoning. No new tests of frontend runtime behavior
were performed. Independent review, usability, crash recovery and full-pattern
recurrence remain open under FEP-WP-0002 T02/T03.

View file

@ -30,3 +30,12 @@ Keep the structure stable for the next cycle. Seek implementation evidence for t
weakest new claim (unknown-outcome recovery), then an independent comparison of both weakest new claim (unknown-outcome recovery), then an independent comparison of both
cases. Rendering/addressing can follow as a bounded new branch after that review; cases. Rendering/addressing can follow as a bounded new branch after that review;
a graph export or broader schema would not resolve the current evidence gaps. a graph export or broader schema would not resolve the current evidence gaps.
## Pinned implementation and recovery follow-up — 2026-09-25
[Zulip/Element inspection](FrontendRecoveryImplementations.md) adds two partial uses
of unsent-intent preservation and asynchronous message reconciliation. They do not
prove the full approval or offline-note designs. [Review disposition](RecoveryWalkthroughReview.md)
records two rejected model findings and three separate editorial lifecycle corrections.
Q03 still needs complete-pattern evidence; Q04 remains unknown. A completed second-model
response does not satisfy independent empirical review.

View file

@ -0,0 +1,8 @@
{
"baseline": "96d11431dc929d4cc2e36862a764f02299dc9607",
"inputs": {
"research/walkthroughs/VC01-TransactionalAdministration.md": "bc46e8e8ba660a56e5151efa9a48f3c5cdf27c8cfad86b82d7d01d9eb661ee8b",
"research/walkthroughs/VC02-OfflineFieldNotes.md": "e24c5881a1d3dc878d993a2ca64589124cfad21633c86ccd92da14a1af3a658c"
},
"prompt_sha256": "84d102beb2ea960d8c3efe894f7b8f77601f26c3b8c2c8ace4638978274633ec"
}

View file

@ -0,0 +1,235 @@
Review these two synthetic architecture walkthroughs adversarially. This is a second-model critique, not independent empirical validation. You have no external sources or runtime. Do not invent evidence. Identify up to four concrete internal omissions or inconsistent state transitions, especially stale acknowledgements, operation lifecycle, and retries. Compare the named design with its plain narrative baseline: say unknown if usefulness cannot be established. Give exact section/step locators, a proposed correction, and which assumption makes each finding conditional. Do not use tables. Do not claim admission or tests passed.
--- research/walkthroughs/VC01-TransactionalAdministration.md ---
# VC-01 — Transactional administration
Status: synthetic draft, self-reviewed by Codex 2026-09-25. Baseline repository:
`cfa249a`. No application runtime or empirical usability result. Evidence references
T01–T05 resolve in [the source review](../reviews/TransactionalEvidenceExpansion.md).
## Fixed brief and explicit assumptions
Shared records, server-validated writes, concurrent edits, deep links, keyboard
operation and recoverable failed requests. Example: edit a shared approval record.
Only server acceptance can change its authoritative approval status.
Additional design assumptions, not properties proven by the sources: each read has
an opaque version; the server atomically checks version, authorization and business
rules with the write. Each submitted attempt has an operation ID scoped to principal
and record, bound to its payload, with a durable result lookup and deduplication
retention covering the agreed recovery period. A modified proposal gets a new ID.
These backend capabilities must be verified before implementation. T03 motivates
bounded retry identity but does not establish this whole protocol.
Drafts survive failed requests while the page remains open. Restart survival is not
required by this brief; adding it requires a separate persistence/privacy decision.
Record identity appears in the deep link; version and draft are separate state.
Authorization is checked on every write and on result access. Sensitive draft data
is not placed in URLs. No numerical latency target is assumed.
## Baseline without pattern labels
Load a record and its version. Keep edits apart from received data. Submit the edits
with the version they were based on. Keep them if validation fails. If someone else
changed the record, show the current record beside the proposal and ask the user to
review it. If the response disappears, investigate that operation before sending a
new one. Refresh affected views after acceptance without overwriting newer typing.
## Ordered decisions and resulting contexts
1. Establish server authority over approved records. Local typing gives feedback but
cannot approve a record. Offline acceptance is outside this case.
2. Use [Local Draft State](../candidates/LocalDraftState.md) to preserve user intent
independently of refreshed observations. This creates a base/draft/current comparison.
3. Use [Version-Checked Mutation](../candidates/VersionCheckedMutation.md) for the
conditional write (T01). Blind overwrite risks lost edits; GitLab's error ambiguity
(T02) demonstrates why adapters must preserve actual endpoint semantics.
4. Use [Mutation Outcome Tracking](../candidates/MutationOutcomeTracking.md) to keep
transport state separate from acceptance. A timeout is unknown, not rejection.
Retry only under the operation contract; a disabled button alone cannot deduplicate.
5. Use [Invalidate and Reproject](../candidates/InvalidateAndReproject.md) to refresh
affected observations after acceptance. Keep drafts intact and reject obsolete
responses. T04 shows why browser cancellation cannot enforce server ordering.
6. Defer optimistic approval display. Immediate input and pending feedback suffice;
T05's optimistic example does not justify claiming approval before validation.
## Failure and recovery trace
| Step | Observed state and action | Required invariant |
| --- | --- | --- |
| 1 | A and B read record R at v10; A types draft dA | Typing changes neither server record nor approval |
| 2 | B's valid conditional command commits v11 | Server atomically validates and advances version |
| 3 | A submits operation x against v10; explicit stale-version rejection arrives | dA remains; mark x rejected, not accepted |
| 4 | Read v11; user compares base v10, dA and v11, then proposes dA2 | No blind automatic resend that erases B's intent |
| 5 | Operation y against v11 fails a business rule before commit | Preserve dA2; explain the actual field/domain error |
| 6 | User corrects it; new operation z succeeds at v12 but response is lost | Mark z unknown; do not show approval as confirmed |
| 7 | Lookup z or replay the identical z within the deduplication contract | Resolve its stored result without a second transition |
| 8 | Accepted z identifies v12; refresh detail and relevant list | Acceptance and freshness remain separate facts |
| 9 | A late read of v11 arrives after v12; user has also started another draft | Discard obsolete observation; preserve new draft |
Opaque versions are compared for equality or through a documented server ordering
contract, never sorted numerically by a generic client. The v10/v11/v12 labels above
are explanatory sequence labels. If another actor changes the record after z, a
read alone cannot establish whether z committed: use operation-specific evidence.
If retention expires before z can be resolved, stop automatic resubmission and show
an unresolved outcome with a reconciliation path. Never infer rejection from a 500,
timeout or browser cancellation alone. If refreshed data cannot be obtained, show
accepted-with-stale-view rather than converting acceptance into a failed mutation.
Quality acceptance proposals: keyboard access to comparison, correction and retry;
text status that does not rely on color; an announced outcome and an error summary
linked to fields; stable focus when a refresh arrives; no silent draft replacement.
Revoked access yields an authorization outcome and prevents further submissions;
retention/export of sensitive drafts follows the product's explicit access policy.
These are requirements for later implementation review, not accessibility certification.
## Change exactly one constraint
Replace concurrent editors with a single authorized writer; all other requirements
remain. The competing-editor branch is omitted. Server validation, draft retention,
unknown-outcome recovery and refresh remain necessary. Multiple in-flight attempts
from that one writer can still race, so version checks are not automatically removed.
This branch weakens one motivation for version checking without erasing transport
uncertainty or turning the application into a local-authoritative editor.
## Self-review
| Criterion | Assessment | Reason |
| --- | --- | --- |
| Traceability | pass for reasoning | Each source claim is separated from proposed backend/UI contracts |
| Coherence | revise | Operation lookup, retention and atomic validation still need implementation evidence |
| Decision usefulness | unknown | Labels organize obligations; baseline reaches the same design; no independent comparison |
| Quality coverage | revise | Keyboard/privacy criteria specified but not exercised |
| Changed constraint | pass for reasoning | One writer removes cross-user conflict while preserving other failures |
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.
--- research/walkthroughs/VC02-OfflineFieldNotes.md ---
# VC-02 — Offline field notes, restart and reconnect
Status: drafted and editorially self-reviewed, 2026-09-25, codex.
Synthetic reasoning exercise; no application or storage engine was fault-tested.
Evidence baseline: repository `ad6f8fa`; candidate additions in this change.
No canonical pattern admission or M1 completion is implied.
## Fixed brief and assumptions
Preserve VC-02: create/edit offline; restart without losing acknowledged work; later
multi-device sync; conflicting edits possible. Additional assumptions for this exercise:
- Two authorized devices edit plain-text notes. Both start with note N, revision r0.
- A completed local storage transaction survives ordinary process restart. The engine
and flush policy are undecided; power-loss survival is explicitly not established.
- Stable document and operation identities plus revision ancestry detect divergent
changes. Wall-clock timestamps alone are not assumed sufficient.
- The sync receiver deduplicates operation IDs and acknowledges a specific revision.
Acknowledgement means this receiver accepted it, not that all devices have converged.
- Delete/edit conflicts, attachments and concurrent authorization changes are outside
this first trace. They remain gaps, not silently solved cases.
- UI must support keyboard use, non-color status and focus-preserving conflict review.
Sensitive note/conflict copies have equal access protection; content is excluded
from telemetry. Threat model, device encryption and key recovery remain open.
- Interaction feedback should remain responsive offline; local commit and replication
latency are measured separately. No invented numerical performance target.
## Baseline narrative without the catalog
Save notes and pending uploads in a local transaction. Show unsaved versus locally
saved status, upload on reconnection, and retain remote acknowledgements. When the
same base revision has diverged, preserve both versions, expose the discrepancy and
let the user merge. Save and synchronize the result. Back up data separately.
This baseline already expresses a plausible architecture. Pattern names must improve
review of boundaries and missing guarantees; they do not get credit merely for naming it.
## Decisions and provisional connections
| Order | Context and forces | Candidate and decision | Alternative rejected for this brief | Resulting context / evidence |
| --- | --- | --- | --- | --- |
| 1 | Offline availability vs recoverability | [Local Commit Boundary](../candidates/LocalCommitBoundary.md): acknowledge only after document plus pending intent commit | Server-only acknowledgement prevents offline save; memory-only save fails restart | Local saved state exists independently of sync; E01/E04 motivate this, atomicity is an assumption |
| 2 | Freshness vs intermittent network | [Pending Synchronization](../candidates/PendingSynchronization.md): retain identity, retry and confirm a specific revision | Fire-and-forget upload loses uncertainty on restart | Durable pending work; E05/E06 motivate separation, exact protocol is proposed |
| 3 | Divergent intent vs continued work | [Conflict Copy](../candidates/ConflictCopy.md): preserve alternate content and mark unresolved before selecting active content | Blind replacement discards an edit; assumed universal automatic merge lacks evidence | Two recoverable versions; E07/E08 document uses, crash-safe sequence is proposed |
| 4 | User control vs reconciliation effort | [Explicit Reconciliation](../candidates/ExplicitReconciliation.md): compare, commit a new revision and queue it | A conflict file alone does not establish user awareness or resolution | New decision can synchronize; E07/E08 support manual comparison, UI contract unverified |
| 5 | Device loss vs operational burden | Require separately recoverable backup and restoration procedure | Calling synchronization a backup does not meet the recovery goal | External recovery obligation; E11, not a newly invented pattern |
E references resolve in [the evidence review](../reviews/LocalFirstEvidenceExpansion.md).
Relations are provisional: local commit enables pending propagation; divergence may
create context for a conflict copy; preserved divergence enables explicit review;
review creates a new local commit. These are not admitted graph edges or a universal
ordering: quality/recovery requirements influence step 1, not only step 5.
## Restart/reconnect trace
| Step | Event | Local and remote state | User-visible statement / required invariant |
| --- | --- | --- | --- |
| 0 | A and B share r0 | Receiver has r0 | No pending edits under these assumptions |
| 1 | Offline A edits r0→a1 | Editor holds new text; transaction pending | Editing feedback, still unsaved; no persistence claim |
| 2 | A commits a1 + operation opA atomically | A has a1 and pending opA | Saved on this device; not yet synchronized |
| 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 |
| 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 |
| 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 |
A deterministic conflict identity derived from document and revision pair is one
proposed way to avoid multiplying copies on retry. The trace assumes that mechanism;
it is not verified product behavior. A crash before step 2 commit can lose unacknowledged
input; a crash within step 6 must leave either the previous state or the full conflict
state. A partial state would violate the chosen transaction contract and fail the design.
## Change one constraint
Change only concurrency: B may read, but only A may edit this note. Keep offline,
restart, sync, privacy and accessibility requirements fixed.
Steps 1–3 and 9–10 remain necessary. Under the single-writer assumption, steps 4–8
for concurrent edits are unnecessary: omit conflict-copy and reconciliation machinery
for that case. Stable IDs and retry handling remain. Do not claim conflicts impossible
if external editors, restoration or another writer later violate the assumption.
This branch shows that Conflict Copy is conditional, not a prerequisite of local storage.
## Failure and recovery boundaries
- Full disk or denied write: keep unsaved status and actionable error; never acknowledge.
- Missing local transaction guarantee: stop adoption until the storage contract is tested.
- Lost sync acknowledgement: preserve operation identity; duplicate requests must not
duplicate the edit. Network recovery alone does not prove this behavior.
- Revoked access: surface blocked synchronization, preserve local work according to
the agreed security policy; do not retry forever or invent offline authorization.
- Conflict notification failure: retained bytes do not satisfy discoverability.
- Device loss/corruption: conflict copies on that device are insufficient; restore from
separately retained data. Recovery point and key availability remain undecided.
## Editorial self-review
| Criterion | Outcome | Reason |
| --- | --- | --- |
| Traceability | pass for bounded reasoning | Documentary claims have E references; proposed transactions/protocols are labeled assumptions |
| Coherence | revise | Trace is consistent under stated assumptions; actual storage and idempotency contracts are unverified |
| Decision usefulness beyond baseline | unknown | Explicit boundary names expose review questions, but the baseline already contains the architecture; no independent comparison |
| Quality constraints | revise | Accessibility, privacy, errors and recovery enter initial decisions; acceptance tests and threat model are still missing |
| Changed-constraint branch | pass for synthetic reasoning | Removing concurrent writers removes two responsibilities while retaining persistence and propagation |
Disposition: retain four connected research drafts; no canonical promotion. Consider
merging Explicit Reconciliation into Conflict Copy if a second walkthrough cannot
justify separate retrieval/use. This is development evidence, not a held-out evaluation.
## Questions that justify the next research work
1. Which storage transaction/acknowledgement contract survives the required restart
modes? Obtain documentation plus a small crash test for a selected implementation.
2. What receiver protocol makes retries and divergent revision detection safe? Locate
an implementation and test lost acknowledgements before claiming correctness.
3. Can a user find, compare and resolve conflicts with keyboard/screen-reader use?
Define and exercise an accessibility acceptance scenario.
4. What changes in VC-01 when a local edit must satisfy a global transaction rule?
Perform that contrasting walkthrough before treating these connections as general.
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.

View file

@ -0,0 +1,56 @@
{
"kind": "second-model-walkthrough-critique",
"empirical_validation": false,
"service_requests_attempted": 1,
"endpoint": "http://127.0.0.1:18081",
"config": {
"model_name": "custodian-triage-balanced",
"temperature": 0.2,
"max_tokens": 2500,
"model_params": {},
"max_depth": 3,
"skip_if_exists": true,
"timeout_seconds": 300
},
"adapter_sha256": "1dade65e456ab7b85d17c2c4c9a6e9ecef245104177a8cad815a685d2c7cf427",
"status": "failed",
"error_type": "ValueError",
"responses": [
{
"stage": "walkthrough-review",
"model": "google/gemini-2.5-flash",
"usage": {
"prompt_tokens": 3646,
"completion_tokens": 2500,
"total_tokens": 6146
},
"finish_reason": "length",
"provider": "openrouter",
"response_id": "gen-1790325508-sl1YfS0T5xCXJ2SjGhjM",
"latency_seconds": 15.14,
"profile": "custodian-triage-balanced",
"profile_model": "google/gemini-2.5-flash",
"profile_provider": "openrouter",
"diagnostics": {
"available": true,
"effective_settings": {
"temperature": 0.2,
"max_tokens": 2500,
"reasoning_effort_present": false,
"reasoning_present": false
},
"provider_usage": {
"prompt_tokens": 3646,
"completion_tokens": 2500,
"total_tokens": 6146,
"cost": 0.0073438,
"completion_tokens_details": {
"reasoning_tokens": 0
}
}
},
"content_characters": 11015,
"content_sha256": "db53f22493233903d65bc42663354e87bd3b8e2fcfe880d706014c43ffb793d0"
}
]
}

View file

@ -0,0 +1,56 @@
Here's an adversarial review of the two synthetic architecture walkthroughs, focusing on internal omissions, inconsistent state transitions, stale acknowledgements, operation lifecycle, and retries.
---
## Review of VC-01 — Transactional administration
**Overall Assessment:** The document clearly articulates a complex problem space and attempts to map it to named patterns. However, it struggles with the practical implications of operation lifecycle and the precise state transitions, particularly around acknowledgements and retries. The "unknown" usefulness of named patterns compared to the baseline is a significant self-critique.
### Internal Omissions/Inconsistent State Transitions:
1. **Stale Acknowledgement/Operation Lifecycle Inconsistency (Step 6 & 7):**
* **Locator:** "Step 6: User corrects it; new operation z succeeds at v12 but response is lost" and "Step 7: Lookup z or replay the identical z within the deduplication contract".
* **Omission/Inconsistency:** Step 6 states `z succeeds at v12` but `response is lost`. Step 7 then suggests `Lookup z or replay the identical z`. If `z succeeds at v12`, the server has already processed and committed the change. A "replay" of an *identical* `z` (implying the same operation ID and payload) should be deduplicated by the server, not re-executed. The narrative implies the client *doesn't know* if it succeeded, which contradicts "succeeds at v12". The state `Mark z unknown; do not show approval as confirmed` is correct for the client's perspective, but the server's state is definitively "succeeded". The transition from client `unknown` to server `succeeded` is not fully reconciled with the client's subsequent actions. The "replay" option is problematic if the server already committed.
* **Proposed Correction:** Step 6 should state "new operation z is sent against v12, but its response is lost, leaving the client's state for z as unknown." Step 7 should then clarify: "Client attempts to resolve the unknown state of z by querying its status (lookup) or, if lookup is unavailable/unsuccessful, resending the *same operation ID and payload* (replay), relying on server-side deduplication." This clarifies the client's uncertainty and the server's idempotent handling.
* **Conditional Assumption:** This finding is conditional on the "deduplication contract" (mentioned in the "Additional design assumptions") being robust and preventing re-execution of already successful operations. If "replay" implies a *new* operation ID for the same logical intent, then the "identical z" phrasing is misleading.
2. **Stale Acknowledgement/Operation Lifecycle Inconsistency (Step 8 & 9):**
* **Locator:** "Step 8: Accepted z identifies v12; refresh detail and relevant list" and "Step 9: A late read of v11 arrives after v12; user has also started another draft".
* **Omission/Inconsistency:** Step 8 states `Accepted z identifies v12`. This implies the client has now confirmed `z`'s success and the record is at `v12`. Step 9 then describes `A late read of v11 arrives after v12`. This is a stale read. While the `Required invariant` correctly states `Discard obsolete observation; preserve new draft`, the walkthrough doesn't explicitly state *how* the client determines `v11` is obsolete relative to `v12` *after* `z` has been accepted. The "opaque versions are compared for equality or through a documented server ordering contract" is mentioned in the prose, but the trace doesn't show this comparison happening or the mechanism for it. The client's state after step 8 should include knowledge of `v12` as the current authoritative version.
* **Proposed Correction:** After Step 8, explicitly state that the client updates its known authoritative version to `v12`. In Step 9, the `Required invariant` should be expanded to: "Discard obsolete observation (v11 is older than known authoritative v12); preserve new draft." This makes the comparison explicit within the trace.
* **Conditional Assumption:** This finding is conditional on the client reliably tracking the *latest known authoritative version* of the record, not just the version it last successfully wrote against.
3. **Operation Lifecycle/Retries (Implicit in "Change exactly one constraint" section):**
* **Locator:** "Change exactly one constraint" section, specifically "Multiple in-flight attempts from that one writer can still race, so version checks are not automatically removed."
* **Omission/Inconsistency:** The document correctly identifies that even with a single writer, multiple in-flight attempts can race. However, the initial "Baseline without pattern labels" and "Ordered decisions" sections, particularly "Mutation Outcome Tracking," don't fully elaborate on the client-side handling of *multiple in-flight operations from the same user on the same record*. If a user rapidly clicks "save" multiple times, or a retry mechanism is aggressive, how does the client manage the operation IDs and potential race conditions between its *own* operations? The trace focuses on *different* users or *lost responses* for a single operation.
* **Proposed Correction:** Add a step to the "Failure and recovery trace" or a specific note in "Mutation Outcome Tracking" addressing the scenario of a single user initiating multiple distinct (or logically identical but separately submitted) operations on the same record before the first one resolves. This would clarify how operation IDs are generated/managed in this scenario and how the client prevents its own operations from racing or overwriting each other's pending state.
* **Conditional Assumption:** This finding is conditional on the application allowing multiple concurrent submissions from a single user for the same record (e.g., rapid clicks, or background retries of different logical operations). If the UI strictly serializes all user-initiated operations, this is less critical.
### Named Design vs. Plain Narrative Baseline:
* **Decision usefulness:** The self-review states "unknown" for "Decision usefulness" because "Labels organize obligations; baseline reaches the same design; no independent comparison." This is a fair assessment. The named patterns (Local Draft State, Version-Checked Mutation, Mutation Outcome Tracking, Invalidate and Reproject, Defer optimistic approval display) *do* provide a structured vocabulary for discussing the design elements. However, the walkthrough itself doesn't demonstrate a scenario where the named patterns *clarify* or *prevent* an issue that the baseline narrative would miss. They primarily serve as organizational labels for concepts already present in the baseline. Their utility for *improving* the design or *identifying gaps* beyond what a careful reading of the baseline would achieve is not established within this document.
---
## Review of VC-02 — Offline field notes, restart and reconnect
**Overall Assessment:** This walkthrough is more detailed in its state transitions and explicitly addresses restart scenarios, which is a strength. However, it still exhibits some ambiguity around the precise lifecycle of operations and the client's knowledge state, particularly concerning acknowledgements and the "deduplication contract."
### Internal Omissions/Inconsistent State Transitions:
1. **Operation Lifecycle/Acknowledgement Inconsistency (Step 2 & 3):**
* **Locator:** "Step 2: A commits a1 + operation opA atomically" and "Step 3: A restarts while offline".
* **Omission/Inconsistency:** Step 2 states "A commits a1 + operation opA atomically" and the invariant is "Saved on this device; not yet synchronized." Step 3 states "Reconstruct a1 and opA from storage." This implies `opA` is a *pending* operation. However, the term "operation opA atomically" could be interpreted as `opA` being the *result* of the commit, or the *intent* to sync. If `opA` is merely the *intent* to sync `a1`, then it's clear. But if `opA` is meant to be the *specific operation ID* that will be sent to the server, then the client is generating this ID *before* network interaction. This is fine, but the lifecycle of `opA` as a pending item needs to be clearer. Is `opA` the *request* or the *record of the request*?
* **Proposed Correction:** Clarify that `opA` refers to the *record of the pending synchronization request* for `a1`, which includes a unique operation ID generated locally. This makes its reconstruction in Step 3 more explicit as a pending task.
* **Conditional Assumption:** This finding is conditional on the interpretation of "operation opA" as the specific network request rather than a general concept of "an operation." The "Pending Synchronization" candidate implies it's a durable record of the intent.
2. **Stale Acknowledgement/Operation Lifecycle (Step 9 & 10):**
* **Locator:** "Step 9: Receiver accepts opC, response is lost" and "Step 10: A retries opC".
* **Omission/Inconsistency:** Similar to VC-01, Step 9 states "Receiver accepts opC" but "response is lost." The client's state is `A still has pending opC`. Step 10 then says "A retries opC." If the receiver *accepted* `opC`, then `opC` has already been processed and committed on the server. A "retry" of `opC` (implying the same operation ID) should be deduplicated. The trace correctly states "Receiver deduplicates and confirms c1," but the client's action of "retries opC" is slightly ambiguous. It should be "A attempts to resolve the status of opC (e.g., by re-sending the same operation ID or querying its status)." The current phrasing could imply a new execution attempt if not for the deduplication.
* **Proposed Correction:** In Step 10, rephrase "A retries opC" to "A attempts to resolve the status of opC (e.g., by re-sending the identical opC with its original ID, relying on deduplication)." This reinforces the idempotent nature of the operation and the client's uncertainty.
* **Conditional Assumption:** This finding is conditional on the "deduplication contract" (mentioned in the "Fixed brief and assumptions") being robust and preventing re-execution of already successful operations.
3. **Inconsistent State Transition/Operation Lifecycle (Conflict Resolution):**
* **Locator:** "Step 6: A preserves a1 and selects b1 as active" and "Step 8: User reconciles to c1".
* **Omission/Inconsistency:** In Step 6, `A preserves a1 and selects b1 as active`. The invariant is `Conflict needs review; remote selection does not establish remote semantic authority`. This implies `b1` is now the *working copy* for the user, but `a1` is preserved as a conflict. Step 8 states `User reconciles to c1`. This implies the user *edited* `b1` (or `a1` or both) to produce `c1`. However, the trace doesn't explicitly show the state transition from `b1` being active to `c1` being the result of a user edit. It jumps from `b1` being active to `c1` being committed.
* **Proposed Correction:** Insert an intermediate

View file

@ -0,0 +1,8 @@
{
"baseline": "96d11431dc929d4cc2e36862a764f02299dc9607",
"inputs": {
"research/walkthroughs/VC01-TransactionalAdministration.md": "bc46e8e8ba660a56e5151efa9a48f3c5cdf27c8cfad86b82d7d01d9eb661ee8b",
"research/walkthroughs/VC02-OfflineFieldNotes.md": "e24c5881a1d3dc878d993a2ca64589124cfad21633c86ccd92da14a1af3a658c"
},
"prompt_sha256": "bf3cff209bc49e318e63c532ed2c0eee7bc185c9294ae7075f4ac5e47dbe8da7"
}

View file

@ -0,0 +1,236 @@
STRICT OUTPUT BOUND: at most 400 words total; at most TWO findings across BOTH cases combined. Do not repeat the walkthrough. State locator, concrete defect, minimal fix. A trace may describe server truth unknown to the client; that is not a contradiction. Reusing an operation identity under the stated deduplication contract is intentional. Do not propose numeric ordering for opaque versions. End with one sentence about baseline usefulness.
Review these two synthetic architecture walkthroughs adversarially. This is a second-model critique, not independent empirical validation. You have no external sources or runtime. Do not invent evidence. Identify up to four concrete internal omissions or inconsistent state transitions, especially stale acknowledgements, operation lifecycle, and retries. Compare the named design with its plain narrative baseline: say unknown if usefulness cannot be established. Give exact section/step locators, a proposed correction, and which assumption makes each finding conditional. Do not use tables. Do not claim admission or tests passed.
--- research/walkthroughs/VC01-TransactionalAdministration.md ---
# VC-01 — Transactional administration
Status: synthetic draft, self-reviewed by Codex 2026-09-25. Baseline repository:
`cfa249a`. No application runtime or empirical usability result. Evidence references
T01–T05 resolve in [the source review](../reviews/TransactionalEvidenceExpansion.md).
## Fixed brief and explicit assumptions
Shared records, server-validated writes, concurrent edits, deep links, keyboard
operation and recoverable failed requests. Example: edit a shared approval record.
Only server acceptance can change its authoritative approval status.
Additional design assumptions, not properties proven by the sources: each read has
an opaque version; the server atomically checks version, authorization and business
rules with the write. Each submitted attempt has an operation ID scoped to principal
and record, bound to its payload, with a durable result lookup and deduplication
retention covering the agreed recovery period. A modified proposal gets a new ID.
These backend capabilities must be verified before implementation. T03 motivates
bounded retry identity but does not establish this whole protocol.
Drafts survive failed requests while the page remains open. Restart survival is not
required by this brief; adding it requires a separate persistence/privacy decision.
Record identity appears in the deep link; version and draft are separate state.
Authorization is checked on every write and on result access. Sensitive draft data
is not placed in URLs. No numerical latency target is assumed.
## Baseline without pattern labels
Load a record and its version. Keep edits apart from received data. Submit the edits
with the version they were based on. Keep them if validation fails. If someone else
changed the record, show the current record beside the proposal and ask the user to
review it. If the response disappears, investigate that operation before sending a
new one. Refresh affected views after acceptance without overwriting newer typing.
## Ordered decisions and resulting contexts
1. Establish server authority over approved records. Local typing gives feedback but
cannot approve a record. Offline acceptance is outside this case.
2. Use [Local Draft State](../candidates/LocalDraftState.md) to preserve user intent
independently of refreshed observations. This creates a base/draft/current comparison.
3. Use [Version-Checked Mutation](../candidates/VersionCheckedMutation.md) for the
conditional write (T01). Blind overwrite risks lost edits; GitLab's error ambiguity
(T02) demonstrates why adapters must preserve actual endpoint semantics.
4. Use [Mutation Outcome Tracking](../candidates/MutationOutcomeTracking.md) to keep
transport state separate from acceptance. A timeout is unknown, not rejection.
Retry only under the operation contract; a disabled button alone cannot deduplicate.
5. Use [Invalidate and Reproject](../candidates/InvalidateAndReproject.md) to refresh
affected observations after acceptance. Keep drafts intact and reject obsolete
responses. T04 shows why browser cancellation cannot enforce server ordering.
6. Defer optimistic approval display. Immediate input and pending feedback suffice;
T05's optimistic example does not justify claiming approval before validation.
## Failure and recovery trace
| Step | Observed state and action | Required invariant |
| --- | --- | --- |
| 1 | A and B read record R at v10; A types draft dA | Typing changes neither server record nor approval |
| 2 | B's valid conditional command commits v11 | Server atomically validates and advances version |
| 3 | A submits operation x against v10; explicit stale-version rejection arrives | dA remains; mark x rejected, not accepted |
| 4 | Read v11; user compares base v10, dA and v11, then proposes dA2 | No blind automatic resend that erases B's intent |
| 5 | Operation y against v11 fails a business rule before commit | Preserve dA2; explain the actual field/domain error |
| 6 | User corrects it; new operation z succeeds at v12 but response is lost | Mark z unknown; do not show approval as confirmed |
| 7 | Lookup z or replay the identical z within the deduplication contract | Resolve its stored result without a second transition |
| 8 | Accepted z identifies v12; refresh detail and relevant list | Acceptance and freshness remain separate facts |
| 9 | A late read of v11 arrives after v12; user has also started another draft | Discard obsolete observation; preserve new draft |
Opaque versions are compared for equality or through a documented server ordering
contract, never sorted numerically by a generic client. The v10/v11/v12 labels above
are explanatory sequence labels. If another actor changes the record after z, a
read alone cannot establish whether z committed: use operation-specific evidence.
If retention expires before z can be resolved, stop automatic resubmission and show
an unresolved outcome with a reconciliation path. Never infer rejection from a 500,
timeout or browser cancellation alone. If refreshed data cannot be obtained, show
accepted-with-stale-view rather than converting acceptance into a failed mutation.
Quality acceptance proposals: keyboard access to comparison, correction and retry;
text status that does not rely on color; an announced outcome and an error summary
linked to fields; stable focus when a refresh arrives; no silent draft replacement.
Revoked access yields an authorization outcome and prevents further submissions;
retention/export of sensitive drafts follows the product's explicit access policy.
These are requirements for later implementation review, not accessibility certification.
## Change exactly one constraint
Replace concurrent editors with a single authorized writer; all other requirements
remain. The competing-editor branch is omitted. Server validation, draft retention,
unknown-outcome recovery and refresh remain necessary. Multiple in-flight attempts
from that one writer can still race, so version checks are not automatically removed.
This branch weakens one motivation for version checking without erasing transport
uncertainty or turning the application into a local-authoritative editor.
## Self-review
| Criterion | Assessment | Reason |
| --- | --- | --- |
| Traceability | pass for reasoning | Each source claim is separated from proposed backend/UI contracts |
| Coherence | revise | Operation lookup, retention and atomic validation still need implementation evidence |
| Decision usefulness | unknown | Labels organize obligations; baseline reaches the same design; no independent comparison |
| Quality coverage | revise | Keyboard/privacy criteria specified but not exercised |
| Changed constraint | pass for reasoning | One writer removes cross-user conflict while preserving other failures |
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.
--- research/walkthroughs/VC02-OfflineFieldNotes.md ---
# VC-02 — Offline field notes, restart and reconnect
Status: drafted and editorially self-reviewed, 2026-09-25, codex.
Synthetic reasoning exercise; no application or storage engine was fault-tested.
Evidence baseline: repository `ad6f8fa`; candidate additions in this change.
No canonical pattern admission or M1 completion is implied.
## Fixed brief and assumptions
Preserve VC-02: create/edit offline; restart without losing acknowledged work; later
multi-device sync; conflicting edits possible. Additional assumptions for this exercise:
- Two authorized devices edit plain-text notes. Both start with note N, revision r0.
- A completed local storage transaction survives ordinary process restart. The engine
and flush policy are undecided; power-loss survival is explicitly not established.
- Stable document and operation identities plus revision ancestry detect divergent
changes. Wall-clock timestamps alone are not assumed sufficient.
- The sync receiver deduplicates operation IDs and acknowledges a specific revision.
Acknowledgement means this receiver accepted it, not that all devices have converged.
- Delete/edit conflicts, attachments and concurrent authorization changes are outside
this first trace. They remain gaps, not silently solved cases.
- UI must support keyboard use, non-color status and focus-preserving conflict review.
Sensitive note/conflict copies have equal access protection; content is excluded
from telemetry. Threat model, device encryption and key recovery remain open.
- Interaction feedback should remain responsive offline; local commit and replication
latency are measured separately. No invented numerical performance target.
## Baseline narrative without the catalog
Save notes and pending uploads in a local transaction. Show unsaved versus locally
saved status, upload on reconnection, and retain remote acknowledgements. When the
same base revision has diverged, preserve both versions, expose the discrepancy and
let the user merge. Save and synchronize the result. Back up data separately.
This baseline already expresses a plausible architecture. Pattern names must improve
review of boundaries and missing guarantees; they do not get credit merely for naming it.
## Decisions and provisional connections
| Order | Context and forces | Candidate and decision | Alternative rejected for this brief | Resulting context / evidence |
| --- | --- | --- | --- | --- |
| 1 | Offline availability vs recoverability | [Local Commit Boundary](../candidates/LocalCommitBoundary.md): acknowledge only after document plus pending intent commit | Server-only acknowledgement prevents offline save; memory-only save fails restart | Local saved state exists independently of sync; E01/E04 motivate this, atomicity is an assumption |
| 2 | Freshness vs intermittent network | [Pending Synchronization](../candidates/PendingSynchronization.md): retain identity, retry and confirm a specific revision | Fire-and-forget upload loses uncertainty on restart | Durable pending work; E05/E06 motivate separation, exact protocol is proposed |
| 3 | Divergent intent vs continued work | [Conflict Copy](../candidates/ConflictCopy.md): preserve alternate content and mark unresolved before selecting active content | Blind replacement discards an edit; assumed universal automatic merge lacks evidence | Two recoverable versions; E07/E08 document uses, crash-safe sequence is proposed |
| 4 | User control vs reconciliation effort | [Explicit Reconciliation](../candidates/ExplicitReconciliation.md): compare, commit a new revision and queue it | A conflict file alone does not establish user awareness or resolution | New decision can synchronize; E07/E08 support manual comparison, UI contract unverified |
| 5 | Device loss vs operational burden | Require separately recoverable backup and restoration procedure | Calling synchronization a backup does not meet the recovery goal | External recovery obligation; E11, not a newly invented pattern |
E references resolve in [the evidence review](../reviews/LocalFirstEvidenceExpansion.md).
Relations are provisional: local commit enables pending propagation; divergence may
create context for a conflict copy; preserved divergence enables explicit review;
review creates a new local commit. These are not admitted graph edges or a universal
ordering: quality/recovery requirements influence step 1, not only step 5.
## Restart/reconnect trace
| Step | Event | Local and remote state | User-visible statement / required invariant |
| --- | --- | --- | --- |
| 0 | A and B share r0 | Receiver has r0 | No pending edits under these assumptions |
| 1 | Offline A edits r0→a1 | Editor holds new text; transaction pending | Editing feedback, still unsaved; no persistence claim |
| 2 | A commits a1 + operation opA atomically | A has a1 and pending opA | Saved on this device; not yet synchronized |
| 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 |
| 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 |
| 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 |
A deterministic conflict identity derived from document and revision pair is one
proposed way to avoid multiplying copies on retry. The trace assumes that mechanism;
it is not verified product behavior. A crash before step 2 commit can lose unacknowledged
input; a crash within step 6 must leave either the previous state or the full conflict
state. A partial state would violate the chosen transaction contract and fail the design.
## Change one constraint
Change only concurrency: B may read, but only A may edit this note. Keep offline,
restart, sync, privacy and accessibility requirements fixed.
Steps 1–3 and 9–10 remain necessary. Under the single-writer assumption, steps 4–8
for concurrent edits are unnecessary: omit conflict-copy and reconciliation machinery
for that case. Stable IDs and retry handling remain. Do not claim conflicts impossible
if external editors, restoration or another writer later violate the assumption.
This branch shows that Conflict Copy is conditional, not a prerequisite of local storage.
## Failure and recovery boundaries
- Full disk or denied write: keep unsaved status and actionable error; never acknowledge.
- Missing local transaction guarantee: stop adoption until the storage contract is tested.
- Lost sync acknowledgement: preserve operation identity; duplicate requests must not
duplicate the edit. Network recovery alone does not prove this behavior.
- Revoked access: surface blocked synchronization, preserve local work according to
the agreed security policy; do not retry forever or invent offline authorization.
- Conflict notification failure: retained bytes do not satisfy discoverability.
- Device loss/corruption: conflict copies on that device are insufficient; restore from
separately retained data. Recovery point and key availability remain undecided.
## Editorial self-review
| Criterion | Outcome | Reason |
| --- | --- | --- |
| Traceability | pass for bounded reasoning | Documentary claims have E references; proposed transactions/protocols are labeled assumptions |
| Coherence | revise | Trace is consistent under stated assumptions; actual storage and idempotency contracts are unverified |
| Decision usefulness beyond baseline | unknown | Explicit boundary names expose review questions, but the baseline already contains the architecture; no independent comparison |
| Quality constraints | revise | Accessibility, privacy, errors and recovery enter initial decisions; acceptance tests and threat model are still missing |
| Changed-constraint branch | pass for synthetic reasoning | Removing concurrent writers removes two responsibilities while retaining persistence and propagation |
Disposition: retain four connected research drafts; no canonical promotion. Consider
merging Explicit Reconciliation into Conflict Copy if a second walkthrough cannot
justify separate retrieval/use. This is development evidence, not a held-out evaluation.
## Questions that justify the next research work
1. Which storage transaction/acknowledgement contract survives the required restart
modes? Obtain documentation plus a small crash test for a selected implementation.
2. What receiver protocol makes retries and divergent revision detection safe? Locate
an implementation and test lost acknowledgements before claiming correctness.
3. Can a user find, compare and resolve conflicts with keyboard/screen-reader use?
Define and exercise an accessibility acceptance scenario.
4. What changes in VC-01 when a local edit must satisfy a global transaction rule?
Perform that contrasting walkthrough before treating these connections as general.
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.

View file

@ -0,0 +1,56 @@
{
"kind": "second-model-walkthrough-critique",
"empirical_validation": false,
"service_requests_attempted": 1,
"endpoint": "http://127.0.0.1:18081",
"config": {
"model_name": "custodian-triage-balanced",
"temperature": 0.2,
"max_tokens": 1800,
"model_params": {},
"max_depth": 3,
"skip_if_exists": true,
"timeout_seconds": 300
},
"retry_reason": "First response exceeded 2500 tokens; new prompt bounds total response to 400 words and two findings.",
"adapter_sha256": "1dade65e456ab7b85d17c2c4c9a6e9ecef245104177a8cad815a685d2c7cf427",
"status": "completed",
"responses": [
{
"stage": "walkthrough-review",
"model": "google/gemini-2.5-flash",
"usage": {
"prompt_tokens": 3733,
"completion_tokens": 726,
"total_tokens": 4459
},
"finish_reason": "stop",
"provider": "openrouter",
"response_id": "gen-1790325609-YssyF5LCyv0oWTGYxJ1h",
"latency_seconds": 4.809,
"profile": "custodian-triage-balanced",
"profile_model": "google/gemini-2.5-flash",
"profile_provider": "openrouter",
"diagnostics": {
"available": true,
"effective_settings": {
"temperature": 0.2,
"max_tokens": 1800,
"reasoning_effort_present": false,
"reasoning_present": false
},
"provider_usage": {
"prompt_tokens": 3733,
"completion_tokens": 726,
"total_tokens": 4459,
"cost": 0.0029349,
"completion_tokens_details": {
"reasoning_tokens": 0
}
}
},
"content_characters": 3201,
"content_sha256": "7504f2b343f327f94e155124f35ada16ab39fdfaa54a100c21215a46ed1d8382"
}
]
}

View file

@ -0,0 +1,17 @@
**Case VC01: Transactional Administration**
* **Finding 1: Stale Acknowledgement Handling**
* **Locator:** "Failure and recovery trace", Step 9.
* **Concrete Defect:** The trace states "A late read of v11 arrives after v12; user has also started another draft. Discard obsolete observation; preserve new draft." This implies the client discards the v11 read. However, the "Required invariant" for Step 8 states "Acceptance and freshness remain separate facts." If the client discards v11, it loses the opportunity to confirm that v11 was indeed superseded by v12, which is crucial for maintaining the separation of acceptance and freshness. The client should process the v11 read to confirm its state, even if it's older, rather than discarding it.
* **Minimal Fix:** In Step 9, change "Discard obsolete observation" to "Process obsolete observation to confirm its state, then update local freshness markers."
* **Conditionality:** This finding is conditional on the interpretation that "discard" means completely ignore, rather than process and then not display.
**Case VC02: Offline Field Notes**
* **Finding 1: Operation Lifecycle and Deduplication**
* **Locator:** "Restart/reconnect trace", Step 9 and 10.
* **Concrete Defect:** Step 9 states "Receiver accepts opC, response is lost. c1 may be stored remotely; A still has pending opC." Step 10 states "A retries opC. Receiver deduplicates and confirms c1; A stores receipt." The narrative implies that "opC" is the *same* operation identity being retried. However, the "Fixed brief and assumptions" section states "Stable document and operation identities plus revision ancestry detect divergent changes." and "The sync receiver deduplicates operation IDs and acknowledges a specific revision." The "Additional design assumptions" in VC01 states "A modified proposal gets a new ID." If "opC" represents a *proposal* (which it does, as it's a reconciliation), and the response is lost, retrying it should ideally generate a *new* operation ID if any aspect of the proposal (even implicitly, like a timestamp) could have changed, to avoid ambiguity if the original opC was partially processed or if the client's state changed between attempts. Reusing the *exact* same `opC` identity for a retry, especially when the client's internal state might have evolved, could lead to subtle issues if the server's deduplication logic is not robust enough to handle potential client-side state changes between retries of the "same" logical operation.
* **Minimal Fix:** In Step 10, clarify that "A retries opC" means "A retries the *logical intent* of opC, generating a new operation ID (e.g., opC') if any aspect of the proposal has changed, or reusing opC if the proposal is strictly identical."
* **Conditionality:** This finding is conditional on the strict interpretation of "A modified proposal gets a new ID" from VC01 applying to all proposals, including retries of previously submitted ones, and the potential for client-side state changes between a lost response and a retry.
The baseline usefulness is unknown for both cases as no independent comparison or empirical validation is provided.

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 Next: inspect real frontend recovery implementations and review this case alongside
[VC-02](VC02-OfflineFieldNotes.md). No canonical admission or M1 completion follows [VC-02](VC02-OfflineFieldNotes.md). No canonical admission or M1 completion follows
from completing a synthetic narrative. 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 | | 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 | | 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 | | 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 | | 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 | | 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 | | 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). 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 Broad source collection, more self-critique and additional provider calls would not
answer them without selecting an implementation or a comparison protocol. 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.

View file

@ -240,3 +240,23 @@ draft retention and unknown-outcome recovery at exact revisions. Under T03: obta
independent review of both cases and their baselines. Existing offline atomicity, independent review of both cases and their baselines. Existing offline atomicity,
receiver ancestry/retry and accessible reconciliation evidence gaps remain active. receiver ancestry/retry and accessible reconciliation evidence gaps remain active.
Evidence: research/reviews/TransactionalEvidenceExpansion.md. Evidence: research/reviews/TransactionalEvidenceExpansion.md.
## Pinned frontend recovery evidence — 2026-09-25
T02: inspected Zulip and Element at exact commits, with a separately pinned Matrix
SDK and Matrix v1.15 protocol reference (SRC-0013–0016). File hashes/locators retained.
Two partial uses support draft/intent separation; full-pattern recurrence and runtime
correctness remain unknown. Element/SDK count as one implementation family; deployed
dependency pairing is not verified. No new patterns or canonical admission.
T03: reviewed frozen VC-01/VC-02 through llm-connect. First response truncated and was
quarantined; one shorter follow-up completed. Two calls, 10,605 reported tokens.
Both model fixes rejected editorially. Separately corrected opA blocking/supersession,
read-generation/consistency assumptions and late receipt/error handling. Independent
human review and baseline usefulness remain open; M1 is not complete.
Next bounded work: T02 pin an actual client/SDK/server pairing and exercise lost
response/delayed echo recovery; retain existing offline crash/ancestry/accessibility
gaps. T03 prepare a blinded matched comparison using unseen variants and independent
review. See research/reviews/FrontendRecoveryImplementations.md and
research/reviews/RecoveryWalkthroughReview.md. T02/T03 remain progress.