Assistant: codex Assistant-Model: gpt-6-astra Assistant-Session: 01a0cffe-206f-7323-89d3-b20ca4cf4bf9
84 lines
5.5 KiB
Markdown
84 lines
5.5 KiB
Markdown
# Activation conflicts and unfinished-work reload — 2026-09-26
|
|
|
|
Status: executed synthetic HTTP/browser experiment, editorial analysis by Codex.
|
|
WP-0003 T01, continuation of [feature release lifecycle](FeatureReleaseExperiment.md).
|
|
[Runner](../experiments/feature-release/conflicts-reload.mjs),
|
|
[reload host](../experiments/feature-release/reload-host.js) and
|
|
[receipt](../experiments/feature-release/conflicts-reload-results.json) record 21/21
|
|
expected observations: three HTTP update cases plus nine reload cases in Chromium
|
|
151.0.7922.34 and Firefox 155.0. No live deployment, backend domain write or model call.
|
|
|
|
## Activation-update cases
|
|
|
|
Two clients read the same revision before either submits. The runner then forces a
|
|
known write ordering over real loopback HTTP; this is a reproducible stale-writer
|
|
interleaving, not an uncontrolled concurrency load test.
|
|
|
|
| Case | Expected and observed |
|
|
| --- | --- |
|
|
| C01 Blind whole-map replacement | Reports update succeeds, then a stale Account replacement silently restores the old Reports binding: negative lost-update control |
|
|
| C02 Conditional replacement, disjoint intent | Stale Account replacement rejected; explicit refetch and reapplication of only Account intent preserves both updates |
|
|
| C03 Competing intent for one feature | Stale Reports rollback rejected; active newer Reports binding retained; no automatic overwrite |
|
|
|
|
The fixture uses an integer revision carried in If-Match and a synthetic 409 conflict
|
|
response, not a full HTTP ETag/precondition implementation. Comparison and replacement
|
|
have no asynchronous gap in one server process. A distributed store still needs its
|
|
own atomic conditional-write primitive. Refetch alone does not justify retry: C02
|
|
reapplies a disjoint intent; C03 deliberately leaves conflicting intent unresolved.
|
|
These tests do not execute import-map-deployer or verify its implementation.
|
|
|
|
## Reload cases
|
|
|
|
The user-controlled update path offers keep-working, preserve-and-reload, and explicit
|
|
discard-and-reload. Persistence uses sessionStorage with synthetic non-sensitive text,
|
|
a draft schema and a base-record marker. No server save or remote acceptance is inferred.
|
|
|
|
| Case | Expected and observed in both browsers |
|
|
| --- | --- |
|
|
| R01 Unguarded reload | Unsaved input disappears and R2 loads: negative control |
|
|
| R02 Defer update | Draft stays editable in the old R1 session |
|
|
| R03 Preserve and reload | R2 loads with exact draft text and original base marker recovered |
|
|
| R04 Inject storage refusal | Reload blocked; original draft and R1 remain |
|
|
| R05 Incompatible target draft schema | Update deferred before reload; original input retained |
|
|
| R06 Explicit discard | Both current input and an older stored draft cleared; R2 starts empty |
|
|
| R07 Unknown write outcome | Reload blocked while the synthetic pending-outcome flag is set |
|
|
| R08 Edit during asynchronous preflight | Latest edited text, not an earlier snapshot, persists and returns |
|
|
| R09 Activation changes after preflight snapshot | New document detects schema mismatch again; stored text retained in read-only recovery state |
|
|
|
|
R08/R09 hold a server response at an explicit barrier, make the intervening edit or
|
|
activation change, then release it. No arbitrary settling delay or automatic retry
|
|
is used. The poll waits for the barrier itself. R09 demonstrates why a successful
|
|
preflight cannot promise that the next document has the same compatibility contract.
|
|
The fixture deliberately changes its declared draft schema; it does not implement
|
|
an actual schema migration or prove compatibility of a real feature's draft format.
|
|
|
|
## Limits and interpretation
|
|
|
|
“Pass” includes intentionally observed failures in C01 and R01. The preservation
|
|
path is an authored policy, not an automatic browser or framework guarantee. Explicit
|
|
recovery retains bytes; it does not resolve a stale base, merge edits or establish
|
|
permission to retain/export them. The unknown-write flag tests a UI gate only; no
|
|
real operation lookup or idempotent replay occurs. Discard does not reverse a remote
|
|
operation and is blocked by that same unknown-outcome gate.
|
|
|
|
sessionStorage covers this tab's same-origin reload, not device loss, guaranteed
|
|
browser restart or independent backup. The injected write refusal tests the failure
|
|
branch, not browser quota exhaustion. Other tabs, login/access revocation, storage
|
|
schema migration, interruptions during navigation, native reload/tab close and browser
|
|
crashes are not covered. An application-level update button is not a universal unload
|
|
interceptor. Persisted drafts remain until explicit discard in this fixture; a real
|
|
product needs an authorized retention/cleanup policy and safe handling of stale drafts.
|
|
|
|
## Candidate disposition
|
|
|
|
[Independent Feature Boundary](../candidates/IndependentFeatureBoundary.md) gains
|
|
conditional activation and session-transition obligations. [Local Draft State](../candidates/LocalDraftState.md)
|
|
gains a partial implementation of explicit preservation/refusal, with post-navigation
|
|
schema revalidation. [VC-06](../walkthroughs/VC06-MicrofrontendEstate.md) remains
|
|
provisional: this supports its release/reload trace, not production rollback or a
|
|
completed accessibility/security review. Corpus remains seventeen hypotheses.
|
|
|
|
Next WP-0003 T01 evidence: navigation/history/full-versus-fragment caching, which is
|
|
still pending from VC-03. Retain distributed activation atomicity, authorized draft
|
|
retention and native-unload/crash behavior as limits requiring evidence before a
|
|
production recommendation; do not grow this fixture into a release platform.
|