Skip to content

fix(accessibility): reject invalid runtime ARIA validation states #206

Description

@seonghobae

Buyer-visible accessibility boundary

Protected main@3b38ead2d00f44eb578d0689087b9293b3dabe1e exposes ariaInvalid?: boolean | 'grammar' | 'spelling' and ariaRequired?: boolean through the editor contract. The historical defect was that the shared accessibility builder stringified a defined hostile runtime value, allowing values outside those finite ARIA contracts to reach authored attributes instead of failing closed.

This is materially significant for aria-invalid: unrecognized tokens can be interpreted as an invalid state rather than being harmlessly ignored. Inkspan therefore owns enforcement of its finite public runtime contract while host accessibility policy remains host-owned.

Canonical owner and implemented contract

Draft PR #230 is now the sole active writer for src/components/editorAccessibility.ts and focused metadata/runtime tests. The earlier stacked #203/#207 direction is superseded; do not revive it or create a competing writer.

At exact #230 head 59d82f8b65cfad5230fa9e11afb97867293a43f5, ariaInvalid and ariaRequired are snapshotted exactly once before validation. ariaInvalid accepts only undefined, false, true, grammar, or spelling; ariaRequired accepts only undefined, false, or true. Invalid runtime values fail through the stable payload-redacted local contract before emission, and the validated snapshot—not a second getter read—is serialized.

Representative ARIA RED lineage is 83d230735aa38c1013b6032dbde4178b1db9a219; the finite-state getter TOCTOU regression was added at test-only d950d610cd2a81ae0d414b247b27323bd3ca83fe and immediately followed by the narrow current implementation. Exact-current #230 repository workflows are terminal success: CI 32322070195, Security Scan 32322070146, and SAST Semgrep 32322070224. Predecessor evidence does not transfer.

Acceptance

  1. Preserve all valid ARIA state serialization and fail closed on hostile runtime values outside the public finite contracts.
  2. Preserve accessible-name precedence, placeholder/language/direction behavior, readonly semantics, standalone/collaborative live prop updates, and existing editor surface behavior.
  3. Prevent validation-to-use drift from hostile getters/Proxies by emitting only validated snapshots.
  4. Add no host validation policy, transport, persistence, authn/authz, tenancy, credentials, model/provider, network, deployment, migration, retention, or durable-audit authority.
  5. Maintain exact owned-production coverage and all applicable package/browser/Office/security gates on the eventual integration head.
  6. Close only when canonical fix(accessibility): harden editor metadata runtime contracts #230 integrates into protected main; Draft/head-green evidence is not protected shipped truth.

Integration boundary

Keep #230 Draft/unmerged while #118 freezes protected main for v0.6.0 operational acceptance and while qualifying independent approval plus every then-live merge/review/governance gate remain incomplete. Never transfer predecessor CI/review evidence or create a competing writer for the same source.

Metadata

Metadata

Assignees

No one assigned

    Labels

    area: accessibilityAccessibility and assistive-technology supportarea: authAuthentication, authorization, identity, or tenant isolationarea: ci-cdCI, GitHub Actions, checks, release, or supply chainarea: securitySecurity boundary, hardening, or vulnerability preventionpriority: mediumNormal-priority or P2 workstatus: triagedOpen issue has an organization taxonomy assignmenttype: bugDefect or incorrect behavior

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions