diff --git a/TREE.md b/TREE.md
index 743178c..26836dc 100644
--- a/TREE.md
+++ b/TREE.md
@@ -360,6 +360,13 @@ research/experiments/boundary-recovery/package.json
research/experiments/boundary-recovery/provenance.json
research/experiments/boundary-recovery/result-immediate.json
research/experiments/boundary-recovery/result-settled.json
+research/experiments/boundary-recovery/routing-design.md
+research/experiments/boundary-recovery/routing-development-results.json
+research/experiments/boundary-recovery/routing-development-runner.mjs
+research/experiments/boundary-recovery/routing-fixture.jsx
+research/experiments/boundary-recovery/routing-results.json
+research/experiments/boundary-recovery/routing-transform.mjs
+research/experiments/boundary-recovery/routing.mjs
research/experiments/matrix-recovery/README.md
research/experiments/matrix-recovery/experiment.mjs
research/experiments/matrix-recovery/package-lock.json
@@ -383,6 +390,7 @@ research/reviews/MatrixRecoveryExperiment.md
research/reviews/NavigationCoverage.md
research/reviews/NavigationRenderingEvidence.md
research/reviews/NestedDismissalIsolation.md
+research/reviews/NestedOwnershipRouting.md
research/reviews/ObsidianConflictScreen.json
research/reviews/PatternBreadthExpansion.md
research/reviews/RecoveryReviewMetrics.json
diff --git a/research/README.md b/research/README.md
index 2333a20..5590638 100644
--- a/research/README.md
+++ b/research/README.md
@@ -56,3 +56,7 @@ and a timing-sensitive nested-dialog failure; no production or accessibility cer
Nested-dialog follow-up: [ownership isolation](reviews/NestedDismissalIsolation.md)
captures a stale Escape-listener interval in a 48-trial browser/build comparison.
A partial guard loses input; a complete remedy remains open. Original results retained.
+
+Latest bounded mechanism test: [ownership routing](reviews/NestedOwnershipRouting.md)
+meets 24/24 routed assertions versus 20/24 unmodified controls, with explicit scope
+limits. No delay or readiness wait; no production fork or canonical promotion.
diff --git a/research/candidates/FocusReturn.md b/research/candidates/FocusReturn.md
index e1070d5..910b1c8 100644
--- a/research/candidates/FocusReturn.md
+++ b/research/candidates/FocusReturn.md
@@ -62,3 +62,15 @@ A current-owner guard can lose the keypress; private listener-readiness waiting
its trials but is not a product solution. Test ownership of dismissal as well as return
focus, including activation/teardown input. No arbitrary-delay fix, production repair
or full-pattern promotion is established.
+
+## Experimental routing evidence — 2026-09-26
+
+[Routing comparison](../reviews/NestedOwnershipRouting.md) tests layout registration,
+a single document Escape dispatcher and event-time owner selection. The experimental
+router meets 24/24 scenario assertions across two browsers/builds; its unmodified
+control meets 20/24. It preserves cancellation and removes ownership on teardown
+without a delay or private-readiness wait. Return to a replacement target still
+requires application policy. This supports separating input ownership from focus
+restoration, not a general production-ready fix: animated exits, competing owners,
+rapid input bursts and assistive technology remain untested. Sixteen hypotheses;
+no new pattern or maturity promotion.
diff --git a/research/catalog/SourceCatalog.md b/research/catalog/SourceCatalog.md
index 7224047..6610b34 100644
--- a/research/catalog/SourceCatalog.md
+++ b/research/catalog/SourceCatalog.md
@@ -127,3 +127,9 @@ SRC-0029 follow-up: [nested dismissal isolation](../reviews/NestedDismissalIsola
reuses the same pinned packages across two browsers/build modes. Instrumented and
experimentally modified bundles are explicitly separated from the unmodified control;
this is additional evidence from the same family, not a new independent use.
+
+SRC-0029 further follow-up: [experimental ownership routing](../reviews/NestedOwnershipRouting.md)
+compares unchanged packages with an explicitly modified in-memory Escape mechanism.
+The routed results are evidence for our proposed design, not observations of shipped
+vendor behavior. Current raw control also reproduces production wrong-owner dismissal
+in the new controlled fixture. Prior receipts remain unchanged.
diff --git a/research/experiments/boundary-recovery/README.md b/research/experiments/boundary-recovery/README.md
index b1a2a14..058dde4 100644
--- a/research/experiments/boundary-recovery/README.md
+++ b/research/experiments/boundary-recovery/README.md
@@ -86,3 +86,28 @@ 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.
diff --git a/research/experiments/boundary-recovery/routing-design.md b/research/experiments/boundary-recovery/routing-design.md
new file mode 100644
index 0000000..1975c31
--- /dev/null
+++ b/research/experiments/boundary-recovery/routing-design.md
@@ -0,0 +1,30 @@
+# Experimental Escape routing
+
+This is a synthetic alternative for one pinned Radix module, implemented through an
+in-memory bundle transform. It is not an upstream patch, supported API or deployment.
+The existing isolation experiment remains unchanged.
+
+Proposed contract:
+
+1. Register a connected dialog owner during layout, before ordinary user interaction.
+2. Keep one capture listener per document. On Escape, snapshot one current owner.
+3. Invoke that owner's callback once; honor cancellation without falling through to
+ its parent. Invoke dismissal only if the callback has not prevented it.
+4. Remove ownership during layout cleanup; disconnecting the final owner removes
+ the document listener. Ignore detached nodes when selecting an owner.
+5. Keep focus restoration separate: a removed invoker still needs an application
+ target, and asynchronous focus restoration has its own lifecycle.
+
+The registry currently uses mount insertion order, which is a limited proxy for
+ownership in the tested two-level nesting. It does not model arbitrary z-order,
+multiple library copies, nested documents, shadow DOM or animation-preserved exiting
+layers. A controlled dialog can reject a dismissal; this router does not mark it
+closed merely because a callback ran. Rapid repeats, same-turn bursts and competing
+non-dialog Escape handlers require separate contracts and testing.
+
+The six scenarios are ordinary close, immediate nested close, cancelled inner close,
+removed invoker with an application target, programmatic inner removal then reopen,
+and ancestor teardown followed by Escape. Each runs once per browser/build/variant:
+Chromium/Firefox, development/production, original behavior/experimental router.
+There are no sleeps, private-readiness waits or automatic retries. This is a mechanism
+comparison, not an estimate of occurrence rates or proof of a general repair.
diff --git a/research/experiments/boundary-recovery/routing-development-results.json b/research/experiments/boundary-recovery/routing-development-results.json
new file mode 100644
index 0000000..844f91e
--- /dev/null
+++ b/research/experiments/boundary-recovery/routing-development-results.json
@@ -0,0 +1,2120 @@
+{
+ "date": "2026-09-26T20:51:27.836Z",
+ "node": "v24.11.1",
+ "files": {
+ "routing.mjs": "9761a98198623d81967f5460c8647eeb13041849f33de1982109f6e046b4e5b7",
+ "routing-fixture.jsx": "d99875390941752047eda63a93c921af977c35b36371dd609cd46e7ba730a51d",
+ "routing-transform.mjs": "417589ab170ea1576452d0a903fbd8e1870d3d91d2a49b50707c36b0aef56335",
+ "package.json": "a0ad37e8518b0c561d6b4a091ee51f5bca90e0ce329b2be7ba75347f6dc26ae7",
+ "package-lock.json": "ec4b544d441f89d9c512bc9931c1818473327105d5ef9047dc04d6a721e68463"
+ },
+ "sourceSha256": "01df449a23d65bab1f2f2215a953cba74741419496ebd9a7932533f267cc873d",
+ "transformedSha256": "1f42e26b9789a12263182ca1ee2b623870499d73456e4ad90172a8fc39c8618b",
+ "bundleHashes": {
+ "development-raw": "7fc5a9df75b15ec7da3c1a625624e2166c74609788cf46dc3ac03a88d5a639d6",
+ "development-routed": "fcdf229aeb5025a038ee6baaec7927031e032b75ed5899d1294ea199cd0921b1",
+ "production-raw": "1846d180a6fcf20426febaa355f47bc86e3b2e59a139fec55882a1ba460ab56d",
+ "production-routed": "fd73a8c4684b7cbb90ac87f08ef318a48c3b9444f8747b994e21217ee9666740"
+ },
+ "summary": [
+ {
+ "engine": "chromium",
+ "mode": "development",
+ "variant": "raw",
+ "passed": 4,
+ "total": 6
+ },
+ {
+ "engine": "chromium",
+ "mode": "development",
+ "variant": "routed",
+ "passed": 5,
+ "total": 6
+ },
+ {
+ "engine": "chromium",
+ "mode": "production",
+ "variant": "raw",
+ "passed": 4,
+ "total": 6
+ },
+ {
+ "engine": "chromium",
+ "mode": "production",
+ "variant": "routed",
+ "passed": 5,
+ "total": 6
+ },
+ {
+ "engine": "firefox",
+ "mode": "development",
+ "variant": "raw",
+ "passed": 5,
+ "total": 6
+ },
+ {
+ "engine": "firefox",
+ "mode": "development",
+ "variant": "routed",
+ "passed": 5,
+ "total": 6
+ },
+ {
+ "engine": "firefox",
+ "mode": "production",
+ "variant": "raw",
+ "passed": 5,
+ "total": 6
+ },
+ {
+ "engine": "firefox",
+ "mode": "production",
+ "variant": "routed",
+ "passed": 5,
+ "total": 6
+ }
+ ],
+ "results": [
+ {
+ "engine": "chromium",
+ "browser": "151.0.7922.34",
+ "mode": "development",
+ "variant": "raw",
+ "case": "ordinary",
+ "status": "pass",
+ "observed": {
+ "active": "outer-trigger",
+ "dialogs": 0,
+ "changes": [
+ {
+ "name": "outer",
+ "value": true
+ },
+ {
+ "name": "outer",
+ "value": false
+ }
+ ],
+ "escapes": [
+ "outer"
+ ],
+ "trace": []
+ },
+ "browserErrors": []
+ },
+ {
+ "engine": "chromium",
+ "browser": "151.0.7922.34",
+ "mode": "development",
+ "variant": "raw",
+ "case": "nested-immediate",
+ "status": "fail",
+ "error": "page.waitForFunction: Timeout 1200ms exceeded.",
+ "observed": {
+ "active": "outer-trigger",
+ "dialogs": 0,
+ "changes": [
+ {
+ "name": "outer",
+ "value": true
+ },
+ {
+ "name": "inner",
+ "value": true
+ },
+ {
+ "name": "outer",
+ "value": false
+ }
+ ],
+ "escapes": [
+ "outer"
+ ],
+ "trace": []
+ },
+ "browserErrors": []
+ },
+ {
+ "engine": "chromium",
+ "browser": "151.0.7922.34",
+ "mode": "development",
+ "variant": "raw",
+ "case": "cancel-inner",
+ "status": "fail",
+ "error": "Expected values to be strictly equal:\n\n1 !== 2\n",
+ "observed": {
+ "active": "inner-close",
+ "dialogs": 2,
+ "changes": [
+ {
+ "name": "outer",
+ "value": true
+ },
+ {
+ "name": "inner",
+ "value": true
+ }
+ ],
+ "escapes": [
+ "inner"
+ ],
+ "trace": []
+ },
+ "browserErrors": []
+ },
+ {
+ "engine": "chromium",
+ "browser": "151.0.7922.34",
+ "mode": "development",
+ "variant": "raw",
+ "case": "remove-trigger",
+ "status": "pass",
+ "observed": {
+ "active": "outer-trigger",
+ "dialogs": 0,
+ "changes": [
+ {
+ "name": "outer",
+ "value": true
+ },
+ {
+ "name": "inner",
+ "value": true
+ },
+ {
+ "name": "outer",
+ "value": false
+ }
+ ],
+ "escapes": [
+ "outer"
+ ],
+ "trace": []
+ },
+ "browserErrors": []
+ },
+ {
+ "engine": "chromium",
+ "browser": "151.0.7922.34",
+ "mode": "development",
+ "variant": "raw",
+ "case": "remove-and-reopen",
+ "status": "pass",
+ "observed": {
+ "active": "inner-trigger",
+ "dialogs": 1,
+ "changes": [
+ {
+ "name": "outer",
+ "value": true
+ },
+ {
+ "name": "inner",
+ "value": true
+ },
+ {
+ "name": "inner",
+ "value": true
+ },
+ {
+ "name": "inner",
+ "value": false
+ }
+ ],
+ "escapes": [
+ "inner"
+ ],
+ "trace": []
+ },
+ "browserErrors": []
+ },
+ {
+ "engine": "chromium",
+ "browser": "151.0.7922.34",
+ "mode": "development",
+ "variant": "raw",
+ "case": "ancestor-teardown",
+ "status": "pass",
+ "observed": {
+ "active": "next",
+ "dialogs": 0,
+ "changes": [
+ {
+ "name": "outer",
+ "value": true
+ },
+ {
+ "name": "inner",
+ "value": true
+ }
+ ],
+ "escapes": [],
+ "trace": []
+ },
+ "browserErrors": []
+ },
+ {
+ "engine": "chromium",
+ "browser": "151.0.7922.34",
+ "mode": "development",
+ "variant": "routed",
+ "case": "ordinary",
+ "status": "pass",
+ "observed": {
+ "active": "outer-trigger",
+ "dialogs": 0,
+ "changes": [
+ {
+ "name": "outer",
+ "value": true
+ },
+ {
+ "name": "outer",
+ "value": false
+ }
+ ],
+ "escapes": [
+ "outer"
+ ],
+ "trace": [
+ {
+ "kind": "register",
+ "owner": "radix-_r_1_",
+ "count": 1
+ },
+ {
+ "kind": "dispatch",
+ "owner": "radix-_r_1_"
+ },
+ {
+ "kind": "unregister",
+ "owner": "radix-_r_1_",
+ "count": 0
+ },
+ {
+ "kind": "listener-removed"
+ }
+ ]
+ },
+ "browserErrors": []
+ },
+ {
+ "engine": "chromium",
+ "browser": "151.0.7922.34",
+ "mode": "development",
+ "variant": "routed",
+ "case": "nested-immediate",
+ "status": "pass",
+ "observed": {
+ "active": "outer-trigger",
+ "dialogs": 0,
+ "changes": [
+ {
+ "name": "outer",
+ "value": true
+ },
+ {
+ "name": "inner",
+ "value": true
+ },
+ {
+ "name": "inner",
+ "value": false
+ },
+ {
+ "name": "outer",
+ "value": false
+ }
+ ],
+ "escapes": [
+ "inner",
+ "outer"
+ ],
+ "trace": [
+ {
+ "kind": "register",
+ "owner": "radix-_r_1_",
+ "count": 1
+ },
+ {
+ "kind": "register",
+ "owner": "radix-_r_4_",
+ "count": 2
+ },
+ {
+ "kind": "dispatch",
+ "owner": "radix-_r_4_"
+ },
+ {
+ "kind": "unregister",
+ "owner": "radix-_r_4_",
+ "count": 1
+ },
+ {
+ "kind": "dispatch",
+ "owner": "radix-_r_1_"
+ },
+ {
+ "kind": "unregister",
+ "owner": "radix-_r_1_",
+ "count": 0
+ },
+ {
+ "kind": "listener-removed"
+ }
+ ]
+ },
+ "browserErrors": []
+ },
+ {
+ "engine": "chromium",
+ "browser": "151.0.7922.34",
+ "mode": "development",
+ "variant": "routed",
+ "case": "cancel-inner",
+ "status": "fail",
+ "error": "Expected values to be strictly equal:\n\n1 !== 2\n",
+ "observed": {
+ "active": "inner-close",
+ "dialogs": 2,
+ "changes": [
+ {
+ "name": "outer",
+ "value": true
+ },
+ {
+ "name": "inner",
+ "value": true
+ }
+ ],
+ "escapes": [
+ "inner"
+ ],
+ "trace": [
+ {
+ "kind": "register",
+ "owner": "radix-_r_1_",
+ "count": 1
+ },
+ {
+ "kind": "register",
+ "owner": "radix-_r_4_",
+ "count": 2
+ },
+ {
+ "kind": "dispatch",
+ "owner": "radix-_r_4_"
+ }
+ ]
+ },
+ "browserErrors": []
+ },
+ {
+ "engine": "chromium",
+ "browser": "151.0.7922.34",
+ "mode": "development",
+ "variant": "routed",
+ "case": "remove-trigger",
+ "status": "pass",
+ "observed": {
+ "active": "outer-trigger",
+ "dialogs": 0,
+ "changes": [
+ {
+ "name": "outer",
+ "value": true
+ },
+ {
+ "name": "inner",
+ "value": true
+ },
+ {
+ "name": "outer",
+ "value": false
+ }
+ ],
+ "escapes": [
+ "outer"
+ ],
+ "trace": [
+ {
+ "kind": "register",
+ "owner": "radix-_r_1_",
+ "count": 1
+ },
+ {
+ "kind": "register",
+ "owner": "radix-_r_4_",
+ "count": 2
+ },
+ {
+ "kind": "unregister",
+ "owner": "radix-_r_4_",
+ "count": 1
+ },
+ {
+ "kind": "dispatch",
+ "owner": "radix-_r_1_"
+ },
+ {
+ "kind": "unregister",
+ "owner": "radix-_r_1_",
+ "count": 0
+ },
+ {
+ "kind": "listener-removed"
+ }
+ ]
+ },
+ "browserErrors": []
+ },
+ {
+ "engine": "chromium",
+ "browser": "151.0.7922.34",
+ "mode": "development",
+ "variant": "routed",
+ "case": "remove-and-reopen",
+ "status": "pass",
+ "observed": {
+ "active": "inner-trigger",
+ "dialogs": 1,
+ "changes": [
+ {
+ "name": "outer",
+ "value": true
+ },
+ {
+ "name": "inner",
+ "value": true
+ },
+ {
+ "name": "inner",
+ "value": true
+ },
+ {
+ "name": "inner",
+ "value": false
+ }
+ ],
+ "escapes": [
+ "inner"
+ ],
+ "trace": [
+ {
+ "kind": "register",
+ "owner": "radix-_r_1_",
+ "count": 1
+ },
+ {
+ "kind": "register",
+ "owner": "radix-_r_4_",
+ "count": 2
+ },
+ {
+ "kind": "unregister",
+ "owner": "radix-_r_4_",
+ "count": 1
+ },
+ {
+ "kind": "register",
+ "owner": "radix-_r_4_",
+ "count": 2
+ },
+ {
+ "kind": "dispatch",
+ "owner": "radix-_r_4_"
+ },
+ {
+ "kind": "unregister",
+ "owner": "radix-_r_4_",
+ "count": 1
+ }
+ ]
+ },
+ "browserErrors": []
+ },
+ {
+ "engine": "chromium",
+ "browser": "151.0.7922.34",
+ "mode": "development",
+ "variant": "routed",
+ "case": "ancestor-teardown",
+ "status": "pass",
+ "observed": {
+ "active": "next",
+ "dialogs": 0,
+ "changes": [
+ {
+ "name": "outer",
+ "value": true
+ },
+ {
+ "name": "inner",
+ "value": true
+ }
+ ],
+ "escapes": [],
+ "trace": [
+ {
+ "kind": "register",
+ "owner": "radix-_r_1_",
+ "count": 1
+ },
+ {
+ "kind": "register",
+ "owner": "radix-_r_4_",
+ "count": 2
+ },
+ {
+ "kind": "unregister",
+ "owner": "radix-_r_1_",
+ "count": 1
+ },
+ {
+ "kind": "unregister",
+ "owner": "radix-_r_4_",
+ "count": 0
+ },
+ {
+ "kind": "listener-removed"
+ }
+ ]
+ },
+ "browserErrors": []
+ },
+ {
+ "engine": "chromium",
+ "browser": "151.0.7922.34",
+ "mode": "production",
+ "variant": "raw",
+ "case": "ordinary",
+ "status": "pass",
+ "observed": {
+ "active": "outer-trigger",
+ "dialogs": 0,
+ "changes": [
+ {
+ "name": "outer",
+ "value": true
+ },
+ {
+ "name": "outer",
+ "value": false
+ }
+ ],
+ "escapes": [
+ "outer"
+ ],
+ "trace": []
+ },
+ "browserErrors": []
+ },
+ {
+ "engine": "chromium",
+ "browser": "151.0.7922.34",
+ "mode": "production",
+ "variant": "raw",
+ "case": "nested-immediate",
+ "status": "pass",
+ "observed": {
+ "active": "outer-trigger",
+ "dialogs": 0,
+ "changes": [
+ {
+ "name": "outer",
+ "value": true
+ },
+ {
+ "name": "inner",
+ "value": true
+ },
+ {
+ "name": "inner",
+ "value": false
+ },
+ {
+ "name": "outer",
+ "value": false
+ }
+ ],
+ "escapes": [
+ "inner",
+ "outer"
+ ],
+ "trace": []
+ },
+ "browserErrors": []
+ },
+ {
+ "engine": "chromium",
+ "browser": "151.0.7922.34",
+ "mode": "production",
+ "variant": "raw",
+ "case": "cancel-inner",
+ "status": "fail",
+ "error": "Expected values to be strictly equal:\n\n1 !== 2\n",
+ "observed": {
+ "active": "inner-close",
+ "dialogs": 2,
+ "changes": [
+ {
+ "name": "outer",
+ "value": true
+ },
+ {
+ "name": "inner",
+ "value": true
+ }
+ ],
+ "escapes": [
+ "inner"
+ ],
+ "trace": []
+ },
+ "browserErrors": []
+ },
+ {
+ "engine": "chromium",
+ "browser": "151.0.7922.34",
+ "mode": "production",
+ "variant": "raw",
+ "case": "remove-trigger",
+ "status": "pass",
+ "observed": {
+ "active": "outer-trigger",
+ "dialogs": 0,
+ "changes": [
+ {
+ "name": "outer",
+ "value": true
+ },
+ {
+ "name": "inner",
+ "value": true
+ },
+ {
+ "name": "outer",
+ "value": false
+ }
+ ],
+ "escapes": [
+ "outer"
+ ],
+ "trace": []
+ },
+ "browserErrors": []
+ },
+ {
+ "engine": "chromium",
+ "browser": "151.0.7922.34",
+ "mode": "production",
+ "variant": "raw",
+ "case": "remove-and-reopen",
+ "status": "fail",
+ "error": "page.waitForFunction: Timeout 1200ms exceeded.",
+ "observed": {
+ "active": "outer-trigger",
+ "dialogs": 0,
+ "changes": [
+ {
+ "name": "outer",
+ "value": true
+ },
+ {
+ "name": "inner",
+ "value": true
+ },
+ {
+ "name": "inner",
+ "value": true
+ },
+ {
+ "name": "outer",
+ "value": false
+ }
+ ],
+ "escapes": [
+ "outer"
+ ],
+ "trace": []
+ },
+ "browserErrors": []
+ },
+ {
+ "engine": "chromium",
+ "browser": "151.0.7922.34",
+ "mode": "production",
+ "variant": "raw",
+ "case": "ancestor-teardown",
+ "status": "pass",
+ "observed": {
+ "active": "next",
+ "dialogs": 0,
+ "changes": [
+ {
+ "name": "outer",
+ "value": true
+ },
+ {
+ "name": "inner",
+ "value": true
+ }
+ ],
+ "escapes": [],
+ "trace": []
+ },
+ "browserErrors": []
+ },
+ {
+ "engine": "chromium",
+ "browser": "151.0.7922.34",
+ "mode": "production",
+ "variant": "routed",
+ "case": "ordinary",
+ "status": "pass",
+ "observed": {
+ "active": "outer-trigger",
+ "dialogs": 0,
+ "changes": [
+ {
+ "name": "outer",
+ "value": true
+ },
+ {
+ "name": "outer",
+ "value": false
+ }
+ ],
+ "escapes": [
+ "outer"
+ ],
+ "trace": [
+ {
+ "kind": "register",
+ "owner": "radix-_r_1_",
+ "count": 1
+ },
+ {
+ "kind": "dispatch",
+ "owner": "radix-_r_1_"
+ },
+ {
+ "kind": "unregister",
+ "owner": "radix-_r_1_",
+ "count": 0
+ },
+ {
+ "kind": "listener-removed"
+ }
+ ]
+ },
+ "browserErrors": []
+ },
+ {
+ "engine": "chromium",
+ "browser": "151.0.7922.34",
+ "mode": "production",
+ "variant": "routed",
+ "case": "nested-immediate",
+ "status": "pass",
+ "observed": {
+ "active": "outer-trigger",
+ "dialogs": 0,
+ "changes": [
+ {
+ "name": "outer",
+ "value": true
+ },
+ {
+ "name": "inner",
+ "value": true
+ },
+ {
+ "name": "inner",
+ "value": false
+ },
+ {
+ "name": "outer",
+ "value": false
+ }
+ ],
+ "escapes": [
+ "inner",
+ "outer"
+ ],
+ "trace": [
+ {
+ "kind": "register",
+ "owner": "radix-_r_1_",
+ "count": 1
+ },
+ {
+ "kind": "register",
+ "owner": "radix-_r_4_",
+ "count": 2
+ },
+ {
+ "kind": "dispatch",
+ "owner": "radix-_r_4_"
+ },
+ {
+ "kind": "unregister",
+ "owner": "radix-_r_4_",
+ "count": 1
+ },
+ {
+ "kind": "dispatch",
+ "owner": "radix-_r_1_"
+ },
+ {
+ "kind": "unregister",
+ "owner": "radix-_r_1_",
+ "count": 0
+ },
+ {
+ "kind": "listener-removed"
+ }
+ ]
+ },
+ "browserErrors": []
+ },
+ {
+ "engine": "chromium",
+ "browser": "151.0.7922.34",
+ "mode": "production",
+ "variant": "routed",
+ "case": "cancel-inner",
+ "status": "fail",
+ "error": "Expected values to be strictly equal:\n\n1 !== 2\n",
+ "observed": {
+ "active": "inner-close",
+ "dialogs": 2,
+ "changes": [
+ {
+ "name": "outer",
+ "value": true
+ },
+ {
+ "name": "inner",
+ "value": true
+ }
+ ],
+ "escapes": [
+ "inner"
+ ],
+ "trace": [
+ {
+ "kind": "register",
+ "owner": "radix-_r_1_",
+ "count": 1
+ },
+ {
+ "kind": "register",
+ "owner": "radix-_r_4_",
+ "count": 2
+ },
+ {
+ "kind": "dispatch",
+ "owner": "radix-_r_4_"
+ }
+ ]
+ },
+ "browserErrors": []
+ },
+ {
+ "engine": "chromium",
+ "browser": "151.0.7922.34",
+ "mode": "production",
+ "variant": "routed",
+ "case": "remove-trigger",
+ "status": "pass",
+ "observed": {
+ "active": "outer-trigger",
+ "dialogs": 0,
+ "changes": [
+ {
+ "name": "outer",
+ "value": true
+ },
+ {
+ "name": "inner",
+ "value": true
+ },
+ {
+ "name": "outer",
+ "value": false
+ }
+ ],
+ "escapes": [
+ "outer"
+ ],
+ "trace": [
+ {
+ "kind": "register",
+ "owner": "radix-_r_1_",
+ "count": 1
+ },
+ {
+ "kind": "register",
+ "owner": "radix-_r_4_",
+ "count": 2
+ },
+ {
+ "kind": "unregister",
+ "owner": "radix-_r_4_",
+ "count": 1
+ },
+ {
+ "kind": "dispatch",
+ "owner": "radix-_r_1_"
+ },
+ {
+ "kind": "unregister",
+ "owner": "radix-_r_1_",
+ "count": 0
+ },
+ {
+ "kind": "listener-removed"
+ }
+ ]
+ },
+ "browserErrors": []
+ },
+ {
+ "engine": "chromium",
+ "browser": "151.0.7922.34",
+ "mode": "production",
+ "variant": "routed",
+ "case": "remove-and-reopen",
+ "status": "pass",
+ "observed": {
+ "active": "inner-trigger",
+ "dialogs": 1,
+ "changes": [
+ {
+ "name": "outer",
+ "value": true
+ },
+ {
+ "name": "inner",
+ "value": true
+ },
+ {
+ "name": "inner",
+ "value": true
+ },
+ {
+ "name": "inner",
+ "value": false
+ }
+ ],
+ "escapes": [
+ "inner"
+ ],
+ "trace": [
+ {
+ "kind": "register",
+ "owner": "radix-_r_1_",
+ "count": 1
+ },
+ {
+ "kind": "register",
+ "owner": "radix-_r_4_",
+ "count": 2
+ },
+ {
+ "kind": "unregister",
+ "owner": "radix-_r_4_",
+ "count": 1
+ },
+ {
+ "kind": "register",
+ "owner": "radix-_r_4_",
+ "count": 2
+ },
+ {
+ "kind": "dispatch",
+ "owner": "radix-_r_4_"
+ },
+ {
+ "kind": "unregister",
+ "owner": "radix-_r_4_",
+ "count": 1
+ }
+ ]
+ },
+ "browserErrors": []
+ },
+ {
+ "engine": "chromium",
+ "browser": "151.0.7922.34",
+ "mode": "production",
+ "variant": "routed",
+ "case": "ancestor-teardown",
+ "status": "pass",
+ "observed": {
+ "active": "next",
+ "dialogs": 0,
+ "changes": [
+ {
+ "name": "outer",
+ "value": true
+ },
+ {
+ "name": "inner",
+ "value": true
+ }
+ ],
+ "escapes": [],
+ "trace": [
+ {
+ "kind": "register",
+ "owner": "radix-_r_1_",
+ "count": 1
+ },
+ {
+ "kind": "register",
+ "owner": "radix-_r_4_",
+ "count": 2
+ },
+ {
+ "kind": "unregister",
+ "owner": "radix-_r_1_",
+ "count": 1
+ },
+ {
+ "kind": "unregister",
+ "owner": "radix-_r_4_",
+ "count": 0
+ },
+ {
+ "kind": "listener-removed"
+ }
+ ]
+ },
+ "browserErrors": []
+ },
+ {
+ "engine": "firefox",
+ "browser": "155.0",
+ "mode": "development",
+ "variant": "raw",
+ "case": "ordinary",
+ "status": "pass",
+ "observed": {
+ "active": "outer-trigger",
+ "dialogs": 0,
+ "changes": [
+ {
+ "name": "outer",
+ "value": true
+ },
+ {
+ "name": "outer",
+ "value": false
+ }
+ ],
+ "escapes": [
+ "outer"
+ ],
+ "trace": []
+ },
+ "browserErrors": []
+ },
+ {
+ "engine": "firefox",
+ "browser": "155.0",
+ "mode": "development",
+ "variant": "raw",
+ "case": "nested-immediate",
+ "status": "pass",
+ "observed": {
+ "active": "outer-trigger",
+ "dialogs": 0,
+ "changes": [
+ {
+ "name": "outer",
+ "value": true
+ },
+ {
+ "name": "inner",
+ "value": true
+ },
+ {
+ "name": "inner",
+ "value": false
+ },
+ {
+ "name": "outer",
+ "value": false
+ }
+ ],
+ "escapes": [
+ "inner",
+ "outer"
+ ],
+ "trace": []
+ },
+ "browserErrors": []
+ },
+ {
+ "engine": "firefox",
+ "browser": "155.0",
+ "mode": "development",
+ "variant": "raw",
+ "case": "cancel-inner",
+ "status": "fail",
+ "error": "Expected values to be strictly equal:\n\n1 !== 2\n",
+ "observed": {
+ "active": "inner-close",
+ "dialogs": 2,
+ "changes": [
+ {
+ "name": "outer",
+ "value": true
+ },
+ {
+ "name": "inner",
+ "value": true
+ }
+ ],
+ "escapes": [
+ "inner"
+ ],
+ "trace": []
+ },
+ "browserErrors": []
+ },
+ {
+ "engine": "firefox",
+ "browser": "155.0",
+ "mode": "development",
+ "variant": "raw",
+ "case": "remove-trigger",
+ "status": "pass",
+ "observed": {
+ "active": "outer-trigger",
+ "dialogs": 0,
+ "changes": [
+ {
+ "name": "outer",
+ "value": true
+ },
+ {
+ "name": "inner",
+ "value": true
+ },
+ {
+ "name": "outer",
+ "value": false
+ }
+ ],
+ "escapes": [
+ "outer"
+ ],
+ "trace": []
+ },
+ "browserErrors": []
+ },
+ {
+ "engine": "firefox",
+ "browser": "155.0",
+ "mode": "development",
+ "variant": "raw",
+ "case": "remove-and-reopen",
+ "status": "pass",
+ "observed": {
+ "active": "inner-trigger",
+ "dialogs": 1,
+ "changes": [
+ {
+ "name": "outer",
+ "value": true
+ },
+ {
+ "name": "inner",
+ "value": true
+ },
+ {
+ "name": "inner",
+ "value": true
+ },
+ {
+ "name": "inner",
+ "value": false
+ }
+ ],
+ "escapes": [
+ "inner"
+ ],
+ "trace": []
+ },
+ "browserErrors": []
+ },
+ {
+ "engine": "firefox",
+ "browser": "155.0",
+ "mode": "development",
+ "variant": "raw",
+ "case": "ancestor-teardown",
+ "status": "pass",
+ "observed": {
+ "active": "next",
+ "dialogs": 0,
+ "changes": [
+ {
+ "name": "outer",
+ "value": true
+ },
+ {
+ "name": "inner",
+ "value": true
+ }
+ ],
+ "escapes": [],
+ "trace": []
+ },
+ "browserErrors": []
+ },
+ {
+ "engine": "firefox",
+ "browser": "155.0",
+ "mode": "development",
+ "variant": "routed",
+ "case": "ordinary",
+ "status": "pass",
+ "observed": {
+ "active": "outer-trigger",
+ "dialogs": 0,
+ "changes": [
+ {
+ "name": "outer",
+ "value": true
+ },
+ {
+ "name": "outer",
+ "value": false
+ }
+ ],
+ "escapes": [
+ "outer"
+ ],
+ "trace": [
+ {
+ "kind": "register",
+ "owner": "radix-_r_1_",
+ "count": 1
+ },
+ {
+ "kind": "dispatch",
+ "owner": "radix-_r_1_"
+ },
+ {
+ "kind": "unregister",
+ "owner": "radix-_r_1_",
+ "count": 0
+ },
+ {
+ "kind": "listener-removed"
+ }
+ ]
+ },
+ "browserErrors": []
+ },
+ {
+ "engine": "firefox",
+ "browser": "155.0",
+ "mode": "development",
+ "variant": "routed",
+ "case": "nested-immediate",
+ "status": "pass",
+ "observed": {
+ "active": "outer-trigger",
+ "dialogs": 0,
+ "changes": [
+ {
+ "name": "outer",
+ "value": true
+ },
+ {
+ "name": "inner",
+ "value": true
+ },
+ {
+ "name": "inner",
+ "value": false
+ },
+ {
+ "name": "outer",
+ "value": false
+ }
+ ],
+ "escapes": [
+ "inner",
+ "outer"
+ ],
+ "trace": [
+ {
+ "kind": "register",
+ "owner": "radix-_r_1_",
+ "count": 1
+ },
+ {
+ "kind": "register",
+ "owner": "radix-_r_4_",
+ "count": 2
+ },
+ {
+ "kind": "dispatch",
+ "owner": "radix-_r_4_"
+ },
+ {
+ "kind": "unregister",
+ "owner": "radix-_r_4_",
+ "count": 1
+ },
+ {
+ "kind": "dispatch",
+ "owner": "radix-_r_1_"
+ },
+ {
+ "kind": "unregister",
+ "owner": "radix-_r_1_",
+ "count": 0
+ },
+ {
+ "kind": "listener-removed"
+ }
+ ]
+ },
+ "browserErrors": []
+ },
+ {
+ "engine": "firefox",
+ "browser": "155.0",
+ "mode": "development",
+ "variant": "routed",
+ "case": "cancel-inner",
+ "status": "fail",
+ "error": "Expected values to be strictly equal:\n\n1 !== 2\n",
+ "observed": {
+ "active": "inner-close",
+ "dialogs": 2,
+ "changes": [
+ {
+ "name": "outer",
+ "value": true
+ },
+ {
+ "name": "inner",
+ "value": true
+ }
+ ],
+ "escapes": [
+ "inner"
+ ],
+ "trace": [
+ {
+ "kind": "register",
+ "owner": "radix-_r_1_",
+ "count": 1
+ },
+ {
+ "kind": "register",
+ "owner": "radix-_r_4_",
+ "count": 2
+ },
+ {
+ "kind": "dispatch",
+ "owner": "radix-_r_4_"
+ }
+ ]
+ },
+ "browserErrors": []
+ },
+ {
+ "engine": "firefox",
+ "browser": "155.0",
+ "mode": "development",
+ "variant": "routed",
+ "case": "remove-trigger",
+ "status": "pass",
+ "observed": {
+ "active": "outer-trigger",
+ "dialogs": 0,
+ "changes": [
+ {
+ "name": "outer",
+ "value": true
+ },
+ {
+ "name": "inner",
+ "value": true
+ },
+ {
+ "name": "outer",
+ "value": false
+ }
+ ],
+ "escapes": [
+ "outer"
+ ],
+ "trace": [
+ {
+ "kind": "register",
+ "owner": "radix-_r_1_",
+ "count": 1
+ },
+ {
+ "kind": "register",
+ "owner": "radix-_r_4_",
+ "count": 2
+ },
+ {
+ "kind": "unregister",
+ "owner": "radix-_r_4_",
+ "count": 1
+ },
+ {
+ "kind": "dispatch",
+ "owner": "radix-_r_1_"
+ },
+ {
+ "kind": "unregister",
+ "owner": "radix-_r_1_",
+ "count": 0
+ },
+ {
+ "kind": "listener-removed"
+ }
+ ]
+ },
+ "browserErrors": []
+ },
+ {
+ "engine": "firefox",
+ "browser": "155.0",
+ "mode": "development",
+ "variant": "routed",
+ "case": "remove-and-reopen",
+ "status": "pass",
+ "observed": {
+ "active": "inner-trigger",
+ "dialogs": 1,
+ "changes": [
+ {
+ "name": "outer",
+ "value": true
+ },
+ {
+ "name": "inner",
+ "value": true
+ },
+ {
+ "name": "inner",
+ "value": true
+ },
+ {
+ "name": "inner",
+ "value": false
+ }
+ ],
+ "escapes": [
+ "inner"
+ ],
+ "trace": [
+ {
+ "kind": "register",
+ "owner": "radix-_r_1_",
+ "count": 1
+ },
+ {
+ "kind": "register",
+ "owner": "radix-_r_4_",
+ "count": 2
+ },
+ {
+ "kind": "unregister",
+ "owner": "radix-_r_4_",
+ "count": 1
+ },
+ {
+ "kind": "register",
+ "owner": "radix-_r_4_",
+ "count": 2
+ },
+ {
+ "kind": "dispatch",
+ "owner": "radix-_r_4_"
+ },
+ {
+ "kind": "unregister",
+ "owner": "radix-_r_4_",
+ "count": 1
+ }
+ ]
+ },
+ "browserErrors": []
+ },
+ {
+ "engine": "firefox",
+ "browser": "155.0",
+ "mode": "development",
+ "variant": "routed",
+ "case": "ancestor-teardown",
+ "status": "pass",
+ "observed": {
+ "active": "next",
+ "dialogs": 0,
+ "changes": [
+ {
+ "name": "outer",
+ "value": true
+ },
+ {
+ "name": "inner",
+ "value": true
+ }
+ ],
+ "escapes": [],
+ "trace": [
+ {
+ "kind": "register",
+ "owner": "radix-_r_1_",
+ "count": 1
+ },
+ {
+ "kind": "register",
+ "owner": "radix-_r_4_",
+ "count": 2
+ },
+ {
+ "kind": "unregister",
+ "owner": "radix-_r_1_",
+ "count": 1
+ },
+ {
+ "kind": "unregister",
+ "owner": "radix-_r_4_",
+ "count": 0
+ },
+ {
+ "kind": "listener-removed"
+ }
+ ]
+ },
+ "browserErrors": []
+ },
+ {
+ "engine": "firefox",
+ "browser": "155.0",
+ "mode": "production",
+ "variant": "raw",
+ "case": "ordinary",
+ "status": "pass",
+ "observed": {
+ "active": "outer-trigger",
+ "dialogs": 0,
+ "changes": [
+ {
+ "name": "outer",
+ "value": true
+ },
+ {
+ "name": "outer",
+ "value": false
+ }
+ ],
+ "escapes": [
+ "outer"
+ ],
+ "trace": []
+ },
+ "browserErrors": []
+ },
+ {
+ "engine": "firefox",
+ "browser": "155.0",
+ "mode": "production",
+ "variant": "raw",
+ "case": "nested-immediate",
+ "status": "pass",
+ "observed": {
+ "active": "outer-trigger",
+ "dialogs": 0,
+ "changes": [
+ {
+ "name": "outer",
+ "value": true
+ },
+ {
+ "name": "inner",
+ "value": true
+ },
+ {
+ "name": "inner",
+ "value": false
+ },
+ {
+ "name": "outer",
+ "value": false
+ }
+ ],
+ "escapes": [
+ "inner",
+ "outer"
+ ],
+ "trace": []
+ },
+ "browserErrors": []
+ },
+ {
+ "engine": "firefox",
+ "browser": "155.0",
+ "mode": "production",
+ "variant": "raw",
+ "case": "cancel-inner",
+ "status": "fail",
+ "error": "Expected values to be strictly equal:\n\n1 !== 2\n",
+ "observed": {
+ "active": "inner-close",
+ "dialogs": 2,
+ "changes": [
+ {
+ "name": "outer",
+ "value": true
+ },
+ {
+ "name": "inner",
+ "value": true
+ }
+ ],
+ "escapes": [
+ "inner"
+ ],
+ "trace": []
+ },
+ "browserErrors": []
+ },
+ {
+ "engine": "firefox",
+ "browser": "155.0",
+ "mode": "production",
+ "variant": "raw",
+ "case": "remove-trigger",
+ "status": "pass",
+ "observed": {
+ "active": "outer-trigger",
+ "dialogs": 0,
+ "changes": [
+ {
+ "name": "outer",
+ "value": true
+ },
+ {
+ "name": "inner",
+ "value": true
+ },
+ {
+ "name": "outer",
+ "value": false
+ }
+ ],
+ "escapes": [
+ "outer"
+ ],
+ "trace": []
+ },
+ "browserErrors": []
+ },
+ {
+ "engine": "firefox",
+ "browser": "155.0",
+ "mode": "production",
+ "variant": "raw",
+ "case": "remove-and-reopen",
+ "status": "pass",
+ "observed": {
+ "active": "inner-trigger",
+ "dialogs": 1,
+ "changes": [
+ {
+ "name": "outer",
+ "value": true
+ },
+ {
+ "name": "inner",
+ "value": true
+ },
+ {
+ "name": "inner",
+ "value": true
+ },
+ {
+ "name": "inner",
+ "value": false
+ }
+ ],
+ "escapes": [
+ "inner"
+ ],
+ "trace": []
+ },
+ "browserErrors": []
+ },
+ {
+ "engine": "firefox",
+ "browser": "155.0",
+ "mode": "production",
+ "variant": "raw",
+ "case": "ancestor-teardown",
+ "status": "pass",
+ "observed": {
+ "active": "next",
+ "dialogs": 0,
+ "changes": [
+ {
+ "name": "outer",
+ "value": true
+ },
+ {
+ "name": "inner",
+ "value": true
+ }
+ ],
+ "escapes": [],
+ "trace": []
+ },
+ "browserErrors": []
+ },
+ {
+ "engine": "firefox",
+ "browser": "155.0",
+ "mode": "production",
+ "variant": "routed",
+ "case": "ordinary",
+ "status": "pass",
+ "observed": {
+ "active": "outer-trigger",
+ "dialogs": 0,
+ "changes": [
+ {
+ "name": "outer",
+ "value": true
+ },
+ {
+ "name": "outer",
+ "value": false
+ }
+ ],
+ "escapes": [
+ "outer"
+ ],
+ "trace": [
+ {
+ "kind": "register",
+ "owner": "radix-_r_1_",
+ "count": 1
+ },
+ {
+ "kind": "dispatch",
+ "owner": "radix-_r_1_"
+ },
+ {
+ "kind": "unregister",
+ "owner": "radix-_r_1_",
+ "count": 0
+ },
+ {
+ "kind": "listener-removed"
+ }
+ ]
+ },
+ "browserErrors": []
+ },
+ {
+ "engine": "firefox",
+ "browser": "155.0",
+ "mode": "production",
+ "variant": "routed",
+ "case": "nested-immediate",
+ "status": "pass",
+ "observed": {
+ "active": "outer-trigger",
+ "dialogs": 0,
+ "changes": [
+ {
+ "name": "outer",
+ "value": true
+ },
+ {
+ "name": "inner",
+ "value": true
+ },
+ {
+ "name": "inner",
+ "value": false
+ },
+ {
+ "name": "outer",
+ "value": false
+ }
+ ],
+ "escapes": [
+ "inner",
+ "outer"
+ ],
+ "trace": [
+ {
+ "kind": "register",
+ "owner": "radix-_r_1_",
+ "count": 1
+ },
+ {
+ "kind": "register",
+ "owner": "radix-_r_4_",
+ "count": 2
+ },
+ {
+ "kind": "dispatch",
+ "owner": "radix-_r_4_"
+ },
+ {
+ "kind": "unregister",
+ "owner": "radix-_r_4_",
+ "count": 1
+ },
+ {
+ "kind": "dispatch",
+ "owner": "radix-_r_1_"
+ },
+ {
+ "kind": "unregister",
+ "owner": "radix-_r_1_",
+ "count": 0
+ },
+ {
+ "kind": "listener-removed"
+ }
+ ]
+ },
+ "browserErrors": []
+ },
+ {
+ "engine": "firefox",
+ "browser": "155.0",
+ "mode": "production",
+ "variant": "routed",
+ "case": "cancel-inner",
+ "status": "fail",
+ "error": "Expected values to be strictly equal:\n\n1 !== 2\n",
+ "observed": {
+ "active": "inner-close",
+ "dialogs": 2,
+ "changes": [
+ {
+ "name": "outer",
+ "value": true
+ },
+ {
+ "name": "inner",
+ "value": true
+ }
+ ],
+ "escapes": [
+ "inner"
+ ],
+ "trace": [
+ {
+ "kind": "register",
+ "owner": "radix-_r_1_",
+ "count": 1
+ },
+ {
+ "kind": "register",
+ "owner": "radix-_r_4_",
+ "count": 2
+ },
+ {
+ "kind": "dispatch",
+ "owner": "radix-_r_4_"
+ }
+ ]
+ },
+ "browserErrors": []
+ },
+ {
+ "engine": "firefox",
+ "browser": "155.0",
+ "mode": "production",
+ "variant": "routed",
+ "case": "remove-trigger",
+ "status": "pass",
+ "observed": {
+ "active": "outer-trigger",
+ "dialogs": 0,
+ "changes": [
+ {
+ "name": "outer",
+ "value": true
+ },
+ {
+ "name": "inner",
+ "value": true
+ },
+ {
+ "name": "outer",
+ "value": false
+ }
+ ],
+ "escapes": [
+ "outer"
+ ],
+ "trace": [
+ {
+ "kind": "register",
+ "owner": "radix-_r_1_",
+ "count": 1
+ },
+ {
+ "kind": "register",
+ "owner": "radix-_r_4_",
+ "count": 2
+ },
+ {
+ "kind": "unregister",
+ "owner": "radix-_r_4_",
+ "count": 1
+ },
+ {
+ "kind": "dispatch",
+ "owner": "radix-_r_1_"
+ },
+ {
+ "kind": "unregister",
+ "owner": "radix-_r_1_",
+ "count": 0
+ },
+ {
+ "kind": "listener-removed"
+ }
+ ]
+ },
+ "browserErrors": []
+ },
+ {
+ "engine": "firefox",
+ "browser": "155.0",
+ "mode": "production",
+ "variant": "routed",
+ "case": "remove-and-reopen",
+ "status": "pass",
+ "observed": {
+ "active": "inner-trigger",
+ "dialogs": 1,
+ "changes": [
+ {
+ "name": "outer",
+ "value": true
+ },
+ {
+ "name": "inner",
+ "value": true
+ },
+ {
+ "name": "inner",
+ "value": true
+ },
+ {
+ "name": "inner",
+ "value": false
+ }
+ ],
+ "escapes": [
+ "inner"
+ ],
+ "trace": [
+ {
+ "kind": "register",
+ "owner": "radix-_r_1_",
+ "count": 1
+ },
+ {
+ "kind": "register",
+ "owner": "radix-_r_4_",
+ "count": 2
+ },
+ {
+ "kind": "unregister",
+ "owner": "radix-_r_4_",
+ "count": 1
+ },
+ {
+ "kind": "register",
+ "owner": "radix-_r_4_",
+ "count": 2
+ },
+ {
+ "kind": "dispatch",
+ "owner": "radix-_r_4_"
+ },
+ {
+ "kind": "unregister",
+ "owner": "radix-_r_4_",
+ "count": 1
+ }
+ ]
+ },
+ "browserErrors": []
+ },
+ {
+ "engine": "firefox",
+ "browser": "155.0",
+ "mode": "production",
+ "variant": "routed",
+ "case": "ancestor-teardown",
+ "status": "pass",
+ "observed": {
+ "active": "next",
+ "dialogs": 0,
+ "changes": [
+ {
+ "name": "outer",
+ "value": true
+ },
+ {
+ "name": "inner",
+ "value": true
+ }
+ ],
+ "escapes": [],
+ "trace": [
+ {
+ "kind": "register",
+ "owner": "radix-_r_1_",
+ "count": 1
+ },
+ {
+ "kind": "register",
+ "owner": "radix-_r_4_",
+ "count": 2
+ },
+ {
+ "kind": "unregister",
+ "owner": "radix-_r_1_",
+ "count": 1
+ },
+ {
+ "kind": "unregister",
+ "owner": "radix-_r_4_",
+ "count": 0
+ },
+ {
+ "kind": "listener-removed"
+ }
+ ]
+ },
+ "browserErrors": []
+ }
+ ]
+}
diff --git a/research/experiments/boundary-recovery/routing-development-runner.mjs b/research/experiments/boundary-recovery/routing-development-runner.mjs
new file mode 100644
index 0000000..2b2011d
--- /dev/null
+++ b/research/experiments/boundary-recovery/routing-development-runner.mjs
@@ -0,0 +1,46 @@
+import {build} from 'esbuild';
+import {chromium, firefox} from 'playwright';
+import {createServer} from 'node:http';
+import {once} from 'node:events';
+import {readFile, writeFile} from 'node:fs/promises';
+import {createHash} from 'node:crypto';
+import {fileURLToPath} from 'node:url';
+import assert from 'node:assert/strict';
+import {routeEscape} from './routing-transform.mjs';
+const dir=fileURLToPath(new URL('.',import.meta.url));
+const hash=x=>createHash('sha256').update(x).digest('hex');
+const source=await readFile(dir+'node_modules/@radix-ui/react-dismissable-layer/dist/index.mjs','utf8');
+assert.equal(hash(source),JSON.parse(await readFile(dir+'provenance.json')).inspected_files['@radix-ui/react-dismissable-layer/dist/index.mjs'].sha256);
+const bundles=new Map();
+for(const mode of ['development','production']) for(const variant of ['raw','routed']) {
+ const b=await build({entryPoints:[dir+'routing-fixture.jsx'],bundle:true,write:false,format:'iife',define:{'process.env.NODE_ENV':JSON.stringify(mode)},plugins:variant==='raw'?[]:[{name:'experimental-escape-router',setup(b){b.onLoad({filter:/@radix-ui\/react-dismissable-layer\/dist\/index\.mjs$/},()=>({contents:routeEscape(source),loader:'js',resolveDir:dir+'node_modules/@radix-ui/react-dismissable-layer/dist'}));}}]});
+ bundles.set(mode+'-'+variant,b.outputFiles[0].contents);
+}
+const server=createServer((req,res)=>{const u=new URL(req.url,'http://localhost');if(u.pathname==='/bundle.js'){res.setHeader('Content-Type','application/javascript');res.end(bundles.get(u.searchParams.get('key')));}else{res.setHeader('Content-Type','text/html');res.end(`
Routing experiment`);}});
+server.listen(0,'127.0.0.1');await once(server,'listening');
+const results=[];
+async function focused(page,id){await page.waitForFunction(id=>document.activeElement?.id===id,id,{timeout:1200});}
+async function outer(page){await page.locator('#outer-trigger').focus();await page.keyboard.press('Enter');await focused(page,'inner-trigger');}
+async function inner(page){await outer(page);await page.keyboard.press('Enter');await focused(page,'inner-close');}
+const cases={
+ 'ordinary':async p=>{await outer(p);await p.keyboard.press('Escape');await focused(p,'outer-trigger');assert.deepEqual(await p.evaluate(()=>window.routingObserved.escapes),['outer']);},
+ 'nested-immediate':async p=>{await inner(p);await p.keyboard.press('Escape');await focused(p,'inner-trigger');assert.equal(await p.getByRole('dialog').count(),1);await p.keyboard.press('Escape');await focused(p,'outer-trigger');assert.deepEqual(await p.evaluate(()=>window.routingObserved.escapes),['inner','outer']);},
+ 'cancel-inner':async p=>{await inner(p);await p.keyboard.press('Escape');assert.deepEqual(await p.evaluate(()=>window.routingObserved.escapes),['inner']);assert.equal(await p.getByRole('dialog').count(),2);await focused(p,'inner-close');},
+ 'remove-trigger':async p=>{await inner(p);await p.keyboard.press('Tab');await focused(p,'remove-trigger');await p.keyboard.press('Enter');await focused(p,'outer-close');await p.keyboard.press('Escape');await focused(p,'outer-trigger');},
+ 'remove-and-reopen':async p=>{await inner(p);await p.evaluate(()=>window.removeInner());await focused(p,'inner-trigger');await p.keyboard.press('Enter');await focused(p,'inner-close');await p.keyboard.press('Escape');await focused(p,'inner-trigger');assert.deepEqual(await p.evaluate(()=>window.routingObserved.escapes),['inner']);},
+ 'ancestor-teardown':async p=>{await inner(p);await p.evaluate(()=>window.removeTask());await p.getByRole('dialog').waitFor({state:'detached'});await p.locator('#next').focus();await p.keyboard.press('Escape');assert.deepEqual(await p.evaluate(()=>window.routingObserved.escapes),[]);await focused(p,'next');}
+};
+try{
+ for(const [engine,launcher]of [['chromium',chromium],['firefox',firefox]]){
+ const browser=await launcher.launch({headless:true,...(engine==='chromium'?{executablePath:process.env.FEP_CHROMIUM_PATH}: {})});
+ try{for(const mode of ['development','production'])for(const variant of ['raw','routed'])for(const [name,run]of Object.entries(cases)){
+ const page=await browser.newPage();page.setDefaultTimeout(2000);const errors=[];page.on('pageerror',e=>errors.push(e.message));const r={engine,browser:browser.version(),mode,variant,case:name,status:'pass'};
+ try{await page.goto(`http://127.0.0.1:${server.address().port}/?key=${mode}-${variant}${name==='cancel-inner'?'&cancel=1':''}`);await run(page);assert.deepEqual(errors,[]);}catch(e){r.status='fail';r.error=e.message;}
+ r.observed=await page.evaluate(()=>({active:document.activeElement?.id,dialogs:document.querySelectorAll('[role=dialog]').length,...window.routingObserved}));r.browserErrors=errors;results.push(r);await page.close();
+ await writeFile('/tmp/fep-routing-checkpoint.json',JSON.stringify({status:'incomplete',results},null,2)+'\n');
+ }}finally{await browser.close();}
+ }
+}finally{await new Promise(resolve=>server.close(resolve));}
+const files={};for(const name of ['routing.mjs','routing-fixture.jsx','routing-transform.mjs','package.json','package-lock.json'])files[name]=hash(await readFile(dir+name));
+const summary=[];for(const engine of ['chromium','firefox'])for(const mode of ['development','production'])for(const variant of ['raw','routed']){const r=results.filter(x=>x.engine===engine&&x.mode===mode&&x.variant===variant);summary.push({engine,mode,variant,passed:r.filter(x=>x.status==='pass').length,total:r.length});}
+const output=process.env.FEP_RESULT_PATH||'/tmp/fep-routing.json';await writeFile(output,JSON.stringify({date:new Date().toISOString(),node:process.version,files,sourceSha256:hash(source),transformedSha256:hash(routeEscape(source)),bundleHashes:Object.fromEntries([...bundles].map(([k,v])=>[k,hash(v)])),summary,results},null,2)+'\n');console.log(JSON.stringify({output,summary},null,2));
diff --git a/research/experiments/boundary-recovery/routing-fixture.jsx b/research/experiments/boundary-recovery/routing-fixture.jsx
new file mode 100644
index 0000000..4518731
--- /dev/null
+++ b/research/experiments/boundary-recovery/routing-fixture.jsx
@@ -0,0 +1,35 @@
+import React, {useState, useRef} from 'react';
+import {createRoot} from 'react-dom/client';
+import * as Dialog from '@radix-ui/react-dialog';
+window.routingObserved = {changes: [], escapes: [], trace: []};
+const options = new URLSearchParams(location.search);
+function App() {
+ const [outer, setOuter] = useState(false);
+ const [inner, setInner] = useState(false);
+ const [mounted, setMounted] = useState(true);
+ const [trigger, setTrigger] = useState(true);
+ const next = useRef(null);
+ const change = (name, setter) => value => {window.routingObserved.changes.push({name, value});setter(value);};
+ window.removeInner = () => setInner(false);
+ window.removeTask = () => setMounted(false);
+ return
+ {mounted &&
+ Open outer
+ window.routingObserved.escapes.push('outer')}>
+ Outer task
+
+ {trigger && Open inner}
+ {window.routingObserved.escapes.push('inner');if(options.has('cancel')) event.preventDefault();}}
+ onCloseAutoFocus={event => {if(!trigger){event.preventDefault();document.getElementById('outer-close')?.focus();}}}>
+ Inner task
+ Close inner
+
+
+
+ Close outer
+
+ }
+ ;
+}
+createRoot(document.getElementById('root')).render();
diff --git a/research/experiments/boundary-recovery/routing-results.json b/research/experiments/boundary-recovery/routing-results.json
new file mode 100644
index 0000000..bbff8a1
--- /dev/null
+++ b/research/experiments/boundary-recovery/routing-results.json
@@ -0,0 +1,2109 @@
+{
+ "date": "2026-09-26T20:56:21.684Z",
+ "node": "v24.11.1",
+ "files": {
+ "routing.mjs": "dfe92f2d5bc12ce0e1fedf7c2cb7f69511fff3fea7219d89fd3095dfb2ccdee8",
+ "routing-fixture.jsx": "d99875390941752047eda63a93c921af977c35b36371dd609cd46e7ba730a51d",
+ "routing-transform.mjs": "417589ab170ea1576452d0a903fbd8e1870d3d91d2a49b50707c36b0aef56335",
+ "package.json": "a0ad37e8518b0c561d6b4a091ee51f5bca90e0ce329b2be7ba75347f6dc26ae7",
+ "package-lock.json": "ec4b544d441f89d9c512bc9931c1818473327105d5ef9047dc04d6a721e68463"
+ },
+ "sourceSha256": "01df449a23d65bab1f2f2215a953cba74741419496ebd9a7932533f267cc873d",
+ "transformedSha256": "1f42e26b9789a12263182ca1ee2b623870499d73456e4ad90172a8fc39c8618b",
+ "bundleHashes": {
+ "development-raw": "7fc5a9df75b15ec7da3c1a625624e2166c74609788cf46dc3ac03a88d5a639d6",
+ "development-routed": "fcdf229aeb5025a038ee6baaec7927031e032b75ed5899d1294ea199cd0921b1",
+ "production-raw": "1846d180a6fcf20426febaa355f47bc86e3b2e59a139fec55882a1ba460ab56d",
+ "production-routed": "fd73a8c4684b7cbb90ac87f08ef318a48c3b9444f8747b994e21217ee9666740"
+ },
+ "summary": [
+ {
+ "engine": "chromium",
+ "mode": "development",
+ "variant": "raw",
+ "passed": 4,
+ "total": 6
+ },
+ {
+ "engine": "chromium",
+ "mode": "development",
+ "variant": "routed",
+ "passed": 6,
+ "total": 6
+ },
+ {
+ "engine": "chromium",
+ "mode": "production",
+ "variant": "raw",
+ "passed": 4,
+ "total": 6
+ },
+ {
+ "engine": "chromium",
+ "mode": "production",
+ "variant": "routed",
+ "passed": 6,
+ "total": 6
+ },
+ {
+ "engine": "firefox",
+ "mode": "development",
+ "variant": "raw",
+ "passed": 6,
+ "total": 6
+ },
+ {
+ "engine": "firefox",
+ "mode": "development",
+ "variant": "routed",
+ "passed": 6,
+ "total": 6
+ },
+ {
+ "engine": "firefox",
+ "mode": "production",
+ "variant": "raw",
+ "passed": 6,
+ "total": 6
+ },
+ {
+ "engine": "firefox",
+ "mode": "production",
+ "variant": "routed",
+ "passed": 6,
+ "total": 6
+ }
+ ],
+ "results": [
+ {
+ "engine": "chromium",
+ "browser": "151.0.7922.34",
+ "mode": "development",
+ "variant": "raw",
+ "case": "ordinary",
+ "status": "pass",
+ "observed": {
+ "active": "outer-trigger",
+ "dialogs": 0,
+ "changes": [
+ {
+ "name": "outer",
+ "value": true
+ },
+ {
+ "name": "outer",
+ "value": false
+ }
+ ],
+ "escapes": [
+ "outer"
+ ],
+ "trace": []
+ },
+ "browserErrors": []
+ },
+ {
+ "engine": "chromium",
+ "browser": "151.0.7922.34",
+ "mode": "development",
+ "variant": "raw",
+ "case": "nested-immediate",
+ "status": "fail",
+ "error": "page.waitForFunction: Timeout 1200ms exceeded.",
+ "observed": {
+ "active": "outer-trigger",
+ "dialogs": 0,
+ "changes": [
+ {
+ "name": "outer",
+ "value": true
+ },
+ {
+ "name": "inner",
+ "value": true
+ },
+ {
+ "name": "outer",
+ "value": false
+ }
+ ],
+ "escapes": [
+ "outer"
+ ],
+ "trace": []
+ },
+ "browserErrors": []
+ },
+ {
+ "engine": "chromium",
+ "browser": "151.0.7922.34",
+ "mode": "development",
+ "variant": "raw",
+ "case": "cancel-inner",
+ "status": "pass",
+ "observed": {
+ "active": "inner-close",
+ "dialogs": 2,
+ "changes": [
+ {
+ "name": "outer",
+ "value": true
+ },
+ {
+ "name": "inner",
+ "value": true
+ }
+ ],
+ "escapes": [
+ "inner"
+ ],
+ "trace": []
+ },
+ "browserErrors": []
+ },
+ {
+ "engine": "chromium",
+ "browser": "151.0.7922.34",
+ "mode": "development",
+ "variant": "raw",
+ "case": "remove-trigger",
+ "status": "pass",
+ "observed": {
+ "active": "outer-trigger",
+ "dialogs": 0,
+ "changes": [
+ {
+ "name": "outer",
+ "value": true
+ },
+ {
+ "name": "inner",
+ "value": true
+ },
+ {
+ "name": "outer",
+ "value": false
+ }
+ ],
+ "escapes": [
+ "outer"
+ ],
+ "trace": []
+ },
+ "browserErrors": []
+ },
+ {
+ "engine": "chromium",
+ "browser": "151.0.7922.34",
+ "mode": "development",
+ "variant": "raw",
+ "case": "remove-and-reopen",
+ "status": "fail",
+ "error": "page.waitForFunction: Timeout 1200ms exceeded.",
+ "observed": {
+ "active": "outer-trigger",
+ "dialogs": 0,
+ "changes": [
+ {
+ "name": "outer",
+ "value": true
+ },
+ {
+ "name": "inner",
+ "value": true
+ },
+ {
+ "name": "inner",
+ "value": true
+ },
+ {
+ "name": "outer",
+ "value": false
+ }
+ ],
+ "escapes": [
+ "outer"
+ ],
+ "trace": []
+ },
+ "browserErrors": []
+ },
+ {
+ "engine": "chromium",
+ "browser": "151.0.7922.34",
+ "mode": "development",
+ "variant": "raw",
+ "case": "ancestor-teardown",
+ "status": "pass",
+ "observed": {
+ "active": "next",
+ "dialogs": 0,
+ "changes": [
+ {
+ "name": "outer",
+ "value": true
+ },
+ {
+ "name": "inner",
+ "value": true
+ }
+ ],
+ "escapes": [],
+ "trace": []
+ },
+ "browserErrors": []
+ },
+ {
+ "engine": "chromium",
+ "browser": "151.0.7922.34",
+ "mode": "development",
+ "variant": "routed",
+ "case": "ordinary",
+ "status": "pass",
+ "observed": {
+ "active": "outer-trigger",
+ "dialogs": 0,
+ "changes": [
+ {
+ "name": "outer",
+ "value": true
+ },
+ {
+ "name": "outer",
+ "value": false
+ }
+ ],
+ "escapes": [
+ "outer"
+ ],
+ "trace": [
+ {
+ "kind": "register",
+ "owner": "radix-_r_1_",
+ "count": 1
+ },
+ {
+ "kind": "dispatch",
+ "owner": "radix-_r_1_"
+ },
+ {
+ "kind": "unregister",
+ "owner": "radix-_r_1_",
+ "count": 0
+ },
+ {
+ "kind": "listener-removed"
+ }
+ ]
+ },
+ "browserErrors": []
+ },
+ {
+ "engine": "chromium",
+ "browser": "151.0.7922.34",
+ "mode": "development",
+ "variant": "routed",
+ "case": "nested-immediate",
+ "status": "pass",
+ "observed": {
+ "active": "outer-trigger",
+ "dialogs": 0,
+ "changes": [
+ {
+ "name": "outer",
+ "value": true
+ },
+ {
+ "name": "inner",
+ "value": true
+ },
+ {
+ "name": "inner",
+ "value": false
+ },
+ {
+ "name": "outer",
+ "value": false
+ }
+ ],
+ "escapes": [
+ "inner",
+ "outer"
+ ],
+ "trace": [
+ {
+ "kind": "register",
+ "owner": "radix-_r_1_",
+ "count": 1
+ },
+ {
+ "kind": "register",
+ "owner": "radix-_r_4_",
+ "count": 2
+ },
+ {
+ "kind": "dispatch",
+ "owner": "radix-_r_4_"
+ },
+ {
+ "kind": "unregister",
+ "owner": "radix-_r_4_",
+ "count": 1
+ },
+ {
+ "kind": "dispatch",
+ "owner": "radix-_r_1_"
+ },
+ {
+ "kind": "unregister",
+ "owner": "radix-_r_1_",
+ "count": 0
+ },
+ {
+ "kind": "listener-removed"
+ }
+ ]
+ },
+ "browserErrors": []
+ },
+ {
+ "engine": "chromium",
+ "browser": "151.0.7922.34",
+ "mode": "development",
+ "variant": "routed",
+ "case": "cancel-inner",
+ "status": "pass",
+ "observed": {
+ "active": "inner-close",
+ "dialogs": 2,
+ "changes": [
+ {
+ "name": "outer",
+ "value": true
+ },
+ {
+ "name": "inner",
+ "value": true
+ }
+ ],
+ "escapes": [
+ "inner"
+ ],
+ "trace": [
+ {
+ "kind": "register",
+ "owner": "radix-_r_1_",
+ "count": 1
+ },
+ {
+ "kind": "register",
+ "owner": "radix-_r_4_",
+ "count": 2
+ },
+ {
+ "kind": "dispatch",
+ "owner": "radix-_r_4_"
+ }
+ ]
+ },
+ "browserErrors": []
+ },
+ {
+ "engine": "chromium",
+ "browser": "151.0.7922.34",
+ "mode": "development",
+ "variant": "routed",
+ "case": "remove-trigger",
+ "status": "pass",
+ "observed": {
+ "active": "outer-trigger",
+ "dialogs": 0,
+ "changes": [
+ {
+ "name": "outer",
+ "value": true
+ },
+ {
+ "name": "inner",
+ "value": true
+ },
+ {
+ "name": "outer",
+ "value": false
+ }
+ ],
+ "escapes": [
+ "outer"
+ ],
+ "trace": [
+ {
+ "kind": "register",
+ "owner": "radix-_r_1_",
+ "count": 1
+ },
+ {
+ "kind": "register",
+ "owner": "radix-_r_4_",
+ "count": 2
+ },
+ {
+ "kind": "unregister",
+ "owner": "radix-_r_4_",
+ "count": 1
+ },
+ {
+ "kind": "dispatch",
+ "owner": "radix-_r_1_"
+ },
+ {
+ "kind": "unregister",
+ "owner": "radix-_r_1_",
+ "count": 0
+ },
+ {
+ "kind": "listener-removed"
+ }
+ ]
+ },
+ "browserErrors": []
+ },
+ {
+ "engine": "chromium",
+ "browser": "151.0.7922.34",
+ "mode": "development",
+ "variant": "routed",
+ "case": "remove-and-reopen",
+ "status": "pass",
+ "observed": {
+ "active": "inner-trigger",
+ "dialogs": 1,
+ "changes": [
+ {
+ "name": "outer",
+ "value": true
+ },
+ {
+ "name": "inner",
+ "value": true
+ },
+ {
+ "name": "inner",
+ "value": true
+ },
+ {
+ "name": "inner",
+ "value": false
+ }
+ ],
+ "escapes": [
+ "inner"
+ ],
+ "trace": [
+ {
+ "kind": "register",
+ "owner": "radix-_r_1_",
+ "count": 1
+ },
+ {
+ "kind": "register",
+ "owner": "radix-_r_4_",
+ "count": 2
+ },
+ {
+ "kind": "unregister",
+ "owner": "radix-_r_4_",
+ "count": 1
+ },
+ {
+ "kind": "register",
+ "owner": "radix-_r_4_",
+ "count": 2
+ },
+ {
+ "kind": "dispatch",
+ "owner": "radix-_r_4_"
+ },
+ {
+ "kind": "unregister",
+ "owner": "radix-_r_4_",
+ "count": 1
+ }
+ ]
+ },
+ "browserErrors": []
+ },
+ {
+ "engine": "chromium",
+ "browser": "151.0.7922.34",
+ "mode": "development",
+ "variant": "routed",
+ "case": "ancestor-teardown",
+ "status": "pass",
+ "observed": {
+ "active": "next",
+ "dialogs": 0,
+ "changes": [
+ {
+ "name": "outer",
+ "value": true
+ },
+ {
+ "name": "inner",
+ "value": true
+ }
+ ],
+ "escapes": [],
+ "trace": [
+ {
+ "kind": "register",
+ "owner": "radix-_r_1_",
+ "count": 1
+ },
+ {
+ "kind": "register",
+ "owner": "radix-_r_4_",
+ "count": 2
+ },
+ {
+ "kind": "unregister",
+ "owner": "radix-_r_1_",
+ "count": 1
+ },
+ {
+ "kind": "unregister",
+ "owner": "radix-_r_4_",
+ "count": 0
+ },
+ {
+ "kind": "listener-removed"
+ }
+ ]
+ },
+ "browserErrors": []
+ },
+ {
+ "engine": "chromium",
+ "browser": "151.0.7922.34",
+ "mode": "production",
+ "variant": "raw",
+ "case": "ordinary",
+ "status": "pass",
+ "observed": {
+ "active": "outer-trigger",
+ "dialogs": 0,
+ "changes": [
+ {
+ "name": "outer",
+ "value": true
+ },
+ {
+ "name": "outer",
+ "value": false
+ }
+ ],
+ "escapes": [
+ "outer"
+ ],
+ "trace": []
+ },
+ "browserErrors": []
+ },
+ {
+ "engine": "chromium",
+ "browser": "151.0.7922.34",
+ "mode": "production",
+ "variant": "raw",
+ "case": "nested-immediate",
+ "status": "fail",
+ "error": "page.waitForFunction: Timeout 1200ms exceeded.",
+ "observed": {
+ "active": "outer-trigger",
+ "dialogs": 0,
+ "changes": [
+ {
+ "name": "outer",
+ "value": true
+ },
+ {
+ "name": "inner",
+ "value": true
+ },
+ {
+ "name": "outer",
+ "value": false
+ }
+ ],
+ "escapes": [
+ "outer"
+ ],
+ "trace": []
+ },
+ "browserErrors": []
+ },
+ {
+ "engine": "chromium",
+ "browser": "151.0.7922.34",
+ "mode": "production",
+ "variant": "raw",
+ "case": "cancel-inner",
+ "status": "pass",
+ "observed": {
+ "active": "inner-close",
+ "dialogs": 2,
+ "changes": [
+ {
+ "name": "outer",
+ "value": true
+ },
+ {
+ "name": "inner",
+ "value": true
+ }
+ ],
+ "escapes": [
+ "inner"
+ ],
+ "trace": []
+ },
+ "browserErrors": []
+ },
+ {
+ "engine": "chromium",
+ "browser": "151.0.7922.34",
+ "mode": "production",
+ "variant": "raw",
+ "case": "remove-trigger",
+ "status": "pass",
+ "observed": {
+ "active": "outer-trigger",
+ "dialogs": 0,
+ "changes": [
+ {
+ "name": "outer",
+ "value": true
+ },
+ {
+ "name": "inner",
+ "value": true
+ },
+ {
+ "name": "outer",
+ "value": false
+ }
+ ],
+ "escapes": [
+ "outer"
+ ],
+ "trace": []
+ },
+ "browserErrors": []
+ },
+ {
+ "engine": "chromium",
+ "browser": "151.0.7922.34",
+ "mode": "production",
+ "variant": "raw",
+ "case": "remove-and-reopen",
+ "status": "fail",
+ "error": "page.waitForFunction: Timeout 1200ms exceeded.",
+ "observed": {
+ "active": "outer-trigger",
+ "dialogs": 0,
+ "changes": [
+ {
+ "name": "outer",
+ "value": true
+ },
+ {
+ "name": "inner",
+ "value": true
+ },
+ {
+ "name": "inner",
+ "value": true
+ },
+ {
+ "name": "outer",
+ "value": false
+ }
+ ],
+ "escapes": [
+ "outer"
+ ],
+ "trace": []
+ },
+ "browserErrors": []
+ },
+ {
+ "engine": "chromium",
+ "browser": "151.0.7922.34",
+ "mode": "production",
+ "variant": "raw",
+ "case": "ancestor-teardown",
+ "status": "pass",
+ "observed": {
+ "active": "next",
+ "dialogs": 0,
+ "changes": [
+ {
+ "name": "outer",
+ "value": true
+ },
+ {
+ "name": "inner",
+ "value": true
+ }
+ ],
+ "escapes": [],
+ "trace": []
+ },
+ "browserErrors": []
+ },
+ {
+ "engine": "chromium",
+ "browser": "151.0.7922.34",
+ "mode": "production",
+ "variant": "routed",
+ "case": "ordinary",
+ "status": "pass",
+ "observed": {
+ "active": "outer-trigger",
+ "dialogs": 0,
+ "changes": [
+ {
+ "name": "outer",
+ "value": true
+ },
+ {
+ "name": "outer",
+ "value": false
+ }
+ ],
+ "escapes": [
+ "outer"
+ ],
+ "trace": [
+ {
+ "kind": "register",
+ "owner": "radix-_r_1_",
+ "count": 1
+ },
+ {
+ "kind": "dispatch",
+ "owner": "radix-_r_1_"
+ },
+ {
+ "kind": "unregister",
+ "owner": "radix-_r_1_",
+ "count": 0
+ },
+ {
+ "kind": "listener-removed"
+ }
+ ]
+ },
+ "browserErrors": []
+ },
+ {
+ "engine": "chromium",
+ "browser": "151.0.7922.34",
+ "mode": "production",
+ "variant": "routed",
+ "case": "nested-immediate",
+ "status": "pass",
+ "observed": {
+ "active": "outer-trigger",
+ "dialogs": 0,
+ "changes": [
+ {
+ "name": "outer",
+ "value": true
+ },
+ {
+ "name": "inner",
+ "value": true
+ },
+ {
+ "name": "inner",
+ "value": false
+ },
+ {
+ "name": "outer",
+ "value": false
+ }
+ ],
+ "escapes": [
+ "inner",
+ "outer"
+ ],
+ "trace": [
+ {
+ "kind": "register",
+ "owner": "radix-_r_1_",
+ "count": 1
+ },
+ {
+ "kind": "register",
+ "owner": "radix-_r_4_",
+ "count": 2
+ },
+ {
+ "kind": "dispatch",
+ "owner": "radix-_r_4_"
+ },
+ {
+ "kind": "unregister",
+ "owner": "radix-_r_4_",
+ "count": 1
+ },
+ {
+ "kind": "dispatch",
+ "owner": "radix-_r_1_"
+ },
+ {
+ "kind": "unregister",
+ "owner": "radix-_r_1_",
+ "count": 0
+ },
+ {
+ "kind": "listener-removed"
+ }
+ ]
+ },
+ "browserErrors": []
+ },
+ {
+ "engine": "chromium",
+ "browser": "151.0.7922.34",
+ "mode": "production",
+ "variant": "routed",
+ "case": "cancel-inner",
+ "status": "pass",
+ "observed": {
+ "active": "inner-close",
+ "dialogs": 2,
+ "changes": [
+ {
+ "name": "outer",
+ "value": true
+ },
+ {
+ "name": "inner",
+ "value": true
+ }
+ ],
+ "escapes": [
+ "inner"
+ ],
+ "trace": [
+ {
+ "kind": "register",
+ "owner": "radix-_r_1_",
+ "count": 1
+ },
+ {
+ "kind": "register",
+ "owner": "radix-_r_4_",
+ "count": 2
+ },
+ {
+ "kind": "dispatch",
+ "owner": "radix-_r_4_"
+ }
+ ]
+ },
+ "browserErrors": []
+ },
+ {
+ "engine": "chromium",
+ "browser": "151.0.7922.34",
+ "mode": "production",
+ "variant": "routed",
+ "case": "remove-trigger",
+ "status": "pass",
+ "observed": {
+ "active": "outer-trigger",
+ "dialogs": 0,
+ "changes": [
+ {
+ "name": "outer",
+ "value": true
+ },
+ {
+ "name": "inner",
+ "value": true
+ },
+ {
+ "name": "outer",
+ "value": false
+ }
+ ],
+ "escapes": [
+ "outer"
+ ],
+ "trace": [
+ {
+ "kind": "register",
+ "owner": "radix-_r_1_",
+ "count": 1
+ },
+ {
+ "kind": "register",
+ "owner": "radix-_r_4_",
+ "count": 2
+ },
+ {
+ "kind": "unregister",
+ "owner": "radix-_r_4_",
+ "count": 1
+ },
+ {
+ "kind": "dispatch",
+ "owner": "radix-_r_1_"
+ },
+ {
+ "kind": "unregister",
+ "owner": "radix-_r_1_",
+ "count": 0
+ },
+ {
+ "kind": "listener-removed"
+ }
+ ]
+ },
+ "browserErrors": []
+ },
+ {
+ "engine": "chromium",
+ "browser": "151.0.7922.34",
+ "mode": "production",
+ "variant": "routed",
+ "case": "remove-and-reopen",
+ "status": "pass",
+ "observed": {
+ "active": "inner-trigger",
+ "dialogs": 1,
+ "changes": [
+ {
+ "name": "outer",
+ "value": true
+ },
+ {
+ "name": "inner",
+ "value": true
+ },
+ {
+ "name": "inner",
+ "value": true
+ },
+ {
+ "name": "inner",
+ "value": false
+ }
+ ],
+ "escapes": [
+ "inner"
+ ],
+ "trace": [
+ {
+ "kind": "register",
+ "owner": "radix-_r_1_",
+ "count": 1
+ },
+ {
+ "kind": "register",
+ "owner": "radix-_r_4_",
+ "count": 2
+ },
+ {
+ "kind": "unregister",
+ "owner": "radix-_r_4_",
+ "count": 1
+ },
+ {
+ "kind": "register",
+ "owner": "radix-_r_4_",
+ "count": 2
+ },
+ {
+ "kind": "dispatch",
+ "owner": "radix-_r_4_"
+ },
+ {
+ "kind": "unregister",
+ "owner": "radix-_r_4_",
+ "count": 1
+ }
+ ]
+ },
+ "browserErrors": []
+ },
+ {
+ "engine": "chromium",
+ "browser": "151.0.7922.34",
+ "mode": "production",
+ "variant": "routed",
+ "case": "ancestor-teardown",
+ "status": "pass",
+ "observed": {
+ "active": "next",
+ "dialogs": 0,
+ "changes": [
+ {
+ "name": "outer",
+ "value": true
+ },
+ {
+ "name": "inner",
+ "value": true
+ }
+ ],
+ "escapes": [],
+ "trace": [
+ {
+ "kind": "register",
+ "owner": "radix-_r_1_",
+ "count": 1
+ },
+ {
+ "kind": "register",
+ "owner": "radix-_r_4_",
+ "count": 2
+ },
+ {
+ "kind": "unregister",
+ "owner": "radix-_r_1_",
+ "count": 1
+ },
+ {
+ "kind": "unregister",
+ "owner": "radix-_r_4_",
+ "count": 0
+ },
+ {
+ "kind": "listener-removed"
+ }
+ ]
+ },
+ "browserErrors": []
+ },
+ {
+ "engine": "firefox",
+ "browser": "155.0",
+ "mode": "development",
+ "variant": "raw",
+ "case": "ordinary",
+ "status": "pass",
+ "observed": {
+ "active": "outer-trigger",
+ "dialogs": 0,
+ "changes": [
+ {
+ "name": "outer",
+ "value": true
+ },
+ {
+ "name": "outer",
+ "value": false
+ }
+ ],
+ "escapes": [
+ "outer"
+ ],
+ "trace": []
+ },
+ "browserErrors": []
+ },
+ {
+ "engine": "firefox",
+ "browser": "155.0",
+ "mode": "development",
+ "variant": "raw",
+ "case": "nested-immediate",
+ "status": "pass",
+ "observed": {
+ "active": "outer-trigger",
+ "dialogs": 0,
+ "changes": [
+ {
+ "name": "outer",
+ "value": true
+ },
+ {
+ "name": "inner",
+ "value": true
+ },
+ {
+ "name": "inner",
+ "value": false
+ },
+ {
+ "name": "outer",
+ "value": false
+ }
+ ],
+ "escapes": [
+ "inner",
+ "outer"
+ ],
+ "trace": []
+ },
+ "browserErrors": []
+ },
+ {
+ "engine": "firefox",
+ "browser": "155.0",
+ "mode": "development",
+ "variant": "raw",
+ "case": "cancel-inner",
+ "status": "pass",
+ "observed": {
+ "active": "inner-close",
+ "dialogs": 2,
+ "changes": [
+ {
+ "name": "outer",
+ "value": true
+ },
+ {
+ "name": "inner",
+ "value": true
+ }
+ ],
+ "escapes": [
+ "inner"
+ ],
+ "trace": []
+ },
+ "browserErrors": []
+ },
+ {
+ "engine": "firefox",
+ "browser": "155.0",
+ "mode": "development",
+ "variant": "raw",
+ "case": "remove-trigger",
+ "status": "pass",
+ "observed": {
+ "active": "outer-trigger",
+ "dialogs": 0,
+ "changes": [
+ {
+ "name": "outer",
+ "value": true
+ },
+ {
+ "name": "inner",
+ "value": true
+ },
+ {
+ "name": "outer",
+ "value": false
+ }
+ ],
+ "escapes": [
+ "outer"
+ ],
+ "trace": []
+ },
+ "browserErrors": []
+ },
+ {
+ "engine": "firefox",
+ "browser": "155.0",
+ "mode": "development",
+ "variant": "raw",
+ "case": "remove-and-reopen",
+ "status": "pass",
+ "observed": {
+ "active": "inner-trigger",
+ "dialogs": 1,
+ "changes": [
+ {
+ "name": "outer",
+ "value": true
+ },
+ {
+ "name": "inner",
+ "value": true
+ },
+ {
+ "name": "inner",
+ "value": true
+ },
+ {
+ "name": "inner",
+ "value": false
+ }
+ ],
+ "escapes": [
+ "inner"
+ ],
+ "trace": []
+ },
+ "browserErrors": []
+ },
+ {
+ "engine": "firefox",
+ "browser": "155.0",
+ "mode": "development",
+ "variant": "raw",
+ "case": "ancestor-teardown",
+ "status": "pass",
+ "observed": {
+ "active": "next",
+ "dialogs": 0,
+ "changes": [
+ {
+ "name": "outer",
+ "value": true
+ },
+ {
+ "name": "inner",
+ "value": true
+ }
+ ],
+ "escapes": [],
+ "trace": []
+ },
+ "browserErrors": []
+ },
+ {
+ "engine": "firefox",
+ "browser": "155.0",
+ "mode": "development",
+ "variant": "routed",
+ "case": "ordinary",
+ "status": "pass",
+ "observed": {
+ "active": "outer-trigger",
+ "dialogs": 0,
+ "changes": [
+ {
+ "name": "outer",
+ "value": true
+ },
+ {
+ "name": "outer",
+ "value": false
+ }
+ ],
+ "escapes": [
+ "outer"
+ ],
+ "trace": [
+ {
+ "kind": "register",
+ "owner": "radix-_r_1_",
+ "count": 1
+ },
+ {
+ "kind": "dispatch",
+ "owner": "radix-_r_1_"
+ },
+ {
+ "kind": "unregister",
+ "owner": "radix-_r_1_",
+ "count": 0
+ },
+ {
+ "kind": "listener-removed"
+ }
+ ]
+ },
+ "browserErrors": []
+ },
+ {
+ "engine": "firefox",
+ "browser": "155.0",
+ "mode": "development",
+ "variant": "routed",
+ "case": "nested-immediate",
+ "status": "pass",
+ "observed": {
+ "active": "outer-trigger",
+ "dialogs": 0,
+ "changes": [
+ {
+ "name": "outer",
+ "value": true
+ },
+ {
+ "name": "inner",
+ "value": true
+ },
+ {
+ "name": "inner",
+ "value": false
+ },
+ {
+ "name": "outer",
+ "value": false
+ }
+ ],
+ "escapes": [
+ "inner",
+ "outer"
+ ],
+ "trace": [
+ {
+ "kind": "register",
+ "owner": "radix-_r_1_",
+ "count": 1
+ },
+ {
+ "kind": "register",
+ "owner": "radix-_r_4_",
+ "count": 2
+ },
+ {
+ "kind": "dispatch",
+ "owner": "radix-_r_4_"
+ },
+ {
+ "kind": "unregister",
+ "owner": "radix-_r_4_",
+ "count": 1
+ },
+ {
+ "kind": "dispatch",
+ "owner": "radix-_r_1_"
+ },
+ {
+ "kind": "unregister",
+ "owner": "radix-_r_1_",
+ "count": 0
+ },
+ {
+ "kind": "listener-removed"
+ }
+ ]
+ },
+ "browserErrors": []
+ },
+ {
+ "engine": "firefox",
+ "browser": "155.0",
+ "mode": "development",
+ "variant": "routed",
+ "case": "cancel-inner",
+ "status": "pass",
+ "observed": {
+ "active": "inner-close",
+ "dialogs": 2,
+ "changes": [
+ {
+ "name": "outer",
+ "value": true
+ },
+ {
+ "name": "inner",
+ "value": true
+ }
+ ],
+ "escapes": [
+ "inner"
+ ],
+ "trace": [
+ {
+ "kind": "register",
+ "owner": "radix-_r_1_",
+ "count": 1
+ },
+ {
+ "kind": "register",
+ "owner": "radix-_r_4_",
+ "count": 2
+ },
+ {
+ "kind": "dispatch",
+ "owner": "radix-_r_4_"
+ }
+ ]
+ },
+ "browserErrors": []
+ },
+ {
+ "engine": "firefox",
+ "browser": "155.0",
+ "mode": "development",
+ "variant": "routed",
+ "case": "remove-trigger",
+ "status": "pass",
+ "observed": {
+ "active": "outer-trigger",
+ "dialogs": 0,
+ "changes": [
+ {
+ "name": "outer",
+ "value": true
+ },
+ {
+ "name": "inner",
+ "value": true
+ },
+ {
+ "name": "outer",
+ "value": false
+ }
+ ],
+ "escapes": [
+ "outer"
+ ],
+ "trace": [
+ {
+ "kind": "register",
+ "owner": "radix-_r_1_",
+ "count": 1
+ },
+ {
+ "kind": "register",
+ "owner": "radix-_r_4_",
+ "count": 2
+ },
+ {
+ "kind": "unregister",
+ "owner": "radix-_r_4_",
+ "count": 1
+ },
+ {
+ "kind": "dispatch",
+ "owner": "radix-_r_1_"
+ },
+ {
+ "kind": "unregister",
+ "owner": "radix-_r_1_",
+ "count": 0
+ },
+ {
+ "kind": "listener-removed"
+ }
+ ]
+ },
+ "browserErrors": []
+ },
+ {
+ "engine": "firefox",
+ "browser": "155.0",
+ "mode": "development",
+ "variant": "routed",
+ "case": "remove-and-reopen",
+ "status": "pass",
+ "observed": {
+ "active": "inner-trigger",
+ "dialogs": 1,
+ "changes": [
+ {
+ "name": "outer",
+ "value": true
+ },
+ {
+ "name": "inner",
+ "value": true
+ },
+ {
+ "name": "inner",
+ "value": true
+ },
+ {
+ "name": "inner",
+ "value": false
+ }
+ ],
+ "escapes": [
+ "inner"
+ ],
+ "trace": [
+ {
+ "kind": "register",
+ "owner": "radix-_r_1_",
+ "count": 1
+ },
+ {
+ "kind": "register",
+ "owner": "radix-_r_4_",
+ "count": 2
+ },
+ {
+ "kind": "unregister",
+ "owner": "radix-_r_4_",
+ "count": 1
+ },
+ {
+ "kind": "register",
+ "owner": "radix-_r_4_",
+ "count": 2
+ },
+ {
+ "kind": "dispatch",
+ "owner": "radix-_r_4_"
+ },
+ {
+ "kind": "unregister",
+ "owner": "radix-_r_4_",
+ "count": 1
+ }
+ ]
+ },
+ "browserErrors": []
+ },
+ {
+ "engine": "firefox",
+ "browser": "155.0",
+ "mode": "development",
+ "variant": "routed",
+ "case": "ancestor-teardown",
+ "status": "pass",
+ "observed": {
+ "active": "next",
+ "dialogs": 0,
+ "changes": [
+ {
+ "name": "outer",
+ "value": true
+ },
+ {
+ "name": "inner",
+ "value": true
+ }
+ ],
+ "escapes": [],
+ "trace": [
+ {
+ "kind": "register",
+ "owner": "radix-_r_1_",
+ "count": 1
+ },
+ {
+ "kind": "register",
+ "owner": "radix-_r_4_",
+ "count": 2
+ },
+ {
+ "kind": "unregister",
+ "owner": "radix-_r_1_",
+ "count": 1
+ },
+ {
+ "kind": "unregister",
+ "owner": "radix-_r_4_",
+ "count": 0
+ },
+ {
+ "kind": "listener-removed"
+ }
+ ]
+ },
+ "browserErrors": []
+ },
+ {
+ "engine": "firefox",
+ "browser": "155.0",
+ "mode": "production",
+ "variant": "raw",
+ "case": "ordinary",
+ "status": "pass",
+ "observed": {
+ "active": "outer-trigger",
+ "dialogs": 0,
+ "changes": [
+ {
+ "name": "outer",
+ "value": true
+ },
+ {
+ "name": "outer",
+ "value": false
+ }
+ ],
+ "escapes": [
+ "outer"
+ ],
+ "trace": []
+ },
+ "browserErrors": []
+ },
+ {
+ "engine": "firefox",
+ "browser": "155.0",
+ "mode": "production",
+ "variant": "raw",
+ "case": "nested-immediate",
+ "status": "pass",
+ "observed": {
+ "active": "outer-trigger",
+ "dialogs": 0,
+ "changes": [
+ {
+ "name": "outer",
+ "value": true
+ },
+ {
+ "name": "inner",
+ "value": true
+ },
+ {
+ "name": "inner",
+ "value": false
+ },
+ {
+ "name": "outer",
+ "value": false
+ }
+ ],
+ "escapes": [
+ "inner",
+ "outer"
+ ],
+ "trace": []
+ },
+ "browserErrors": []
+ },
+ {
+ "engine": "firefox",
+ "browser": "155.0",
+ "mode": "production",
+ "variant": "raw",
+ "case": "cancel-inner",
+ "status": "pass",
+ "observed": {
+ "active": "inner-close",
+ "dialogs": 2,
+ "changes": [
+ {
+ "name": "outer",
+ "value": true
+ },
+ {
+ "name": "inner",
+ "value": true
+ }
+ ],
+ "escapes": [
+ "inner"
+ ],
+ "trace": []
+ },
+ "browserErrors": []
+ },
+ {
+ "engine": "firefox",
+ "browser": "155.0",
+ "mode": "production",
+ "variant": "raw",
+ "case": "remove-trigger",
+ "status": "pass",
+ "observed": {
+ "active": "outer-trigger",
+ "dialogs": 0,
+ "changes": [
+ {
+ "name": "outer",
+ "value": true
+ },
+ {
+ "name": "inner",
+ "value": true
+ },
+ {
+ "name": "outer",
+ "value": false
+ }
+ ],
+ "escapes": [
+ "outer"
+ ],
+ "trace": []
+ },
+ "browserErrors": []
+ },
+ {
+ "engine": "firefox",
+ "browser": "155.0",
+ "mode": "production",
+ "variant": "raw",
+ "case": "remove-and-reopen",
+ "status": "pass",
+ "observed": {
+ "active": "inner-trigger",
+ "dialogs": 1,
+ "changes": [
+ {
+ "name": "outer",
+ "value": true
+ },
+ {
+ "name": "inner",
+ "value": true
+ },
+ {
+ "name": "inner",
+ "value": true
+ },
+ {
+ "name": "inner",
+ "value": false
+ }
+ ],
+ "escapes": [
+ "inner"
+ ],
+ "trace": []
+ },
+ "browserErrors": []
+ },
+ {
+ "engine": "firefox",
+ "browser": "155.0",
+ "mode": "production",
+ "variant": "raw",
+ "case": "ancestor-teardown",
+ "status": "pass",
+ "observed": {
+ "active": "next",
+ "dialogs": 0,
+ "changes": [
+ {
+ "name": "outer",
+ "value": true
+ },
+ {
+ "name": "inner",
+ "value": true
+ }
+ ],
+ "escapes": [],
+ "trace": []
+ },
+ "browserErrors": []
+ },
+ {
+ "engine": "firefox",
+ "browser": "155.0",
+ "mode": "production",
+ "variant": "routed",
+ "case": "ordinary",
+ "status": "pass",
+ "observed": {
+ "active": "outer-trigger",
+ "dialogs": 0,
+ "changes": [
+ {
+ "name": "outer",
+ "value": true
+ },
+ {
+ "name": "outer",
+ "value": false
+ }
+ ],
+ "escapes": [
+ "outer"
+ ],
+ "trace": [
+ {
+ "kind": "register",
+ "owner": "radix-_r_1_",
+ "count": 1
+ },
+ {
+ "kind": "dispatch",
+ "owner": "radix-_r_1_"
+ },
+ {
+ "kind": "unregister",
+ "owner": "radix-_r_1_",
+ "count": 0
+ },
+ {
+ "kind": "listener-removed"
+ }
+ ]
+ },
+ "browserErrors": []
+ },
+ {
+ "engine": "firefox",
+ "browser": "155.0",
+ "mode": "production",
+ "variant": "routed",
+ "case": "nested-immediate",
+ "status": "pass",
+ "observed": {
+ "active": "outer-trigger",
+ "dialogs": 0,
+ "changes": [
+ {
+ "name": "outer",
+ "value": true
+ },
+ {
+ "name": "inner",
+ "value": true
+ },
+ {
+ "name": "inner",
+ "value": false
+ },
+ {
+ "name": "outer",
+ "value": false
+ }
+ ],
+ "escapes": [
+ "inner",
+ "outer"
+ ],
+ "trace": [
+ {
+ "kind": "register",
+ "owner": "radix-_r_1_",
+ "count": 1
+ },
+ {
+ "kind": "register",
+ "owner": "radix-_r_4_",
+ "count": 2
+ },
+ {
+ "kind": "dispatch",
+ "owner": "radix-_r_4_"
+ },
+ {
+ "kind": "unregister",
+ "owner": "radix-_r_4_",
+ "count": 1
+ },
+ {
+ "kind": "dispatch",
+ "owner": "radix-_r_1_"
+ },
+ {
+ "kind": "unregister",
+ "owner": "radix-_r_1_",
+ "count": 0
+ },
+ {
+ "kind": "listener-removed"
+ }
+ ]
+ },
+ "browserErrors": []
+ },
+ {
+ "engine": "firefox",
+ "browser": "155.0",
+ "mode": "production",
+ "variant": "routed",
+ "case": "cancel-inner",
+ "status": "pass",
+ "observed": {
+ "active": "inner-close",
+ "dialogs": 2,
+ "changes": [
+ {
+ "name": "outer",
+ "value": true
+ },
+ {
+ "name": "inner",
+ "value": true
+ }
+ ],
+ "escapes": [
+ "inner"
+ ],
+ "trace": [
+ {
+ "kind": "register",
+ "owner": "radix-_r_1_",
+ "count": 1
+ },
+ {
+ "kind": "register",
+ "owner": "radix-_r_4_",
+ "count": 2
+ },
+ {
+ "kind": "dispatch",
+ "owner": "radix-_r_4_"
+ }
+ ]
+ },
+ "browserErrors": []
+ },
+ {
+ "engine": "firefox",
+ "browser": "155.0",
+ "mode": "production",
+ "variant": "routed",
+ "case": "remove-trigger",
+ "status": "pass",
+ "observed": {
+ "active": "outer-trigger",
+ "dialogs": 0,
+ "changes": [
+ {
+ "name": "outer",
+ "value": true
+ },
+ {
+ "name": "inner",
+ "value": true
+ },
+ {
+ "name": "outer",
+ "value": false
+ }
+ ],
+ "escapes": [
+ "outer"
+ ],
+ "trace": [
+ {
+ "kind": "register",
+ "owner": "radix-_r_1_",
+ "count": 1
+ },
+ {
+ "kind": "register",
+ "owner": "radix-_r_4_",
+ "count": 2
+ },
+ {
+ "kind": "unregister",
+ "owner": "radix-_r_4_",
+ "count": 1
+ },
+ {
+ "kind": "dispatch",
+ "owner": "radix-_r_1_"
+ },
+ {
+ "kind": "unregister",
+ "owner": "radix-_r_1_",
+ "count": 0
+ },
+ {
+ "kind": "listener-removed"
+ }
+ ]
+ },
+ "browserErrors": []
+ },
+ {
+ "engine": "firefox",
+ "browser": "155.0",
+ "mode": "production",
+ "variant": "routed",
+ "case": "remove-and-reopen",
+ "status": "pass",
+ "observed": {
+ "active": "inner-trigger",
+ "dialogs": 1,
+ "changes": [
+ {
+ "name": "outer",
+ "value": true
+ },
+ {
+ "name": "inner",
+ "value": true
+ },
+ {
+ "name": "inner",
+ "value": true
+ },
+ {
+ "name": "inner",
+ "value": false
+ }
+ ],
+ "escapes": [
+ "inner"
+ ],
+ "trace": [
+ {
+ "kind": "register",
+ "owner": "radix-_r_1_",
+ "count": 1
+ },
+ {
+ "kind": "register",
+ "owner": "radix-_r_4_",
+ "count": 2
+ },
+ {
+ "kind": "unregister",
+ "owner": "radix-_r_4_",
+ "count": 1
+ },
+ {
+ "kind": "register",
+ "owner": "radix-_r_4_",
+ "count": 2
+ },
+ {
+ "kind": "dispatch",
+ "owner": "radix-_r_4_"
+ },
+ {
+ "kind": "unregister",
+ "owner": "radix-_r_4_",
+ "count": 1
+ }
+ ]
+ },
+ "browserErrors": []
+ },
+ {
+ "engine": "firefox",
+ "browser": "155.0",
+ "mode": "production",
+ "variant": "routed",
+ "case": "ancestor-teardown",
+ "status": "pass",
+ "observed": {
+ "active": "next",
+ "dialogs": 0,
+ "changes": [
+ {
+ "name": "outer",
+ "value": true
+ },
+ {
+ "name": "inner",
+ "value": true
+ }
+ ],
+ "escapes": [],
+ "trace": [
+ {
+ "kind": "register",
+ "owner": "radix-_r_1_",
+ "count": 1
+ },
+ {
+ "kind": "register",
+ "owner": "radix-_r_4_",
+ "count": 2
+ },
+ {
+ "kind": "unregister",
+ "owner": "radix-_r_1_",
+ "count": 1
+ },
+ {
+ "kind": "unregister",
+ "owner": "radix-_r_4_",
+ "count": 0
+ },
+ {
+ "kind": "listener-removed"
+ }
+ ]
+ },
+ "browserErrors": []
+ }
+ ]
+}
diff --git a/research/experiments/boundary-recovery/routing-transform.mjs b/research/experiments/boundary-recovery/routing-transform.mjs
new file mode 100644
index 0000000..6c54c44
--- /dev/null
+++ b/research/experiments/boundary-recovery/routing-transform.mjs
@@ -0,0 +1,49 @@
+// Experimental in-memory patch to one pinned module, not an upstream/product change.
+export function routeEscape(source) {
+ const start = source.indexOf(' const isHighestLayer = node ? index === layers.length - 1 : false;');
+ const end = source.indexOf(' React.useEffect(() => {\n if (!node) return;', start);
+ if (start < 0 || end < 0) throw new Error('Pinned source locators changed');
+ const helper = `
+const fepDocuments = new WeakMap();
+function fepRegister(doc, node, callback) {
+ let state = fepDocuments.get(doc);
+ if (!state) {
+ state = { owners: new Map() };
+ state.listener = event => {
+ if (event.key !== 'Escape' || event.defaultPrevented) return;
+ const entry = [...state.owners].filter(([element]) => element.isConnected).at(-1);
+ if (!entry) return;
+ window.routingObserved.trace.push({kind:'dispatch', owner:entry[0].getAttribute('aria-labelledby')});
+ // Snapshot one owner. No fall-through to the parent after cancellation or teardown.
+ entry[1](event);
+ };
+ doc.addEventListener('keydown', state.listener, {capture:true});
+ fepDocuments.set(doc, state);
+ }
+ state.owners.set(node, callback);
+ window.routingObserved.trace.push({kind:'register', owner:node.getAttribute('aria-labelledby'), count:state.owners.size});
+ return () => {
+ state.owners.delete(node);
+ window.routingObserved.trace.push({kind:'unregister', owner:node.getAttribute('aria-labelledby'), count:state.owners.size});
+ if (!state.owners.size) {
+ doc.removeEventListener('keydown', state.listener, {capture:true});
+ fepDocuments.delete(doc);
+ window.routingObserved.trace.push({kind:'listener-removed'});
+ }
+ };
+}
+`;
+ const replacement = ` const fepHandler = React.useRef(null);
+ React.useLayoutEffect(() => {
+ fepHandler.current = event => {
+ onEscapeKeyDown?.(event);
+ if (!event.defaultPrevented && onDismiss) {event.preventDefault();onDismiss();}
+ };
+ });
+ React.useLayoutEffect(() => {
+ if (!node) return;
+ return fepRegister(ownerDocument, node, event => fepHandler.current?.(event));
+ }, [node, ownerDocument]);
+`;
+ return helper + source.slice(0,start) + replacement + source.slice(end);
+}
diff --git a/research/experiments/boundary-recovery/routing.mjs b/research/experiments/boundary-recovery/routing.mjs
new file mode 100644
index 0000000..c472642
--- /dev/null
+++ b/research/experiments/boundary-recovery/routing.mjs
@@ -0,0 +1,46 @@
+import {build} from 'esbuild';
+import {chromium, firefox} from 'playwright';
+import {createServer} from 'node:http';
+import {once} from 'node:events';
+import {readFile, writeFile} from 'node:fs/promises';
+import {createHash} from 'node:crypto';
+import {fileURLToPath} from 'node:url';
+import assert from 'node:assert/strict';
+import {routeEscape} from './routing-transform.mjs';
+const dir=fileURLToPath(new URL('.',import.meta.url));
+const hash=x=>createHash('sha256').update(x).digest('hex');
+const source=await readFile(dir+'node_modules/@radix-ui/react-dismissable-layer/dist/index.mjs','utf8');
+assert.equal(hash(source),JSON.parse(await readFile(dir+'provenance.json')).inspected_files['@radix-ui/react-dismissable-layer/dist/index.mjs'].sha256);
+const bundles=new Map();
+for(const mode of ['development','production']) for(const variant of ['raw','routed']) {
+ const b=await build({entryPoints:[dir+'routing-fixture.jsx'],bundle:true,write:false,format:'iife',define:{'process.env.NODE_ENV':JSON.stringify(mode)},plugins:variant==='raw'?[]:[{name:'experimental-escape-router',setup(b){b.onLoad({filter:/@radix-ui\/react-dismissable-layer\/dist\/index\.mjs$/},()=>({contents:routeEscape(source),loader:'js',resolveDir:dir+'node_modules/@radix-ui/react-dismissable-layer/dist'}));}}]});
+ bundles.set(mode+'-'+variant,b.outputFiles[0].contents);
+}
+const server=createServer((req,res)=>{const u=new URL(req.url,'http://localhost');if(u.pathname==='/bundle.js'){res.setHeader('Content-Type','application/javascript');res.end(bundles.get(u.searchParams.get('key')));}else{res.setHeader('Content-Type','text/html');res.end(`Routing experiment`);}});
+server.listen(0,'127.0.0.1');await once(server,'listening');
+const results=[];
+async function focused(page,id){await page.waitForFunction(id=>document.activeElement?.id===id,id,{timeout:1200});}
+async function outer(page){await page.locator('#outer-trigger').focus();await page.keyboard.press('Enter');await focused(page,'inner-trigger');}
+async function inner(page){await outer(page);await page.keyboard.press('Enter');await focused(page,'inner-close');}
+const cases={
+ 'ordinary':async p=>{await outer(p);await p.keyboard.press('Escape');await focused(p,'outer-trigger');assert.deepEqual(await p.evaluate(()=>window.routingObserved.escapes),['outer']);},
+ 'nested-immediate':async p=>{await inner(p);await p.keyboard.press('Escape');await focused(p,'inner-trigger');assert.equal(await p.getByRole('dialog').count(),1);await p.keyboard.press('Escape');await focused(p,'outer-trigger');assert.deepEqual(await p.evaluate(()=>window.routingObserved.escapes),['inner','outer']);},
+ 'cancel-inner':async p=>{await inner(p);await p.keyboard.press('Escape');assert.deepEqual(await p.evaluate(()=>window.routingObserved.escapes),['inner']);assert.equal(await p.getByRole('dialog', {includeHidden:true}).count(),2);await focused(p,'inner-close');},
+ 'remove-trigger':async p=>{await inner(p);await p.keyboard.press('Tab');await focused(p,'remove-trigger');await p.keyboard.press('Enter');await focused(p,'outer-close');await p.keyboard.press('Escape');await focused(p,'outer-trigger');},
+ 'remove-and-reopen':async p=>{await inner(p);await p.evaluate(()=>window.removeInner());await focused(p,'inner-trigger');await p.keyboard.press('Enter');await focused(p,'inner-close');await p.keyboard.press('Escape');await focused(p,'inner-trigger');assert.deepEqual(await p.evaluate(()=>window.routingObserved.escapes),['inner']);},
+ 'ancestor-teardown':async p=>{await inner(p);await p.evaluate(()=>window.removeTask());await p.getByRole('dialog').waitFor({state:'detached'});await p.locator('#next').focus();await p.keyboard.press('Escape');assert.deepEqual(await p.evaluate(()=>window.routingObserved.escapes),[]);await focused(p,'next');}
+};
+try{
+ for(const [engine,launcher]of [['chromium',chromium],['firefox',firefox]]){
+ const browser=await launcher.launch({headless:true,...(engine==='chromium'?{executablePath:process.env.FEP_CHROMIUM_PATH}: {})});
+ try{for(const mode of ['development','production'])for(const variant of ['raw','routed'])for(const [name,run]of Object.entries(cases)){
+ const page=await browser.newPage();page.setDefaultTimeout(2000);const errors=[];page.on('pageerror',e=>errors.push(e.message));const r={engine,browser:browser.version(),mode,variant,case:name,status:'pass'};
+ try{await page.goto(`http://127.0.0.1:${server.address().port}/?key=${mode}-${variant}${name==='cancel-inner'?'&cancel=1':''}`);await run(page);assert.deepEqual(errors,[]);if(variant==='routed' && name==='ancestor-teardown'){const trace=await page.evaluate(()=>window.routingObserved.trace);assert.equal(trace.at(-1)?.kind,'listener-removed');assert.equal(trace.filter(x=>x.kind==='register').length,trace.filter(x=>x.kind==='unregister').length);}}catch(e){r.status='fail';r.error=e.message;}
+ r.observed=await page.evaluate(()=>({active:document.activeElement?.id,dialogs:document.querySelectorAll('[role=dialog]').length,...window.routingObserved}));r.browserErrors=errors;results.push(r);await page.close();
+ await writeFile('/tmp/fep-routing-checkpoint.json',JSON.stringify({status:'incomplete',results},null,2)+'\n');
+ }}finally{await browser.close();}
+ }
+}finally{await new Promise(resolve=>server.close(resolve));}
+const files={};for(const name of ['routing.mjs','routing-fixture.jsx','routing-transform.mjs','package.json','package-lock.json'])files[name]=hash(await readFile(dir+name));
+const summary=[];for(const engine of ['chromium','firefox'])for(const mode of ['development','production'])for(const variant of ['raw','routed']){const r=results.filter(x=>x.engine===engine&&x.mode===mode&&x.variant===variant);summary.push({engine,mode,variant,passed:r.filter(x=>x.status==='pass').length,total:r.length});}
+const output=process.env.FEP_RESULT_PATH||'/tmp/fep-routing.json';await writeFile(output,JSON.stringify({date:new Date().toISOString(),node:process.version,files,sourceSha256:hash(source),transformedSha256:hash(routeEscape(source)),bundleHashes:Object.fromEntries([...bundles].map(([k,v])=>[k,hash(v)])),summary,results},null,2)+'\n');console.log(JSON.stringify({output,summary},null,2));
diff --git a/research/plan/OpenQuestions.md b/research/plan/OpenQuestions.md
index e0e5122..98f6384 100644
--- a/research/plan/OpenQuestions.md
+++ b/research/plan/OpenQuestions.md
@@ -87,3 +87,8 @@ visible/focused interaction from ownership of its dismissal handler. A guard can
prevent the wrong close while losing valid input. Q05 remains open: lifecycle and
input-routing contracts may need to shape composition before focus-return rules.
No new pattern or canonical dimension follows from one synthetic family.
+
+Q05 routing follow-up: [experimental owner dispatch](../reviews/NestedOwnershipRouting.md)
+separates input delivery from return-focus policy. Successful cancellation and cleanup
+matter alongside correct close targeting. The bounded mechanism comparison supports
+this distinction; it does not establish a universal ownership model or close Q05.
diff --git a/research/reviews/NestedDismissalIsolation.md b/research/reviews/NestedDismissalIsolation.md
index 3bc0cbc..3b047f3 100644
--- a/research/reviews/NestedDismissalIsolation.md
+++ b/research/reviews/NestedDismissalIsolation.md
@@ -93,3 +93,11 @@ WP-0003 T01 retains a bounded residual: evaluate a lifecycle-safe ownership stra
without arbitrary delay and verify ordinary/nested dismissal in both browsers before
recommending it. Feature/import versus release-boundary research and navigation
checks remain open; this focused investigation does not complete those tasks or M2.
+
+## Routing follow-up
+
+[Experimental routing](NestedOwnershipRouting.md) now supplies a mechanism that
+passes the tested ordinary/nested/cancel/removal/reopen/teardown cases without a
+settling delay. It changes the owner-selection architecture, not just the stale
+handler guard. Broader lifecycle coverage is still required for a recommendation;
+this does not overwrite the failed isolation or guard results above.
diff --git a/research/reviews/NestedOwnershipRouting.md b/research/reviews/NestedOwnershipRouting.md
new file mode 100644
index 0000000..0187a87
--- /dev/null
+++ b/research/reviews/NestedOwnershipRouting.md
@@ -0,0 +1,97 @@
+# Experimental nested ownership routing — 2026-09-26
+
+Status: synthetic browser comparison, editorial analysis by Codex, WP-0003 T01.
+Follow-up to [stale-listener isolation](NestedDismissalIsolation.md). The aim is to
+preserve the intended Escape action during ownership changes, not merely prevent
+a wrong close or wait an arbitrary duration. This does not deploy or recommend a
+vendor patch. Installed dependencies and earlier experiments remain unchanged.
+
+## Proposed mechanism
+
+[routing-transform.mjs](../experiments/boundary-recovery/routing-transform.mjs)
+replaces only the pinned dismissable-layer module's Escape handling during bundling.
+A document registry holds connected owners and a single capture listener. Layout
+registration/cleanup changes ownership; each Escape snapshots the current owner,
+invokes its callback once, honors cancellation and does not fall through to a parent.
+Removing the last owner removes the listener. The [design contract](../experiments/boundary-recovery/routing-design.md)
+states what this simple mount-order registry does and does not model.
+
+This addresses both observed problems: the old effect-based listener handoff could
+route to the parent, while the prior guard could reject the stale handler and lose
+the action. The new approach changes how the handler is selected, not just whether
+a selected handler is allowed to close. Focus restoration remains the responsibility
+of the dialog/application; it is not implied by routing success.
+
+## Comparison and validity
+
+[Runner](../experiments/boundary-recovery/routing.mjs) compares raw and routed builds
+in Chromium 151.0.7922.34 and Firefox 155.0, development and production. Six scenarios
+run once per condition: ordinary close, immediate nested close, cancelled inner close,
+removed invoker with explicit application return target, programmatic inner removal
+and reopening, and ancestor teardown followed by Escape. The routed teardown check
+also verifies balanced registrations and removal of the document listener.
+
+No sleep, readiness wait or retry is used. Browser focus polling synchronizes on
+observable focus, not on the router's private registration state. The raw control
+uses the same new fixture as the routed condition. Its controlled inner state differs
+from the original isolation fixture, so counts across those experiments are not a
+paired comparison. One run per scenario/condition is bounded mechanism evidence,
+not a failure rate or complete regression suite.
+
+The initial development matrix contained a harness mistake: its cancellation check
+counted only accessibility-exposed dialogs, excluding the parent hidden by the modal.
+Raw observations showed two DOM dialogs and retained focus even when that assertion
+failed. The corrected check includes hidden dialogs; listener cleanup is also asserted.
+[Development receipt](../experiments/boundary-recovery/routing-development-results.json)
+and [original runner bytes](../experiments/boundary-recovery/routing-development-runner.mjs)
+are preserved. Its `files.routing.mjs` hash resolves to the archived runner name.
+Do not pool those erroneous cancellation scores with corrected results.
+
+## Results
+
+| Browser | Build | Unmodified | Experimental router |
+| --- | --- | --- | --- |
+| Chromium | development | 4/6 | 6/6 |
+| Chromium | production | 4/6 | 6/6 |
+| Firefox | development | 6/6 | 6/6 |
+| Firefox | production | 6/6 | 6/6 |
+
+The router meets 24/24 assertions; the control meets 20/24. The four control failures
+are immediate nesting and removal/reopening in both Chromium builds: the outer Escape
+callback fires and focus returns to the outer trigger. The routed cases deliver the
+inner callback and preserve the parent. Unlike the previous isolation matrix, this
+new raw production fixture does reproduce wrong-owner dismissal. This changes the
+observed scope, not the historical results.
+
+Cancelled inner Escape remains inside the inner task. Removed-trigger return still
+uses explicit application policy. Ancestor teardown leaves no router listener, and
+Escape then causes no stale dismissal callback. No keypress loss was observed in
+these six scenarios; other input timing patterns remain untested.
+
+[Corrected raw results](../experiments/boundary-recovery/routing-results.json) retain
+all outcomes, browser errors, focus, dialog transitions and router dispatch/cleanup
+traces. Source, transformed module, bundle and input hashes identify the exact
+experimental implementation. Browser/package provenance is inherited from the
+unchanged [pinned experiment](../experiments/boundary-recovery/provenance.json) and
+[Firefox comparison](../experiments/boundary-recovery/isolation-provenance.json).
+
+## Research disposition
+
+This supplies a concrete candidate mechanism for the tested lifecycle. Keep its
+claims narrower than “nested dialogs fixed”: insertion order is not a complete
+z-order model, and multiple roots/library copies, exiting animations, shadow DOM,
+iframes, repeated held keys, same-turn input bursts and competing Escape handlers
+are not covered. React StrictMode, SSR and assistive-technology behavior are also
+untested. No upstream message or deployment was performed.
+
+Refine [Focus Return](../candidates/FocusReturn.md) with an explicit input-owner
+lifecycle and separate return-target policy. A dismissal callback is a request to
+close; a controlled application may refuse it. Temporal ownership remains a proposed
+interaction contract, not a newly admitted pattern or general library abstraction.
+
+The immediate research question now has an executable routing candidate and bounded
+comparison. WP-0003 T01 retains any recommendation gate: test animation-preserved
+exits and competing owners before considering broader reuse. Resume the other breadth
+work—feature/import versus release boundaries and navigation/history/cache evidence—
+without requiring this repository to maintain a production dialog fork. Sixteen
+hypotheses, M1 human validation and M2 completion status remain unchanged.
diff --git a/workplans/FEP-WP-0003-contrasting-schools.md b/workplans/FEP-WP-0003-contrasting-schools.md
index 0ec7d63..50e4132 100644
--- a/workplans/FEP-WP-0003-contrasting-schools.md
+++ b/workplans/FEP-WP-0003-contrasting-schools.md
@@ -113,3 +113,20 @@ research/reviews/NestedDismissalIsolation.md. Residual under T01: assess lifecyc
ownership/routing during activation and teardown before recommending a product repair.
No upstream message, deployment, new inference, canonical promotion or M2 completion.
Feature/release coupling and navigation evidence remain pending; T02/T03 unchanged.
+
+## Experimental ownership routing — 2026-09-26
+
+T01 progress: in-memory layout-registered document router tested against unchanged
+Radix behavior in a new controlled-dialog fixture. Six scenarios × two browsers ×
+two builds × two variants: routed 24/24, raw 20/24. Raw Chromium fails immediate nested
+and reopen dismissal in both builds; routed delivery, cancellation, replacement focus
+and cleanup pass. No sleep, private-readiness wait or retry. Initial development run
+and its faulty exposed-dialog cancellation assertion retained; corrected runner includes
+hidden dialogs and verifies listener removal. See research/reviews/NestedOwnershipRouting.md.
+
+The focused question now has an executable candidate mechanism. Broader reuse remains
+conditional on animated-exit/competing-owner coverage; no production dependency patch,
+upstream message, pattern promotion or M2 completion. Resume feature/import versus
+release-boundary and navigation evidence next; keep the router limitation as a live
+T01 follow-up rather than requiring a production fork here. Sixteen hypotheses,
+T02/T03 and the independent-human gate unchanged. No model calls.