Assistant: codex Assistant-Model: gpt-6-astra Assistant-Session: 01a0cffe-206f-7323-89d3-b20ca4cf4bf9
77 lines
4.5 KiB
Markdown
77 lines
4.5 KiB
Markdown
# Feature publication, activation and rollback experiment
|
||
|
||
Executed 2026-09-26. Seven scenarios in Chromium 151.0.7922.34 and Firefox 155.0;
|
||
14/14 assertions met. [Review](../../reviews/FeatureReleaseExperiment.md),
|
||
[results](result.json), [provenance](provenance.json).
|
||
|
||
This is an authored synthetic host using real browser-native modules/import maps,
|
||
not execution of the earlier FSD/single-spa examples or a production release system.
|
||
The host API is fixed at 1. Reports R1/R2 support 1, R3 declares 2; Account A1 stays
|
||
unchanged. Each new HTML document receives the current map. Published assets and
|
||
activation bindings are separate in-memory controls in the test server.
|
||
|
||
## Reproduce
|
||
|
||
From this directory:
|
||
|
||
```bash
|
||
npm ci --ignore-scripts --cache /tmp/fep-npm-cache
|
||
PLAYWRIGHT_BROWSERS_PATH=/tmp/fep-playwright-browsers node node_modules/playwright/cli.js install firefox
|
||
PLAYWRIGHT_BROWSERS_PATH=/tmp/fep-playwright-browsers FEP_CHROMIUM_PATH=/path/to/chrome npm test
|
||
```
|
||
|
||
Playwright 1.63.0 is locked. Recorded runs used the same browser binaries identified
|
||
by hashes in provenance.json, with an explicit Chromium executable override. Firefox
|
||
required execution outside the workspace sandbox to access its temporary profile.
|
||
No external network is used during cases. Loopback server/browser cleanup is automatic.
|
||
Outputs default to `/tmp/fep-release-result.json` and an incomplete checkpoint at
|
||
`/tmp/fep-release-checkpoint.json`; `FEP_RESULT_PATH` overrides the final destination.
|
||
Any failed assertion produces nonzero exit. Receipts are not overwritten automatically.
|
||
|
||
## Cases and limits
|
||
|
||
| Case | Observed result in both browsers |
|
||
| --- | --- |
|
||
| X01 Publish R2 without changing binding | Fresh page still uses R1; no R2 request |
|
||
| X02 Activate compatible R2 | Fresh page R2; old loaded and old lazy pages R1; Account A1 unchanged |
|
||
| X03 Activate incompatible R3 | Host rejects mount, Account works; R3 module has already evaluated |
|
||
| X04 Point binding to missing artifact | Reports error, Account navigation still usable |
|
||
| X05 Roll binding back R2 → R1 | Fresh page R1; running page R2; explicit reload gets R1 |
|
||
| X06 Retire R1 after activating R2 | Old loaded page retains R1; old lazy page fails; new page uses R2 |
|
||
| X07 Fail shared startup module | Both navigation buttons remain disabled; feature loading never starts |
|
||
|
||
Negative controls intentionally pass when the specified failure is observed. All
|
||
responses disable HTTP caching, so this is not a CDN/cache invalidation test. Existing
|
||
pages retain their document maps; dynamic map mutation/hot replacement is not tested.
|
||
Only the host's deliberately tiny API-version contract is checked; module evaluation
|
||
can already have side effects before that check. No backend writes, authentication,
|
||
API migrations, atomic/concurrent map updates, accessibility audit or safe reload of
|
||
unsaved work is modeled. The startup outage reflects this fixture's chosen dependency,
|
||
not an assertion that every independently released frontend must fail that way.
|
||
|
||
## Activation conflicts and safe update reload
|
||
|
||
[Review](../../reviews/ActivationConflictsAndReload.md) and
|
||
[receipt](conflicts-reload-results.json): three deterministic stale-writer HTTP cases
|
||
and nine reload scenarios in each browser, 21/21 expected observations.
|
||
|
||
```bash
|
||
PLAYWRIGHT_BROWSERS_PATH=/tmp/fep-playwright-browsers FEP_CHROMIUM_PATH=/path/to/chrome node conflicts-reload.mjs
|
||
```
|
||
|
||
Uses the same pinned dependencies/browsers as the original release experiment.
|
||
Default output `/tmp/fep-conflicts-reload.json`; `FEP_RESULT_PATH` overrides it.
|
||
Incomplete browser progress goes to `/tmp/fep-conflicts-reload-checkpoint.json`.
|
||
The earlier host, runner and receipts remain unchanged. The new reload-host.js is
|
||
an authored policy using sessionStorage, explicit user choices and schema checks.
|
||
|
||
C01 and R01 deliberately reproduce data loss from unsafe choices. C02 refetches and
|
||
reapplies a disjoint intent; C03 rejects a conflicting stale rollback. R02–R09 exercise
|
||
update deferral, preservation, storage refusal, incompatible schema, explicit discard,
|
||
unknown-outcome gating, edits during preflight and activation after preflight.
|
||
|
||
Activation comparison/replacement is atomic only within this single-process model;
|
||
its revision header and 409 response are not a full HTTP precondition implementation.
|
||
Storage refusal is injected. Preservation assumes retention is authorized and protects
|
||
only the tested same-tab reload. Native reload/tab close, crashes, real backend
|
||
outcome recovery, multiple tabs and automatic schema migration remain out of scope.
|