Rule Authoring Guide
Overview
Rules are the core detection units in A11YSmith. Each rule analyzes page evidence and produces zero or more findings.
Rule Interface
Every rule implements the WebRule interface:
interface WebRule {
rule_id: string; // e.g., 'web-buttons-vs-links'
title: string; // Human-readable title
detect(evidence: PageEvidence): RuleDetection[];
} PageEvidence
Rules receive collected evidence about a page:
interface PageEvidence {
url: string;
html: string; // Full DOM snapshot
axeResults: AxeViolation[]; // axe-core violations
accessibilityTree: AccessibilityNode | null;
consoleMessages: string[];
timestamp: string;
} RuleDetection
Each detection must include:
| Field | Required | Description |
|---|---|---|
detected | Yes | Whether the issue was found |
title | Yes | Short, component-focused title |
summary | Yes | One paragraph description |
impact_statement | Yes | Who is affected, how, with what AT |
expected_behavior | Yes | What should happen |
actual_behavior | Yes | What does happen |
suggested_fix | Yes | Primary recommendation |
severity | Yes | highest, high, medium, low |
confidence | Yes | high, medium, low |
confidence_rationale | Yes | Why this confidence level |
verdict | Yes | fail, recommended_improvement, needs_discussion, informational_note |
target_standard_ids | Yes | Target standard references |
wcag_sc_ids | Yes | WCAG SC references |
validation_steps | Yes | How to confirm the fix |
caveats | Yes | What is uncertain |
Creating a New Rule
- Create a file in
packages/web-auditor/src/rules/ - Implement the
WebRuleinterface - Register it in
packages/web-auditor/src/rules/index.ts - Add passing and failing test fixtures
- Write tests in
packages/web-auditor/src/__tests__/
Testing Rules
Rules are tested against HTML string fixtures (no browser needed):
const evidence = {
url: 'https://example.com',
html: '<div onclick="submit()">Submit</div>',
axeResults: [],
accessibilityTree: null,
consoleMessages: [],
timestamp: '2026-03-16T12:00:00Z',
};
const detections = rule.detect(evidence);
expect(detections.filter((d) => d.detected)).toHaveLength(1); Standards Mapping
Every rule must declare which standards it maps to, following the standards precedence rules: Target standards first, WCAG as fallback.