@kennethsolomon/shipkit 3.3.0 → 3.4.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
@@ -100,7 +100,7 @@ Brainstorm → Plan → Branch → [Schema] → Write Tests → Implement → Co
100
100
  | 17 | `/sk:smart-commit` | Auto-skip if already clean |
101
101
  | 18 | **`/sk:perf`** | **GATE** *(optional)* — critical/high findings = 0 |
102
102
  | 19 | `/sk:smart-commit` | Auto-skip if already clean |
103
- | 20 | **`/sk:review`** | **GATE** — Review + Simplify — 0 issues including nitpicks |
103
+ | 20 | **`/sk:review`** | **GATE** — Review + Simplify + Blast Radius — 0 issues including nitpicks |
104
104
  | 21 | `/sk:smart-commit` | Auto-skip if already clean |
105
105
  | 22 | **`/sk:e2e`** | **GATE** — E2E Tests — prefers Playwright CLI when config detected, falls back to agent-browser; all scenarios must pass |
106
106
  | 23 | `/sk:smart-commit` | Auto-skip if already clean |
@@ -211,7 +211,7 @@ Requirement changes → /sk:change → re-enter at correct step
211
211
  | `/sk:security-check` | OWASP security audit across changed code |
212
212
  | `/sk:perf` | Performance audit: bundle size, N+1 queries, Core Web Vitals |
213
213
  | `/sk:seo-audit` | SEO audit — dual-mode (source templates + dev server), ask-before-fix, checklist output to `tasks/seo-findings.md` |
214
- | `/sk:review` | Rigorous self-review across 7 dimensions |
214
+ | `/sk:review` | Blast-radius-aware self-review across 7 dimensions + cross-file impact analysis |
215
215
 
216
216
  ### Shipping
217
217
 
@@ -33,7 +33,7 @@ Run these commands in order for a complete, quality-gated feature build.
33
33
  | `/sk:lint` | **GATE** — all linters must pass |
34
34
  | `/sk:test` | **GATE** — 100% coverage on new code |
35
35
  | `/sk:security-check` | **GATE** — 0 security issues |
36
- | `/sk:review` | **GATE** — self-review across 7 dimensions |
36
+ | `/sk:review` | **GATE** — blast-radius-aware self-review across 7 dimensions + cross-file impact |
37
37
  | `/sk:update-task` | Mark task done, log completion |
38
38
  | `/sk:finish-feature` | Changelog + PR creation |
39
39
 
@@ -80,7 +80,7 @@ Requirements change mid-workflow? Run `/sk:change` — it classifies the scope a
80
80
  | `/sk:perf` | Performance audit |
81
81
  | `/sk:plan` | Create/refresh task planning files |
82
82
  | `/sk:release` | Automate releases: bump version, update CHANGELOG, create tag, push to GitHub. Use --android and/or --ios flags for App Store / Play Store readiness audit |
83
- | `/sk:review` | Self-review of branch changes |
83
+ | `/sk:review` | Blast-radius-aware self-review of branch changes |
84
84
  | `/sk:schema-migrate` | Multi-ORM schema change analysis |
85
85
  | `/sk:security-check` | OWASP security audit |
86
86
  | `/sk:setup-claude` | Bootstrap project scaffolding |
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kennethsolomon/shipkit",
3
- "version": "3.3.0",
3
+ "version": "3.4.0",
4
4
  "description": "A structured workflow toolkit for Claude Code.",
5
5
  "keywords": [
6
6
  "claude",
@@ -58,16 +58,23 @@ If `tasks/security-findings.md` exists, read the most recent audit. Use any unre
58
58
  Critical/High findings as additional targeted checks — verify the current diff doesn't
59
59
  reintroduce previously flagged vulnerabilities.
60
60
 
61
- ### 2. Collect All Changes
61
+ ### 2. Collect Changes + Blast Radius
62
+
63
+ Instead of reading the entire codebase or only the diff, build a **blast radius** — the minimal set of files that could be affected by the changes. This produces focused, high-signal context that leads to better review quality.
64
+
65
+ **2a — Baseline git info:**
62
66
 
63
67
  ```bash
64
68
  # Determine base branch
65
- git symbolic-ref refs/remotes/origin/HEAD 2>/dev/null | sed 's@^refs/remotes/origin/@@' || echo "main"
69
+ BASE=$(git symbolic-ref refs/remotes/origin/HEAD 2>/dev/null | sed 's@^refs/remotes/origin/@@' || echo "main")
70
+
71
+ # Changed files and stats
72
+ CHANGED_FILES=$(git diff $BASE..HEAD --name-only)
73
+ git diff $BASE..HEAD --stat
74
+ git log $BASE..HEAD --oneline
66
75
 
67
- # All changes on this branch
68
- git diff main..HEAD
69
- git diff main..HEAD --stat
70
- git log main..HEAD --oneline
76
+ # Full diff for reference
77
+ git diff $BASE..HEAD
71
78
 
72
79
  # Check for uncommitted changes
73
80
  git status --short
@@ -76,12 +83,103 @@ git status --short
76
83
  If there are uncommitted changes, warn:
77
84
  > **Warning:** You have uncommitted changes. These will NOT be included in the review. Commit or stash them first.
78
85
 
79
- Read the full content of every changed file (not just the diff hunks) to understand context around the changes.
86
+ **2b Extract changed symbols:**
87
+
88
+ Use **git hunk headers** as the primary extraction method. Git already parses the enclosing function/class name into every `@@` header — this is more reliable than regex or AST tools:
89
+
90
+ ```bash
91
+ # Phase 1: Enclosing scope names from hunk headers (free from git, no parsing needed)
92
+ git diff $BASE..HEAD -U0 | grep '^@@' | sed 's/.*@@\s*//' | \
93
+ grep -oE '[A-Za-z_][A-Za-z0-9_]*\s*\(' | sed 's/\s*(//' | sort -u
94
+ ```
95
+
96
+ Then supplement with **new/modified definitions** from added lines using language-specific patterns. Only match definition keywords — not `const`, `export`, `type`, or other high-noise terms:
97
+
98
+ ```bash
99
+ # Phase 2: Definitions from added lines (supplement, not replace)
100
+ # JS/TS: function foo(, class Foo, interface Foo
101
+ # Python: def foo(, class Foo
102
+ # Go: func foo(, func (r *T) foo(
103
+ # PHP: function foo(, class Foo
104
+ # Rust: fn foo(, struct Foo, impl Foo, trait Foo
105
+ git diff $BASE..HEAD | grep '^+' | grep -v '^+++' | \
106
+ grep -oE '(function|class|interface|def|fn|func|struct|trait|impl)\s+[A-Za-z_][A-Za-z0-9_]+' | \
107
+ awk '{print $2}' | sort -u
108
+ ```
109
+
110
+ Combine both phases. Filter out symbols shorter than 3 characters (too generic for blast-radius search).
111
+
112
+ Classify each symbol:
113
+ - **Modified/removed** — existed before the branch, changed or deleted now. These can break callers. **Run blast radius on these.**
114
+ - **New** — added in this branch, no prior callers exist. **Skip blast radius** (nothing to break).
115
+
116
+ To classify, check if the symbol appears in the base branch:
117
+ ```bash
118
+ # If symbol exists in base branch files, it's modified/removed → needs blast radius
119
+ git show $BASE:$FILE 2>/dev/null | grep -q "\b$SYMBOL\b"
120
+ ```
121
+
122
+ **2c — Find blast radius (modified/removed symbols only):**
123
+
124
+ For each modified/removed symbol, use **import-chain narrowing** to find dependents with minimal false positives:
125
+
126
+ ```bash
127
+ # Step 1: Find files that import the module containing the changed symbol
128
+ CHANGED_MODULE_PATHS=$(echo "$CHANGED_FILES" | sed 's/\.[^.]*$//' | sed 's/\/index$//')
129
+ for module_path in $CHANGED_MODULE_PATHS; do
130
+ rg -l "(import|require|from|use)\s.*$(basename $module_path)" \
131
+ --glob '!node_modules/**' --glob '!vendor/**' --glob '!dist/**' \
132
+ --glob '!build/**' --glob '!*.lock' --glob '!*.md' \
133
+ 2>/dev/null
134
+ done | sort -u > /tmp/importers.txt
135
+
136
+ # Step 2: Within importers, find which ones reference the specific changed symbols
137
+ for symbol in $MODIFIED_SYMBOLS; do
138
+ rg -wl "$symbol" $(cat /tmp/importers.txt) 2>/dev/null
139
+ done | sort -u > /tmp/dependents.txt
140
+
141
+ # Remove files already in the changed set
142
+ comm -23 /tmp/dependents.txt <(echo "$CHANGED_FILES" | sort) > /tmp/blast_radius.txt
143
+ ```
144
+
145
+ **Noise guard:** If a symbol produces >100 matches, it's too generic for grep-based analysis. Note it in the review as "unable to determine blast radius for `symbol` — manual verification recommended."
146
+
147
+ Log the blast radius before reading:
148
+ ```
149
+ Blast Radius Summary
150
+ ──────────────────────────────────
151
+ Changed files: X
152
+ Blast-radius dependents: Y (files importing changed symbols)
153
+ Total review scope: X+Y files
154
+ Symbols analyzed: N modified, M new (skipped)
155
+
156
+ Symbol → Dependents:
157
+ processOrder → src/checkout/cart.ts, src/api/orders.ts
158
+ validateInput → src/middleware/auth.ts
159
+ ──────────────────────────────────
160
+ ```
161
+
162
+ **2d — Read context (focused, not exhaustive):**
163
+
164
+ Read in this priority order:
165
+ 1. **Changed files in full** — not just the diff. The full file provides surrounding context (imports, related functions, class-level state) needed to judge whether the change is correct. For files >500 lines, read the changed function + 30 lines of surrounding context instead.
166
+ 2. **The diff** — for precise change tracking (already collected above).
167
+ 3. **Blast-radius dependent files** — read only the call sites that reference changed symbols. Use `rg -B5 -A10 "\bsymbol\b" dependent_file` to get the call site with surrounding context, not the entire file.
168
+ 4. **Test files** for changed symbols — verify existing tests still cover the changed behavior.
169
+
170
+ Do **not** read unchanged files outside the blast radius.
171
+
172
+ Carry the blast-radius mapping (symbol → dependents) forward into Steps 3-9. When analyzing a changed function, always cross-reference its dependents.
80
173
 
81
174
  ### 3. Analyze — Correctness & Bugs
82
175
 
83
176
  The most important dimension. A bug that ships is worse than ugly code that works.
84
177
 
178
+ **Blast-radius check (mandatory):** For every modified/removed symbol, verify its dependents (from Step 2c) are still compatible:
179
+ - Do callers pass arguments the changed function still accepts?
180
+ - Do callers depend on return values whose shape/type changed?
181
+ - Do callers rely on side effects the changed code no longer produces?
182
+
85
183
  **Logic errors:**
86
184
  - Wrong operator (`&&` vs `||`, `==` vs `===`, `<` vs `<=`)
87
185
  - Inverted conditions, missing negation
@@ -114,7 +212,11 @@ The most important dimension. A bug that ships is worse than ugly code that work
114
212
 
115
213
  ### 4. Analyze — Security
116
214
 
117
- Load `references/security-checklist.md` and apply its grep patterns systematically. Check for:
215
+ Load `references/security-checklist.md` and apply its grep patterns against the **diff and blast-radius files** (not the entire codebase). Only flag patterns **newly introduced** in the diff — pre-existing issues are out of scope unless they interact with the changed code.
216
+
217
+ **Blast-radius check:** If a validation or auth function was modified, check all its callers (from Step 2c) — a weakened check affects every endpoint that depends on it.
218
+
219
+ Check for:
118
220
 
119
221
  **Injection (OWASP A03):**
120
222
  - SQL, NoSQL, OS command, LDAP, template injection
@@ -184,6 +286,8 @@ Think about what happens at 10x, 100x current scale. Performance bugs are often
184
286
 
185
287
  Production code must handle failure gracefully. The question isn't "does it work?" but "what happens when things go wrong?"
186
288
 
289
+ **Blast-radius check:** If error handling changed (e.g., function now throws instead of returning null, or error type changed), check all callers from Step 2c — they may not have matching try/catch or null checks.
290
+
187
291
  **Error handling quality:**
188
292
  - Swallowed errors (empty catch blocks, `.catch(() => {})`)
189
293
  - Generic catch blocks that hide the actual error type
@@ -217,8 +321,9 @@ Think about the next engineer who reads this code. Is the intent clear? Does the
217
321
  - Components doing too many things (should be split)
218
322
  - Side effects in pure functions or constructors
219
323
 
220
- **API design (if endpoints changed):**
324
+ **API design (if endpoints or function signatures changed):**
221
325
  - Breaking changes to existing API contracts without versioning
326
+ - **Blast-radius check:** If a function signature changed, the blast radius from Step 2c is the definitive answer to whether it's a breaking change — every dependent file that calls the old signature will break
222
327
  - Inconsistent response format across endpoints
223
328
  - Missing or inconsistent HTTP status codes
224
329
  - Unclear or missing error response schema
@@ -294,7 +399,8 @@ Format findings with severity levels and review dimensions:
294
399
 
295
400
  **Changes:** X files changed, +Y/-Z lines
296
401
  **Commits:** N commits
297
- **Review dimensions:** Correctness, Security, Performance, Reliability, Design, Best Practices, Testing
402
+ **Blast radius:** X changed files + Y dependents = Z total review scope
403
+ **Review dimensions:** Correctness, Security, Performance, Reliability, Design, Best Practices, Testing, Blast Radius
298
404
 
299
405
  ### Critical (must fix before merge)
300
406
  - **[Correctness]** [FILE:LINE] Description of critical issue
@@ -323,7 +429,8 @@ Format findings with severity levels and review dimensions:
323
429
 
324
430
  **Rules:**
325
431
  - Maximum 20 items total (prioritize by severity, then by category)
326
- - Every item must tag its review dimension: `[Correctness]`, `[Security]`, `[Performance]`, `[Reliability]`, `[Design]`, `[Best Practices]`, `[Testing]`
432
+ - Every item must tag its review dimension: `[Correctness]`, `[Security]`, `[Performance]`, `[Reliability]`, `[Design]`, `[Best Practices]`, `[Testing]`, `[Blast Radius]`
433
+ - Use `[Blast Radius]` for issues found in dependent files — callers broken by changed signatures, importers affected by removed exports, tests that no longer cover the changed behavior
327
434
  - Every item must reference a specific file and line
328
435
  - Every item must explain **why** it matters — the impact, not just the symptom
329
436
  - Include a brief "What Looks Good" section (2-3 items) — acknowledge strong patterns so they're reinforced. This isn't cheerleading — it's calibrating signal.