Assistant: codex Assistant-Model: gpt-6-astra Assistant-Session: 01a0cffe-206f-7323-89d3-b20ca4cf4bf9
8.1 KiB
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.
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
- Establish server authority over approved records. Local typing gives feedback but cannot approve a record. Offline acceptance is outside this case.
- Use Local Draft State to preserve user intent independently of refreshed observations. This creates a base/draft/current comparison.
- Use Version-Checked Mutation for the conditional write (T01). Blind overwrite risks lost edits; GitLab's error ambiguity (T02) demonstrates why adapters must preserve actual endpoint semantics.
- Use Mutation Outcome Tracking 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.
- Use Invalidate and Reproject to refresh affected observations after acceptance. Keep drafts intact and reject obsolete responses. T04 shows why browser cancellation cannot enforce server ordering.
- 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. 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 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.