# 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](../../reviews/BoundaryRecoveryExperiment.md). ## Reproduce From this directory: ```bash 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](provenance.json); 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](result-immediate.json) records 7/8; [result-settled.json](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](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](../../reviews/NestedDismissalIsolation.md) and [48-trial receipt](isolation-results.json) 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. ```bash 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](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. ## Follow-up: experimental routing [Routing design](routing-design.md), [review](../../reviews/NestedOwnershipRouting.md) and [corrected results](routing-results.json) compare a single document router with unmodified behavior. Six scenarios across two browsers/builds: routed 24/24, raw 20/24. This is a research patch, not a production repair or published dependency fork. ```bash PLAYWRIGHT_BROWSERS_PATH=/tmp/fep-playwright-browsers FEP_CHROMIUM_PATH=/path/to/chrome node routing.mjs ``` Uses the same installed dependencies/browsers as isolation.mjs. Outputs `/tmp/fep-routing.json` (override with `FEP_RESULT_PATH`) and an incomplete checkpoint at `/tmp/fep-routing-checkpoint.json`. No sleep, readiness wait or automatic retry. The transform changes Escape routing only in memory and verifies the pinned source hash before use. `routing-fixture.jsx` explicitly controls both dialogs, so its results cannot be pooled with the earlier uncontrolled-inner fixture as matched trials. The initial [development results](routing-development-results.json) used an incorrect accessibility-exposed dialog count for cancellation. Their original `routing.mjs` bytes are retained as [routing-development-runner.mjs](routing-development-runner.mjs) for hash verification; that archived file is provenance, not the reproduction entry. The corrected runner counts hidden parents and checks listener cleanup. Both runs are retained, and the earlier faulty cancellation scores are excluded from conclusions.