frontend-patterns/research/experiments/boundary-recovery/README.md
tegwick 85ae4f62af Isolate nested dismissal ownership across browsers and builds
Assistant: codex
Assistant-Model: gpt-6-astra
Assistant-Session: 01a0cffe-206f-7323-89d3-b20ca4cf4bf9
2026-09-26 22:35:12 +02:00

5 KiB

Rendering and focus boundary experiment

Executed 2026-09-26. Real React 19.3.0 / Radix Dialog 1.1.23 in a synthetic browser fixture; no deployed application, provider inference or production requests. Review and interpretation.

Reproduce

From this directory:

npm ci --ignore-scripts --cache /tmp/fep-npm-cache
FEP_CHROMIUM_PATH=/path/to/chrome FEP_RESULT_PATH=/tmp/immediate.json npm test
FEP_CHROMIUM_PATH=/path/to/chrome FEP_NESTED_SETTLE_MS=100 FEP_RESULT_PATH=/tmp/settled.json npm test

Use a locally available Chromium executable, or omit FEP_CHROMIUM_PATH to use Playwright's installed browser. The recorded runs used preinstalled Chromium 151.0.7922.34, not an assertion of compatibility with every browser. Version and executable hash are in provenance; the lockfile pins all packages with archive integrity. Installation does not download a browser automatically here. The runner binds an ephemeral loopback port, bundles the fixture in memory, and closes browser/server in finally. No external network is used by the cases.

Output defaults to /tmp/fep-boundary-result.json; reviewed receipts are not overwritten automatically. A failed obligation makes the runner exit nonzero. The immediate nested-dialog case is known to be timing-sensitive; do not hide it with retries or interpret a later pass as its resolution. FEP_NESTED_SETTLE_MS changes only the pause after nested activation before the first Escape. It is an experimental variable, not a proposed product fix. The browser uses React's development build, without StrictMode. Production builds and other browsers remain untested.

Recorded cases

Case Observation Immediate / 100 ms settled
X01 Render fault uses inner fallback; sibling stays interactive pass / pass
X02 Event-handler exception reaches browser error reporting, not boundary pass / pass
X03 Synthetic GET returns 503; explicit catch sets request-failure state pass / pass
X04 Fault in inner fallback reaches outer boundary pass / pass
X05 Closing modal returns focus to surviving invoker pass / pass
X06 Removing invoker leaves BODY focused with default behavior pass / pass (negative control)
X07 Application close policy selects surviving next-record button pass / pass
X08 Nested close should return to parent trigger, then outer trigger fail / pass

result-immediate.json records 7/8; result-settled.json records 8/8 with identical code/input hashes, except the declared timing parameter. “Pass” means an observation matched its assertion, not that the UX is acceptable: X06 deliberately expects the missing workflow target.

development-results.json preserves three earlier runs in order: 7/8, 8/8, 7/8. They preceded final diagnostic instrumentation; their old runner bytes are not archived, so they are development history, not exact reproducible snapshots. Current-code receipts above retain their matching SHA-256 input hashes. All five runs are reported; no estimate of failure frequency is justified.

Scope

Focus checks inspect activeElement and keyboard behavior, not screen-reader output or full accessibility conformance. X03 handles a response error explicitly; it does not test unhandled promises, timeouts, mutation idempotency or remote rollback. Nested dismissal remains unresolved. Dependency/version compatibility and fixture lifecycle effects must be separated before attributing a library defect.

Follow-up: nested ownership isolation

Review and 48-trial receipt compare development/production, Chromium/Firefox and four explicit variants. The original experiment and receipts above remain unchanged. Follow-up reports 43/48 obligations met, including failures; it is a research runner, not a green CI gate.

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 node isolation.mjs

Runs three trials per browser/build/variant, without automatic retries. Default output is /tmp/fep-isolation.json; FEP_RESULT_PATH overrides it. A separate /tmp/fep-isolation-checkpoint.json preserves completed trials if a later launch fails. Launch failures abort; completed matrices retain assertion failures in JSON. A sandbox prevented Firefox accessing its temporary profile here; the recorded completed matrix ran outside that sandbox. Firefox build and limitations are in isolation-provenance.json.

Instrumentation and an experimental guard are applied in memory during bundling; installed vendor files are not modified. The readiness variant observes private listener state and is not a proposed public readiness API. The guard can lose input and is not a validated fix. Do not replace raw failures with readiness passes.