Skip to content

fix: enforce accessibility scopes for focus findings#2072

Merged
chubes4 merged 1 commit into
mainfrom
fix/2069-accessibility-scope-enforcement
Jul 26, 2026
Merged

fix: enforce accessibility scopes for focus findings#2072
chubes4 merged 1 commit into
mainfrom
fix/2069-accessibility-scope-enforcement

Conversation

@chubes4

@chubes4 chubes4 commented Jul 25, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • enforce includeScopes and excludeScopes for focus-visible, attributable focus-loss, and dialog focus findings using the collector's existing scope matcher
  • retain out-of-scope focus only as bounded transition or expected/actual context, while keeping finding targets scoped and frame-aware
  • mark scans inconclusive when declared include scopes match no inspectable frame, and document selector, exclusion, frame, and cross-boundary semantics

Scope semantics

Targets match when they are a declared include root or its descendant, or when no include scope is declared. Matching exclude roots and descendants always win over includes. Static accessible-name, keyboard-reachable, tab-order, and ARIA-state scans continue through the same matcher; focus and dialog findings now obey it too.

Focus loss is attributed to the in-scope element that lost focus rather than the out-of-scope document body. Dialog entry and restoration obligations are attributed to the scoped dialog, while trigger and destination focus may remain contextual. Dialog and focus identities include frame identity internally so equivalent structural locators in different same-origin frames do not collide.

Invalid selectors remain inconclusive. Valid include selectors that collectively match no inspectable frame now emit browser_accessibility_scope_unmatched and are inconclusive rather than silently passing. Uninspectable frames retain the existing explicit browser_accessibility_frame_unsupported diagnostic.

Tests

Passed:

  • npm run build
  • npm run test:browser-accessibility-oracles (34 tests)
  • npm run test:adversarial-runtime (16 tests)
  • npm run test:redaction
  • npm run test:runtime-command-artifact-bounds
  • npm run test:evidence-bundle-digest-and-recipe-artifact
  • npm run test:schema-parity
  • npm run test:runtime-contract-manifest
  • npm run test:runtime-contract-package-exports
  • git diff --check

New browser fixtures cover inside/outside focus targets, nested exclude precedence, attributable focus loss, cross-boundary dialog focus and restoration, unmatched scopes, and same-origin frame filtering with preserved frame IDs. Existing replay, fingerprint, privacy, and artifact-bound assertions remain passing.

Baseline failures

  • npm run test:public-api-contract fails in untouched code because the expected public barrel list omits the already-exported ./browser-accessibility.js introduced on main.
  • npm run check passes production-boundary enforcement and then reaches an unrelated existing command-registry-smoke failure: wordpress.collect-workload-result outputShape should mention outputSchema id.

Limitations

Cross-origin or otherwise unavailable frame DOM remains outside the collector's inspection capability and is reported diagnostically; this change does not add cross-origin access or retain additional sensitive target content.

Fixes #2069

@chubes4
chubes4 merged commit 897e232 into main Jul 26, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Focus accessibility rules ignore declared includeScopes

1 participant