agentharness / rules
Cursor rule1 starsChanged 2 months agoMITView on GitHub
Use when building or reviewing web UIs for accessibility — WCAG 2.2 Level AA compliance, semantic HTML over ARIA, keyboard navigation, color contrast, screen reader patterns, and testing approach.
We split this accessibility.mdc into the rules it gives an agent
4 rules. About 0 are common, 1 is distinctive, and 3 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈1
Distinctive · estimate
This author's own choices. Worth a look.
3
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 37
Verify computed colors — don't eyeball.
- Very specific: line 43
Keyboard: All interactive elements must be reachable by Tab, in logical order, with no keyboard trap.
- Very specific: line 46
Visible focus: Never outline: none without a clearly visible replacement.
- Very specific: line 92
Run axe-core in CI as a smoke test, not a complete audit.
≈ “Common” is an estimate: at least 1 in 5 of the 6,350 Cursor rule files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
---
description: "Use when building or reviewing web UIs for accessibility — WCAG 2.2 Level AA compliance, semantic HTML over ARIA, keyboard navigation, color contrast, screen reader patterns, and testing approach."
---
## Accessibility
This skill is self-contained for day-to-day use. Deeper reference (needs
the full harness checkout): `patterns/accessibility/README.md` (full
examples including ARIA live regions and APG patterns). External
canonical sources: [WCAG 2.2](https://www.w3.org/TR/WCAG22/) and the
[WAI-ARIA Authoring Practices](https://www.w3.org/WAI/ARIA/apg/).
**Target: WCAG 2.2 Level AA.**
### The first rule: don't use ARIA if a native element exists
A native `<button>`, `<a href>`, `<input>`, `<label>`, `<nav>`, or
`<table>` brings keyboard behavior, focus management, and the correct
role/state for free. `role="button"` + `tabindex` + keyboard handler is
a liability you now own forever.
```html
<!-- Good: browser handles focus, Enter, Space, and role automatically -->
<button type="button" onclick="save()">Save</button>
<!-- Avoid: you must re-implement everything the native button provides -->
<div role="button" tabindex="0" onclick="save()" onkeydown="handleKey(event)">Save</div>
```
### Perceivable
- **Text alternatives.** Meaningful images: `alt` describing *purpose*.
Decorative images: `alt=""`. Icon-only controls: `aria-label` or
visually-hidden text.
- **Contrast.** Body text ≥ **4.5:1** against background. Large text
(≥ 24px, or ≥ 18.66px bold) and UI components/graphics ≥ **3:1**.
Verify computed colors — don't eyeball.
- **Color alone is not enough.** A red border *and* an error text/icon —
not red alone.
### Operable
- **Keyboard.** All interactive elements must be reachable by Tab, in
logical order, with no keyboard trap. `tabindex="0"` for natural order;
`tabindex="-1"` for programmatic-only focus; never positive values.
- **Visible focus.** Never `outline: none` without a clearly visible
replacement. Keyboard users navigate by it.
- **Skip link.** First focusable element on pages with repeated
navigation: `<a href="#main">Skip to main content</a>`.
- **Target size.** Interactive targets ≥ **24×24 px** (WCAG 2.2 §2.5.8),
with adequate spacing if smaller.
### Understandable
- **Label every input.** `<label for>` or `aria-labelledby`. Placeholder
text is not a label — it disappears when the user starts typing.
- **Errors in text.** On validation failure: describe what's wrong and
how to fix it; associate via `aria-describedby`; set
`aria-invalid="true"` on the field.
- **Consistent, predictable behavior.** Focus doesn't jump unexpectedly;
forms don't submit on focus change.
### Robust
- **Name, Role, Value** for every custom widget. Follow the matching
[ARIA APG pattern](https://www.w3.org/WAI/ARIA/apg/patterns/) exactly —
its roles, states, and keyboard interactions. A half-implemented ARIA
widget is worse than a native element.
- **Announce dynamic changes.** Content that updates without a page load
(toasts, async results, validation) needs an `aria-live` region
(`polite` for status updates, `assertive` only for urgent/time-sensitive
changes) or `role="alert"`.
```html
<!-- Status message that updates asynchronously -->
<div aria-live="polite" aria-atomic="true" class="sr-only" id="status">
<!-- Updated by JS: "3 items saved." -->
</div>
```
### Testing: automated is not enough
Automated tools (`axe-core`, Lighthouse) catch ~30–50% of WCAG issues —
contrast, missing labels/alt, invalid ARIA. The rest requires manual
testing:
1. **Tab through every interactive element** — confirm logical order,
visible focus, no traps.
2. **Run a screen reader** (NVDA + Firefox, VoiceOver + Safari) on each
flow. Hear, don't just read, what's announced.
3. **Check at 200% browser zoom** — layout must not break or lose content.
4. Run `axe-core` in CI as a smoke test, not a complete audit.
### Pitfalls to catch in review
```tsx
// Missing alt — screen reader announces the file path
<img src="/hero.png" /> // WRONG
<img src="/hero.png" alt="Developer reviewing code" /> // RIGHT
// Form input with no label
<input type="email" placeholder="you@example.com" /> // WRONG
<label htmlFor="email">Email</label>
<input type="email" id="email" placeholder="you@example.com" /> // RIGHT
// Click handler on non-interactive element — keyboard users can't trigger
<div onClick={handleSave}>Save</div> // WRONG
<button type="button" onClick={handleSave}>Save</button> // RIGHT
// outline: none without a replacement focus style
button:focus { outline: none; } // WRONG
button:focus-visible { outline: 2px solid #005fcc; outline-offset: 2px; } // RIGHT
```
Where files are headingNew Cursor rule files have more rules about planning and tracking tasks, and fewer about code style.
Of the Cursor rule files we read, the 3,978 first seen in the last six months, against the older ones: the kind of rule that gained most share, and the kind that lost most. About files like this in general, not this one, and an estimate, since a kind is a pattern in the words.
In this repository77 other files it gives its agents.
- AGENTS.mdAGENTS.md
- CLAUDE.mdCLAUDE.md
- .github/copilot-instructions.mdCopilot instructions
- .cursor/rules/agentharness-router.mdcCursor rule
- .cursor/rules/agentic-loops.mdcCursor rule
- .cursor/rules/api-design.mdcCursor rule
- .cursor/rules/audit-review-followup.mdcCursor rule
- .cursor/rules/big-work-plan-review.mdcCursor rule
- .cursor/rules/branching.mdcCursor rule
- .cursor/rules/clean-architecture.mdcCursor rule
- .cursor/rules/code-review-api.mdcCursor rule
- .cursor/rules/code-review-db.mdcCursor rule
- .cursor/rules/code-review.mdcCursor rule
- .cursor/rules/code-review-ui.mdcCursor rule
- .cursor/rules/committing.mdcCursor rule
- .cursor/rules/database-conventions.mdcCursor rule
- .cursor/rules/dependency-audit.mdcCursor rule
- .cursor/rules/dependency-injection.mdcCursor rule
- .cursor/rules/design-patterns.mdcCursor rule
- .cursor/rules/docker-conventions.mdcCursor rule
- .cursor/rules/error-handling.mdcCursor rule
- .cursor/rules/file-placement-policy.mdcCursor rule
- .cursor/rules/github-issue-triage.mdcCursor rule
- .cursor/rules/go-conventions.mdcCursor rule
- .cursor/rules/harness-feedback.mdcCursor rule
- .cursor/rules/logging.mdcCursor rule
- .cursor/rules/multi-agent-coordination.mdcCursor rule
- .cursor/rules/mutation-testing.mdcCursor rule
- .cursor/rules/performance-profiling.mdcCursor rule
- .cursor/rules/planning-with-files.mdcCursor rule
- .cursor/rules/port-agent-config.mdcCursor rule
- .cursor/rules/project-bootstrap.mdcCursor rule
- .cursor/rules/python-conventions.mdcCursor rule
- .cursor/rules/react-best-practices.mdcCursor rule
- .cursor/rules/refactoring.mdcCursor rule
- .cursor/rules/requirements-clarification.mdcCursor rule
- .cursor/rules/security-review.mdcCursor rule
- .cursor/rules/solid-principles.mdcCursor rule
- .cursor/rules/testing.mdcCursor rule
- .cursor/rules/typescript-conventions.mdcCursor rule
- accessibilitySkill
- agentic-loopsSkill
- api-designSkill
- audit-review-followupSkill
- big-work-plan-reviewSkill
- branchingSkill
- clean-architectureSkill
- code-review-apiSkill
- code-review-dbSkill
- code-reviewSkill
- code-review-uiSkill
- committingSkill
- database-conventionsSkill
- dependency-auditSkill
- dependency-injectionSkill
- design-patternsSkill
- docker-conventionsSkill
- error-handlingSkill
- file-placement-policySkill
- github-issue-triageSkill
- The first 60 shown.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
Reviews can't be read right now.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

