@softspark/ai-toolkit 4.20.0 → 4.22.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.
- package/CHANGELOG.md +107 -0
- package/README.md +32 -22
- package/app/.claude-plugin/plugin.json +1 -1
- package/app/agents/code-reviewer.md +32 -15
- package/app/skills/a11y-validate/SKILL.md +61 -179
- package/app/skills/a11y-validate/reference/scanner-categories.md +174 -0
- package/app/skills/brainstorm/SKILL.md +174 -0
- package/app/skills/ci/SKILL.md +1 -0
- package/app/skills/debug/SKILL.md +2 -1
- package/app/skills/documentation-standards/SKILL.md +25 -5
- package/app/skills/fix/SKILL.md +1 -1
- package/app/skills/hipaa-validate/SKILL.md +25 -221
- package/app/skills/hipaa-validate/reference/scanner-categories.md +224 -0
- package/app/skills/pr/SKILL.md +1 -1
- package/app/skills/review/SKILL.md +49 -4
- package/app/skills/seo-validate/SKILL.md +63 -309
- package/app/skills/seo-validate/reference/scanner-categories.md +304 -0
- package/app/surface.json +296 -0
- package/benchmarks/ecosystem-doctor-snapshot.json +15 -19
- package/kb/procedures/release-preparation-sop.md +44 -2
- package/kb/reference/architecture-overview.md +3 -3
- package/kb/reference/skills-catalog.md +10 -14
- package/llms-full.txt +59 -20
- package/manifest.json +3 -3
- package/package.json +6 -3
- package/scripts/check_split.py +493 -0
- package/scripts/surface_manifest.py +246 -0
- package/scripts/sync_badges.py +133 -0
- package/scripts/validate.py +84 -2
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
# Accessibility Scanner Categories
|
|
2
|
+
|
|
3
|
+
### Category 1: Semantic Structure & Landmarks
|
|
4
|
+
|
|
5
|
+
WCAG 1.3.1 (Info and Relationships), 2.4.1 (Bypass Blocks), 2.4.6 (Headings and Labels), 3.1.1 (Language of Page), 3.1.2 (Language of Parts).
|
|
6
|
+
|
|
7
|
+
| Pattern | Severity | Confidence | Description |
|
|
8
|
+
|---------|----------|------------|-------------|
|
|
9
|
+
| `<html>` missing `lang` attribute | HIGH | definitive | WCAG 3.1.1 |
|
|
10
|
+
| Mixed-language content without `<span lang="...">` wrapper (heuristic: non-Latin characters in otherwise-Latin content) | WARN | heuristic | WCAG 3.1.2 |
|
|
11
|
+
| Page/route component with >1 `<h1>` | WARN | heuristic | WCAG 1.3.1 |
|
|
12
|
+
| Heading level skip (h1 → h3 without h2) | WARN | heuristic | WCAG 1.3.1 |
|
|
13
|
+
| No landmark roles / semantic elements (`<main>`, `<nav>`, `<header>`, `<footer>`) | WARN | heuristic | WCAG 1.3.1, 2.4.1 |
|
|
14
|
+
| `role="presentation"` / `role="none"` on semantic element | WARN | definitive | Strips meaning; misuse of ARIA |
|
|
15
|
+
| Multiple `<main>` per page | HIGH | definitive | WCAG 1.3.1 — only one `<main>` allowed |
|
|
16
|
+
|
|
17
|
+
### Category 2: Text Alternatives & Non-Text Content
|
|
18
|
+
|
|
19
|
+
WCAG 1.1.1 (Non-text Content).
|
|
20
|
+
|
|
21
|
+
| Pattern | Severity | Confidence | Description |
|
|
22
|
+
|---------|----------|------------|-------------|
|
|
23
|
+
| `<img>` without `alt` attribute | HIGH | definitive | WCAG 1.1.1 — required even if empty |
|
|
24
|
+
| `<img alt="">` on informational image (heuristic: image inside `<article>`, `<figure>`, or with adjacent caption) | WARN | heuristic | Empty alt only for decorative |
|
|
25
|
+
| `<img alt="image">` / `<img alt="photo">` / `<img alt="picture">` (redundant/meaningless) | WARN | definitive | Alt should describe content |
|
|
26
|
+
| `<svg>` without `<title>` + `role="img"` + `aria-label`, used in interactive context | WARN | heuristic | Inline SVG needs alternative |
|
|
27
|
+
| Icon font (`<i class="fa-...">`, `<span class="material-icons">`) without `aria-label` or text alternative | WARN | definitive | WCAG 1.1.1 |
|
|
28
|
+
| `<img>` used for text content (heuristic: `alt` contains a full sentence like "Click here to...") | WARN | heuristic | WCAG 1.4.5 Images of Text |
|
|
29
|
+
| Complex image (`<img>` with `src` matching `chart|graph|diagram|infographic`) without long description (`aria-describedby` or `longdesc` or linked description) | WARN | heuristic | WCAG 1.1.1 for complex content |
|
|
30
|
+
|
|
31
|
+
### Category 3: Keyboard & Focus
|
|
32
|
+
|
|
33
|
+
WCAG 2.1.1 (Keyboard), 2.1.2 (No Keyboard Trap), 2.4.3 (Focus Order), 2.4.7 (Focus Visible).
|
|
34
|
+
|
|
35
|
+
| Pattern | Severity | Confidence | Description |
|
|
36
|
+
|---------|----------|------------|-------------|
|
|
37
|
+
| `tabindex` value >0 (positive) | HIGH | definitive | WCAG 2.4.3 — breaks natural tab order |
|
|
38
|
+
| `tabindex="-1"` on natively interactive element (`<button>`, `<a href>`, `<input>`, etc.) | WARN | definitive | Removes from tab order |
|
|
39
|
+
| `outline: none` or `outline: 0` on focusable selector without `:focus-visible` replacement | HIGH | definitive | WCAG 2.4.7 |
|
|
40
|
+
| `onClick` / `onKeyDown` handler on `<div>` / `<span>` without `role="button"` + `tabindex="0"` + keydown handler for Enter/Space | HIGH | heuristic | WCAG 2.1.1 — not keyboard-accessible |
|
|
41
|
+
| No skip link (`<a href="#main">`, `<a href="#content">`) on page with navigation | WARN | heuristic | WCAG 2.4.1 Bypass Blocks |
|
|
42
|
+
| Potential keyboard trap: `event.preventDefault()` / `event.stopPropagation()` in keydown handler on modal/dialog without Escape handling | WARN | heuristic | WCAG 2.1.2 |
|
|
43
|
+
| Custom dropdown / combobox without `aria-expanded` + `aria-haspopup` + keyboard handlers | WARN | heuristic | WAI-ARIA Authoring Practices |
|
|
44
|
+
| `autofocus` on page load on non-critical input (distracts keyboard users, moves focus unexpectedly) | WARN | definitive | Confuses assistive tech |
|
|
45
|
+
| `contenteditable="true"` without `aria-label` / `aria-labelledby` | WARN | definitive | WCAG 4.1.2 |
|
|
46
|
+
|
|
47
|
+
### Category 4: Color, Contrast & Visual Cues
|
|
48
|
+
|
|
49
|
+
WCAG 1.4.1 (Use of Color), 1.4.3 (Contrast Minimum), 1.4.11 (Non-text Contrast).
|
|
50
|
+
|
|
51
|
+
**Static analysis limitation**: actual contrast ratios depend on the CSS cascade, custom properties, theme switching, and background images. The skill flags patterns where contrast is AT RISK; pair with runtime tools (axe-core, Lighthouse) for definitive measurement.
|
|
52
|
+
|
|
53
|
+
| Pattern | Severity | Confidence | Description |
|
|
54
|
+
|---------|----------|------------|-------------|
|
|
55
|
+
| Hardcoded foreground+background color pairs in CSS where computed contrast is <4.5:1 (normal) or <3:1 (large text) | WARN | heuristic | WCAG 1.4.3 — verify at runtime |
|
|
56
|
+
| Link inside body text without underline/border AND only `color` distinguishing it | WARN | heuristic | WCAG 1.4.1 — color-only signalling |
|
|
57
|
+
| Error/required field indicated only by red color (no icon, text, or shape) | WARN | heuristic | WCAG 1.4.1 |
|
|
58
|
+
| Required form field marked only with `*` character without `aria-required="true"` + text explanation | WARN | definitive | WCAG 1.4.1 + 3.3.2 |
|
|
59
|
+
| CSS uses `color: red`/`color: green` as sole signal (success vs error) | WARN | heuristic | WCAG 1.4.1 |
|
|
60
|
+
| Focus indicator with <3:1 contrast against background (heuristic from color values) | WARN | heuristic | WCAG 1.4.11 |
|
|
61
|
+
| Button/input border color with <3:1 contrast against adjacent color | WARN | heuristic | WCAG 1.4.11 |
|
|
62
|
+
| CSS `text-shadow`/`opacity` on body text reducing effective contrast | INFO | heuristic | May affect 1.4.3 |
|
|
63
|
+
|
|
64
|
+
### Category 5: Forms, Labels & Errors
|
|
65
|
+
|
|
66
|
+
WCAG 1.3.5 (Identify Input Purpose), 3.3.1 (Error Identification), 3.3.2 (Labels or Instructions), 3.3.3 (Error Suggestion), 4.1.2 (Name, Role, Value).
|
|
67
|
+
|
|
68
|
+
| Pattern | Severity | Confidence | Description |
|
|
69
|
+
|---------|----------|------------|-------------|
|
|
70
|
+
| `<input>` / `<select>` / `<textarea>` without `<label for="...">` AND without `aria-label` / `aria-labelledby` | HIGH | heuristic | WCAG 3.3.2, 4.1.2 |
|
|
71
|
+
| `<label>` without `for` attribute (implicit association only works if input is a child) | WARN | definitive | WCAG 3.3.2 |
|
|
72
|
+
| `<input type="email"/tel/name/password/address">` without `autocomplete` attribute | WARN | definitive | WCAG 1.3.5 |
|
|
73
|
+
| Missing `autocomplete="one-time-code"` on OTP input with `inputmode="numeric"` | INFO | definitive | Improves user experience |
|
|
74
|
+
| Radio / checkbox group without `<fieldset>` + `<legend>` | WARN | heuristic | WCAG 1.3.1 |
|
|
75
|
+
| Error messages displayed visually but not linked via `aria-describedby` to the input | WARN | heuristic | WCAG 3.3.1 |
|
|
76
|
+
| `required` attribute without accompanying `aria-required="true"` (belt-and-suspenders for assistive tech consistency) | INFO | definitive | WCAG 4.1.2 (modern SR handle `required` but legacy may not) |
|
|
77
|
+
| Error uses `role="alert"` without being updated dynamically (static alert on page load) | INFO | heuristic | WCAG 4.1.3 |
|
|
78
|
+
| Placeholder used as label (no visible label, only `placeholder`) | WARN | heuristic | WCAG 3.3.2 — placeholder disappears on focus |
|
|
79
|
+
| `<input type="email">` without `inputmode="email"` (mobile UX) | INFO | definitive | EN 301 549 mobile |
|
|
80
|
+
|
|
81
|
+
### Category 6: Media (Audio, Video, Embeds)
|
|
82
|
+
|
|
83
|
+
WCAG 1.2.1–1.2.5 (Captions, audio description, sign language), 1.4.2 (Audio Control).
|
|
84
|
+
|
|
85
|
+
**EAA is specifically strict about media** — video without captions is a common legal-risk finding.
|
|
86
|
+
|
|
87
|
+
| Pattern | Severity | Confidence | Description |
|
|
88
|
+
|---------|----------|------------|-------------|
|
|
89
|
+
| `<video>` without `<track kind="captions">` child (or `<track kind="subtitles">` for foreign-language) | HIGH | definitive | WCAG 1.2.2 — EAA legal risk |
|
|
90
|
+
| `<video>` without transcript link or `<track kind="descriptions">` | WARN | heuristic | WCAG 1.2.3 / 1.2.5 |
|
|
91
|
+
| `<audio>` without transcript link or `<track kind="captions">` | HIGH | definitive | WCAG 1.2.1 |
|
|
92
|
+
| `<video autoplay>` without `muted` | HIGH | definitive | WCAG 1.4.2 — auto-playing audio |
|
|
93
|
+
| `<video autoplay loop>` running >5 seconds without pause control | WARN | heuristic | WCAG 1.4.2, 2.2.2 |
|
|
94
|
+
| YouTube/Vimeo embed URL without `cc_load_policy=1` or equivalent CC parameter | INFO | definitive | Platform-dependent captioning |
|
|
95
|
+
| YouTube embed via `<iframe src="https://www.youtube.com/embed/...">` without accessibility enhancements | INFO | definitive | Note: platform controls most a11y |
|
|
96
|
+
| Live media without real-time caption indication | WARN | heuristic | WCAG 1.2.4 |
|
|
97
|
+
| Background video (hero section) without pause button in DOM | WARN | heuristic | WCAG 2.2.2 |
|
|
98
|
+
|
|
99
|
+
### Category 7: ARIA, Live Regions & Dynamic Content
|
|
100
|
+
|
|
101
|
+
WCAG 4.1.2 (Name, Role, Value), 4.1.3 (Status Messages).
|
|
102
|
+
|
|
103
|
+
| Pattern | Severity | Confidence | Description |
|
|
104
|
+
|---------|----------|------------|-------------|
|
|
105
|
+
| `aria-hidden="true"` on focusable element | HIGH | definitive | Creates orphaned focus — serious a11y bug |
|
|
106
|
+
| `role="button"` on native `<button>` (redundant ARIA) | WARN | definitive | ARIA Authoring: avoid redundant roles |
|
|
107
|
+
| `role="link"` on `<a href>` / `role="heading"` on `<h1–h6>` (redundant ARIA) | WARN | definitive | Same |
|
|
108
|
+
| Conflicting roles (`<button role="link">`, `<a role="button">`) | WARN | definitive | WAI-ARIA — wrong role |
|
|
109
|
+
| Custom toggle (disclosure, menu, accordion) without `aria-expanded` + `aria-controls` | WARN | heuristic | WAI-ARIA |
|
|
110
|
+
| `aria-labelledby` referencing non-existent ID | HIGH | heuristic | Broken reference |
|
|
111
|
+
| `aria-describedby` referencing non-existent ID | HIGH | heuristic | Broken reference |
|
|
112
|
+
| `aria-live` region without `role="status"` / `role="alert"` AND async updates in component (heuristic) | WARN | heuristic | WCAG 4.1.3 |
|
|
113
|
+
| Toast/notification component without `role="status"` or `role="alert"` | WARN | heuristic | WCAG 4.1.3 |
|
|
114
|
+
| Modal / dialog without `role="dialog"` + `aria-modal="true"` + focus trap | WARN | heuristic | WAI-ARIA Authoring Practices |
|
|
115
|
+
| Tabs without proper roles (`role="tablist"` + `role="tab"` + `role="tabpanel"`) | WARN | heuristic | WAI-ARIA Authoring Practices |
|
|
116
|
+
|
|
117
|
+
### Category 8: Motion, Target Size, Mobile & EAA Docs
|
|
118
|
+
|
|
119
|
+
#### 8a. Motion & Animation
|
|
120
|
+
|
|
121
|
+
WCAG 2.2.2 (Pause, Stop, Hide), 2.3.3 (Animation from Interactions — AAA but EAA-recommended).
|
|
122
|
+
|
|
123
|
+
| Pattern | Severity | Confidence | Description |
|
|
124
|
+
|---------|----------|------------|-------------|
|
|
125
|
+
| CSS animation / transition / transform without matching `@media (prefers-reduced-motion: reduce)` override | WARN | heuristic | WCAG 2.3.3 |
|
|
126
|
+
| JS animation library (GSAP, framer-motion, anime.js) without `matchMedia('(prefers-reduced-motion: reduce)')` check | WARN | heuristic | WCAG 2.3.3 |
|
|
127
|
+
| Parallax scrolling without opt-out | WARN | heuristic | WCAG 2.3.3 |
|
|
128
|
+
| Infinite animation (CSS `animation: name infinite`) on content element without pause control | WARN | heuristic | WCAG 2.2.2 |
|
|
129
|
+
| `<marquee>` / `<blink>` (deprecated) | HIGH | definitive | WCAG 2.2.2 |
|
|
130
|
+
|
|
131
|
+
#### 8b. Target Size (WCAG 2.2 Minimum AA 2.5.8 + EN 301 549)
|
|
132
|
+
|
|
133
|
+
| Pattern | Severity | Confidence | Description |
|
|
134
|
+
|---------|----------|------------|-------------|
|
|
135
|
+
| Interactive target with declared size <24×24 px (heuristic from CSS: `width`/`height`/`padding` on buttons/links/inputs) | WARN | heuristic | WCAG 2.2 2.5.8 / EN 301 549 |
|
|
136
|
+
| Touch-target spacing <8 px between adjacent interactive elements | INFO | heuristic | Best practice |
|
|
137
|
+
|
|
138
|
+
#### 8c. Viewport & Zoom
|
|
139
|
+
|
|
140
|
+
| Pattern | Severity | Confidence | Description |
|
|
141
|
+
|---------|----------|------------|-------------|
|
|
142
|
+
| `<meta name="viewport">` containing `user-scalable=no` / `user-scalable=0` | HIGH | definitive | WCAG 1.4.4 — blocks zoom |
|
|
143
|
+
| `<meta name="viewport">` with `maximum-scale=1` / `maximum-scale=1.0` | HIGH | definitive | WCAG 1.4.4 |
|
|
144
|
+
| Content rendered via `<img>` for text (text-as-image) | WARN | heuristic | WCAG 1.4.5 |
|
|
145
|
+
|
|
146
|
+
#### 8d. Mobile (React Native + Flutter)
|
|
147
|
+
|
|
148
|
+
EN 301 549 mobile chapter. Critical for EAA scope since consumer apps are in-scope.
|
|
149
|
+
|
|
150
|
+
| Pattern | Severity | Confidence | Description |
|
|
151
|
+
|---------|----------|------------|-------------|
|
|
152
|
+
| **React Native**: `<TouchableOpacity>` / `<TouchableHighlight>` / `<Pressable>` without `accessibilityLabel` | HIGH | definitive | EN 301 549 mobile |
|
|
153
|
+
| **React Native**: `<Image>` without `accessibilityLabel` or `accessible={false}` | WARN | heuristic | EN 301 549 |
|
|
154
|
+
| **React Native**: Missing `accessibilityRole` on custom components that behave as buttons/links | WARN | heuristic | EN 301 549 |
|
|
155
|
+
| **React Native**: `Alert.alert` for error flow without `AccessibilityInfo.announceForAccessibility` fallback | INFO | heuristic | — |
|
|
156
|
+
| **Flutter**: Interactive widget (`GestureDetector`, `InkWell`, `TextButton`, `IconButton`) without `Semantics()` wrapper or `semanticLabel` parameter | HIGH | definitive | EN 301 549 mobile |
|
|
157
|
+
| **Flutter**: `Image()` / `Image.asset()` / `Image.network()` without `semanticLabel` (or `excludeFromSemantics: true` for decorative) | WARN | definitive | EN 301 549 |
|
|
158
|
+
| **Flutter**: Missing `ExcludeSemantics` / `MergeSemantics` where child semantics conflict | INFO | heuristic | Semantics tree cleanup |
|
|
159
|
+
|
|
160
|
+
#### 8e. EAA Accessibility Documentation
|
|
161
|
+
|
|
162
|
+
**Activated by `--standard eaa`.** EAA Article 14 + member-state transpositions require consumer-facing services to publish an accessibility statement. Missing statement = HIGH legal finding.
|
|
163
|
+
|
|
164
|
+
| Pattern | Severity | Confidence | Description |
|
|
165
|
+
|---------|----------|------------|-------------|
|
|
166
|
+
| No route at any of: `/accessibility`, `/accessibility-statement`, `/a11y`, `/dostepnosc` (PL), `/barrierefreiheit` (DE), `/declaration-accessibilite` (FR), `/declaración-accesibilidad` (ES), `/dichiarazione-accessibilita` (IT), `/toegankelijkheidsverklaring` (NL) | HIGH | heuristic | EAA Article 14 |
|
|
167
|
+
| Footer / sitemap lacks link to accessibility statement | HIGH | heuristic | EAA visibility requirement |
|
|
168
|
+
| Accessibility statement present but missing required elements: (a) conformance level (WCAG/EN 301 549), (b) list of non-conformant content, (c) feedback mechanism, (d) enforcement procedure link | WARN | heuristic | Member-state template requirement |
|
|
169
|
+
| No contact mechanism (email / form) for accessibility feedback referenced in statement | WARN | heuristic | EAA Article 14 |
|
|
170
|
+
| `robots.txt` disallows `/accessibility*` path (accidentally blocks statement from crawlers + assistive tech) | WARN | definitive | Discoverability |
|
|
171
|
+
|
|
172
|
+
See: [eaa-compliance.md](eaa-compliance.md) for directive text, member-state deadlines, statement templates.
|
|
173
|
+
|
|
174
|
+
---
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: brainstorm
|
|
3
|
+
description: "Pre-artifact conversation that prices the zero option and can end in 'do not build this'. Triggers: brainstorm, should we build, is this worth it, explore idea, thinking out loud, half-formed idea."
|
|
4
|
+
user-invocable: true
|
|
5
|
+
effort: high
|
|
6
|
+
argument-hint: "[the idea, problem, or half-formed thought]"
|
|
7
|
+
allowed-tools: Read, Grep, Glob, Bash, Agent
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Brainstorm
|
|
11
|
+
|
|
12
|
+
$ARGUMENTS
|
|
13
|
+
|
|
14
|
+
The conversation that happens *before* an artifact exists. Every other planning
|
|
15
|
+
skill here produces something — a PRD, a plan, issues, a design. This one is
|
|
16
|
+
allowed to produce nothing, and that is its point.
|
|
17
|
+
|
|
18
|
+
## The zero option is a real candidate
|
|
19
|
+
|
|
20
|
+
Price "build nothing" against the proposal properly. Not as a strawman, not as a
|
|
21
|
+
sentence acknowledged and moved past — as a genuine option with its own costs:
|
|
22
|
+
|
|
23
|
+
- what breaks or stays broken if nobody does this
|
|
24
|
+
- who currently absorbs that, and how much it costs them
|
|
25
|
+
- how long the problem has existed without being fixed, and what that says about it
|
|
26
|
+
- what the codebase carries forever once this exists: another surface, another
|
|
27
|
+
migration path, another thing that has to keep working
|
|
28
|
+
|
|
29
|
+
If the zero option wins, say so and stop. **Do not invent a deliverable to justify
|
|
30
|
+
the conversation.** A brainstorm that ends in "this is not worth building, and
|
|
31
|
+
here is what it would have cost" has done its job.
|
|
32
|
+
|
|
33
|
+
## Steps
|
|
34
|
+
|
|
35
|
+
### Step 1: Understand before proposing
|
|
36
|
+
|
|
37
|
+
Explore the actual codebase before shaping anything. Read what exists, grep for
|
|
38
|
+
prior attempts, check whether the problem is already solved somewhere.
|
|
39
|
+
|
|
40
|
+
Ask what the user is trying to achieve, not what they want built. The stated
|
|
41
|
+
request is a proposed solution; the problem behind it is what matters. Keep
|
|
42
|
+
asking until you can state the problem without naming the solution.
|
|
43
|
+
|
|
44
|
+
### Step 2: Shape the options
|
|
45
|
+
|
|
46
|
+
Produce at least three genuinely different approaches, one of which is always
|
|
47
|
+
"do nothing / do it manually / wait". Different means different in kind, not
|
|
48
|
+
three variants of the same shape.
|
|
49
|
+
|
|
50
|
+
For each: what it costs, what it forecloses, what has to stay true for it to keep
|
|
51
|
+
working.
|
|
52
|
+
|
|
53
|
+
### Step 3: Resolve the unknowns
|
|
54
|
+
|
|
55
|
+
List what nobody in the conversation actually knows. For each, decide whether it
|
|
56
|
+
can be resolved now (read the code, check the data, run something) or whether it
|
|
57
|
+
stays open and becomes a risk the next stage inherits.
|
|
58
|
+
|
|
59
|
+
Resolve what is cheap to resolve. An unknown carried into a PRD becomes an Open
|
|
60
|
+
Question; an unknown carried past a PRD becomes a bug.
|
|
61
|
+
|
|
62
|
+
### Step 4: Challenge the conclusion
|
|
63
|
+
|
|
64
|
+
Before routing anywhere, spawn a **separate** agent to attack the conclusion. Not
|
|
65
|
+
you re-reading your own reasoning — a different context that did not fall in love
|
|
66
|
+
with the idea.
|
|
67
|
+
|
|
68
|
+
```
|
|
69
|
+
Use the Agent tool with subagent_type: general-purpose.
|
|
70
|
+
|
|
71
|
+
Your job is to break the conclusion below, not to improve it. Assume it is wrong
|
|
72
|
+
and find out where. If you cannot break it, say what specifically held.
|
|
73
|
+
|
|
74
|
+
Conclusion reached: <one paragraph>
|
|
75
|
+
Options rejected, with reasons: <list — the zero option is always one of them>
|
|
76
|
+
Unknowns still open: <list>
|
|
77
|
+
|
|
78
|
+
Work through these in order:
|
|
79
|
+
|
|
80
|
+
1. Restate the problem without naming any solution. If you cannot, the problem
|
|
81
|
+
was never separated from the proposal and everything below is downstream of
|
|
82
|
+
that.
|
|
83
|
+
2. Who pays for the problem today, how often, and how much? If nobody can be
|
|
84
|
+
named, the cost is assumed rather than observed.
|
|
85
|
+
3. The problem has existed until now without this being built. What changed —
|
|
86
|
+
or is the trigger just that someone thought of it?
|
|
87
|
+
4. Take the zero-option reasoning and argue the opposite side as well as you can.
|
|
88
|
+
If that argument is stronger than the one that won, the zero option was
|
|
89
|
+
dismissed rather than priced.
|
|
90
|
+
5. What does the codebase carry permanently once this exists? Count the surface,
|
|
91
|
+
the migration path, the thing that must keep working.
|
|
92
|
+
6. Name the single assumption that, if false, wastes the most work — and the
|
|
93
|
+
cheapest thing that would prove it false today.
|
|
94
|
+
7. Hand the brief to someone who was not here. What do they ask first?
|
|
95
|
+
|
|
96
|
+
Report as: BLOCKER (the conclusion or the chosen next step does not survive),
|
|
97
|
+
CONCERN (holds, but on an assumption worth naming), HOLDS (what you tried to
|
|
98
|
+
break and could not).
|
|
99
|
+
|
|
100
|
+
Write plainly and skip the closing summary. Do not soften findings to be
|
|
101
|
+
agreeable — agreement you did not test is worth nothing here. A first pass over
|
|
102
|
+
a fresh idea that produces no BLOCKER and no CONCERN almost always means the
|
|
103
|
+
attack was shallow; go back to question 4.
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
Any BLOCKER goes back to Step 2 or Step 3. Do not route past one.
|
|
107
|
+
|
|
108
|
+
### Step 5: Take an exit ramp
|
|
109
|
+
|
|
110
|
+
Pick exactly one and say which, in the user's words, before invoking anything.
|
|
111
|
+
|
|
112
|
+
| # | When | Next |
|
|
113
|
+
|---|------|------|
|
|
114
|
+
| 1 | Nothing worth building, or the question is answered | **stop** — no artifact, no handoff |
|
|
115
|
+
| 2 | Worth doing, not now | write a brief to `kb/planning/`, stop |
|
|
116
|
+
| 3 | Feature, unknowns resolved | `/write-a-prd` |
|
|
117
|
+
| 4 | Feature, user wants to co-design | `/design-an-interface`, then `/write-a-prd` |
|
|
118
|
+
| 5 | Small and obvious, no spec needed | `/tdd` or `/fix` directly |
|
|
119
|
+
| 6 | Already tracked somewhere | point at the existing issue or task, stop |
|
|
120
|
+
|
|
121
|
+
Ramp 1 and ramp 6 are the two most likely to be correct and the two most likely to
|
|
122
|
+
be skipped. Check both before considering the others.
|
|
123
|
+
|
|
124
|
+
## Rules
|
|
125
|
+
|
|
126
|
+
- **MUST** price the zero option explicitly and state why it lost, before any ramp
|
|
127
|
+
other than 1 is taken
|
|
128
|
+
- **MUST** spawn the challenger as a separate agent — self-review at Step 4 does
|
|
129
|
+
not count and is the failure mode this skill exists to prevent
|
|
130
|
+
- **NEVER** invoke a downstream skill without naming the ramp and the reason first
|
|
131
|
+
- **NEVER** produce a PRD, plan, or issue from inside this skill — it routes, it
|
|
132
|
+
does not build
|
|
133
|
+
- **CRITICAL**: ending at ramp 1 is a success, and is reported as one, not as an
|
|
134
|
+
apology
|
|
135
|
+
- **MANDATORY**: at least one of the three options in Step 2 is always the zero
|
|
136
|
+
option
|
|
137
|
+
|
|
138
|
+
## Gotchas
|
|
139
|
+
|
|
140
|
+
- The challenger only works from a **separate** context. Re-reading your own
|
|
141
|
+
reasoning in the same conversation reproduces the same blind spots and returns
|
|
142
|
+
OK on everything, which reads as validation and is nothing of the kind.
|
|
143
|
+
- A challenger that never returns BLOCKER or CONCERN is broken, not agreeable. If
|
|
144
|
+
several runs come back clean, check that the conclusion, the rejected options
|
|
145
|
+
and the open unknowns are actually being passed in — an attacker given nothing
|
|
146
|
+
to attack reports that everything holds.
|
|
147
|
+
- "The user asked for it" is not the problem statement. Users arrive with a
|
|
148
|
+
solution already chosen; Step 1 is not finished until the problem stands without
|
|
149
|
+
it.
|
|
150
|
+
- Sunk conversation is not evidence. Forty minutes of good discussion does not make
|
|
151
|
+
the idea worth building, and the pull toward a handoff gets stronger the longer
|
|
152
|
+
the conversation ran. That pull is exactly what ramp 1 resists.
|
|
153
|
+
- Ramp 6 loses to novelty. Searching the tracker feels like admitting the
|
|
154
|
+
conversation was wasted, so it gets skipped — do it early, in Step 1.
|
|
155
|
+
- This skill costs roughly double a plain planning session, because of the
|
|
156
|
+
challenger. That is only worth paying if ramp 1 or ramp 6 sometimes wins. If
|
|
157
|
+
every run of this skill routes to `/write-a-prd`, stop using it — it has become
|
|
158
|
+
ceremony.
|
|
159
|
+
|
|
160
|
+
## When NOT to Use
|
|
161
|
+
|
|
162
|
+
- The decision is already made and you want it executed — use `/plan` or `/write-a-prd`
|
|
163
|
+
- A concrete plan exists and needs stress-testing — use `/grill-me`
|
|
164
|
+
- An architectural choice needs several expert perspectives — use `/council`
|
|
165
|
+
- A bug needs a root cause — use `/debug` or `/triage-issue`
|
|
166
|
+
- The change is one obvious line — just make it; a brainstorm about a typo is the
|
|
167
|
+
same waste as a PRD about one
|
|
168
|
+
|
|
169
|
+
## Related Skills
|
|
170
|
+
|
|
171
|
+
- Chose to build it? → `/write-a-prd` for the requirements, then `/prd-to-plan`
|
|
172
|
+
- Need to compare interface shapes first? → `/design-an-interface`
|
|
173
|
+
- Want the plan attacked instead of the idea? → `/grill-me`
|
|
174
|
+
- Want four expert lenses on a decision? → `/council`
|
package/app/skills/ci/SKILL.md
CHANGED
|
@@ -82,6 +82,7 @@ Use `ci-cd-patterns` skill for pipeline templates and best practices.
|
|
|
82
82
|
- **NEVER** commit generated CI configs that embed hardcoded secrets or tokens
|
|
83
83
|
- **CRITICAL**: preserve existing job names and triggers unless the user explicitly asks for a restructure
|
|
84
84
|
- **MANDATORY**: every generated pipeline must include lint + test stages at minimum
|
|
85
|
+
- **MUST** collect every failing job before diagnosing — do not stop at the first red check. A pipeline usually breaks in more than one place, and reporting only the first one costs a full cycle per remaining failure
|
|
85
86
|
|
|
86
87
|
## Gotchas
|
|
87
88
|
|
|
@@ -25,7 +25,7 @@ Pipe error output through the error parser for structured diagnosis:
|
|
|
25
25
|
|
|
26
26
|
```bash
|
|
27
27
|
# Pipe from failing command
|
|
28
|
-
your_command 2>&1 | python3
|
|
28
|
+
your_command 2>&1 | python3 ${CLAUDE_SKILL_DIR}/scripts/error-parser.py
|
|
29
29
|
|
|
30
30
|
# Or from a log file
|
|
31
31
|
cat /var/log/app/error.log | python3 scripts/error-parser.py
|
|
@@ -197,6 +197,7 @@ Report consensus when done.
|
|
|
197
197
|
- **NEVER** apply fixes without first reproducing the symptom
|
|
198
198
|
- **CRITICAL**: trace from symptom to root cause — do not stop at the first plausible explanation
|
|
199
199
|
- **MANDATORY**: if the bug is intermittent, log enough state to reproduce it deterministically before fixing
|
|
200
|
+
- **MUST** finish collecting evidence (logs, health, recent diff, error-parser output) before forming the hypothesis — an investigation that halts at the first error found reports what the user already saw and misses the one they did not
|
|
200
201
|
|
|
201
202
|
## Gotchas
|
|
202
203
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: documentation-standards
|
|
3
|
-
description: "KB conventions: YAML frontmatter,
|
|
3
|
+
description: "KB conventions: YAML frontmatter, 8-category taxonomy (reference/howto/procedures/troubleshooting/best-practices/decisions/runbooks/planning). Triggers: kb/, SOP, runbook, howto, frontmatter, knowledge base."
|
|
4
4
|
effort: medium
|
|
5
5
|
user-invocable: false
|
|
6
6
|
allowed-tools: Read
|
|
@@ -27,7 +27,19 @@ version: "1.0.0" # optional — semver
|
|
|
27
27
|
---
|
|
28
28
|
```
|
|
29
29
|
|
|
30
|
-
**All 7 fields above are REQUIRED.** Documents without valid frontmatter **fail
|
|
30
|
+
**All 7 fields above are REQUIRED.** Documents without valid frontmatter **fail
|
|
31
|
+
`scripts/validate.py` and block CI**.
|
|
32
|
+
|
|
33
|
+
### `section`: a legacy alias, not a second field
|
|
34
|
+
|
|
35
|
+
Older documents and the `kb-migration` SOP write `section:` where this
|
|
36
|
+
specification writes `category:`. Both names are read in the wild, so a document
|
|
37
|
+
may carry both — and when it does **they must hold the same value**. A document
|
|
38
|
+
filed as `category: reference` and `section: howto` is indexed twice, found
|
|
39
|
+
once, and the reader gets whichever the index ranked higher.
|
|
40
|
+
|
|
41
|
+
New documents should write `category:`. `section:` is accepted, never required,
|
|
42
|
+
and never authoritative on its own.
|
|
31
43
|
|
|
32
44
|
## Category Taxonomy
|
|
33
45
|
|
|
@@ -35,11 +47,17 @@ version: "1.0.0" # optional — semver
|
|
|
35
47
|
|----------|-----------|---------|----------|
|
|
36
48
|
| `reference` | `kb/reference/` | Technical specifications, catalogs, architecture notes, API docs | `agents-catalog.md`, `architecture-overview.md` |
|
|
37
49
|
| `howto` | `kb/howto/` | Step-by-step task guides | `use-corrective-rag.md`, `configure-mcp-server.md` |
|
|
38
|
-
| `procedures` | `kb/procedures/` | SOPs,
|
|
50
|
+
| `procedures` | `kb/procedures/` | SOPs a person follows: release, migration, review | `maintenance-sop.md`, `sop-release.md` |
|
|
39
51
|
| `troubleshooting` | `kb/troubleshooting/` | Problem resolution, debugging guides | `database-connection-issues.md` |
|
|
40
52
|
| `best-practices` | `kb/best-practices/` | Guidelines, recommendations, standards | `security-checklist.md` |
|
|
53
|
+
| `decisions` | `kb/decisions/` | Architecture decision records and design rationale | `adr-004-kb-migration.md` |
|
|
54
|
+
| `runbooks` | `kb/runbooks/` | Procedures run against a live system, usually under pressure | `deployment.md`, `incident-response.md` |
|
|
55
|
+
| `planning` | `kb/planning/` | Roadmaps, PRDs, work not yet done | `q3-roadmap.md` |
|
|
41
56
|
|
|
42
|
-
**Rule:**
|
|
57
|
+
**Rule:** A document filed under one of the directories above MUST declare that
|
|
58
|
+
category. The rule is scoped to those directories deliberately: `kb/history/`
|
|
59
|
+
and similar are lifecycle locations rather than types, and a finished plan filed
|
|
60
|
+
under `history/completed/` is still a `planning` document.
|
|
43
61
|
|
|
44
62
|
## Naming Conventions
|
|
45
63
|
|
|
@@ -178,7 +196,9 @@ scripts/validate.py
|
|
|
178
196
|
# Checks: required fields present, category is valid, tags non-empty
|
|
179
197
|
```
|
|
180
198
|
|
|
181
|
-
Valid categories
|
|
199
|
+
Valid categories are the eight in the table above. `scripts/validate.py` holds
|
|
200
|
+
the same set in `VALID_KB_CATEGORIES`; the two are the same list in two places
|
|
201
|
+
and a change belongs in both.
|
|
182
202
|
|
|
183
203
|
## Anti-Patterns
|
|
184
204
|
|
package/app/skills/fix/SKILL.md
CHANGED
|
@@ -26,7 +26,7 @@ Before entering the fix loop, classify errors to prioritize auto-fixable ones:
|
|
|
26
26
|
|
|
27
27
|
```bash
|
|
28
28
|
# Pipe lint or test output
|
|
29
|
-
ruff check . 2>&1 | python3
|
|
29
|
+
ruff check . 2>&1 | python3 ${CLAUDE_SKILL_DIR}/scripts/error-classifier.py
|
|
30
30
|
mypy src/ 2>&1 | python3 scripts/error-classifier.py
|
|
31
31
|
npx eslint . 2>&1 | python3 scripts/error-classifier.py
|
|
32
32
|
```
|