@kennethsolomon/shipkit 1.0.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 +321 -0
- package/bin/shipkit.js +146 -0
- package/commands/sk/brainstorm.md +63 -0
- package/commands/sk/branch.md +35 -0
- package/commands/sk/config.md +96 -0
- package/commands/sk/execute-plan.md +85 -0
- package/commands/sk/features.md +238 -0
- package/commands/sk/finish-feature.md +154 -0
- package/commands/sk/help.md +103 -0
- package/commands/sk/hotfix.md +61 -0
- package/commands/sk/plan.md +30 -0
- package/commands/sk/release.md +72 -0
- package/commands/sk/security-check.md +188 -0
- package/commands/sk/set-profile.md +71 -0
- package/commands/sk/status.md +25 -0
- package/commands/sk/update-task.md +35 -0
- package/commands/sk/write-plan.md +72 -0
- package/package.json +23 -0
- package/skills/sk:accessibility/LICENSE.txt +177 -0
- package/skills/sk:accessibility/SKILL.md +150 -0
- package/skills/sk:api-design/LICENSE.txt +177 -0
- package/skills/sk:api-design/SKILL.md +158 -0
- package/skills/sk:brainstorming/SKILL.md +124 -0
- package/skills/sk:debug/SKILL.md +252 -0
- package/skills/sk:debug/debug_conductor.py +177 -0
- package/skills/sk:debug/lib/__init__.py +1 -0
- package/skills/sk:debug/lib/bug_gatherer.py +55 -0
- package/skills/sk:debug/lib/context_reader.py +139 -0
- package/skills/sk:debug/lib/findings_writer.py +76 -0
- package/skills/sk:debug/lib/lessons_writer.py +165 -0
- package/skills/sk:debug/lib/step_runner.py +326 -0
- package/skills/sk:features/SKILL.md +238 -0
- package/skills/sk:frontend-design/LICENSE.txt +177 -0
- package/skills/sk:frontend-design/SKILL.md +191 -0
- package/skills/sk:laravel-init/SKILL.md +37 -0
- package/skills/sk:laravel-new/SKILL.md +68 -0
- package/skills/sk:lint/SKILL.md +113 -0
- package/skills/sk:perf/LICENSE.txt +177 -0
- package/skills/sk:perf/SKILL.md +188 -0
- package/skills/sk:release/SKILL.md +113 -0
- package/skills/sk:release/references/android-checklist.md +269 -0
- package/skills/sk:release/references/ios-checklist.md +339 -0
- package/skills/sk:release/release.sh +378 -0
- package/skills/sk:review/SKILL.md +346 -0
- package/skills/sk:review/references/security-checklist.md +223 -0
- package/skills/sk:schema-migrate/SKILL.md +125 -0
- package/skills/sk:schema-migrate/orms/drizzle.md +546 -0
- package/skills/sk:schema-migrate/orms/laravel.md +367 -0
- package/skills/sk:schema-migrate/orms/prisma.md +357 -0
- package/skills/sk:schema-migrate/orms/rails.md +351 -0
- package/skills/sk:schema-migrate/orms/sqlalchemy.md +385 -0
- package/skills/sk:schema-migrate/references/detection.md +110 -0
- package/skills/sk:setup-claude/SKILL.md +365 -0
- package/skills/sk:setup-claude/references/detection.md +6 -0
- package/skills/sk:setup-claude/references/templates.md +11 -0
- package/skills/sk:setup-claude/scripts/apply_setup_claude.py +443 -0
- package/skills/sk:setup-claude/scripts/detect_arch_changes.py +437 -0
- package/skills/sk:setup-claude/templates/.claude/docs/arch-changelog-guide.md.template +6 -0
- package/skills/sk:setup-claude/templates/.claude/docs/changelog-guide.md.template +12 -0
- package/skills/sk:setup-claude/templates/CHANGELOG.md.template +21 -0
- package/skills/sk:setup-claude/templates/CLAUDE.md.template +299 -0
- package/skills/sk:setup-claude/templates/arch-changelog-guide.md.template +3 -0
- package/skills/sk:setup-claude/templates/changelog-guide.md.template +3 -0
- package/skills/sk:setup-claude/templates/commands/brainstorm.md.template +74 -0
- package/skills/sk:setup-claude/templates/commands/execute-plan.md.template +57 -0
- package/skills/sk:setup-claude/templates/commands/features.md.template +238 -0
- package/skills/sk:setup-claude/templates/commands/finish-feature.md.template +155 -0
- package/skills/sk:setup-claude/templates/commands/plan.md.template +30 -0
- package/skills/sk:setup-claude/templates/commands/re-setup.md.template +38 -0
- package/skills/sk:setup-claude/templates/commands/release.md.template +74 -0
- package/skills/sk:setup-claude/templates/commands/security-check.md.template +172 -0
- package/skills/sk:setup-claude/templates/commands/status.md.template +17 -0
- package/skills/sk:setup-claude/templates/commands/write-plan.md.template +34 -0
- package/skills/sk:setup-claude/templates/finish-feature.md.template +3 -0
- package/skills/sk:setup-claude/templates/plan.md.template +3 -0
- package/skills/sk:setup-claude/templates/status.md.template +3 -0
- package/skills/sk:setup-claude/templates/tasks/findings.md.template +19 -0
- package/skills/sk:setup-claude/templates/tasks/lessons.md.template +26 -0
- package/skills/sk:setup-claude/templates/tasks/progress.md.template +20 -0
- package/skills/sk:setup-claude/templates/tasks/security-findings.md.template +5 -0
- package/skills/sk:setup-claude/templates/tasks/todo.md.template +26 -0
- package/skills/sk:setup-claude/templates/tasks/workflow-status.md.template +31 -0
- package/skills/sk:setup-claude/templates/tasks-findings.md.template +3 -0
- package/skills/sk:setup-claude/templates/tasks-lessons.md.template +3 -0
- package/skills/sk:setup-claude/templates/tasks-progress.md.template +3 -0
- package/skills/sk:setup-claude/templates/tasks-todo.md.template +3 -0
- package/skills/sk:setup-claude/tests/test_apply_setup_claude.py +193 -0
- package/skills/sk:setup-optimizer/SKILL.md +184 -0
- package/skills/sk:setup-optimizer/lib/__init__.py +24 -0
- package/skills/sk:setup-optimizer/lib/detect.py +205 -0
- package/skills/sk:setup-optimizer/lib/discover.py +221 -0
- package/skills/sk:setup-optimizer/lib/enrich.py +163 -0
- package/skills/sk:setup-optimizer/lib/merge.py +277 -0
- package/skills/sk:setup-optimizer/lib/sidecar.py +129 -0
- package/skills/sk:setup-optimizer/optimize_claude.py +174 -0
- package/skills/sk:setup-optimizer/templates/CLAUDE.md.template +105 -0
- package/skills/sk:skill-creator/LICENSE.txt +202 -0
- package/skills/sk:skill-creator/SKILL.md +479 -0
- package/skills/sk:skill-creator/agents/analyzer.md +274 -0
- package/skills/sk:skill-creator/agents/comparator.md +202 -0
- package/skills/sk:skill-creator/agents/grader.md +223 -0
- package/skills/sk:skill-creator/assets/eval_review.html +146 -0
- package/skills/sk:skill-creator/eval-viewer/generate_review.py +471 -0
- package/skills/sk:skill-creator/eval-viewer/viewer.html +1325 -0
- package/skills/sk:skill-creator/references/schemas.md +430 -0
- package/skills/sk:skill-creator/scripts/aggregate_benchmark.py +401 -0
- package/skills/sk:skill-creator/scripts/generate_report.py +326 -0
- package/skills/sk:skill-creator/scripts/improve_description.py +248 -0
- package/skills/sk:skill-creator/scripts/package_skill.py +136 -0
- package/skills/sk:skill-creator/scripts/quick_validate.py +103 -0
- package/skills/sk:skill-creator/scripts/run_eval.py +310 -0
- package/skills/sk:skill-creator/scripts/run_loop.py +332 -0
- package/skills/sk:skill-creator/scripts/utils.py +47 -0
- package/skills/sk:smart-commit/SKILL.md +175 -0
- package/skills/sk:test/SKILL.md +171 -0
- package/skills/sk:write-tests/SKILL.md +195 -0
- package/skills/sk:write-tests/references/patterns.md +209 -0
|
@@ -0,0 +1,346 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: sk:review
|
|
3
|
+
description: "Rigorous self-review of all branch changes across 7 dimensions: correctness, security, performance, reliability, design quality, best practices, and testing. Report-only — no PR creation (that's /sk:finish-feature's job). Use when code is complete and ready for review before merging."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Self-Review
|
|
7
|
+
|
|
8
|
+
## Overview
|
|
9
|
+
|
|
10
|
+
Perform a rigorous, multi-dimensional review of all changes on the current branch. This review aims for the quality bar of a senior engineer at a top-tier tech company — thorough, specific, and honest.
|
|
11
|
+
|
|
12
|
+
**You are the reviewer, not the cheerleader.** Your job is to find problems, not to praise the code. If you find nothing wrong, look harder. Real code almost always has something worth flagging. Think about what could go wrong in production at scale, under adversarial conditions, and over time as the codebase evolves.
|
|
13
|
+
|
|
14
|
+
This is a **report-only** step. If Critical or Warning issues are found, the user loops back to `/sk:debug` → `/sk:smart-commit` → `/sk:review` until the branch is clean. Once clean, the user runs `/sk:finish-feature` to finalize and create the PR.
|
|
15
|
+
|
|
16
|
+
## Allowed Tools
|
|
17
|
+
|
|
18
|
+
Bash, Read, Glob, Grep
|
|
19
|
+
|
|
20
|
+
**Intentionally NO Write or Edit** — this skill is report-only. If issues are found, the user decides what to fix.
|
|
21
|
+
|
|
22
|
+
## Steps
|
|
23
|
+
|
|
24
|
+
You MUST complete these steps in order:
|
|
25
|
+
|
|
26
|
+
### 1. Read Project Context
|
|
27
|
+
|
|
28
|
+
```
|
|
29
|
+
CLAUDE.md — Coding standards, conventions, known patterns
|
|
30
|
+
tasks/lessons.md — Recurrent bug patterns for this project (if exists)
|
|
31
|
+
tasks/security-findings.md — Prior security audit results (if exists)
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Understand what "correct" looks like for this project — the tech stack, conventions, and known pitfalls.
|
|
35
|
+
|
|
36
|
+
If `tasks/lessons.md` exists, read it in full. Use each active lesson's **Bug** field
|
|
37
|
+
as an additional targeted check during analysis — treat each lesson as a known failure
|
|
38
|
+
mode to explicitly scan for across all review dimensions.
|
|
39
|
+
|
|
40
|
+
If `tasks/security-findings.md` exists, read the most recent audit. Use any unresolved
|
|
41
|
+
Critical/High findings as additional targeted checks — verify the current diff doesn't
|
|
42
|
+
reintroduce previously flagged vulnerabilities.
|
|
43
|
+
|
|
44
|
+
### 2. Collect All Changes
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
# Determine base branch
|
|
48
|
+
git symbolic-ref refs/remotes/origin/HEAD 2>/dev/null | sed 's@^refs/remotes/origin/@@' || echo "main"
|
|
49
|
+
|
|
50
|
+
# All changes on this branch
|
|
51
|
+
git diff main..HEAD
|
|
52
|
+
git diff main..HEAD --stat
|
|
53
|
+
git log main..HEAD --oneline
|
|
54
|
+
|
|
55
|
+
# Check for uncommitted changes
|
|
56
|
+
git status --short
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
If there are uncommitted changes, warn:
|
|
60
|
+
> **Warning:** You have uncommitted changes. These will NOT be included in the review. Commit or stash them first.
|
|
61
|
+
|
|
62
|
+
Read the full content of every changed file (not just the diff hunks) to understand context around the changes.
|
|
63
|
+
|
|
64
|
+
### 3. Analyze — Correctness & Bugs
|
|
65
|
+
|
|
66
|
+
The most important dimension. A bug that ships is worse than ugly code that works.
|
|
67
|
+
|
|
68
|
+
**Logic errors:**
|
|
69
|
+
- Wrong operator (`&&` vs `||`, `==` vs `===`, `<` vs `<=`)
|
|
70
|
+
- Inverted conditions, missing negation
|
|
71
|
+
- Missing `break`/`return`/`continue` in control flow
|
|
72
|
+
- Off-by-one errors in loops, array indexing, string slicing, pagination
|
|
73
|
+
|
|
74
|
+
**Null/undefined safety:**
|
|
75
|
+
- Missing null checks before property access
|
|
76
|
+
- Optional chaining needed but not used
|
|
77
|
+
- Nullable values passed where non-null expected
|
|
78
|
+
- Array/object destructuring on potentially undefined values
|
|
79
|
+
|
|
80
|
+
**Async correctness:**
|
|
81
|
+
- Missing `await` on async calls (floating promises)
|
|
82
|
+
- Unhandled promise rejections
|
|
83
|
+
- Race conditions from shared state mutation across async boundaries
|
|
84
|
+
- Async operations in loops without proper batching (`Promise.all` vs sequential)
|
|
85
|
+
|
|
86
|
+
**Data integrity:**
|
|
87
|
+
- Partial updates without transactions (DB operations that should be atomic)
|
|
88
|
+
- Missing rollback on error in multi-step operations
|
|
89
|
+
- Stale closures capturing outdated state
|
|
90
|
+
- Cache invalidation gaps (data updated but cache not cleared)
|
|
91
|
+
|
|
92
|
+
**Edge cases:**
|
|
93
|
+
- Empty arrays/strings/objects not handled
|
|
94
|
+
- Negative numbers, zero, MAX_INT boundaries
|
|
95
|
+
- Unicode/special characters in user input
|
|
96
|
+
- Concurrent access to shared resources
|
|
97
|
+
|
|
98
|
+
### 4. Analyze — Security
|
|
99
|
+
|
|
100
|
+
Load `references/security-checklist.md` and apply its grep patterns systematically. Check for:
|
|
101
|
+
|
|
102
|
+
**Injection (OWASP A03):**
|
|
103
|
+
- SQL, NoSQL, OS command, LDAP, template injection
|
|
104
|
+
- String concatenation/interpolation in queries instead of parameterized queries
|
|
105
|
+
- `eval()`, `exec()`, `Function()` with any dynamic input
|
|
106
|
+
|
|
107
|
+
**Cross-Site Scripting (OWASP A03):**
|
|
108
|
+
- `dangerouslySetInnerHTML`, `innerHTML`, `v-html` without sanitization
|
|
109
|
+
- URL parameters reflected without encoding
|
|
110
|
+
- User content rendered in `href`, `src`, or event handler attributes
|
|
111
|
+
|
|
112
|
+
**Authentication & Authorization (OWASP A01, A07):**
|
|
113
|
+
- Hardcoded secrets, API keys, tokens in source code
|
|
114
|
+
- Missing auth checks on endpoints (especially admin, destructive operations)
|
|
115
|
+
- IDOR — user-controlled IDs accessing other users' resources without ownership verification
|
|
116
|
+
- Weak session management, missing token rotation
|
|
117
|
+
|
|
118
|
+
**Data exposure (OWASP A02):**
|
|
119
|
+
- Credentials, PII, or tokens in logs
|
|
120
|
+
- Stack traces or internal errors leaked to clients
|
|
121
|
+
- Sensitive data in client-side bundles (secret keys in frontend code)
|
|
122
|
+
- Missing encryption for sensitive data at rest
|
|
123
|
+
|
|
124
|
+
**Configuration (OWASP A05):**
|
|
125
|
+
- Missing security headers (CSP, HSTS, X-Frame-Options)
|
|
126
|
+
- Overly permissive CORS (`origin: '*'`)
|
|
127
|
+
- Debug mode enabled in production paths
|
|
128
|
+
- Missing rate limiting on auth/sensitive endpoints
|
|
129
|
+
|
|
130
|
+
### 5. Analyze — Performance
|
|
131
|
+
|
|
132
|
+
Think about what happens at 10x, 100x current scale. Performance bugs are often invisible in development but catastrophic in production.
|
|
133
|
+
|
|
134
|
+
**Database & queries:**
|
|
135
|
+
- N+1 query patterns (fetching related data in a loop instead of a join or batch)
|
|
136
|
+
- Missing database indexes for frequently queried columns
|
|
137
|
+
- `SELECT *` when only specific columns are needed
|
|
138
|
+
- Unbounded queries without `LIMIT`/pagination
|
|
139
|
+
- Missing connection pooling or pool exhaustion risks
|
|
140
|
+
|
|
141
|
+
**Algorithm & data structures:**
|
|
142
|
+
- O(n²) or worse in hot paths (nested loops over large collections)
|
|
143
|
+
- Repeated expensive computations that should be memoized
|
|
144
|
+
- Large data structures held in memory unnecessarily
|
|
145
|
+
- String concatenation in tight loops (use array join/builder)
|
|
146
|
+
|
|
147
|
+
**Frontend performance (React/Next.js):**
|
|
148
|
+
- Unnecessary re-renders (missing `React.memo`, `useMemo`, `useCallback` where beneficial)
|
|
149
|
+
- Large bundle imports (importing entire library when only one function needed)
|
|
150
|
+
- Missing code splitting for heavy routes/components
|
|
151
|
+
- Images without lazy loading or size optimization
|
|
152
|
+
- Blocking operations on the main thread
|
|
153
|
+
|
|
154
|
+
**Network & I/O:**
|
|
155
|
+
- Sequential API calls that could be parallelized
|
|
156
|
+
- Missing request timeouts on external service calls
|
|
157
|
+
- Large payloads without compression or pagination
|
|
158
|
+
- Missing caching headers for static/rarely-changing resources
|
|
159
|
+
|
|
160
|
+
**Memory:**
|
|
161
|
+
- Event listeners added but never removed (memory leaks)
|
|
162
|
+
- Growing arrays/maps without bounds or cleanup
|
|
163
|
+
- Large file processing without streaming
|
|
164
|
+
- Closures capturing large scopes unnecessarily
|
|
165
|
+
|
|
166
|
+
### 6. Analyze — Reliability & Error Handling
|
|
167
|
+
|
|
168
|
+
Production code must handle failure gracefully. The question isn't "does it work?" but "what happens when things go wrong?"
|
|
169
|
+
|
|
170
|
+
**Error handling quality:**
|
|
171
|
+
- Swallowed errors (empty catch blocks, `.catch(() => {})`)
|
|
172
|
+
- Generic catch blocks that hide the actual error type
|
|
173
|
+
- Missing error messages that would help debugging
|
|
174
|
+
- Errors caught but not logged or reported
|
|
175
|
+
- Cleanup logic missing in error paths (connections, file handles, locks)
|
|
176
|
+
|
|
177
|
+
**Graceful degradation:**
|
|
178
|
+
- What happens when an external service is down? Does the whole feature break?
|
|
179
|
+
- Missing fallback behavior for optional dependencies
|
|
180
|
+
- Timeout handling on external calls (HTTP, database, third-party APIs)
|
|
181
|
+
- Missing retry logic with backoff for transient failures
|
|
182
|
+
|
|
183
|
+
**Data validation at boundaries:**
|
|
184
|
+
- API inputs not validated before processing
|
|
185
|
+
- Missing type/schema validation on external data (webhooks, API responses)
|
|
186
|
+
- File uploads without type/size validation
|
|
187
|
+
- Trusting client-side validation without server-side checks
|
|
188
|
+
|
|
189
|
+
**State management:**
|
|
190
|
+
- Inconsistent error states (loading indicator stays forever on error)
|
|
191
|
+
- Missing loading/error/empty states in UI
|
|
192
|
+
- Optimistic updates without rollback on failure
|
|
193
|
+
|
|
194
|
+
### 7. Analyze — Design & Best Practices
|
|
195
|
+
|
|
196
|
+
Think about the next engineer who reads this code. Is the intent clear? Does the design scale with the codebase?
|
|
197
|
+
|
|
198
|
+
**Separation of concerns:**
|
|
199
|
+
- Business logic mixed with presentation/routing/data access
|
|
200
|
+
- Components doing too many things (should be split)
|
|
201
|
+
- Side effects in pure functions or constructors
|
|
202
|
+
|
|
203
|
+
**API design (if endpoints changed):**
|
|
204
|
+
- Breaking changes to existing API contracts without versioning
|
|
205
|
+
- Inconsistent response format across endpoints
|
|
206
|
+
- Missing or inconsistent HTTP status codes
|
|
207
|
+
- Unclear or missing error response schema
|
|
208
|
+
|
|
209
|
+
**Code clarity:**
|
|
210
|
+
- Naming — are names descriptive and consistent with project conventions?
|
|
211
|
+
- Dead code — commented-out code, unused imports, unreachable branches
|
|
212
|
+
- DRY violations — copy-pasted logic that should be extracted
|
|
213
|
+
- Function length — functions over ~50 lines that should be split
|
|
214
|
+
- Deeply nested logic (>3 levels) that should be flattened with early returns
|
|
215
|
+
|
|
216
|
+
**Dependency management:**
|
|
217
|
+
- New dependencies added — are they necessary? Well-maintained? License-compatible?
|
|
218
|
+
- Are there lighter alternatives for heavy imports?
|
|
219
|
+
- Lock file updated when dependencies change?
|
|
220
|
+
|
|
221
|
+
### 8. Analyze — Framework-Specific
|
|
222
|
+
|
|
223
|
+
Based on what the project uses:
|
|
224
|
+
|
|
225
|
+
**React/Next.js:**
|
|
226
|
+
- Missing keys in list rendering (or using array index as key for dynamic lists)
|
|
227
|
+
- `useEffect` dependency arrays — missing deps cause stale data, unnecessary deps cause infinite loops
|
|
228
|
+
- Client vs server component boundaries (Next.js App Router) — using hooks in server components, importing server-only code in client
|
|
229
|
+
- State updates on unmounted components
|
|
230
|
+
- Missing `Suspense` boundaries for async components
|
|
231
|
+
- Missing `ErrorBoundary` for component-level error isolation
|
|
232
|
+
|
|
233
|
+
**Python:**
|
|
234
|
+
- Missing type hints on public functions and API endpoints
|
|
235
|
+
- Mutable default arguments (`def f(items=[])`)
|
|
236
|
+
- Bare `except:` clauses (should catch specific exceptions)
|
|
237
|
+
- Async context managers not used (`async with` for DB connections)
|
|
238
|
+
- Missing `__all__` exports in public modules
|
|
239
|
+
|
|
240
|
+
**Go:**
|
|
241
|
+
- Unchecked error returns (especially on `Close()`, `Write()`, `Flush()`)
|
|
242
|
+
- Deferred function errors ignored (`defer f.Close()` without checking error)
|
|
243
|
+
- Goroutine leaks (goroutines started without cancellation context)
|
|
244
|
+
- Missing mutex for concurrent access to shared state
|
|
245
|
+
- Context not propagated through call chain
|
|
246
|
+
|
|
247
|
+
**Node.js/Express:**
|
|
248
|
+
- Missing error-handling middleware
|
|
249
|
+
- Unhandled promise rejections in route handlers
|
|
250
|
+
- Missing `helmet` or equivalent security headers
|
|
251
|
+
- `req.body` used without validation middleware
|
|
252
|
+
|
|
253
|
+
**General:**
|
|
254
|
+
- Environment-specific code without feature flags or env checks
|
|
255
|
+
- Missing input validation at system boundaries
|
|
256
|
+
- Inconsistent error response format across endpoints
|
|
257
|
+
- Magic numbers/strings that should be named constants
|
|
258
|
+
|
|
259
|
+
### 9. Analyze — Testing (if tests are included in the diff)
|
|
260
|
+
|
|
261
|
+
If the diff includes test files, review them with the same rigor as production code.
|
|
262
|
+
|
|
263
|
+
- **Coverage gaps:** Are all new code paths exercised? Happy path AND error paths?
|
|
264
|
+
- **Edge cases:** Do tests cover boundary conditions, empty inputs, invalid data?
|
|
265
|
+
- **Test isolation:** Do tests depend on external state, order, or other tests?
|
|
266
|
+
- **Assertion quality:** Are assertions specific enough to catch regressions? (not just `toBeTruthy`)
|
|
267
|
+
- **Test naming:** Do test names describe the behavior being verified?
|
|
268
|
+
- **Mocking:** Are mocks minimal and realistic? Over-mocking hides real bugs.
|
|
269
|
+
- **Flakiness risks:** Timing-dependent assertions, network calls, random data without seeding
|
|
270
|
+
|
|
271
|
+
### 10. Generate Review Report
|
|
272
|
+
|
|
273
|
+
Format findings with severity levels and review dimensions:
|
|
274
|
+
|
|
275
|
+
```markdown
|
|
276
|
+
## Code Review: [branch-name]
|
|
277
|
+
|
|
278
|
+
**Changes:** X files changed, +Y/-Z lines
|
|
279
|
+
**Commits:** N commits
|
|
280
|
+
**Review dimensions:** Correctness, Security, Performance, Reliability, Design, Best Practices, Testing
|
|
281
|
+
|
|
282
|
+
### Critical (must fix before merge)
|
|
283
|
+
- **[Correctness]** [FILE:LINE] Description of critical issue
|
|
284
|
+
**Why:** Explanation of impact — what breaks, who is affected, how likely
|
|
285
|
+
- **[Security]** [FILE:LINE] Description
|
|
286
|
+
**Why:** ...
|
|
287
|
+
|
|
288
|
+
### Warning (should fix)
|
|
289
|
+
- **[Performance]** [FILE:LINE] Description
|
|
290
|
+
**Why:** Explanation of risk — what degrades, under what conditions
|
|
291
|
+
- **[Reliability]** [FILE:LINE] Description
|
|
292
|
+
**Why:** ...
|
|
293
|
+
|
|
294
|
+
### Nitpick (consider for next time)
|
|
295
|
+
- **[Design]** [FILE:LINE] Description
|
|
296
|
+
**Why:** Explanation of improvement — readability, maintainability, conventions
|
|
297
|
+
|
|
298
|
+
### What Looks Good
|
|
299
|
+
- Brief acknowledgment of well-done aspects (1-3 bullet points max)
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
**Severity guidelines:**
|
|
303
|
+
- **Critical:** Will cause bugs in production, security vulnerability, data loss, or crash. Must fix.
|
|
304
|
+
- **Warning:** Likely to cause problems at scale, makes future bugs likely, or degrades reliability/performance meaningfully. Should fix.
|
|
305
|
+
- **Nitpick:** Style, conventions, minor improvements. Won't break anything but worth noting.
|
|
306
|
+
|
|
307
|
+
**Rules:**
|
|
308
|
+
- Maximum 20 items total (prioritize by severity, then by category)
|
|
309
|
+
- Every item must tag its review dimension: `[Correctness]`, `[Security]`, `[Performance]`, `[Reliability]`, `[Design]`, `[Best Practices]`, `[Testing]`
|
|
310
|
+
- Every item must reference a specific file and line
|
|
311
|
+
- Every item must explain **why** it matters — the impact, not just the symptom
|
|
312
|
+
- 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.
|
|
313
|
+
- If you genuinely find nothing wrong after all 7 dimensions, say so — but that's rare
|
|
314
|
+
|
|
315
|
+
### 11. Next Steps
|
|
316
|
+
|
|
317
|
+
After presenting the review:
|
|
318
|
+
|
|
319
|
+
If there are **Critical** or **Warning** items:
|
|
320
|
+
> "Review found issues that should be addressed. Fix them with `/sk:debug`, commit with `/sk:smart-commit`, then re-run `/sk:review` to verify."
|
|
321
|
+
|
|
322
|
+
If there are only **Nitpick** items (no Critical/Warning):
|
|
323
|
+
> "Review complete — no critical issues found, but there are some nitpicks. Would you like to fix them now, or proceed to `/sk:finish-feature`?"
|
|
324
|
+
|
|
325
|
+
If the user wants to fix nitpicks, loop back to `/sk:debug` + `/sk:smart-commit` → `/sk:review`.
|
|
326
|
+
|
|
327
|
+
If the review is **completely clean**:
|
|
328
|
+
> "Review complete — no issues found. Run `/sk:finish-feature` to finalize the branch and create a PR."
|
|
329
|
+
|
|
330
|
+
---
|
|
331
|
+
|
|
332
|
+
## Model Routing
|
|
333
|
+
|
|
334
|
+
Read `.shipkit/sk:config.json` from the project root if it exists.
|
|
335
|
+
|
|
336
|
+
- If `model_overrides["sk:review"]` is set, use that model — it takes precedence.
|
|
337
|
+
- Otherwise use the `profile` field. Default: `balanced`.
|
|
338
|
+
|
|
339
|
+
| Profile | Model |
|
|
340
|
+
|---------|-------|
|
|
341
|
+
| `full-sail` | opus (inherit) |
|
|
342
|
+
| `quality` | opus (inherit) |
|
|
343
|
+
| `balanced` | sonnet |
|
|
344
|
+
| `budget` | sonnet |
|
|
345
|
+
|
|
346
|
+
> `opus` = inherit (uses the current session model). When spawning sub-agents via the Agent tool, pass `model: "<resolved-model>"`.
|
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
# Security Checklist (OWASP Top 10 Condensed)
|
|
2
|
+
|
|
3
|
+
Use this checklist when reviewing code changes. For each category, grep for the listed patterns and inspect matches in the diff.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 1. Injection (SQL, NoSQL, Command, Template)
|
|
8
|
+
|
|
9
|
+
**Grep patterns:**
|
|
10
|
+
```
|
|
11
|
+
query( — raw SQL queries
|
|
12
|
+
exec( — command execution
|
|
13
|
+
eval( — code evaluation
|
|
14
|
+
system( — system calls
|
|
15
|
+
subprocess — Python subprocess
|
|
16
|
+
child_process — Node.js child process
|
|
17
|
+
${ — template literals in queries
|
|
18
|
+
f" — Python f-strings in queries
|
|
19
|
+
.format( — Python format strings in queries
|
|
20
|
+
% ( — Python % formatting in queries
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
**What to check:**
|
|
24
|
+
- Are user inputs parameterized/escaped before use in queries?
|
|
25
|
+
- Are shell commands built from user input?
|
|
26
|
+
- Is `eval()` or equivalent used with dynamic input?
|
|
27
|
+
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
## 2. Broken Authentication
|
|
31
|
+
|
|
32
|
+
**Grep patterns:**
|
|
33
|
+
```
|
|
34
|
+
password — hardcoded passwords
|
|
35
|
+
secret — hardcoded secrets
|
|
36
|
+
token — token handling
|
|
37
|
+
jwt — JWT implementation
|
|
38
|
+
session — session management
|
|
39
|
+
cookie — cookie settings
|
|
40
|
+
httpOnly — cookie security flags
|
|
41
|
+
secure: — secure flag on cookies
|
|
42
|
+
sameSite — CSRF protection
|
|
43
|
+
bcrypt — password hashing
|
|
44
|
+
argon2 — password hashing
|
|
45
|
+
md5 — weak hashing (red flag)
|
|
46
|
+
sha1 — weak hashing (red flag)
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
**What to check:**
|
|
50
|
+
- Are passwords hashed with bcrypt/argon2 (not MD5/SHA1)?
|
|
51
|
+
- Do JWTs have expiration and proper validation?
|
|
52
|
+
- Are session cookies httpOnly, secure, sameSite?
|
|
53
|
+
- Is there rate limiting on auth endpoints?
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
## 3. Sensitive Data Exposure
|
|
58
|
+
|
|
59
|
+
**Grep patterns:**
|
|
60
|
+
```
|
|
61
|
+
console.log — logging sensitive data
|
|
62
|
+
print( — logging sensitive data
|
|
63
|
+
logger. — logging sensitive data
|
|
64
|
+
.env — environment file references
|
|
65
|
+
process.env — environment variable access
|
|
66
|
+
os.environ — Python environment access
|
|
67
|
+
API_KEY — API key references
|
|
68
|
+
SECRET — secret references
|
|
69
|
+
PASSWORD — password references
|
|
70
|
+
PRIVATE_KEY — private key references
|
|
71
|
+
credential — credential references
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
**What to check:**
|
|
75
|
+
- Are secrets loaded from environment variables (not hardcoded)?
|
|
76
|
+
- Is sensitive data excluded from logs?
|
|
77
|
+
- Are API keys, tokens, passwords in `.gitignore`?
|
|
78
|
+
- Is PII encrypted at rest and in transit?
|
|
79
|
+
|
|
80
|
+
---
|
|
81
|
+
|
|
82
|
+
## 4. XML External Entities (XXE)
|
|
83
|
+
|
|
84
|
+
**Grep patterns:**
|
|
85
|
+
```
|
|
86
|
+
xml.parse — XML parsing
|
|
87
|
+
DOMParser — browser XML parsing
|
|
88
|
+
lxml — Python XML
|
|
89
|
+
etree — Python XML
|
|
90
|
+
<!ENTITY — XML entity declarations
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
**What to check:**
|
|
94
|
+
- Is external entity processing disabled?
|
|
95
|
+
- Are XML parsers configured securely?
|
|
96
|
+
|
|
97
|
+
---
|
|
98
|
+
|
|
99
|
+
## 5. Broken Access Control
|
|
100
|
+
|
|
101
|
+
**Grep patterns:**
|
|
102
|
+
```
|
|
103
|
+
isAdmin — admin checks
|
|
104
|
+
role — role-based access
|
|
105
|
+
permission — permission checks
|
|
106
|
+
authorize — authorization logic
|
|
107
|
+
@auth — auth decorators
|
|
108
|
+
middleware — middleware (auth)
|
|
109
|
+
req.user — user from request
|
|
110
|
+
currentUser — current user reference
|
|
111
|
+
req.params.id — user-controlled IDs (IDOR risk)
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
**What to check:**
|
|
115
|
+
- Does every endpoint check authorization (not just authentication)?
|
|
116
|
+
- Are object IDs validated against the current user (prevent IDOR)?
|
|
117
|
+
- Is there server-side access control (not just UI hiding)?
|
|
118
|
+
- Are admin routes protected?
|
|
119
|
+
|
|
120
|
+
---
|
|
121
|
+
|
|
122
|
+
## 6. Security Misconfiguration
|
|
123
|
+
|
|
124
|
+
**Grep patterns:**
|
|
125
|
+
```
|
|
126
|
+
CORS — CORS configuration
|
|
127
|
+
Access-Control — CORS headers
|
|
128
|
+
origin: '*' — permissive CORS (red flag)
|
|
129
|
+
debug — debug mode
|
|
130
|
+
DEBUG = True — Python debug mode
|
|
131
|
+
NODE_ENV — environment setting
|
|
132
|
+
helmet — security headers (Node.js)
|
|
133
|
+
X-Frame-Options — clickjacking protection
|
|
134
|
+
Content-Security — CSP headers
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
**What to check:**
|
|
138
|
+
- Is CORS configured to specific origins (not `*`)?
|
|
139
|
+
- Is debug mode off in production?
|
|
140
|
+
- Are security headers set (CSP, X-Frame-Options, HSTS)?
|
|
141
|
+
- Are default credentials changed?
|
|
142
|
+
|
|
143
|
+
---
|
|
144
|
+
|
|
145
|
+
## 7. Cross-Site Scripting (XSS)
|
|
146
|
+
|
|
147
|
+
**Grep patterns:**
|
|
148
|
+
```
|
|
149
|
+
innerHTML — direct HTML insertion
|
|
150
|
+
dangerouslySetInnerHTML — React raw HTML
|
|
151
|
+
v-html — Vue raw HTML
|
|
152
|
+
{!! !!} — Laravel unescaped output
|
|
153
|
+
| safe — Django/Jinja safe filter
|
|
154
|
+
document.write — DOM manipulation
|
|
155
|
+
.html( — jQuery HTML insertion
|
|
156
|
+
DOMPurify — sanitization library (good sign)
|
|
157
|
+
sanitize — sanitization
|
|
158
|
+
escape — escaping
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
**What to check:**
|
|
162
|
+
- Is all user-generated content escaped before rendering?
|
|
163
|
+
- Is `dangerouslySetInnerHTML` / `innerHTML` used with sanitized content?
|
|
164
|
+
- Are URL parameters reflected without encoding?
|
|
165
|
+
|
|
166
|
+
---
|
|
167
|
+
|
|
168
|
+
## 8. Insecure Deserialization
|
|
169
|
+
|
|
170
|
+
**Grep patterns:**
|
|
171
|
+
```
|
|
172
|
+
JSON.parse — JSON deserialization
|
|
173
|
+
pickle — Python pickle (dangerous)
|
|
174
|
+
yaml.load — YAML loading (use safe_load)
|
|
175
|
+
unserialize — PHP deserialization
|
|
176
|
+
Marshal.load — Ruby deserialization
|
|
177
|
+
deserialize — generic deserialization
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
**What to check:**
|
|
181
|
+
- Is `pickle` used with untrusted data? (Critical vulnerability)
|
|
182
|
+
- Is `yaml.load` used instead of `yaml.safe_load`?
|
|
183
|
+
- Is deserialized data validated before use?
|
|
184
|
+
|
|
185
|
+
---
|
|
186
|
+
|
|
187
|
+
## 9. Using Components with Known Vulnerabilities
|
|
188
|
+
|
|
189
|
+
**Check commands:**
|
|
190
|
+
```bash
|
|
191
|
+
npm audit # Node.js
|
|
192
|
+
pip-audit # Python
|
|
193
|
+
bundle audit # Ruby
|
|
194
|
+
composer audit # PHP
|
|
195
|
+
govulncheck ./... # Go
|
|
196
|
+
cargo audit # Rust
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
**What to check:**
|
|
200
|
+
- Are dependencies up to date?
|
|
201
|
+
- Are there known vulnerabilities in direct dependencies?
|
|
202
|
+
- Is there a lockfile committed?
|
|
203
|
+
|
|
204
|
+
---
|
|
205
|
+
|
|
206
|
+
## 10. Insufficient Logging & Monitoring
|
|
207
|
+
|
|
208
|
+
**Grep patterns:**
|
|
209
|
+
```
|
|
210
|
+
catch — error handling (are errors logged?)
|
|
211
|
+
except — Python error handling
|
|
212
|
+
rescue — Ruby error handling
|
|
213
|
+
console.error — client-side error logging
|
|
214
|
+
logger.error — server-side error logging
|
|
215
|
+
winston — logging library
|
|
216
|
+
pino — logging library
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
**What to check:**
|
|
220
|
+
- Are authentication failures logged?
|
|
221
|
+
- Are authorization failures logged?
|
|
222
|
+
- Are errors caught and logged (not swallowed)?
|
|
223
|
+
- Do logs include enough context for debugging without sensitive data?
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: sk:schema-migrate
|
|
3
|
+
description: "/sk:schema-migrate — Multi-ORM Schema Change Analysis"
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# /sk:schema-migrate — Multi-ORM Schema Change Analysis
|
|
7
|
+
|
|
8
|
+
**Invocation:** `/sk:schema-migrate`
|
|
9
|
+
|
|
10
|
+
Analyzes pending schema changes across **5 ORMs** and provides safe, dialect-specific migration
|
|
11
|
+
guidance. Auto-detects the ORM from project files — no configuration needed.
|
|
12
|
+
|
|
13
|
+
**Supported:** Drizzle ORM · Prisma · Laravel + Eloquent · SQLAlchemy + Alembic · Rails + ActiveRecord
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## Overview: 5-Phase Analysis
|
|
18
|
+
|
|
19
|
+
1. **Detect ORM** — Read project files, identify ORM + dialect, load the correct analysis module
|
|
20
|
+
2. **Classify Changes** — Parse diffs, categorize by risk, detect unsafe patterns
|
|
21
|
+
3. **Present Risk Report** — Formatted report with warnings and dialect-specific notes
|
|
22
|
+
4. **Per-Change Migration Plans** — Concrete safe paths for breaking/risky changes
|
|
23
|
+
5. **Command Recommendations** — ORM-specific workflows and commands
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## Phase 1: ORM Detection
|
|
28
|
+
|
|
29
|
+
### Step 1 — Read in Parallel
|
|
30
|
+
|
|
31
|
+
Read the following files simultaneously (read-only, tolerate missing files):
|
|
32
|
+
|
|
33
|
+
```
|
|
34
|
+
drizzle.config.ts prisma/schema.prisma
|
|
35
|
+
drizzle.config.js composer.json
|
|
36
|
+
alembic.ini Gemfile
|
|
37
|
+
package.json supabase/sk:config.toml
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### Step 2 — Apply Priority Rules (first match wins)
|
|
41
|
+
|
|
42
|
+
| Priority | ORM | Definitive Signal | Secondary Check |
|
|
43
|
+
|----------|-----|-------------------|-----------------|
|
|
44
|
+
| 1 | Drizzle | `drizzle.config.ts` or `drizzle.config.js` exists | `package.json` → `drizzle-orm` dep |
|
|
45
|
+
| 2 | Prisma | `prisma/schema.prisma` exists | `package.json` → `@prisma/client` |
|
|
46
|
+
| 3 | Laravel | `composer.json` → `laravel/framework` key | `database/migrations/` exists |
|
|
47
|
+
| 4 | SQLAlchemy | `alembic.ini` exists | `alembic/versions/` exists |
|
|
48
|
+
| 5 | Rails | `Gemfile` → `rails` or `activerecord` gem | `db/migrate/` + `db/schema.rb` |
|
|
49
|
+
|
|
50
|
+
**Supabase overlay (independent check):** If `supabase/sk:config.toml` exists → set `isSupabase = true`. This adds Supabase CLI commands in Phase 5, alongside standard ORM commands.
|
|
51
|
+
|
|
52
|
+
**Ambiguity:** If two definitive signals match (e.g., monorepo), ask the user before proceeding:
|
|
53
|
+
> "Found both `drizzle.config.ts` (Drizzle) and `composer.json` (Laravel). Which ORM should I analyze?"
|
|
54
|
+
|
|
55
|
+
**Unknown:** If no signal matches any ORM, report:
|
|
56
|
+
> "Could not detect ORM. Checked for: drizzle.config.ts, prisma/schema.prisma, composer.json (laravel/framework), alembic.ini, Gemfile (rails/activerecord). Please specify which ORM this project uses."
|
|
57
|
+
|
|
58
|
+
For more detailed detection heuristics and dialect rules, see `references/detection.md`.
|
|
59
|
+
|
|
60
|
+
### Step 3 — Report Detection Result
|
|
61
|
+
|
|
62
|
+
```
|
|
63
|
+
Detected: [ORM] ([dialect]) — loading orms/[orm].md
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
Examples:
|
|
67
|
+
- `Detected: Drizzle ORM (SQLite) — loading orms/drizzle.md`
|
|
68
|
+
- `Detected: Prisma (PostgreSQL + Supabase) — loading orms/prisma.md`
|
|
69
|
+
- `Detected: Laravel + Eloquent (MySQL) — loading orms/laravel.md`
|
|
70
|
+
- `Detected: SQLAlchemy + Alembic (PostgreSQL) — loading orms/sqlalchemy.md`
|
|
71
|
+
- `Detected: Rails + ActiveRecord (PostgreSQL) — loading orms/rails.md`
|
|
72
|
+
|
|
73
|
+
### Step 4 — Load and Execute ORM Module
|
|
74
|
+
|
|
75
|
+
Read the appropriate file from `orms/` and execute **Phases 2 through 5** as defined there:
|
|
76
|
+
|
|
77
|
+
| ORM | File |
|
|
78
|
+
|-----|------|
|
|
79
|
+
| Drizzle | `orms/drizzle.md` |
|
|
80
|
+
| Prisma | `orms/prisma.md` |
|
|
81
|
+
| Laravel | `orms/laravel.md` |
|
|
82
|
+
| SQLAlchemy | `orms/sqlalchemy.md` |
|
|
83
|
+
| Rails | `orms/rails.md` |
|
|
84
|
+
|
|
85
|
+
---
|
|
86
|
+
|
|
87
|
+
## Safety Contract
|
|
88
|
+
|
|
89
|
+
✅ **Read-only analysis** — this skill never modifies files, schemas, or databases
|
|
90
|
+
|
|
91
|
+
✅ **No auto-execution** — never runs `db:push`, `db:generate`, `db:migrate`, `prisma migrate`, `php artisan migrate`, `alembic upgrade`, `rails db:migrate`, or `supabase push` automatically
|
|
92
|
+
|
|
93
|
+
✅ **User confirms** — user must read and understand the risk report before proceeding
|
|
94
|
+
|
|
95
|
+
✅ **ORM + dialect-specific guidance** — recommendations are tailored to the detected stack
|
|
96
|
+
|
|
97
|
+
✅ **Data safety first** — flags orphan rows, duplicates, NULL violations, and breaking changes before they cause data loss
|
|
98
|
+
|
|
99
|
+
---
|
|
100
|
+
|
|
101
|
+
## Known Limitations
|
|
102
|
+
|
|
103
|
+
1. **MongoDB (Prisma):** Prisma + MongoDB does not use migration files — schema-migrate reports this and stops analysis
|
|
104
|
+
2. **Autogenerate blindspots (SQLAlchemy):** Alembic cannot detect column renames, check constraints, or server defaults from model files alone
|
|
105
|
+
3. **Remote schema sync:** Supabase remote schema comparison requires a valid `SUPABASE_ACCESS_TOKEN` — falls back to local-only analysis if unavailable
|
|
106
|
+
4. **Custom SQL migrations:** Manually written SQL migration files (outside ORM conventions) cannot be fully parsed — user must verify independently
|
|
107
|
+
5. **Type cast validation:** Cannot predict if a type cast will succeed at runtime — always recommend staging test first
|
|
108
|
+
|
|
109
|
+
---
|
|
110
|
+
|
|
111
|
+
## Model Routing
|
|
112
|
+
|
|
113
|
+
Read `.shipkit/sk:config.json` from the project root if it exists.
|
|
114
|
+
|
|
115
|
+
- If `model_overrides["sk:schema-migrate"]` is set, use that model — it takes precedence.
|
|
116
|
+
- Otherwise use the `profile` field. Default: `balanced`.
|
|
117
|
+
|
|
118
|
+
| Profile | Model |
|
|
119
|
+
|---------|-------|
|
|
120
|
+
| `full-sail` | opus (inherit) |
|
|
121
|
+
| `quality` | sonnet |
|
|
122
|
+
| `balanced` | sonnet |
|
|
123
|
+
| `budget` | haiku |
|
|
124
|
+
|
|
125
|
+
> `opus` = inherit (uses the current session model). When spawning sub-agents via the Agent tool, pass `model: "<resolved-model>"`.
|