@harness-engineering/cli 1.6.2 → 1.8.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 (180) hide show
  1. package/dist/agents/personas/documentation-maintainer.yaml +3 -1
  2. package/dist/agents/personas/performance-guardian.yaml +23 -0
  3. package/dist/agents/personas/planner.yaml +27 -0
  4. package/dist/agents/personas/verifier.yaml +30 -0
  5. package/dist/agents/skills/claude-code/align-documentation/SKILL.md +13 -0
  6. package/dist/agents/skills/claude-code/cleanup-dead-code/SKILL.md +25 -1
  7. package/dist/agents/skills/claude-code/cleanup-dead-code/skill.yaml +5 -2
  8. package/dist/agents/skills/claude-code/detect-doc-drift/SKILL.md +12 -0
  9. package/dist/agents/skills/claude-code/enforce-architecture/SKILL.md +67 -1
  10. package/dist/agents/skills/claude-code/enforce-architecture/skill.yaml +5 -2
  11. package/dist/agents/skills/claude-code/harness-accessibility/SKILL.md +281 -0
  12. package/dist/agents/skills/claude-code/harness-accessibility/skill.yaml +51 -0
  13. package/dist/agents/skills/claude-code/harness-autopilot/SKILL.md +119 -72
  14. package/dist/agents/skills/claude-code/harness-autopilot/skill.yaml +4 -2
  15. package/dist/agents/skills/claude-code/harness-brainstorming/SKILL.md +76 -4
  16. package/dist/agents/skills/claude-code/harness-brainstorming/skill.yaml +2 -0
  17. package/dist/agents/skills/claude-code/harness-code-review/SKILL.md +487 -234
  18. package/dist/agents/skills/claude-code/harness-code-review/skill.yaml +15 -2
  19. package/dist/agents/skills/claude-code/harness-codebase-cleanup/SKILL.md +226 -0
  20. package/dist/agents/skills/claude-code/harness-codebase-cleanup/skill.yaml +64 -0
  21. package/dist/agents/skills/claude-code/harness-dependency-health/SKILL.md +35 -6
  22. package/dist/agents/skills/claude-code/harness-dependency-health/skill.yaml +1 -1
  23. package/dist/agents/skills/claude-code/harness-design/SKILL.md +265 -0
  24. package/dist/agents/skills/claude-code/harness-design/skill.yaml +53 -0
  25. package/dist/agents/skills/claude-code/harness-design-mobile/SKILL.md +336 -0
  26. package/dist/agents/skills/claude-code/harness-design-mobile/skill.yaml +49 -0
  27. package/dist/agents/skills/claude-code/harness-design-system/SKILL.md +282 -0
  28. package/dist/agents/skills/claude-code/harness-design-system/skill.yaml +50 -0
  29. package/dist/agents/skills/claude-code/harness-design-web/SKILL.md +360 -0
  30. package/dist/agents/skills/claude-code/harness-design-web/skill.yaml +52 -0
  31. package/dist/agents/skills/claude-code/harness-docs-pipeline/SKILL.md +460 -0
  32. package/dist/agents/skills/claude-code/harness-docs-pipeline/skill.yaml +69 -0
  33. package/dist/agents/skills/claude-code/harness-execution/SKILL.md +73 -8
  34. package/dist/agents/skills/claude-code/harness-execution/skill.yaml +1 -0
  35. package/dist/agents/skills/claude-code/harness-hotspot-detector/SKILL.md +32 -6
  36. package/dist/agents/skills/claude-code/harness-hotspot-detector/skill.yaml +1 -1
  37. package/dist/agents/skills/claude-code/harness-i18n/SKILL.md +484 -0
  38. package/dist/agents/skills/claude-code/harness-i18n/skill.yaml +54 -0
  39. package/dist/agents/skills/claude-code/harness-i18n-process/SKILL.md +388 -0
  40. package/dist/agents/skills/claude-code/harness-i18n-process/skill.yaml +43 -0
  41. package/dist/agents/skills/claude-code/harness-i18n-workflow/SKILL.md +512 -0
  42. package/dist/agents/skills/claude-code/harness-i18n-workflow/skill.yaml +53 -0
  43. package/dist/agents/skills/claude-code/harness-impact-analysis/SKILL.md +51 -6
  44. package/dist/agents/skills/claude-code/harness-integrity/SKILL.md +35 -1
  45. package/dist/agents/skills/claude-code/harness-knowledge-mapper/SKILL.md +46 -5
  46. package/dist/agents/skills/claude-code/harness-knowledge-mapper/skill.yaml +1 -1
  47. package/dist/agents/skills/claude-code/harness-onboarding/SKILL.md +19 -1
  48. package/dist/agents/skills/claude-code/harness-perf/SKILL.md +37 -8
  49. package/dist/agents/skills/claude-code/harness-perf/skill.yaml +3 -0
  50. package/dist/agents/skills/claude-code/harness-perf-tdd/SKILL.md +17 -4
  51. package/dist/agents/skills/claude-code/harness-planning/SKILL.md +57 -3
  52. package/dist/agents/skills/claude-code/harness-planning/skill.yaml +2 -0
  53. package/dist/agents/skills/claude-code/harness-release-readiness/SKILL.md +29 -9
  54. package/dist/agents/skills/claude-code/harness-roadmap/SKILL.md +562 -0
  55. package/dist/agents/skills/claude-code/harness-roadmap/skill.yaml +43 -0
  56. package/dist/agents/skills/claude-code/harness-security-review/SKILL.md +36 -2
  57. package/dist/agents/skills/claude-code/harness-security-review/skill.yaml +8 -6
  58. package/dist/agents/skills/claude-code/harness-security-scan/skill.yaml +1 -1
  59. package/dist/agents/skills/claude-code/harness-soundness-review/SKILL.md +1267 -0
  60. package/dist/agents/skills/claude-code/harness-soundness-review/skill.yaml +48 -0
  61. package/dist/agents/skills/claude-code/harness-test-advisor/SKILL.md +35 -6
  62. package/dist/agents/skills/claude-code/harness-verification/SKILL.md +66 -0
  63. package/dist/agents/skills/claude-code/harness-verification/skill.yaml +1 -0
  64. package/dist/agents/skills/claude-code/harness-verify/SKILL.md +37 -0
  65. package/dist/agents/skills/claude-code/initialize-harness-project/SKILL.md +15 -1
  66. package/dist/agents/skills/claude-code/validate-context-engineering/SKILL.md +12 -0
  67. package/dist/agents/skills/gemini-cli/harness-accessibility/SKILL.md +281 -0
  68. package/dist/agents/skills/gemini-cli/harness-accessibility/skill.yaml +51 -0
  69. package/dist/agents/skills/gemini-cli/harness-autopilot/SKILL.md +119 -72
  70. package/dist/agents/skills/gemini-cli/harness-autopilot/skill.yaml +4 -2
  71. package/dist/agents/skills/gemini-cli/harness-codebase-cleanup/SKILL.md +226 -0
  72. package/dist/agents/skills/gemini-cli/harness-codebase-cleanup/skill.yaml +64 -0
  73. package/dist/agents/skills/gemini-cli/harness-dependency-health/SKILL.md +35 -6
  74. package/dist/agents/skills/gemini-cli/harness-dependency-health/skill.yaml +1 -1
  75. package/dist/agents/skills/gemini-cli/harness-design/SKILL.md +265 -0
  76. package/dist/agents/skills/gemini-cli/harness-design/skill.yaml +53 -0
  77. package/dist/agents/skills/gemini-cli/harness-design-mobile/SKILL.md +336 -0
  78. package/dist/agents/skills/gemini-cli/harness-design-mobile/skill.yaml +49 -0
  79. package/dist/agents/skills/gemini-cli/harness-design-system/SKILL.md +282 -0
  80. package/dist/agents/skills/gemini-cli/harness-design-system/skill.yaml +50 -0
  81. package/dist/agents/skills/gemini-cli/harness-design-web/SKILL.md +360 -0
  82. package/dist/agents/skills/gemini-cli/harness-design-web/skill.yaml +52 -0
  83. package/dist/agents/skills/gemini-cli/harness-docs-pipeline/SKILL.md +460 -0
  84. package/dist/agents/skills/gemini-cli/harness-docs-pipeline/skill.yaml +69 -0
  85. package/dist/agents/skills/gemini-cli/harness-hotspot-detector/SKILL.md +32 -6
  86. package/dist/agents/skills/gemini-cli/harness-hotspot-detector/skill.yaml +1 -1
  87. package/dist/agents/skills/gemini-cli/harness-i18n/SKILL.md +484 -0
  88. package/dist/agents/skills/gemini-cli/harness-i18n/skill.yaml +54 -0
  89. package/dist/agents/skills/gemini-cli/harness-i18n-process/SKILL.md +388 -0
  90. package/dist/agents/skills/gemini-cli/harness-i18n-process/skill.yaml +43 -0
  91. package/dist/agents/skills/gemini-cli/harness-i18n-workflow/SKILL.md +512 -0
  92. package/dist/agents/skills/gemini-cli/harness-i18n-workflow/skill.yaml +53 -0
  93. package/dist/agents/skills/gemini-cli/harness-impact-analysis/SKILL.md +51 -6
  94. package/dist/agents/skills/gemini-cli/harness-knowledge-mapper/SKILL.md +46 -5
  95. package/dist/agents/skills/gemini-cli/harness-knowledge-mapper/skill.yaml +1 -1
  96. package/dist/agents/skills/gemini-cli/harness-perf/SKILL.md +37 -8
  97. package/dist/agents/skills/gemini-cli/harness-perf/skill.yaml +3 -0
  98. package/dist/agents/skills/gemini-cli/harness-perf-tdd/SKILL.md +17 -4
  99. package/dist/agents/skills/gemini-cli/harness-release-readiness/SKILL.md +29 -9
  100. package/dist/agents/skills/gemini-cli/harness-roadmap/SKILL.md +562 -0
  101. package/dist/agents/skills/gemini-cli/harness-roadmap/skill.yaml +43 -0
  102. package/dist/agents/skills/gemini-cli/harness-security-review/skill.yaml +8 -6
  103. package/dist/agents/skills/gemini-cli/harness-security-scan/skill.yaml +1 -1
  104. package/dist/agents/skills/gemini-cli/harness-soundness-review/SKILL.md +1267 -0
  105. package/dist/agents/skills/gemini-cli/harness-soundness-review/skill.yaml +48 -0
  106. package/dist/agents/skills/gemini-cli/harness-test-advisor/SKILL.md +35 -6
  107. package/dist/agents/skills/node_modules/.bin/vitest +2 -2
  108. package/dist/agents/skills/shared/design-knowledge/anti-patterns/color.yaml +106 -0
  109. package/dist/agents/skills/shared/design-knowledge/anti-patterns/layout.yaml +109 -0
  110. package/dist/agents/skills/shared/design-knowledge/anti-patterns/motion.yaml +109 -0
  111. package/dist/agents/skills/shared/design-knowledge/anti-patterns/typography.yaml +112 -0
  112. package/dist/agents/skills/shared/design-knowledge/industries/creative.yaml +80 -0
  113. package/dist/agents/skills/shared/design-knowledge/industries/ecommerce.yaml +80 -0
  114. package/dist/agents/skills/shared/design-knowledge/industries/emerging-tech.yaml +83 -0
  115. package/dist/agents/skills/shared/design-knowledge/industries/fintech.yaml +80 -0
  116. package/dist/agents/skills/shared/design-knowledge/industries/healthcare.yaml +80 -0
  117. package/dist/agents/skills/shared/design-knowledge/industries/lifestyle.yaml +80 -0
  118. package/dist/agents/skills/shared/design-knowledge/industries/saas.yaml +80 -0
  119. package/dist/agents/skills/shared/design-knowledge/industries/services.yaml +80 -0
  120. package/dist/agents/skills/shared/design-knowledge/palettes/curated.yaml +234 -0
  121. package/dist/agents/skills/shared/design-knowledge/platform-rules/android.yaml +125 -0
  122. package/dist/agents/skills/shared/design-knowledge/platform-rules/flutter.yaml +144 -0
  123. package/dist/agents/skills/shared/design-knowledge/platform-rules/ios.yaml +106 -0
  124. package/dist/agents/skills/shared/design-knowledge/platform-rules/web.yaml +102 -0
  125. package/dist/agents/skills/shared/design-knowledge/typography/pairings.yaml +274 -0
  126. package/dist/agents/skills/shared/i18n-knowledge/accessibility/intersection.yaml +142 -0
  127. package/dist/agents/skills/shared/i18n-knowledge/anti-patterns/encoding.yaml +67 -0
  128. package/dist/agents/skills/shared/i18n-knowledge/anti-patterns/formatting.yaml +106 -0
  129. package/dist/agents/skills/shared/i18n-knowledge/anti-patterns/layout.yaml +80 -0
  130. package/dist/agents/skills/shared/i18n-knowledge/anti-patterns/pluralization.yaml +80 -0
  131. package/dist/agents/skills/shared/i18n-knowledge/anti-patterns/string-handling.yaml +106 -0
  132. package/dist/agents/skills/shared/i18n-knowledge/frameworks/android-resources.yaml +47 -0
  133. package/dist/agents/skills/shared/i18n-knowledge/frameworks/apple-strings.yaml +47 -0
  134. package/dist/agents/skills/shared/i18n-knowledge/frameworks/backend-patterns.yaml +50 -0
  135. package/dist/agents/skills/shared/i18n-knowledge/frameworks/flutter-intl.yaml +47 -0
  136. package/dist/agents/skills/shared/i18n-knowledge/frameworks/i18next.yaml +47 -0
  137. package/dist/agents/skills/shared/i18n-knowledge/frameworks/react-intl.yaml +47 -0
  138. package/dist/agents/skills/shared/i18n-knowledge/frameworks/vue-i18n.yaml +47 -0
  139. package/dist/agents/skills/shared/i18n-knowledge/industries/ecommerce.yaml +66 -0
  140. package/dist/agents/skills/shared/i18n-knowledge/industries/fintech.yaml +66 -0
  141. package/dist/agents/skills/shared/i18n-knowledge/industries/gaming.yaml +69 -0
  142. package/dist/agents/skills/shared/i18n-knowledge/industries/healthcare.yaml +66 -0
  143. package/dist/agents/skills/shared/i18n-knowledge/industries/legal.yaml +66 -0
  144. package/dist/agents/skills/shared/i18n-knowledge/locales/ar.yaml +41 -0
  145. package/dist/agents/skills/shared/i18n-knowledge/locales/de.yaml +35 -0
  146. package/dist/agents/skills/shared/i18n-knowledge/locales/en.yaml +32 -0
  147. package/dist/agents/skills/shared/i18n-knowledge/locales/es.yaml +35 -0
  148. package/dist/agents/skills/shared/i18n-knowledge/locales/fi.yaml +35 -0
  149. package/dist/agents/skills/shared/i18n-knowledge/locales/fr.yaml +35 -0
  150. package/dist/agents/skills/shared/i18n-knowledge/locales/he.yaml +41 -0
  151. package/dist/agents/skills/shared/i18n-knowledge/locales/hi.yaml +35 -0
  152. package/dist/agents/skills/shared/i18n-knowledge/locales/it.yaml +32 -0
  153. package/dist/agents/skills/shared/i18n-knowledge/locales/ja.yaml +38 -0
  154. package/dist/agents/skills/shared/i18n-knowledge/locales/ko.yaml +38 -0
  155. package/dist/agents/skills/shared/i18n-knowledge/locales/nl.yaml +32 -0
  156. package/dist/agents/skills/shared/i18n-knowledge/locales/pl.yaml +35 -0
  157. package/dist/agents/skills/shared/i18n-knowledge/locales/pt.yaml +32 -0
  158. package/dist/agents/skills/shared/i18n-knowledge/locales/ru.yaml +35 -0
  159. package/dist/agents/skills/shared/i18n-knowledge/locales/sv.yaml +32 -0
  160. package/dist/agents/skills/shared/i18n-knowledge/locales/th.yaml +35 -0
  161. package/dist/agents/skills/shared/i18n-knowledge/locales/tr.yaml +35 -0
  162. package/dist/agents/skills/shared/i18n-knowledge/locales/zh-Hans.yaml +38 -0
  163. package/dist/agents/skills/shared/i18n-knowledge/locales/zh-Hant.yaml +35 -0
  164. package/dist/agents/skills/shared/i18n-knowledge/mcp-interop/i18next-mcp.yaml +56 -0
  165. package/dist/agents/skills/shared/i18n-knowledge/mcp-interop/lingo-dev.yaml +56 -0
  166. package/dist/agents/skills/shared/i18n-knowledge/mcp-interop/lokalise.yaml +60 -0
  167. package/dist/agents/skills/shared/i18n-knowledge/mcp-interop/tolgee.yaml +60 -0
  168. package/dist/agents/skills/shared/i18n-knowledge/testing/locale-testing.yaml +107 -0
  169. package/dist/agents/skills/shared/i18n-knowledge/testing/pseudo-localization.yaml +86 -0
  170. package/dist/bin/harness.js +64 -4
  171. package/dist/{chunk-UDWGSL3T.js → chunk-3JWCBVUZ.js} +3 -3
  172. package/dist/{chunk-IUFFBBYV.js → chunk-LNI4T7R6.js} +179 -61
  173. package/dist/{chunk-USEYPS7F.js → chunk-SJECMKSS.js} +2250 -40
  174. package/dist/{dist-4MYPT3OE.js → dist-BDO5GFEM.js} +295 -14
  175. package/dist/{dist-RBZXXJHG.js → dist-NT3GXHQZ.js} +95 -1
  176. package/dist/index.d.ts +266 -7
  177. package/dist/index.js +7 -3
  178. package/dist/validate-cross-check-2OPGCGGU.js +7 -0
  179. package/package.json +7 -7
  180. package/dist/validate-cross-check-CPEPNLOD.js +0 -7
@@ -0,0 +1,48 @@
1
+ name: harness-soundness-review
2
+ version: "1.0.0"
3
+ description: Deep soundness analysis of specs and plans with auto-fix and convergence loop
4
+ cognitive_mode: meticulous-verifier
5
+ triggers:
6
+ - manual
7
+ platforms:
8
+ - claude-code
9
+ - gemini-cli
10
+ tools:
11
+ - Bash
12
+ - Read
13
+ - Write
14
+ - Edit
15
+ - Glob
16
+ - Grep
17
+ cli:
18
+ command: harness skill run harness-soundness-review
19
+ args:
20
+ - name: path
21
+ description: Project root path
22
+ required: false
23
+ - name: mode
24
+ description: Review mode — "spec" for spec soundness or "plan" for plan soundness
25
+ required: true
26
+ mcp:
27
+ tool: run_skill
28
+ input:
29
+ skill: harness-soundness-review
30
+ path: string
31
+ type: rigid
32
+ phases:
33
+ - name: check
34
+ description: Run all checks for the current mode and classify findings
35
+ required: true
36
+ - name: fix
37
+ description: Auto-fix inferrable issues and log changes
38
+ required: true
39
+ - name: converge
40
+ description: Re-run checks, compare issue counts, loop or stop
41
+ required: true
42
+ - name: surface
43
+ description: Present remaining issues to user for resolution
44
+ required: true
45
+ state:
46
+ persistent: false
47
+ files: []
48
+ depends_on: []
@@ -13,8 +13,23 @@
13
13
 
14
14
  ## Prerequisites
15
15
 
16
- A knowledge graph must exist at `.harness/graph/`. Run `harness scan` if no graph is available.
17
- If the graph exists but code has changed since the last scan, re-run `harness scan` first — stale graph data leads to inaccurate results.
16
+ A knowledge graph at `.harness/graph/` enables full analysis. If no graph exists,
17
+ the skill uses static analysis fallbacks (see Graph Availability section).
18
+ Run `harness scan` to enable graph-enhanced analysis.
19
+
20
+ ### Graph Availability
21
+
22
+ Before starting, check if `.harness/graph/graph.json` exists.
23
+
24
+ **If graph exists:** Check staleness — compare `.harness/graph/metadata.json`
25
+ scanTimestamp against `git log -1 --format=%ct` (latest commit timestamp).
26
+ If graph is more than 10 commits behind (`git log --oneline <scanTimestamp>..HEAD | wc -l`),
27
+ run `harness scan` to refresh before proceeding. (Staleness sensitivity: **Medium**)
28
+
29
+ **If graph exists and is fresh (or refreshed):** Use graph tools as primary strategy.
30
+
31
+ **If no graph exists:** Output "Running without graph (run `harness scan` to
32
+ enable full analysis)" and use fallback strategies for all subsequent steps.
18
33
 
19
34
  ## Process
20
35
 
@@ -43,6 +58,20 @@ For each changed file, use graph traversal to find test files:
43
58
 
44
59
  3. **Co-change tests**: Check `co_changes_with` edges for test files that historically change alongside the modified files.
45
60
 
61
+ #### Fallback (without graph)
62
+
63
+ When no graph is available, use naming conventions, import parsing, and git history:
64
+
65
+ 1. **Tier 1 — Filename convention matching**: For each changed file `foo.ts`, search for:
66
+ - `foo.test.ts`, `foo.spec.ts` (same directory)
67
+ - `__tests__/foo.ts`, `__tests__/foo.test.ts`
68
+ - Test files in a parallel `tests/` directory mirroring the source path
69
+ 2. **Tier 2 — Import-linked tests**: Parse test files' import statements (grep for `import.*from` in `*.test.*` and `*.spec.*` files). If a test file imports the changed file, it belongs in Tier 2 (if not already in Tier 1).
70
+ 3. **Tier 3 — Co-change correlated tests**: Use `git log --format="%H" --name-only` to find test files that frequently change in the same commit as the target file. Files that co-change in >2 commits are co-change correlated.
71
+ 4. **Rank**: Tier 1 = direct filename match, Tier 2 = import-linked tests, Tier 3 = co-change correlated tests. Output the same tiered format as the graph version.
72
+
73
+ > Fallback completeness: ~80% — naming conventions and imports catch most mappings; misses dynamic imports and indirect coverage.
74
+
46
75
  ### Phase 3: PRIORITIZE — Rank and Generate Commands
47
76
 
48
77
  Organize tests into three tiers:
@@ -85,7 +114,7 @@ npx vitest run tests/services/auth.test.ts tests/types/user.test.ts tests/routes
85
114
 
86
115
  ## Harness Integration
87
116
 
88
- - **`harness scan`** — Must run before this skill to ensure graph is current.
117
+ - **`harness scan`** — Recommended before this skill for full graph-enhanced analysis. If graph is missing, skill uses naming convention and import parsing fallbacks.
89
118
  - **`harness validate`** — Run after acting on findings to verify project health.
90
119
  - **Graph tools** — This skill uses `query_graph`, `get_impact`, and `get_relationships` MCP tools.
91
120
 
@@ -95,7 +124,7 @@ npx vitest run tests/services/auth.test.ts tests/types/user.test.ts tests/routes
95
124
  - Executable run commands generated for quick and full test runs
96
125
  - Coverage gaps flagged for changed files with no test coverage
97
126
  - Report follows the structured output format
98
- - All findings are backed by graph query evidence, not heuristics
127
+ - All findings are backed by graph query evidence (with graph) or systematic static analysis (without graph)
99
128
 
100
129
  ## Examples
101
130
 
@@ -122,8 +151,8 @@ Output:
122
151
 
123
152
  ## Gates
124
153
 
125
- - **No advice without graph.** If no graph exists, fall back to: "Run all tests in the same directory as changed files."
126
- - **Always include Tier 1.** Direct test coverage is non-negotiable — always recommend running these.
154
+ - **Graph preferred, fallback available.** If no graph exists, use naming conventions, import parsing, and git co-change analysis to identify relevant tests. Do not stop — produce the best test selection possible.
155
+ - **Always include Tier 1.** Direct test coverage is non-negotiable — always recommend running these (whether found via graph or naming conventions).
127
156
 
128
157
  ## Escalation
129
158
 
@@ -160,6 +160,70 @@ After running all three levels, produce a structured gap report:
160
160
  ### Verdict: INCOMPLETE — 2 gaps must be resolved
161
161
  ```
162
162
 
163
+ The verification report uses conventional markdown patterns for structured output:
164
+
165
+ ```
166
+ **[CRITICAL]** path/to/file.ts:22 — TODO: implement validation (anti-pattern)
167
+ **[IMPORTANT]** path/to/file.ts — exported but not imported by any other file
168
+ ```
169
+
170
+ ### Verification Sign-Off
171
+
172
+ After producing the verification report, request acceptance:
173
+
174
+ ```json
175
+ emit_interaction({
176
+ path: "<project-root>",
177
+ type: "confirmation",
178
+ confirmation: {
179
+ text: "Verification report: <VERDICT>. Accept and proceed?",
180
+ context: "<summary: N artifacts checked, N gaps found>"
181
+ }
182
+ })
183
+ ```
184
+
185
+ ### Handoff and Transition
186
+
187
+ After producing the verification report, write the handoff and conditionally transition:
188
+
189
+ Write `.harness/handoff.json`:
190
+
191
+ ```json
192
+ {
193
+ "fromSkill": "harness-verification",
194
+ "phase": "COMPLETE",
195
+ "summary": "<verdict summary>",
196
+ "artifacts": ["<verified file paths>"],
197
+ "verdict": "pass | fail",
198
+ "gaps": ["<gap descriptions if any>"]
199
+ }
200
+ ```
201
+
202
+ **If verdict is PASS (all levels passed, no gaps):**
203
+
204
+ Call `emit_interaction`:
205
+
206
+ ```json
207
+ {
208
+ "type": "transition",
209
+ "transition": {
210
+ "completedPhase": "verification",
211
+ "suggestedNext": "review",
212
+ "reason": "Verification passed at all 3 levels",
213
+ "artifacts": ["<verified file paths>"],
214
+ "requiresConfirmation": false,
215
+ "summary": "Verification passed: <N> artifacts checked. EXISTS, SUBSTANTIVE, WIRED all passed."
216
+ }
217
+ }
218
+ ```
219
+
220
+ The response will include `nextAction: "Invoke harness-code-review skill now"`.
221
+ Immediately invoke harness-code-review without waiting for user input.
222
+
223
+ **If verdict is FAIL or INCOMPLETE:**
224
+
225
+ Do NOT emit a transition. Surface gaps to the user for resolution. The handoff is written with the gaps recorded for future reference.
226
+
163
227
  ---
164
228
 
165
229
  ### Regression Test Verification
@@ -184,6 +248,8 @@ If step 4 passes (test does not fail without the fix), the test is not a valid r
184
248
 
185
249
  All commands must be run fresh in the current session. Do not rely on results from a previous session or a previous run in the same session if code has changed since.
186
250
 
251
+ - **`emit_interaction`** -- Call after verification passes to auto-transition to harness-code-review. Only emitted on PASS verdict. Uses auto-transition (proceeds immediately).
252
+
187
253
  ## Success Criteria
188
254
 
189
255
  - Every claimed deliverable has been verified at all 3 levels
@@ -13,6 +13,7 @@ tools:
13
13
  - Bash
14
14
  - Read
15
15
  - Glob
16
+ - emit_interaction
16
17
  cli:
17
18
  command: harness skill run harness-verification
18
19
  args:
@@ -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,12 +73,32 @@ 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.
65
89
  - If all checks are SKIPPED, overall result is `PASS` (nothing to fail).
66
90
  - On FAIL, include a brief summary of what failed (e.g., "3 type errors", "2 lint errors", "5 tests failed") below the structured block.
67
91
 
92
+ ### Roadmap Sync (conditional)
93
+
94
+ When all non-skipped checks pass (overall `Verification: PASS`) and `docs/roadmap.md` exists:
95
+
96
+ 1. Trigger a roadmap sync to update feature statuses based on the verified state.
97
+ 2. Use the `manage_roadmap` MCP tool with `sync` action if available, or note to the caller that a roadmap sync is recommended.
98
+ 3. Features linked to plans whose tasks are all complete and verified may be marked as `done`.
99
+
100
+ If `docs/roadmap.md` does not exist, skip this step silently. If verification failed, do not sync — the roadmap should only reflect verified completions.
101
+
68
102
  ## Deterministic Checks
69
103
 
70
104
  This skill is entirely deterministic. There are no LLM judgment calls anywhere in the process.
@@ -80,6 +114,9 @@ This skill is entirely deterministic. There are no LLM judgment calls anywhere i
80
114
  - Invoked as the final step by code-producing skills (harness-execution, harness-tdd)
81
115
  - Complements harness-verification (deep audit) — use verify for quick checks, verification for milestones
82
116
  - Output format is consumed by harness-integrity for the unified pipeline
117
+ - Invokes `harness-accessibility` for design constraint checking when `design` config exists
118
+ - Design violations respect `design.strictness` from `harness.config.json`
119
+ - **Roadmap sync** — When verification passes and `docs/roadmap.md` exists, triggers `manage_roadmap sync` to mark verified features as `done`. Only fires on overall PASS.
83
120
 
84
121
  ## Success Criteria
85
122
 
@@ -59,6 +59,11 @@
59
59
 
60
60
  4. **For advanced:** Configure state management (`.harness/state.json` schema), learnings capture (`.harness/learnings.md` conventions), and CI integration hooks.
61
61
 
62
+ 5. **Configure i18n (all levels).** Ask: "Will this project support multiple languages?" Based on the answer:
63
+ - **Yes:** Invoke `harness-i18n-workflow` configure phase to set up i18n config in `harness.config.json` (source locale, target locales, framework, strictness). Then invoke `harness-i18n-workflow` scaffold phase to create translation file structure and extraction config. Set `i18n.enabled: true`.
64
+ - **No:** Set `i18n.enabled: false` in `harness.config.json`. The `harness-i18n-process` skill will still fire gentle prompts for unconfigured projects when features touch user-facing strings.
65
+ - **Not sure yet:** Skip i18n configuration entirely. Do not set `i18n.enabled`. The project can enable i18n later by running `harness-i18n-workflow` directly.
66
+
62
67
  ### Phase 4: VALIDATE — Confirm Everything Works
63
68
 
64
69
  1. **Run `harness validate`** to verify the full configuration. This checks:
@@ -82,7 +87,9 @@ harness scan [path]
82
87
 
83
88
  This creates the `.harness/graph/` directory and populates it with the project's dependency and relationship data. Subsequent graph queries (impact analysis, dependency health, test advisor) depend on this initial scan.
84
89
 
85
- 4. **Commit the initialization.** All generated and configured files in a single commit.
90
+ 4. **Mention roadmap.** After validation passes, inform the user: "When you are ready to set up a project roadmap, run `/harness:roadmap --create`. This creates a unified `docs/roadmap.md` that tracks features, milestones, and status across your specs and plans." This is informational only — do not create the roadmap automatically.
91
+
92
+ 5. **Commit the initialization.** All generated and configured files in a single commit.
86
93
 
87
94
  ## Harness Integration
88
95
 
@@ -91,6 +98,8 @@ This creates the `.harness/graph/` directory and populates it with the project's
91
98
  - **`harness persona generate`** — Generate persona definitions based on project stack and team structure.
92
99
  - **`harness validate`** — Verify the full project configuration is valid and complete.
93
100
  - **`harness check-deps`** — Verify dependency constraints match the actual codebase (intermediate and above).
101
+ - **`harness-i18n-workflow configure` + `harness-i18n-workflow scaffold`** — Invoked during Phase 3 if the project will support multiple languages. Sets up i18n configuration and translation file structure.
102
+ - **Roadmap nudge** — After successful initialization, inform the user about `/harness:roadmap --create` for setting up project-level feature tracking. Informational only; does not create the roadmap.
94
103
 
95
104
  ## Success Criteria
96
105
 
@@ -102,6 +111,7 @@ This creates the `.harness/graph/` directory and populates it with the project's
102
111
  - Personas are configured if the project uses them
103
112
  - The adoption level matches what was agreed upon with the human
104
113
  - All generated files are committed in a single atomic commit
114
+ - i18n configuration is set if the human chose to enable it during init
105
115
 
106
116
  ## Examples
107
117
 
@@ -131,6 +141,10 @@ Edit AGENTS.md:
131
141
  - Add stack: TypeScript, Express, Vitest, PostgreSQL
132
142
  - Add conventions: "Use zod for validation, repository pattern for data access"
133
143
  - Add constraints: "No direct SQL queries outside repository layer"
144
+ - Ask: "Will this project support multiple languages?"
145
+ - Human: "Yes, Spanish and French."
146
+ - Run harness-i18n-workflow configure (source: en, targets: es, fr)
147
+ - Run harness-i18n-workflow scaffold (creates locales/ directory structure)
134
148
  ```
135
149
 
136
150
  **VALIDATE:**
@@ -32,6 +32,18 @@ When a knowledge graph exists at `.harness/graph/`, use graph queries for faster
32
32
 
33
33
  When a graph is available, it IS the source of truth for documentation coverage. Drift = stale or missing edges between code and doc nodes. Fall back to file-based commands if no graph is available.
34
34
 
35
+ ### Pipeline Context (when orchestrated)
36
+
37
+ When invoked by `harness-docs-pipeline`, check for a `pipeline` field in `.harness/handoff.json`:
38
+
39
+ - If `pipeline` field exists: read `DocPipelineContext` from it
40
+ - Use `pipeline.exclusions` to skip findings that were already addressed in the FIX phase
41
+ - Write `GapFinding[]` results back to `pipeline.gapFindings` in handoff.json
42
+ - This enables dedup across FIX and AUDIT phases
43
+ - If `pipeline` field does not exist: behave exactly as today (standalone mode)
44
+
45
+ No changes to the skill's interface or output format — the pipeline field is purely additive.
46
+
35
47
  ### Phase 2: Detect Gaps
36
48
 
37
49
  Categorize findings into four types:
@@ -0,0 +1,281 @@
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
+ 2.5. **Check for i18n skill overlap.** Read `harness.config.json` for `i18n.enabled`:
29
+
30
+ - If `i18n.enabled: true`, **defer** `lang` and `dir` attribute checks to `harness-i18n`. Do not scan for missing `lang` on `<html>` or missing `dir` on user-content containers -- those checks are covered by the i18n skill's scan phase with more context (locale-aware, RTL-aware).
31
+ - If `i18n.enabled` is false or absent, scan for `lang`/`dir` as normal (these remain part of the accessibility audit).
32
+ - This deduplication prevents the same finding from appearing in both the accessibility report and the i18n report.
33
+
34
+ 3. **Scan component files.** Search all files matching `.tsx`, `.jsx`, `.vue`, `.svelte`, `.html` for the following violations:
35
+
36
+ **Images and media:**
37
+ - `<img>` tags without `alt` attribute (`A11Y-001`)
38
+ - `<img>` tags with empty `alt=""` on non-decorative images (`A11Y-002`)
39
+ - `<video>` and `<audio>` without captions/transcripts (`A11Y-003`)
40
+
41
+ **ARIA and semantics:**
42
+ - Interactive elements (`<button>`, `<a>`, `<input>`) without accessible labels (`A11Y-010`)
43
+ - Icon-only buttons without `aria-label` or visually hidden text (`A11Y-011`)
44
+ - Clickable `<div>` or `<span>` without `role="button"` and keyboard handler (`A11Y-012`)
45
+ - Missing `role` attributes on custom interactive widgets (`A11Y-013`)
46
+ - `aria-hidden="true"` on focusable elements (`A11Y-014`)
47
+
48
+ **Heading structure:**
49
+ - Non-sequential heading levels (e.g., `<h1>` followed by `<h3>`, skipping `<h2>`) (`A11Y-020`)
50
+ - Multiple `<h1>` elements on a single page/component (`A11Y-021`)
51
+ - Empty headings (`A11Y-022`)
52
+
53
+ **Color and contrast:**
54
+ - Hardcoded color values not from the token set (`A11Y-030`)
55
+ - Inline styles with color/background-color that may fail contrast (`A11Y-031`)
56
+
57
+ **Keyboard navigation:**
58
+ - `onClick` handlers without corresponding `onKeyDown`/`onKeyUp` (`A11Y-040`)
59
+ - Missing `tabIndex` on custom interactive elements (`A11Y-041`)
60
+ - Positive `tabIndex` values (disrupts natural tab order) (`A11Y-042`)
61
+ - Missing focus indicators (`:focus` or `:focus-visible` styles) (`A11Y-043`)
62
+
63
+ **Forms:**
64
+ - `<input>`, `<select>`, `<textarea>` without associated `<label>` or `aria-label` (`A11Y-050`)
65
+ - Missing `id` attributes on form controls (needed for label association) (`A11Y-051`)
66
+ - Missing error messages or `aria-invalid` on validation states (`A11Y-052`)
67
+
68
+ 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).
69
+
70
+ 5. **Record all findings.** Each finding includes:
71
+ - File path
72
+ - Line number (approximate, from Grep output)
73
+ - Violation code (e.g., `A11Y-001`)
74
+ - Element or pattern that triggered the finding
75
+ - Raw evidence (the matching line of code)
76
+
77
+ ### Phase 2: EVALUATE -- Assess Severity and Categorize
78
+
79
+ 1. **Assign severity based on `design.strictness`:**
80
+ - `strict` mode: all violations are `error` severity
81
+ - `standard` mode: missing alt, missing labels, contrast failures are `error`; heading order, tabIndex are `warn`; informational patterns are `info`
82
+ - `permissive` mode: contrast failures and missing labels are `warn`; everything else is `info`
83
+
84
+ 2. **Calculate contrast ratios.** For every color pair found in scanned code:
85
+ - Extract foreground and background colors (from inline styles, class mappings, or token references)
86
+ - Calculate relative luminance for each color using the WCAG 2.1 formula:
87
+ - `L = 0.2126 * R + 0.7152 * G + 0.0722 * B` (where R, G, B are linearized sRGB values)
88
+ - Calculate contrast ratio: `(L1 + 0.05) / (L2 + 0.05)` where L1 is the lighter color
89
+ - Compare against thresholds:
90
+ - Normal text (< 18px regular, < 14px bold): 4.5:1 minimum (WCAG AA)
91
+ - Large text (>= 18px regular, >= 14px bold): 3:1 minimum (WCAG AA)
92
+
93
+ 3. **Cross-reference with design tokens.** If `design-system/tokens.json` exists:
94
+ - Map hardcoded colors in code to their nearest token equivalents
95
+ - 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
96
+ - If a hardcoded color fails contrast, flag both the contrast issue and the non-token usage
97
+
98
+ 4. **Check graph constraints.** If a graph exists at `.harness/graph/`, use `DesignConstraintAdapter` from `packages/graph/src/constraints/DesignConstraintAdapter.ts` to:
99
+ - Query for existing `VIOLATES` edges (violations already recorded in the graph)
100
+ - Add new `VIOLATES` edges for findings from this scan
101
+ - The adapter reads `design.strictness` to control which violations produce edges
102
+
103
+ 5. **Categorize findings.** Group into categories:
104
+ - **Contrast** (A11Y-030, A11Y-031): color-related violations
105
+ - **ARIA** (A11Y-010 through A11Y-014): attribute and role violations
106
+ - **Semantics** (A11Y-020 through A11Y-022): heading and structure violations
107
+ - **Keyboard** (A11Y-040 through A11Y-043): navigation and focus violations
108
+ - **Forms** (A11Y-050 through A11Y-052): form control violations
109
+ - **Media** (A11Y-001 through A11Y-003): image, video, audio violations
110
+
111
+ ### Phase 3: REPORT -- Generate Accessibility Report
112
+
113
+ 1. **Generate summary header:**
114
+
115
+ ```
116
+ Accessibility Report
117
+ ====================
118
+ Scanned: 42 component files
119
+ Findings: 18 total (6 error, 8 warn, 4 info)
120
+ Strictness: standard
121
+ ```
122
+
123
+ 2. **List findings grouped by category.** Each finding follows this format:
124
+
125
+ ```
126
+ A11Y-001 [error] Missing alt attribute on <img>
127
+ File: src/components/UserAvatar.tsx
128
+ Line: 24
129
+ Element: <img src={user.avatarUrl} className="avatar" />
130
+ WCAG: 1.1.1 Non-text Content
131
+ Fix: Add alt={user.name} or alt="" if decorative
132
+ ```
133
+
134
+ ```
135
+ A11Y-031 [error] Contrast ratio 2.8:1 fails WCAG AA (requires 4.5:1)
136
+ File: src/components/Button.tsx
137
+ Line: 15
138
+ Element: color: #999 on background: #fff
139
+ WCAG: 1.4.3 Contrast (Minimum)
140
+ Fix: Use color token "neutral.600" (#475569, ratio 4.9:1) instead
141
+ ```
142
+
143
+ 3. **Provide category summaries** with counts and severity breakdown.
144
+
145
+ 4. **List actionable next steps:**
146
+ - Errors that can be auto-fixed (Phase 4)
147
+ - Errors that require human judgment
148
+ - Warnings to address in next iteration
149
+ - Token-level issues to escalate to harness-design-system
150
+
151
+ ### Phase 4: FIX -- Apply Automated Remediation (Optional)
152
+
153
+ 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.
154
+
155
+ 1. **Fixable violations:**
156
+ - `A11Y-001`: Add `alt=""` to `<img>` tags that are decorative (inside `<button>`, `<a>`, or with `role="presentation"`)
157
+ - `A11Y-011`: Add `aria-label` to icon-only `<button>` elements (using the icon name as label)
158
+ - `A11Y-012`: Add `role="button"` and `tabIndex={0}` to clickable `<div>` elements
159
+ - `A11Y-041`: Add `tabIndex={0}` to custom interactive elements missing it
160
+ - `A11Y-051`: Generate `id` attributes for form controls and link them to labels
161
+
162
+ 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.
163
+
164
+ 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.
165
+
166
+ 4. **Re-scan after fixes.** Run the scan phase again on fixed files to confirm violations are resolved. Report:
167
+ - Fixes applied: N
168
+ - Violations resolved: N
169
+ - Remaining violations (require human judgment): M
170
+
171
+ 5. **Do NOT fix:**
172
+ - Color choices (subjective -- escalate to harness-design-system)
173
+ - Content for alt text on meaningful images (requires human judgment about image meaning)
174
+ - Layout and heading structure changes (may affect design intent)
175
+ - Any fix that would change the visual appearance of the component
176
+
177
+ ## Harness Integration
178
+
179
+ - **`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.
180
+ - **`harness scan`** -- Refresh the knowledge graph after fixes to update `VIOLATES` edges. Ensures impact analysis stays current.
181
+ - **`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.
182
+ - **`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.
183
+ - **`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.
184
+ - **`harness-design-system`** -- Dependency. When contrast failures originate from token definitions (not component code), escalate to harness-design-system to fix at the source.
185
+ - **`harness-i18n` deduplication** -- When `i18n.enabled: true` in config, `lang` and `dir` attribute checks are deferred to the i18n skill. This prevents duplicate findings across the accessibility and i18n reports. When i18n is not enabled, these checks remain part of the accessibility scan.
186
+
187
+ ## Success Criteria
188
+
189
+ - All scanned component files have findings categorized by severity (`error`, `warn`, `info`)
190
+ - Contrast failures detected with correct ratios and WCAG criterion references
191
+ - Missing ARIA attributes flagged with specific file paths and line numbers
192
+ - Non-sequential heading hierarchy violations identified
193
+ - Keyboard navigation gaps (missing handlers, broken tab order) detected
194
+ - Form accessibility issues (missing labels, missing error states) found
195
+ - Report generated with violation codes, WCAG references, and actionable remediation
196
+ - Automated fixes applied without breaking existing functionality or tests
197
+ - `harness validate` reflects accessibility findings at the configured strictness level
198
+ - Token-level contrast issues escalated to harness-design-system (not fixed locally)
199
+
200
+ ## Examples
201
+
202
+ ### Example: Scanning a React Dashboard Component
203
+
204
+ **Context:** A React component `DashboardCard.tsx` with known accessibility issues.
205
+
206
+ **Source file:**
207
+
208
+ ```tsx
209
+ // src/components/DashboardCard.tsx
210
+ export function DashboardCard({ title, value, icon, onClick }) {
211
+ return (
212
+ <div className="card" onClick={onClick}>
213
+ <img src={icon} />
214
+ <h3>{title}</h3>
215
+ <span style={{ color: '#999', fontSize: '14px' }}>{value}</span>
216
+ </div>
217
+ );
218
+ }
219
+ ```
220
+
221
+ **SCAN findings:**
222
+
223
+ ```
224
+ A11Y-001 [error] Missing alt attribute on <img>
225
+ File: src/components/DashboardCard.tsx
226
+ Line: 5
227
+ Element: <img src={icon} />
228
+ WCAG: 1.1.1 Non-text Content
229
+
230
+ A11Y-012 [error] Clickable <div> without role="button" and keyboard handler
231
+ File: src/components/DashboardCard.tsx
232
+ Line: 4
233
+ Element: <div className="card" onClick={onClick}>
234
+ WCAG: 2.1.1 Keyboard
235
+
236
+ A11Y-031 [warn] Contrast ratio 2.8:1 for #999 on #fff fails WCAG AA
237
+ File: src/components/DashboardCard.tsx
238
+ Line: 7
239
+ Element: <span style={{ color: '#999' }}>
240
+ WCAG: 1.4.3 Contrast (Minimum)
241
+ Note: Hardcoded color -- not from token set
242
+
243
+ A11Y-030 [info] Hardcoded color value not from design token set
244
+ File: src/components/DashboardCard.tsx
245
+ Line: 7
246
+ Element: color: '#999'
247
+ ```
248
+
249
+ **FIX phase (auto-fixable only):**
250
+
251
+ ```diff
252
+ - <img src={icon} />
253
+ + <img src={icon} alt="" />
254
+
255
+ - <div className="card" onClick={onClick}>
256
+ + <div className="card" role="button" tabIndex={0} onClick={onClick} onKeyDown={(e) => { if (e.key === 'Enter' || e.key === ' ') onClick?.(); }}>
257
+ ```
258
+
259
+ **Remaining (requires human judgment):**
260
+
261
+ - `A11Y-031`: Contrast failure -- fix requires choosing a darker color. Escalate to design tokens or get human input on replacement color.
262
+ - `A11Y-001`: The `alt=""` fix assumes decorative. If the icon conveys meaning, human must write descriptive alt text.
263
+
264
+ ## Gates
265
+
266
+ These are hard stops. Violating any gate means the process has broken down.
267
+
268
+ - **No component marked "accessible" without passing WCAG AA contrast checks.** A passing scan means zero `error`-severity contrast violations, not zero findings overall.
269
+ - **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.
270
+ - **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.
271
+ - **The scan phase must complete before evaluate.** No partial evaluations on incomplete scan results. All files must be scanned before severity assignment begins.
272
+ - **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.
273
+
274
+ ## Escalation
275
+
276
+ - **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."
277
+ - **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."
278
+ - **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."
279
+ - **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?"
280
+ - **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."
281
+ - **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."