@harness-engineering/cli 1.6.1 → 1.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (72) hide show
  1. package/dist/agents/personas/planner.yaml +27 -0
  2. package/dist/agents/personas/verifier.yaml +30 -0
  3. package/dist/agents/skills/claude-code/enforce-architecture/SKILL.md +19 -0
  4. package/dist/agents/skills/claude-code/harness-accessibility/SKILL.md +274 -0
  5. package/dist/agents/skills/claude-code/harness-accessibility/skill.yaml +51 -0
  6. package/dist/agents/skills/claude-code/harness-autopilot/SKILL.md +111 -72
  7. package/dist/agents/skills/claude-code/harness-autopilot/skill.yaml +4 -2
  8. package/dist/agents/skills/claude-code/harness-dependency-health/skill.yaml +1 -1
  9. package/dist/agents/skills/claude-code/harness-design/SKILL.md +265 -0
  10. package/dist/agents/skills/claude-code/harness-design/skill.yaml +53 -0
  11. package/dist/agents/skills/claude-code/harness-design-mobile/SKILL.md +336 -0
  12. package/dist/agents/skills/claude-code/harness-design-mobile/skill.yaml +49 -0
  13. package/dist/agents/skills/claude-code/harness-design-system/SKILL.md +282 -0
  14. package/dist/agents/skills/claude-code/harness-design-system/skill.yaml +50 -0
  15. package/dist/agents/skills/claude-code/harness-design-web/SKILL.md +360 -0
  16. package/dist/agents/skills/claude-code/harness-design-web/skill.yaml +52 -0
  17. package/dist/agents/skills/claude-code/harness-hotspot-detector/skill.yaml +1 -1
  18. package/dist/agents/skills/claude-code/harness-impact-analysis/SKILL.md +16 -0
  19. package/dist/agents/skills/claude-code/harness-integrity/SKILL.md +19 -1
  20. package/dist/agents/skills/claude-code/harness-knowledge-mapper/skill.yaml +1 -1
  21. package/dist/agents/skills/claude-code/harness-onboarding/SKILL.md +19 -1
  22. package/dist/agents/skills/claude-code/harness-release-readiness/SKILL.md +13 -9
  23. package/dist/agents/skills/claude-code/harness-security-scan/skill.yaml +1 -1
  24. package/dist/agents/skills/claude-code/harness-verify/SKILL.md +26 -0
  25. package/dist/agents/skills/gemini-cli/harness-accessibility/SKILL.md +274 -0
  26. package/dist/agents/skills/gemini-cli/harness-accessibility/skill.yaml +51 -0
  27. package/dist/agents/skills/gemini-cli/harness-autopilot/SKILL.md +111 -72
  28. package/dist/agents/skills/gemini-cli/harness-autopilot/skill.yaml +4 -2
  29. package/dist/agents/skills/gemini-cli/harness-dependency-health/skill.yaml +1 -1
  30. package/dist/agents/skills/gemini-cli/harness-design/SKILL.md +265 -0
  31. package/dist/agents/skills/gemini-cli/harness-design/skill.yaml +53 -0
  32. package/dist/agents/skills/gemini-cli/harness-design-mobile/SKILL.md +336 -0
  33. package/dist/agents/skills/gemini-cli/harness-design-mobile/skill.yaml +49 -0
  34. package/dist/agents/skills/gemini-cli/harness-design-system/SKILL.md +282 -0
  35. package/dist/agents/skills/gemini-cli/harness-design-system/skill.yaml +50 -0
  36. package/dist/agents/skills/gemini-cli/harness-design-web/SKILL.md +360 -0
  37. package/dist/agents/skills/gemini-cli/harness-design-web/skill.yaml +52 -0
  38. package/dist/agents/skills/gemini-cli/harness-hotspot-detector/skill.yaml +1 -1
  39. package/dist/agents/skills/gemini-cli/harness-impact-analysis/SKILL.md +16 -0
  40. package/dist/agents/skills/gemini-cli/harness-knowledge-mapper/skill.yaml +1 -1
  41. package/dist/agents/skills/gemini-cli/harness-release-readiness/SKILL.md +13 -9
  42. package/dist/agents/skills/gemini-cli/harness-security-scan/skill.yaml +1 -1
  43. package/dist/agents/skills/node_modules/.bin/vitest +2 -2
  44. package/dist/agents/skills/shared/design-knowledge/anti-patterns/color.yaml +106 -0
  45. package/dist/agents/skills/shared/design-knowledge/anti-patterns/layout.yaml +109 -0
  46. package/dist/agents/skills/shared/design-knowledge/anti-patterns/motion.yaml +109 -0
  47. package/dist/agents/skills/shared/design-knowledge/anti-patterns/typography.yaml +112 -0
  48. package/dist/agents/skills/shared/design-knowledge/industries/creative.yaml +80 -0
  49. package/dist/agents/skills/shared/design-knowledge/industries/ecommerce.yaml +80 -0
  50. package/dist/agents/skills/shared/design-knowledge/industries/emerging-tech.yaml +83 -0
  51. package/dist/agents/skills/shared/design-knowledge/industries/fintech.yaml +80 -0
  52. package/dist/agents/skills/shared/design-knowledge/industries/healthcare.yaml +80 -0
  53. package/dist/agents/skills/shared/design-knowledge/industries/lifestyle.yaml +80 -0
  54. package/dist/agents/skills/shared/design-knowledge/industries/saas.yaml +80 -0
  55. package/dist/agents/skills/shared/design-knowledge/industries/services.yaml +80 -0
  56. package/dist/agents/skills/shared/design-knowledge/palettes/curated.yaml +234 -0
  57. package/dist/agents/skills/shared/design-knowledge/platform-rules/android.yaml +125 -0
  58. package/dist/agents/skills/shared/design-knowledge/platform-rules/flutter.yaml +144 -0
  59. package/dist/agents/skills/shared/design-knowledge/platform-rules/ios.yaml +106 -0
  60. package/dist/agents/skills/shared/design-knowledge/platform-rules/web.yaml +102 -0
  61. package/dist/agents/skills/shared/design-knowledge/typography/pairings.yaml +274 -0
  62. package/dist/bin/harness.js +3 -2
  63. package/dist/{chunk-3U5VZYR7.js → chunk-4WUGOJQ7.js} +6 -3
  64. package/dist/{chunk-O6NEKDYP.js → chunk-FFIX3QVG.js} +697 -349
  65. package/dist/chunk-GA6GN5J2.js +6150 -0
  66. package/dist/dist-C4J67MPP.js +242 -0
  67. package/dist/dist-N4D4QWFV.js +2809 -0
  68. package/dist/index.d.ts +79 -0
  69. package/dist/index.js +3 -2
  70. package/dist/validate-cross-check-WGXQ7K62.js +7 -0
  71. package/package.json +12 -8
  72. package/dist/validate-cross-check-LNIZ7KGZ.js +0 -6
@@ -48,6 +48,20 @@ Rules:
48
48
  - Run each command from the project root directory.
49
49
  - Do not modify any files. Do not install dependencies. Do not fix errors.
50
50
 
51
+ ### Design Constraint Check (conditional)
52
+
53
+ When `harness.config.json` contains a `design` block:
54
+
55
+ 1. **Run design constraint checks** by invoking `harness-accessibility` in scan+evaluate mode against the project.
56
+ 2. Apply the `design.strictness` setting to determine severity:
57
+ - `strict`: accessibility violations are FAIL; anti-pattern violations are WARN
58
+ - `standard`: accessibility and anti-pattern violations are WARN; nothing blocks
59
+ - `permissive`: all design violations are INFO
60
+ 3. Capture the result as `Design: [PASS/WARN/FAIL/SKIPPED]`.
61
+ 4. If no `design` block exists in config, mark Design as `SKIPPED`.
62
+
63
+ The design check runs AFTER test/lint/typecheck. It does not short-circuit on earlier failures.
64
+
51
65
  ### Phase 3: REPORT
52
66
 
53
67
  Output a structured result in this exact format:
@@ -59,6 +73,16 @@ Verification: [PASS/FAIL]
59
73
  - Test: [PASS/FAIL/SKIPPED]
60
74
  ```
61
75
 
76
+ When design config is present, include the design line:
77
+
78
+ ```
79
+ Verification: [PASS/FAIL]
80
+ - Typecheck: [PASS/FAIL/SKIPPED]
81
+ - Lint: [PASS/FAIL/SKIPPED]
82
+ - Test: [PASS/FAIL/SKIPPED]
83
+ - Design: [PASS/WARN/FAIL/SKIPPED]
84
+ ```
85
+
62
86
  Rules:
63
87
 
64
88
  - Overall `Verification: PASS` only if all non-skipped checks passed.
@@ -80,6 +104,8 @@ This skill is entirely deterministic. There are no LLM judgment calls anywhere i
80
104
  - Invoked as the final step by code-producing skills (harness-execution, harness-tdd)
81
105
  - Complements harness-verification (deep audit) — use verify for quick checks, verification for milestones
82
106
  - Output format is consumed by harness-integrity for the unified pipeline
107
+ - Invokes `harness-accessibility` for design constraint checking when `design` config exists
108
+ - Design violations respect `design.strictness` from `harness.config.json`
83
109
 
84
110
  ## Success Criteria
85
111
 
@@ -0,0 +1,274 @@
1
+ # Harness Accessibility
2
+
3
+ > WCAG compliance verification and remediation. Scan components for accessibility violations, evaluate severity against design strictness, generate actionable reports, and apply automated fixes for mechanical issues.
4
+
5
+ ## When to Use
6
+
7
+ - Auditing new or existing UI components for WCAG AA accessibility compliance
8
+ - Before PR merge to catch accessibility regressions in UI changes
9
+ - When `on_new_feature` triggers fire and the feature includes UI components
10
+ - When design tokens change (color updates may break contrast compliance)
11
+ - After running harness-design-system to validate the generated palette
12
+ - When `on_project_init` triggers fire to establish an accessibility baseline
13
+ - NOT for design token generation or palette selection (use harness-design-system)
14
+ - NOT for visual design review or aesthetic direction (use harness-design, Phase 4)
15
+ - NOT for non-UI code (backend services, CLI tools, data pipelines)
16
+
17
+ ## Process
18
+
19
+ ### Phase 1: SCAN -- Detect Accessibility Violations
20
+
21
+ 1. **Load design tokens.** Read `design-system/tokens.json` (if it exists) to identify declared color values and contrast pairs. Token-defined colors are the source of truth -- hardcoded colors in components are themselves a violation.
22
+
23
+ 2. **Read design strictness.** Check `harness.config.json` for `design.strictness`:
24
+ - `strict` -- all findings are errors that block (CI fails, PR cannot merge)
25
+ - `standard` -- warnings are visible, errors block (default behavior)
26
+ - `permissive` -- all findings are informational (nothing blocks, but everything is reported)
27
+
28
+ 3. **Scan component files.** Search all files matching `.tsx`, `.jsx`, `.vue`, `.svelte`, `.html` for the following violations:
29
+
30
+ **Images and media:**
31
+ - `<img>` tags without `alt` attribute (`A11Y-001`)
32
+ - `<img>` tags with empty `alt=""` on non-decorative images (`A11Y-002`)
33
+ - `<video>` and `<audio>` without captions/transcripts (`A11Y-003`)
34
+
35
+ **ARIA and semantics:**
36
+ - Interactive elements (`<button>`, `<a>`, `<input>`) without accessible labels (`A11Y-010`)
37
+ - Icon-only buttons without `aria-label` or visually hidden text (`A11Y-011`)
38
+ - Clickable `<div>` or `<span>` without `role="button"` and keyboard handler (`A11Y-012`)
39
+ - Missing `role` attributes on custom interactive widgets (`A11Y-013`)
40
+ - `aria-hidden="true"` on focusable elements (`A11Y-014`)
41
+
42
+ **Heading structure:**
43
+ - Non-sequential heading levels (e.g., `<h1>` followed by `<h3>`, skipping `<h2>`) (`A11Y-020`)
44
+ - Multiple `<h1>` elements on a single page/component (`A11Y-021`)
45
+ - Empty headings (`A11Y-022`)
46
+
47
+ **Color and contrast:**
48
+ - Hardcoded color values not from the token set (`A11Y-030`)
49
+ - Inline styles with color/background-color that may fail contrast (`A11Y-031`)
50
+
51
+ **Keyboard navigation:**
52
+ - `onClick` handlers without corresponding `onKeyDown`/`onKeyUp` (`A11Y-040`)
53
+ - Missing `tabIndex` on custom interactive elements (`A11Y-041`)
54
+ - Positive `tabIndex` values (disrupts natural tab order) (`A11Y-042`)
55
+ - Missing focus indicators (`:focus` or `:focus-visible` styles) (`A11Y-043`)
56
+
57
+ **Forms:**
58
+ - `<input>`, `<select>`, `<textarea>` without associated `<label>` or `aria-label` (`A11Y-050`)
59
+ - Missing `id` attributes on form controls (needed for label association) (`A11Y-051`)
60
+ - Missing error messages or `aria-invalid` on validation states (`A11Y-052`)
61
+
62
+ 4. **Load anti-pattern catalogs.** Read additional detection rules from `agents/skills/shared/design-knowledge/` if available. These catalogs contain industry-specific accessibility patterns (e.g., healthcare forms require higher contrast, fintech requires screen reader-compatible data tables).
63
+
64
+ 5. **Record all findings.** Each finding includes:
65
+ - File path
66
+ - Line number (approximate, from Grep output)
67
+ - Violation code (e.g., `A11Y-001`)
68
+ - Element or pattern that triggered the finding
69
+ - Raw evidence (the matching line of code)
70
+
71
+ ### Phase 2: EVALUATE -- Assess Severity and Categorize
72
+
73
+ 1. **Assign severity based on `design.strictness`:**
74
+ - `strict` mode: all violations are `error` severity
75
+ - `standard` mode: missing alt, missing labels, contrast failures are `error`; heading order, tabIndex are `warn`; informational patterns are `info`
76
+ - `permissive` mode: contrast failures and missing labels are `warn`; everything else is `info`
77
+
78
+ 2. **Calculate contrast ratios.** For every color pair found in scanned code:
79
+ - Extract foreground and background colors (from inline styles, class mappings, or token references)
80
+ - Calculate relative luminance for each color using the WCAG 2.1 formula:
81
+ - `L = 0.2126 * R + 0.7152 * G + 0.0722 * B` (where R, G, B are linearized sRGB values)
82
+ - Calculate contrast ratio: `(L1 + 0.05) / (L2 + 0.05)` where L1 is the lighter color
83
+ - Compare against thresholds:
84
+ - Normal text (< 18px regular, < 14px bold): 4.5:1 minimum (WCAG AA)
85
+ - Large text (>= 18px regular, >= 14px bold): 3:1 minimum (WCAG AA)
86
+
87
+ 3. **Cross-reference with design tokens.** If `design-system/tokens.json` exists:
88
+ - Map hardcoded colors in code to their nearest token equivalents
89
+ - If a token-based color pair fails contrast, flag the **token definition** (not just the component usage) -- the fix belongs in harness-design-system, not here
90
+ - If a hardcoded color fails contrast, flag both the contrast issue and the non-token usage
91
+
92
+ 4. **Check graph constraints.** If a graph exists at `.harness/graph/`, use `DesignConstraintAdapter` from `packages/graph/src/constraints/DesignConstraintAdapter.ts` to:
93
+ - Query for existing `VIOLATES` edges (violations already recorded in the graph)
94
+ - Add new `VIOLATES` edges for findings from this scan
95
+ - The adapter reads `design.strictness` to control which violations produce edges
96
+
97
+ 5. **Categorize findings.** Group into categories:
98
+ - **Contrast** (A11Y-030, A11Y-031): color-related violations
99
+ - **ARIA** (A11Y-010 through A11Y-014): attribute and role violations
100
+ - **Semantics** (A11Y-020 through A11Y-022): heading and structure violations
101
+ - **Keyboard** (A11Y-040 through A11Y-043): navigation and focus violations
102
+ - **Forms** (A11Y-050 through A11Y-052): form control violations
103
+ - **Media** (A11Y-001 through A11Y-003): image, video, audio violations
104
+
105
+ ### Phase 3: REPORT -- Generate Accessibility Report
106
+
107
+ 1. **Generate summary header:**
108
+
109
+ ```
110
+ Accessibility Report
111
+ ====================
112
+ Scanned: 42 component files
113
+ Findings: 18 total (6 error, 8 warn, 4 info)
114
+ Strictness: standard
115
+ ```
116
+
117
+ 2. **List findings grouped by category.** Each finding follows this format:
118
+
119
+ ```
120
+ A11Y-001 [error] Missing alt attribute on <img>
121
+ File: src/components/UserAvatar.tsx
122
+ Line: 24
123
+ Element: <img src={user.avatarUrl} className="avatar" />
124
+ WCAG: 1.1.1 Non-text Content
125
+ Fix: Add alt={user.name} or alt="" if decorative
126
+ ```
127
+
128
+ ```
129
+ A11Y-031 [error] Contrast ratio 2.8:1 fails WCAG AA (requires 4.5:1)
130
+ File: src/components/Button.tsx
131
+ Line: 15
132
+ Element: color: #999 on background: #fff
133
+ WCAG: 1.4.3 Contrast (Minimum)
134
+ Fix: Use color token "neutral.600" (#475569, ratio 4.9:1) instead
135
+ ```
136
+
137
+ 3. **Provide category summaries** with counts and severity breakdown.
138
+
139
+ 4. **List actionable next steps:**
140
+ - Errors that can be auto-fixed (Phase 4)
141
+ - Errors that require human judgment
142
+ - Warnings to address in next iteration
143
+ - Token-level issues to escalate to harness-design-system
144
+
145
+ ### Phase 4: FIX -- Apply Automated Remediation (Optional)
146
+
147
+ This phase is optional. It applies fixes only for **mechanical issues** -- violations with a single, unambiguous correct fix. Subjective issues (color choices, layout decisions, content writing) are never auto-fixed.
148
+
149
+ 1. **Fixable violations:**
150
+ - `A11Y-001`: Add `alt=""` to `<img>` tags that are decorative (inside `<button>`, `<a>`, or with `role="presentation"`)
151
+ - `A11Y-011`: Add `aria-label` to icon-only `<button>` elements (using the icon name as label)
152
+ - `A11Y-012`: Add `role="button"` and `tabIndex={0}` to clickable `<div>` elements
153
+ - `A11Y-041`: Add `tabIndex={0}` to custom interactive elements missing it
154
+ - `A11Y-051`: Generate `id` attributes for form controls and link them to labels
155
+
156
+ 2. **Apply each fix as a minimal, targeted edit.** Use the Edit tool. Do not refactor surrounding code. Do not change formatting. The fix should be the smallest possible change that resolves the violation.
157
+
158
+ 3. **Show before/after diff for each fix.** Present the exact change to the user. This is a hard gate -- no fix is applied without showing the diff first.
159
+
160
+ 4. **Re-scan after fixes.** Run the scan phase again on fixed files to confirm violations are resolved. Report:
161
+ - Fixes applied: N
162
+ - Violations resolved: N
163
+ - Remaining violations (require human judgment): M
164
+
165
+ 5. **Do NOT fix:**
166
+ - Color choices (subjective -- escalate to harness-design-system)
167
+ - Content for alt text on meaningful images (requires human judgment about image meaning)
168
+ - Layout and heading structure changes (may affect design intent)
169
+ - Any fix that would change the visual appearance of the component
170
+
171
+ ## Harness Integration
172
+
173
+ - **`harness validate`** -- Accessibility findings surface as design constraint violations when `design.strictness` is `strict` or `standard`. Running validate after a scan reflects the current a11y state.
174
+ - **`harness scan`** -- Refresh the knowledge graph after fixes to update `VIOLATES` edges. Ensures impact analysis stays current.
175
+ - **`DesignConstraintAdapter`** (`packages/graph/src/constraints/DesignConstraintAdapter.ts`) -- Reads `design.strictness` from project config to control violation severity. Manages `VIOLATES` edges in the graph for design and accessibility constraints.
176
+ - **`DesignIngestor`** (`packages/graph/src/ingest/DesignIngestor.ts`) -- Provides token data used for contrast checking. The ingestor parses `tokens.json` so the accessibility scanner can compare code colors against declared tokens.
177
+ - **`harness-impact-analysis`** -- When tokens change (palette update, new colors), impact analysis traces affected components. The accessibility skill uses this to determine which components need re-scanning.
178
+ - **`harness-design-system`** -- Dependency. When contrast failures originate from token definitions (not component code), escalate to harness-design-system to fix at the source.
179
+
180
+ ## Success Criteria
181
+
182
+ - All scanned component files have findings categorized by severity (`error`, `warn`, `info`)
183
+ - Contrast failures detected with correct ratios and WCAG criterion references
184
+ - Missing ARIA attributes flagged with specific file paths and line numbers
185
+ - Non-sequential heading hierarchy violations identified
186
+ - Keyboard navigation gaps (missing handlers, broken tab order) detected
187
+ - Form accessibility issues (missing labels, missing error states) found
188
+ - Report generated with violation codes, WCAG references, and actionable remediation
189
+ - Automated fixes applied without breaking existing functionality or tests
190
+ - `harness validate` reflects accessibility findings at the configured strictness level
191
+ - Token-level contrast issues escalated to harness-design-system (not fixed locally)
192
+
193
+ ## Examples
194
+
195
+ ### Example: Scanning a React Dashboard Component
196
+
197
+ **Context:** A React component `DashboardCard.tsx` with known accessibility issues.
198
+
199
+ **Source file:**
200
+
201
+ ```tsx
202
+ // src/components/DashboardCard.tsx
203
+ export function DashboardCard({ title, value, icon, onClick }) {
204
+ return (
205
+ <div className="card" onClick={onClick}>
206
+ <img src={icon} />
207
+ <h3>{title}</h3>
208
+ <span style={{ color: '#999', fontSize: '14px' }}>{value}</span>
209
+ </div>
210
+ );
211
+ }
212
+ ```
213
+
214
+ **SCAN findings:**
215
+
216
+ ```
217
+ A11Y-001 [error] Missing alt attribute on <img>
218
+ File: src/components/DashboardCard.tsx
219
+ Line: 5
220
+ Element: <img src={icon} />
221
+ WCAG: 1.1.1 Non-text Content
222
+
223
+ A11Y-012 [error] Clickable <div> without role="button" and keyboard handler
224
+ File: src/components/DashboardCard.tsx
225
+ Line: 4
226
+ Element: <div className="card" onClick={onClick}>
227
+ WCAG: 2.1.1 Keyboard
228
+
229
+ A11Y-031 [warn] Contrast ratio 2.8:1 for #999 on #fff fails WCAG AA
230
+ File: src/components/DashboardCard.tsx
231
+ Line: 7
232
+ Element: <span style={{ color: '#999' }}>
233
+ WCAG: 1.4.3 Contrast (Minimum)
234
+ Note: Hardcoded color -- not from token set
235
+
236
+ A11Y-030 [info] Hardcoded color value not from design token set
237
+ File: src/components/DashboardCard.tsx
238
+ Line: 7
239
+ Element: color: '#999'
240
+ ```
241
+
242
+ **FIX phase (auto-fixable only):**
243
+
244
+ ```diff
245
+ - <img src={icon} />
246
+ + <img src={icon} alt="" />
247
+
248
+ - <div className="card" onClick={onClick}>
249
+ + <div className="card" role="button" tabIndex={0} onClick={onClick} onKeyDown={(e) => { if (e.key === 'Enter' || e.key === ' ') onClick?.(); }}>
250
+ ```
251
+
252
+ **Remaining (requires human judgment):**
253
+
254
+ - `A11Y-031`: Contrast failure -- fix requires choosing a darker color. Escalate to design tokens or get human input on replacement color.
255
+ - `A11Y-001`: The `alt=""` fix assumes decorative. If the icon conveys meaning, human must write descriptive alt text.
256
+
257
+ ## Gates
258
+
259
+ These are hard stops. Violating any gate means the process has broken down.
260
+
261
+ - **No component marked "accessible" without passing WCAG AA contrast checks.** A passing scan means zero `error`-severity contrast violations, not zero findings overall.
262
+ - **No automated fix applied without showing the before/after diff.** Every fix must be presented to the user with the exact code change before being written to disk.
263
+ - **No severity downgrade below what `design.strictness` config specifies.** If the project is in `strict` mode, a missing alt attribute is an error. The scanner does not get to decide it is a warning.
264
+ - **The scan phase must complete before evaluate.** No partial evaluations on incomplete scan results. All files must be scanned before severity assignment begins.
265
+ - **No fixes that change visual appearance.** Automated fixes are structural (adding attributes, roles, handlers). If a fix would visibly change the rendered output, it requires human approval.
266
+
267
+ ## Escalation
268
+
269
+ - **When contrast ratio is borderline (4.5:1 to 5:1):** Flag for human review rather than auto-passing. Report: "Contrast ratio 4.6:1 technically passes WCAG AA but is borderline. Consider using a higher-contrast alternative for better readability."
270
+ - **When a component has more than 10 findings:** Suggest architectural refactoring rather than piecemeal fixes. The component likely has systemic accessibility issues that individual fixes will not adequately address. Recommend: "This component has 14 accessibility findings. Consider refactoring to use accessible base components rather than fixing each issue individually."
271
+ - **When design tokens themselves have contrast failures:** Do not fix at the usage site. Escalate to harness-design-system: "Token pair primary-500 on neutral-50 has contrast ratio 3.2:1. This must be fixed in design-system/tokens.json, not in individual components. Run harness-design-system to update the palette."
272
+ - **When automated fix would change visual appearance:** Require explicit human approval. Present the fix with a note: "This fix changes the rendered output. The current <div> will become keyboard-focusable with a visible focus ring. Approve this change?"
273
+ - **When `design.strictness` is not configured:** Default to `standard` mode. Report: "No design.strictness found in harness.config.json. Using 'standard' (warnings visible, errors block). Set design.strictness in config to customize."
274
+ - **After 3 failed attempts to resolve a contrast issue:** The color pair may be fundamentally incompatible. Suggest: "Consider using a different color combination. The current pair cannot achieve WCAG AA compliance without changing one of the colors significantly."
@@ -0,0 +1,51 @@
1
+ name: harness-accessibility
2
+ version: "1.0.0"
3
+ description: WCAG accessibility scanning, contrast checking, ARIA validation, and remediation
4
+ cognitive_mode: meticulous-verifier
5
+ triggers:
6
+ - manual
7
+ - on_new_feature
8
+ - on_project_init
9
+ platforms:
10
+ - claude-code
11
+ - gemini-cli
12
+ tools:
13
+ - Bash
14
+ - Read
15
+ - Write
16
+ - Edit
17
+ - Glob
18
+ - Grep
19
+ cli:
20
+ command: harness skill run harness-accessibility
21
+ args:
22
+ - name: path
23
+ description: Project root path
24
+ required: false
25
+ - name: scope
26
+ description: Scope of scan (full, component, page)
27
+ required: false
28
+ mcp:
29
+ tool: run_skill
30
+ input:
31
+ skill: harness-accessibility
32
+ path: string
33
+ type: rigid
34
+ phases:
35
+ - name: scan
36
+ description: Scan codebase for accessibility issues (WCAG AA baseline)
37
+ required: true
38
+ - name: evaluate
39
+ description: Evaluate severity and categorize findings
40
+ required: true
41
+ - name: report
42
+ description: Generate structured accessibility report
43
+ required: true
44
+ - name: fix
45
+ description: Apply automated fixes for mechanical issues
46
+ required: false
47
+ state:
48
+ persistent: false
49
+ files: []
50
+ depends_on:
51
+ - harness-design-system