2026-09-25 10:32:13 +02:00
|
|
|
|
# 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.
|
2026-09-25 10:41:59 +02:00
|
|
|
|
|
|
|
|
|
|
## 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.
|
2026-09-25 11:02:03 +02:00
|
|
|
|
|
|
|
|
|
|
## Executable supporting observation — 2026-09-25
|
|
|
|
|
|
|
|
|
|
|
|
[Matrix recovery experiment](../reviews/MatrixRecoveryExperiment.md) X03 exercises
|
|
|
|
|
|
one related client mechanism: an early server event can reconcile an operation even
|
|
|
|
|
|
when its request promise later rejects. In this case, derive z's outcome from
|
|
|
|
|
|
correlated authoritative evidence rather than treating any rejected promise as a
|
|
|
|
|
|
failed approval. A user cancelling local tracking cannot undo z; reversal requires
|
|
|
|
|
|
a separate authorized domain action after its outcome is known. The SDK experiment
|
|
|
|
|
|
does not implement this approval application or its server transaction contract.
|