Files
fusion/packages
gsxdsm 0738fb1c8a test(a11y): the aria-label role guard was blind to the role word inside the t() default (#2979)
## What

[#2965](https://github.com/../pull/2965) fixed thirteen dialogs whose
accessible name restated its role, and shipped a source-scanning guard
so the next copy-paste could not sneak back in. Good fix, real ratchet —
its own header even documents catching one blind spot by mutation during
review.

It has a second one. The matcher looks for the role word at the **end**
of the `ariaLabel` value, which is where all thirteen had it. One
position over is invisible:

```tsx
ariaLabel={t("scripts.title", "Scripts dialog")}
```

That renders the accessible name **"Scripts dialog"** — identical
symptom, announced as *"Scripts dialog, dialog"* — but the value does
not END in the role word, because a `")` closes the call after it.

**Measured:** re-introducing this shape into `ScriptsModal` left the
shipped suite green at **13/13**.

## Why this shape matters more than the one already covered

The rendered label *is* the translator's default string. Whoever writes
the next modal naturally puts the word where the title lives, inside
`t()`, rather than appending it outside the call. The suffix form is
what the original thirteen happened to be; this is the form the
fourteenth takes.

## The fix

Every quoted literal that is actually rendered is checked with the same
matcher, not just the whole value.

i18n **keys** are excluded, or the guard fires on
`t("agents.onboarding.dialogLabel", "AI Interview")` — live in the tree
today, and it announces nothing of the sort. Key-shaped means dotted and
whitespace-free, which no real accessible name is. Keeping this narrow
is the whole difficulty: a scan that flags every translated title gets
deleted within a week.

## Measured

| run | result |
|---|---|
| baseline, unmutated `main` | **18/18 green** — no false positive
anywhere in the corpus |
| mutation A — role word inside the `t()` default | **1 failed / 17
passed** (was green before) |
| mutation B — original trailing-suffix shape | **1 failed / 17 passed**
— no regression |

Both defect shapes now fail the guard. Five matcher cases added, three
of them negative; the negatives are what keep the scan from flagging
every translated title.

## Note for the queue

**#2946 is fixed on `main` and can be closed** — I verified all thirteen
callers are clean there, the one grep hit being that i18n key. This PR
is about the guard behind it, not the fix.

Third time in this program an instrument has been blind to a case in its
own motivating class, now across three tools and three authors. The
pattern is not carelessness — each guard was checked against the shapes
its author had in mind. Mutation against a shape you did *not* have in
mind is the only thing that has caught any of them, which is an argument
for making it routine when a ratchet ships rather than when someone gets
suspicious later.

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-30 22:51:45 -07:00
..
2026-07-26 18:11:47 -07:00