@kennethsolomon/shipkit 3.0.7 → 3.2.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/README.md CHANGED
@@ -62,7 +62,7 @@ npm install -g @kennethsolomon/shipkit && shipkit
62
62
 
63
63
  ShipKit installs slash commands and skills into `~/.claude/`. Each command is a focused instruction set that Claude follows — no magic, just structured prompts that enforce quality gates.
64
64
 
65
- The workflow is linear: **Brainstorm → Plan → Branch → Test → Implement → Lint → Security → Review → Ship.**
65
+ The workflow is linear: **ReadExplore → Design → Accessibility → Plan → Branch → MigrateWrite Tests → Implement → Lint → Verify Tests → Security → Performance → Review → E2E Tests → Finish → Sync Features**
66
66
 
67
67
  Every gate must pass before the next step. If lint fails, fix it. If tests don't cover new code, write them. Security issues block the PR. This isn't optional — it's the whole point.
68
68
 
@@ -76,7 +76,7 @@ Every gate must pass before the next step. If lint fails, fix it. If tests don't
76
76
 
77
77
  ```
78
78
  Brainstorm → Plan → Branch → [Schema] → Write Tests → Implement → Commit
79
- → Lint ✓ → Test ✓ → Security ✓ → Review ✓ → Update Task → Finish
79
+ → Lint ✓ → Test ✓ → Security ✓ → Review ✓ → E2E ✓ → Update Task → Finish → Sync Features
80
80
  ```
81
81
 
82
82
  | # | Command | Purpose |
@@ -84,26 +84,32 @@ Brainstorm → Plan → Branch → [Schema] → Write Tests → Implement → Co
84
84
  | 1 | read `tasks/todo.md` | Pick the next task |
85
85
  | 2 | read `tasks/lessons.md` | Review past corrections |
86
86
  | 3 | `/sk:brainstorm` | Clarify requirements — no code |
87
- | 4 | `/sk:frontend-design` | UI design spec *(skip if backend-only)*. Add `--pencil` to also generate a Pencil visual mockup |
88
- | 5 | `/sk:api-design` | API contracts *(skip if no new endpoints)* |
89
- | 6 | `/sk:accessibility` | WCAG 2.1 AA audit on design *(skip if no frontend)* |
90
- | 7 | `/sk:write-plan` | Write plan to `tasks/todo.md` |
91
- | 8 | `/sk:branch` | Create branch from current task |
92
- | 9 | `/sk:schema-migrate` | Schema change analysis *(skip if no DB changes)* |
93
- | 10 | `/sk:write-tests` | TDD red: write failing tests first |
94
- | 11 | `/sk:execute-plan` | TDD green: make tests pass |
95
- | 12 | `/sk:smart-commit` | Conventional commit |
96
- | 13 | **`/sk:lint`** | **GATE** all linters must pass |
97
- | 14 | `/sk:smart-commit` | Auto-skip if already clean |
98
- | 15 | **`/sk:test`** | **GATE** 100% coverage on new code |
99
- | 16 | `/sk:smart-commit` | Auto-skip if already clean |
100
- | 17 | **`/sk:security-check`** | **GATE** 0 issues |
101
- | 18 | `/sk:smart-commit` | Auto-skip if already clean |
102
- | 19 | **`/sk:review`** | **GATE** 0 issues including nitpicks |
103
- | 20 | `/sk:smart-commit` | Auto-skip if already clean |
104
- | 21 | `/sk:update-task` | Mark done, log completion |
105
- | 22 | `/sk:finish-feature` | Changelog + PR |
106
- | 23 | `/sk:release` | Version bump + tag *(optional)* |
87
+ | 4 | `/sk:frontend-design` or `/sk:api-design` | Design spec *(skip if not needed)*. Frontend: add `--pencil` for Pencil visual mockup. API: REST/GraphQL contracts. |
88
+ | 5 | `/sk:accessibility` | WCAG 2.1 AA audit on design *(skip if no frontend)* |
89
+ | 6 | `/sk:write-plan` | Write plan to `tasks/todo.md` |
90
+ | 7 | `/sk:branch` | Create branch from current task |
91
+ | 8 | `/sk:schema-migrate` | Schema change analysis *(skip if no DB changes)* |
92
+ | 9 | `/sk:write-tests` | TDD red: write failing tests first |
93
+ | 10 | `/sk:execute-plan` | TDD green: make tests pass |
94
+ | 11 | `/sk:smart-commit` | Conventional commit |
95
+ | 12 | **`/sk:lint`** | **GATE** Lint + Dep Audit — all linters must pass |
96
+ | 13 | `/sk:smart-commit` | Auto-skip if already clean |
97
+ | 14 | **`/sk:test`** | **GATE** 100% coverage on new code |
98
+ | 15 | `/sk:smart-commit` | Auto-skip if already clean |
99
+ | 16 | **`/sk:security-check`** | **GATE** 0 issues |
100
+ | 17 | `/sk:smart-commit` | Auto-skip if already clean |
101
+ | 18 | **`/sk:perf`** | **GATE** *(optional)* critical/high findings = 0 |
102
+ | 19 | `/sk:smart-commit` | Auto-skip if already clean |
103
+ | 20 | **`/sk:review`** | **GATE** Review + Simplify — 0 issues including nitpicks |
104
+ | 21 | `/sk:smart-commit` | Auto-skip if already clean |
105
+ | 22 | **`/sk:e2e`** | **GATE** E2E Tests — all end-to-end tests must pass |
106
+ | 23 | `/sk:smart-commit` | Auto-skip if already clean |
107
+ | 24 | `/sk:update-task` | Mark done, log completion |
108
+ | 25 | `/sk:finish-feature` | Changelog + PR |
109
+ | 26 | `/sk:features` | Sync Features — update docs/features/ specs *(required)* |
110
+ | 27 | `/sk:release` | Version bump + tag *(optional)* |
111
+
112
+ > **Fix & Retest Protocol:** All code-producing gates (Lint, Test, Security, Performance, Review, E2E) apply the Fix & Retest Protocol: logic changes require updating unit tests before committing the fix. Fix immediately, then re-run — never ask the user to re-run.
107
113
 
108
114
  ### Bug Fix Flow
109
115
 
@@ -118,8 +124,8 @@ Debug → Plan → Branch → Write Tests → Implement → Lint ✓ → Test
118
124
  | 3 | `/sk:branch` | Create branch |
119
125
  | 4 | `/sk:write-tests` | Reproduce the bug in a test |
120
126
  | 5 | `/sk:execute-plan` | Fix — make the test pass |
121
- | 6–9 | lint → test → security → review | Quality gates |
122
- | 10 | `/sk:finish-feature` | Changelog + PR |
127
+ | 6–10 | `/sk:lint``/sk:test``/sk:security-check``/sk:review` → `/sk:e2e` | Quality gates |
128
+ | 11 | `/sk:finish-feature` | Changelog + PR |
123
129
 
124
130
  ### Hotfix Flow
125
131
 
@@ -198,6 +204,7 @@ Requirement changes → /sk:change → re-enter at correct step
198
204
  | `/sk:test` | Auto-detect and run all test suites, verify 100% coverage on new code |
199
205
  | `/sk:security-check` | OWASP security audit across changed code |
200
206
  | `/sk:perf` | Performance audit: bundle size, N+1 queries, Core Web Vitals |
207
+ | `/sk:seo-audit` | SEO audit — dual-mode (source templates + dev server), ask-before-fix, checklist output to `tasks/seo-findings.md` |
201
208
  | `/sk:review` | Rigorous self-review across 7 dimensions |
202
209
 
203
210
  ### Shipping
@@ -108,7 +108,7 @@ Detect the project stack from `CLAUDE.md`, `package.json`, `composer.json`, `pyp
108
108
 
109
109
  ## Generate Report
110
110
 
111
- Write findings to `tasks/security-findings.md` using this format:
111
+ Write findings to `tasks/security-findings.md` using this format. **Never overwrite** `tasks/security-findings.md` — append new audits with a date header. Old run checkboxes stay as-is (audit trail); only update findings from the current run.
112
112
 
113
113
  ```markdown
114
114
  # Security Audit — YYYY-MM-DD
@@ -119,42 +119,43 @@ Write findings to `tasks/security-findings.md` using this format:
119
119
 
120
120
  ## Critical (must fix before deploy)
121
121
 
122
- - **[FILE:LINE]** Description of vulnerability
122
+ - [ ] **[FILE:LINE]** Description of vulnerability
123
123
  **Standard:** OWASP A03 — Injection (CWE-89)
124
124
  **Risk:** What could happen if exploited
125
125
  **Recommendation:** How to fix it
126
+ - [x] **[FILE:LINE]** Description *(resolved)*
126
127
 
127
128
  ## High (fix before production)
128
129
 
129
- - **[FILE:LINE]** Description
130
+ - [ ] **[FILE:LINE]** Description
130
131
  **Standard:** ...
131
132
  **Risk:** ...
132
133
  **Recommendation:** ...
133
134
 
134
135
  ## Medium (should fix)
135
136
 
136
- - **[FILE:LINE]** Description
137
+ - [ ] **[FILE:LINE]** Description
137
138
  **Standard:** ...
138
139
  **Recommendation:** ...
139
140
 
140
141
  ## Low / Informational
141
142
 
142
- - **[FILE:LINE]** Description
143
+ - [ ] **[FILE:LINE]** Description
143
144
  **Recommendation:** ...
144
145
 
145
146
  ## Passed Checks
146
147
 
147
- - List of categories that passed with no findings
148
+ - [Categories with no findings]
148
149
 
149
150
  ## Summary
150
151
 
151
- | Severity | Count |
152
- |----------|-------|
153
- | Critical | N |
154
- | High | N |
155
- | Medium | N |
156
- | Low | N |
157
- | **Total** | **N** |
152
+ | Severity | Open | Resolved this run |
153
+ |----------|------|-------------------|
154
+ | Critical | N | N |
155
+ | High | N | N |
156
+ | Medium | N | N |
157
+ | Low | N | N |
158
+ | **Total** | **N** | **N** |
158
159
  ```
159
160
 
160
161
  ## When Done
@@ -162,15 +163,29 @@ Write findings to `tasks/security-findings.md` using this format:
162
163
  Tell the user:
163
164
 
164
165
  > "Security audit complete. Findings saved to `tasks/security-findings.md`.
165
- > - **Critical:** N | **High:** N | **Medium:** N | **Low:** N
166
+ > - **Critical:** N open (N resolved) | **High:** N open (N resolved) | **Medium:** N open | **Low:** N open
166
167
  >
167
168
  > Review the findings, then run `/sk:finish-feature` when ready to finalize."
168
169
 
169
170
  If there are Critical or High findings:
170
- > "There are critical/high findings that should be addressed before merging. Fix them, then re-run `/sk:security-check` to verify."
171
+ > "There are critical/high findings that MUST be fixed before merging. These are HARD GATE items — `- [ ]` findings block all forward progress. Fix them, then re-run `/sk:security-check` to verify."
171
172
 
172
173
  **Do not auto-fix.** The user decides what to address.
173
174
 
175
+ ### Fix & Retest Protocol
176
+
177
+ When applying a fix, classify it before committing:
178
+
179
+ **a. Config/hardening change** (adding security header, fixing CORS config, adding rate limit, sanitizing output without changing logic) → commit and re-run `/sk:security-check`. No test update needed.
180
+
181
+ **b. Logic change** (new input validation branch, modified query parameterization, changed auth check, refactored data handling) → trigger protocol:
182
+ 1. Update or add failing unit tests for the new secure behavior
183
+ 2. Re-run `/sk:test` — must pass at 100% coverage
184
+ 3. Commit (tests + fix together in one commit)
185
+ 4. Re-run `/sk:security-check` from scratch
186
+
187
+ **Why:** Security fixes often change logic (e.g., adding parameterized queries, sanitizing inputs). Tests must cover the new secure behavior, not just the old vulnerable path.
188
+
174
189
  ---
175
190
 
176
191
  ## Model Routing
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kennethsolomon/shipkit",
3
- "version": "3.0.7",
3
+ "version": "3.2.0",
4
4
  "description": "A structured workflow toolkit for Claude Code.",
5
5
  "keywords": [
6
6
  "claude",
@@ -89,20 +89,25 @@ Write findings to `tasks/accessibility-findings.md`:
89
89
 
90
90
  ## Failures (must fix)
91
91
 
92
- - **[Component/File:Line]** Description
92
+ - [ ] **[Component/File:Line]** Description
93
+ **Criterion:** WCAG X.X.X — [Name]
94
+ **Impact:** [Who is affected and how]
95
+ **Recommendation:** [How to fix]
96
+
97
+ - [x] **[Component/File:Line]** Description *(resolved)*
93
98
  **Criterion:** WCAG X.X.X — [Name]
94
99
  **Impact:** [Who is affected and how]
95
100
  **Recommendation:** [How to fix]
96
101
 
97
102
  ## Warnings (should fix)
98
103
 
99
- - **[Component/File:Line]** Description
104
+ - [ ] **[Component/File:Line]** Description
100
105
  **Criterion:** WCAG X.X.X — [Name]
101
106
  **Recommendation:** [How to fix]
102
107
 
103
108
  ## Manual Checks Required
104
109
 
105
- - [Things that require human/screen reader testing]
110
+ - [ ] [Things that require human/screen reader testing]
106
111
 
107
112
  ## Passed Checks
108
113
 
@@ -110,11 +115,11 @@ Write findings to `tasks/accessibility-findings.md`:
110
115
 
111
116
  ## Summary
112
117
 
113
- | Level | Count |
114
- |----------|-------|
115
- | Failures | N |
116
- | Warnings | N |
117
- | Manual | N |
118
+ | Level | Open | Resolved this run |
119
+ |----------|------|-------------------|
120
+ | Failures | N | N |
121
+ | Warnings | N | N |
122
+ | Manual | N | N |
118
123
  ```
119
124
 
120
125
  **Never overwrite** `tasks/accessibility-findings.md` — append new audits with a date header.
@@ -0,0 +1,147 @@
1
+ ---
2
+ name: sk:e2e
3
+ description: "Run E2E behavioral verification using agent-browser as the final quality gate before finalize. Tests the complete, reviewed, secure implementation from a user's perspective."
4
+ ---
5
+
6
+ # /sk:e2e
7
+
8
+ E2E behavioral verification — the final quality gate before `/sk:finish-feature`. Runs after Review to verify the complete, reviewed, secure implementation works end-to-end from a user's perspective.
9
+
10
+ **Hard gate:** all scenarios must pass. Zero failures allowed.
11
+
12
+ ## Allowed Tools
13
+
14
+ Bash, Read, Glob, Grep
15
+
16
+ ## Steps
17
+
18
+ ### 1. Read Context
19
+
20
+ Read these files to understand what to test:
21
+ - `tasks/todo.md` — planned features and acceptance criteria
22
+ - `tasks/findings.md` — design decisions and expected behaviors
23
+ - `tasks/progress.md` — implementation notes
24
+
25
+ ### 2. Check agent-browser is Available
26
+
27
+ ```bash
28
+ agent-browser --version
29
+ ```
30
+
31
+ If not found, instruct the user:
32
+ ```
33
+ agent-browser is required. Install it:
34
+ npm install -g agent-browser
35
+ agent-browser install # downloads Chrome (~100MB)
36
+ Then re-run /sk:e2e.
37
+ ```
38
+ Stop if not available.
39
+
40
+ ### 3. Detect Local Server
41
+
42
+ Determine what URL to test against:
43
+ - Check for a dev server command in `package.json` scripts (`dev`, `start`)
44
+ - Check for `artisan serve` in Laravel projects (`php artisan serve`)
45
+ - Check for `vite` or `next dev`
46
+ - If a server is already running (check common ports: 3000, 5173, 8000, 8080), use it
47
+ - If no server is running, start one in the background and note the URL
48
+
49
+ ### 4. Locate E2E Test Files
50
+
51
+ Find E2E test scenarios written during the Write Tests step:
52
+ ```bash
53
+ find . -name "*.e2e.*" -o -name "*.spec.*" | grep -v node_modules
54
+ ls tests/e2e/ 2>/dev/null
55
+ ```
56
+
57
+ If no E2E test files exist, derive scenarios from `tasks/todo.md` acceptance criteria and `tasks/findings.md`.
58
+
59
+ ### 5. Run E2E Scenarios
60
+
61
+ For each scenario, use agent-browser following this core pattern:
62
+
63
+ ```bash
64
+ # Navigate to the page
65
+ agent-browser open <url>
66
+
67
+ # Get interactive elements (token-efficient ref-based snapshot)
68
+ agent-browser snapshot -i
69
+
70
+ # Interact using @refs (never CSS selectors)
71
+ agent-browser click @e1
72
+ agent-browser fill @e2 "input value"
73
+ agent-browser press Enter
74
+
75
+ # Use semantic locators when @refs aren't stable
76
+ agent-browser find role button
77
+ agent-browser find text "Expected Text"
78
+ agent-browser find label "Email"
79
+
80
+ # Assert expected state
81
+ agent-browser snapshot # check content
82
+ agent-browser find text "Success Message"
83
+ ```
84
+
85
+ **Ref-based interaction is required.** Never use CSS selectors (`#id`, `.class`) — use semantic locators (`find role`, `find text`, `find label`, `find placeholder`) for stability.
86
+
87
+ For each scenario, record:
88
+ - Scenario name
89
+ - Steps executed
90
+ - Result: PASS or FAIL
91
+ - On FAIL: what was expected vs. what was found (include snapshot excerpt)
92
+
93
+ ### 6. Report Results
94
+
95
+ ```
96
+ E2E Results:
97
+ PASS [scenario name]
98
+ PASS [scenario name]
99
+ FAIL [scenario name] — expected "X" but found "Y"
100
+
101
+ Total: X passed, Y failed
102
+ ```
103
+
104
+ If all pass → proceed to Fix & Retest Protocol section (no action needed).
105
+ If any fail → apply Fix & Retest Protocol.
106
+
107
+ ## Fix & Retest Protocol
108
+
109
+ When this gate requires a fix, classify it before committing:
110
+
111
+ **a. Style/config/wording change** (CSS tweak, copy change, selector fix) → commit and re-run `/sk:e2e` (no unit test update needed)
112
+
113
+ **b. Logic change** (new branch, modified condition, new data path, query change, new function, API change) → trigger protocol:
114
+ 1. Update or add failing unit tests for the new behavior
115
+ 2. Re-run `/sk:test` — must pass at 100% coverage
116
+ 3. Commit (tests + fix together in one commit)
117
+ 4. Re-run `/sk:e2e` from scratch
118
+
119
+ **Exception:** Formatter auto-fixes are never logic changes — bypass protocol automatically.
120
+
121
+ **This gate cannot be skipped.** All scenarios must pass before proceeding to `/sk:update-task`.
122
+
123
+ ## Next Steps
124
+
125
+ If all scenarios pass:
126
+ > "E2E gate clean. Run `/sk:update-task` to mark the task done."
127
+
128
+ If failures remain after fixes:
129
+ > "Re-running /sk:e2e — [N] scenarios still failing."
130
+
131
+ ---
132
+
133
+ ## Model Routing
134
+
135
+ Read `.shipkit/config.json` from the project root if it exists.
136
+
137
+ - If `model_overrides["sk:e2e"]` is set, use that model — it takes precedence.
138
+ - Otherwise use the `profile` field. Default: `balanced`.
139
+
140
+ | Profile | Model |
141
+ |---------|-------|
142
+ | `full-sail` | opus (inherit) |
143
+ | `quality` | sonnet |
144
+ | `balanced` | sonnet |
145
+ | `budget` | haiku |
146
+
147
+ > `opus` = inherit (uses the current session model). When spawning sub-agents via the Agent tool, pass `model: "<resolved-model>"`.
@@ -66,15 +66,38 @@ Agent 2: "Run vendor/bin/rector --dry-run. Report all suggested changes with fil
66
66
  Agent 3: "Run npx eslint . Report all errors with file:line."
67
67
  ```
68
68
 
69
- ### 5. Fix and Re-run
69
+ ### 5. Run Dependency Audit
70
70
 
71
- If any analyzer reports errors:
71
+ Run dependency vulnerability checks for detected stacks:
72
+
73
+ | Stack | Command | Block on |
74
+ |-------|---------|----------|
75
+ | PHP (composer.json) | `composer audit` | any severity with fix available (`composer audit` has no severity filter) |
76
+ | Node (package.json) | `npm audit --audit-level=high` | high or critical |
77
+ | Node (yarn.lock) | `yarn audit --level high` | high or critical |
78
+ | Node (pnpm-lock.yaml) | `pnpm audit --audit-level high` | high or critical |
79
+ | Python (pyproject.toml / requirements.txt) | `pip-audit` | high or critical |
80
+
81
+ For each detected package manager, run the audit command and capture output.
82
+
83
+ **Block (fail this gate):**
84
+ - PHP: any vulnerability that has a fix available (`composer audit` exits non-zero for all severities — no filtering option exists)
85
+ - Node/Python: critical or high severity vulnerabilities that have a fix available
86
+
87
+ **Warn (pass with note):** medium/low severity for Node/Python, or any severity with no available fix — note in report but do not block.
88
+
89
+ Skip stacks not present in the project.
90
+
91
+ ### 6. Fix and Re-run
92
+
93
+ If any analyzer reports errors or the dep audit blocks:
72
94
  1. Fix all reported issues
73
95
  2. Re-run formatters (fixes may need formatting)
74
96
  3. Re-launch all analyzers in parallel
75
- 4. Loop until every tool exits clean
97
+ 4. Re-run dep audit if any dependency was fixed
98
+ 5. Loop until every tool exits clean
76
99
 
77
- ### 6. Report Results
100
+ ### 7. Report Results
78
101
 
79
102
  Print one line per tool:
80
103
 
@@ -90,12 +113,34 @@ ESLint: X errors fixed / clean
90
113
  ruff check: X issues fixed / clean
91
114
  golangci-lint: X issues fixed / clean
92
115
  cargo clippy: X warnings fixed / clean
116
+ composer audit: clean / X vulns blocked
117
+ npm audit: clean / X vulns blocked
93
118
  ```
94
119
 
95
120
  Only include lines for detected tools. All must show "clean" before this skill passes.
96
121
 
97
122
  ---
98
123
 
124
+ ## Fix & Retest Protocol
125
+
126
+ When this gate requires a fix, classify it before committing:
127
+
128
+ **a. Formatter auto-fix** (Pint, Prettier, gofmt, cargo fmt changed whitespace/style) → commit and re-run `/sk:lint`. Never a logic change — bypass protocol.
129
+
130
+ **b. Analyzer fix** (PHPStan type error, Rector suggestion, ESLint error, ruff violation) → classify each fix:
131
+ - Type annotation, import order, unused var, style rule → **style fix** → commit and re-run
132
+ - New guard clause, changed condition, extracted function, modified data flow → **logic change** → trigger protocol:
133
+ 1. Update or add failing unit tests for the new behavior
134
+ 2. Re-run `/sk:test` — must pass at 100% coverage
135
+ 3. Commit (tests + fix together in one commit)
136
+ 4. Re-run `/sk:lint` from scratch
137
+
138
+ **c. Dependency vulnerability fix** (composer audit / npm audit finding) → classify:
139
+ - Version bump with no API change → **style fix** → commit and re-run
140
+ - Version bump with API/behavior change → **logic change** → trigger protocol
141
+
142
+ ---
143
+
99
144
  ## Model Routing
100
145
 
101
146
  Read `.shipkit/config.json` from the project root if it exists.
@@ -120,24 +120,25 @@ Write findings to `tasks/perf-findings.md`:
120
120
 
121
121
  ## Critical
122
122
 
123
- - **[FILE:LINE]** Description
123
+ - [ ] **[FILE:LINE]** Description
124
124
  **Impact:** What happens at scale
125
125
  **Recommendation:** How to fix
126
+ - [x] **[FILE:LINE]** Description *(resolved)*
126
127
 
127
128
  ## High
128
129
 
129
- - **[FILE:LINE]** Description
130
+ - [ ] **[FILE:LINE]** Description
130
131
  **Impact:** ...
131
132
  **Recommendation:** ...
132
133
 
133
134
  ## Medium
134
135
 
135
- - **[FILE:LINE]** Description
136
+ - [ ] **[FILE:LINE]** Description
136
137
  **Recommendation:** ...
137
138
 
138
139
  ## Low
139
140
 
140
- - **[FILE:LINE]** Description
141
+ - [ ] **[FILE:LINE]** Description
141
142
  **Recommendation:** ...
142
143
 
143
144
  ## Passed Checks
@@ -146,13 +147,13 @@ Write findings to `tasks/perf-findings.md`:
146
147
 
147
148
  ## Summary
148
149
 
149
- | Severity | Count |
150
- |----------|-------|
151
- | Critical | N |
152
- | High | N |
153
- | Medium | N |
154
- | Low | N |
155
- | **Total** | **N** |
150
+ | Severity | Open | Resolved this run |
151
+ |----------|------|-------------------|
152
+ | Critical | N | N |
153
+ | High | N | N |
154
+ | Medium | N | N |
155
+ | Low | N | N |
156
+ | **Total** | **N** | **N** |
156
157
  ```
157
158
 
158
159
  **Never overwrite** `tasks/perf-findings.md` — append new audits with a date header.
@@ -171,6 +172,27 @@ If there are no critical or high findings:
171
172
 
172
173
  ---
173
174
 
175
+ ## Fix & Retest Protocol
176
+
177
+ When applying a performance fix, classify it before committing:
178
+
179
+ **a. Config/infrastructure change** (adding cache headers, enabling compression, changing CDN config, adjusting connection pool size) → commit and re-run `/sk:perf`. No test update needed.
180
+
181
+ **b. Logic change** (fixing N+1 query by changing data-fetching logic, refactoring algorithm, modifying data structure, changing pagination logic) → trigger protocol:
182
+ 1. Update or add failing unit tests for the new optimized behavior
183
+ 2. Re-run `/sk:test` — must pass at 100% coverage
184
+ 3. Commit (tests + fix together in one commit)
185
+ 4. Re-run `/sk:perf` to verify the fix resolved the finding
186
+
187
+ **Common logic-change performance fixes:**
188
+ - N+1 fix: changes how related data is fetched → update tests that assert on query count or data shape
189
+ - Algorithm change: O(n²) → O(n log n) → update tests that assert on output correctness
190
+ - Pagination: adding LIMIT/offset → update tests that assert on result set size
191
+
192
+ **Why:** Performance fixes often change how data is fetched or processed. Tests must verify the optimized path produces correct results.
193
+
194
+ ---
195
+
174
196
  ## Model Routing
175
197
 
176
198
  Read `.shipkit/config.json` from the project root if it exists.
@@ -15,14 +15,31 @@ This is a **report-only** step. If Critical or Warning issues are found, the use
15
15
 
16
16
  ## Allowed Tools
17
17
 
18
- Bash, Read, Glob, Grep
18
+ Bash, Read, Glob, Grep, Skill
19
19
 
20
- **Intentionally NO Write or Edit** this skill is report-only. If issues are found, the user decides what to fix.
20
+ **Step 0 only:** the `simplify` skill is invoked via the Skill tool, which carries its own Write/Edit permissions. All other steps are read-only — no direct Write or Edit calls. If issues are found in the main review, the user decides what to fix.
21
21
 
22
22
  ## Steps
23
23
 
24
24
  You MUST complete these steps in order:
25
25
 
26
+ ### 0. Run Simplify First
27
+
28
+ Before reviewing, invoke the built-in `simplify` skill on the changed files to catch reuse, quality, and efficiency issues automatically:
29
+
30
+ > "Review the changed files on this branch for reuse, quality, and efficiency. Fix any issues found."
31
+
32
+ Use `git diff main..HEAD --name-only` to identify the changed files, then run simplify on them.
33
+
34
+ If simplify makes any changes:
35
+ 1. Verify the changes are correct
36
+ 2. Commit them with `/sk:smart-commit` before continuing the review
37
+ 3. Note in the review report: "Simplify pre-pass: X files updated"
38
+
39
+ If simplify makes no changes, proceed directly to step 1.
40
+
41
+ **Note:** Simplify runs automatically as part of `/sk:review` — users do not need to run it separately.
42
+
26
43
  ### 1. Read Project Context
27
44
 
28
45
  ```
@@ -327,6 +344,20 @@ If the user wants to fix nitpicks, loop back to `/sk:debug` + `/sk:smart-commit`
327
344
  If the review is **completely clean**:
328
345
  > "Review complete — no issues found. Run `/sk:finish-feature` to finalize the branch and create a PR."
329
346
 
347
+ ### Fix & Retest Protocol
348
+
349
+ When applying a fix from this review, classify it before committing:
350
+
351
+ **a. Style/naming/comment change** (rename variable, add doc comment, reorder imports, extract constant) → commit and re-run `/sk:review`. No test update needed.
352
+
353
+ **b. Logic change** (fix incorrect condition, add missing null check, change data flow, refactor algorithm, fix async bug) → trigger protocol:
354
+ 1. Update or add failing unit tests for the corrected behavior
355
+ 2. Re-run `/sk:test` — must pass at 100% coverage
356
+ 3. Commit (tests + fix together in one commit)
357
+ 4. Re-run `/sk:review` from scratch
358
+
359
+ **Why:** Review catches logic bugs. Fixing a logic bug without updating tests leaves the test suite asserting on the old (wrong) behavior.
360
+
330
361
  ---
331
362
 
332
363
  ## Model Routing