@softspark/ai-toolkit 2.4.1 → 2.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/AGENTS.md +33 -20
  2. package/CHANGELOG.md +57 -0
  3. package/README.md +29 -13
  4. package/app/.claude-plugin/plugin.json +3 -2
  5. package/app/ARCHITECTURE.md +11 -0
  6. package/app/agents/code-reviewer.md +6 -7
  7. package/app/agents/frontend-specialist.md +33 -2
  8. package/app/agents/seo-specialist.md +1 -1
  9. package/app/personas/frontend-lead.md +48 -5
  10. package/app/skills/a11y-validate/SKILL.md +377 -0
  11. package/app/skills/a11y-validate/reference/aria-patterns.md +259 -0
  12. package/app/skills/a11y-validate/reference/eaa-compliance.md +252 -0
  13. package/app/skills/a11y-validate/reference/mobile-eaa.md +329 -0
  14. package/app/skills/a11y-validate/reference/wcag-2-1-aa.md +285 -0
  15. package/app/skills/a11y-validate/reference/wcag-2-2-aa.md +221 -0
  16. package/app/skills/a11y-validate/scripts/a11y-scanner.py +639 -0
  17. package/app/skills/clean-code/reference/python.md +3 -3
  18. package/app/skills/design-engineering/SKILL.md +2 -5
  19. package/app/skills/hipaa-validate/SKILL.md +39 -23
  20. package/app/skills/hipaa-validate/scripts/hipaa_scan.py +64 -7
  21. package/app/skills/review/SKILL.md +30 -6
  22. package/app/skills/seo-validate/SKILL.md +460 -0
  23. package/app/skills/seo-validate/reference/core-web-vitals.md +445 -0
  24. package/app/skills/seo-validate/reference/geo-aeo-patterns.md +259 -0
  25. package/app/skills/seo-validate/reference/geo-guidelines.md +248 -0
  26. package/app/skills/seo-validate/reference/schema-types.md +465 -0
  27. package/app/skills/seo-validate/reference/spa-ssg-patterns.md +351 -0
  28. package/app/skills/seo-validate/reference/w3c-guidelines.md +289 -0
  29. package/app/skills/seo-validate/scripts/seo-scanner.py +549 -0
  30. package/bin/ai-toolkit.js +24 -9
  31. package/kb/reference/architecture-overview.md +1 -1
  32. package/kb/reference/comparison.md +1 -1
  33. package/kb/reference/opencode-compatibility.md +161 -0
  34. package/kb/reference/skills-catalog.md +3 -1
  35. package/llms-full.txt +177 -6
  36. package/llms.txt +1 -0
  37. package/manifest.json +3 -3
  38. package/package.json +6 -3
  39. package/scripts/config_cli.py +4 -10
  40. package/scripts/doctor.py +3 -3
  41. package/scripts/generate_opencode.py +117 -0
  42. package/scripts/generate_opencode_agents.py +126 -0
  43. package/scripts/generate_opencode_commands.py +158 -0
  44. package/scripts/generate_opencode_json.py +133 -0
  45. package/scripts/generate_opencode_plugin.py +169 -0
  46. package/scripts/install_steps/ai_tools.py +117 -1
  47. package/scripts/install_steps/install_state.py +1 -1
  48. package/scripts/plugin.py +1 -1
@@ -100,7 +100,11 @@ Scan the full project for log/print statements that reference PHI keywords.
100
100
  | `console\.\w+\(.*req\.body` | WARN | JS/TS | Raw request body may contain PHI |
101
101
  | `JSON\.stringify\(.*patient` | WARN | JS/TS | Full patient object serialization |
102
102
  | `print\(.*\b(patient\|ssn\|social.security)` | HIGH | Python | PHI in print statements |
103
- | `logging\.\w+\(.*\b(patient\|ssn\|mrn\|dob)` | HIGH | Python | PHI fields in logger calls |
103
+ | `(logging\|logger\|pprint)\.\w+\(.*\b(patient\|ssn\|mrn\|dob)` | HIGH | Python | PHI in logger/named logger/pprint output |
104
+ | `print\(.*request\.(data\|json\|form\|POST\|body)` | WARN | Python | Raw request body may contain PHI (Django/Flask/FastAPI) |
105
+ | `(logging\|logger)\.\w+\(.*request\.(data\|json\|form\|POST\|body)` | WARN | Python | Raw request body in logger |
106
+ | `\brepr\(.*\b(patient\|ssn\|mrn)` | WARN | Python | repr() may expose PHI fields |
107
+ | `\bvars\(.*\b(patient\|ssn\|mrn)` | WARN | Python | vars() dumps all PHI fields |
104
108
  | `fmt\.Print.*\b(patient\|ssn\|mrn)` | HIGH | Go | PHI in fmt output |
105
109
  | `log\.\w+\(.*\b(patient\|ssn\|mrn)` | HIGH | Go/Any | PHI in log calls |
106
110
  | `System\.out\.print.*\b(patient\|ssn\|mrn)` | HIGH | Java | PHI in stdout |
@@ -110,7 +114,7 @@ Scan the full project for log/print statements that reference PHI keywords.
110
114
  | `Console\.Write.*\b(patient\|ssn\|mrn)` | HIGH | C# | PHI in Console output |
111
115
  | `_logger\.\w+\(.*\b(patient\|ssn\|mrn\|dob)` | HIGH | C# | PHI in ILogger calls |
112
116
 
113
- > **Language coverage note**: JS/TS patterns are the most comprehensive. Go, Ruby, and Java have baseline coverage for common log patterns. Contributions for additional language-specific patterns are welcome.
117
+ > **Language coverage note**: JS/TS and Python patterns are the most comprehensive. Go, Ruby, and Java have baseline coverage for common log patterns. Contributions for additional language-specific patterns are welcome.
114
118
 
115
119
  **Minimum Necessary violations** (§164.502(b)):
116
120
 
@@ -135,7 +139,7 @@ Scan the full project for files that handle PHI data operations but lack audit-r
135
139
 
136
140
  **PHI route file definition**: A file qualifies if it contains BOTH:
137
141
  1. A healthcare keyword from Step 0 (`patient`, `diagnosis`, `medication`, etc.)
138
- 2. A data operation pattern: `router`, `app.get`, `app.post`, `app.put`, `app.delete`, `@RequestMapping`, `@GetMapping`, `@PostMapping`, `@PutMapping`, `@DeleteMapping`, `Model.find`, `Model.save`, `Model.update`, `db.query`, `db.execute`, `cursor.execute`, `repository.`, `findBy`, `save(`, `delete(`
142
+ 2. A data operation pattern: `router`, `app.get`, `app.post`, `app.put`, `app.delete`, `@RequestMapping`, `@GetMapping`, `@PostMapping`, `@PutMapping`, `@DeleteMapping`, `Model.find`, `Model.save`, `Model.update`, `db.query`, `db.execute`, `cursor.execute`, `repository.`, `findBy`, `save(`, `delete(`, `@app.route`, `@blueprint.route`, `@api_view`, `ViewSet`, `APIView`, `\bsession.(query|add|execute|delete|merge)\b` (word-anchored — SQLAlchemy only, avoids matching Express `req.session.save`)
139
143
 
140
144
  Files with a healthcare keyword but no data operation pattern are excluded.
141
145
 
@@ -158,13 +162,20 @@ See: [reference/hipaa-rules.md](reference/hipaa-rules.md) §164.312(b) for audit
158
162
 
159
163
  *Context-gated: scans PHI-adjacent files only.*
160
164
 
161
- | Pattern | Severity | Description |
162
- |---------|----------|-------------|
163
- | `http://` in API calls (not `localhost`/`127.0.0.1`) | HIGH | §164.312(e)(1) requires encryption in transit |
164
- | Missing TLS/SSL config in database connections | HIGH | Database connections must be encrypted |
165
- | `rejectUnauthorized:\s*false` | HIGH | TLS verification disabled |
166
- | `ws://` (WebSocket without TLS) | WARN | Unencrypted WebSocket may carry PHI |
167
- | Email sending without TLS config | WARN | PHI in email must use TLS |
165
+ | Pattern | Severity | Language | Description |
166
+ |---------|----------|----------|-------------|
167
+ | `http://` in API calls (not `localhost`/`127.0.0.1`) | HIGH | Any | §164.312(e)(1) requires encryption in transit |
168
+ | Missing TLS/SSL config in database connections | HIGH | Any | Database connections must be encrypted |
169
+ | `rejectUnauthorized:\s*false` | HIGH | Any | TLS verification disabled |
170
+ | `ws://` (WebSocket without TLS) | WARN | Any | Unencrypted WebSocket may carry PHI |
171
+ | `verify\s*=\s*False` | HIGH | Python | TLS verification disabled (requests/httpx) |
172
+ | `InsecureRequestWarning` | WARN | Python | TLS warning suppressed |
173
+ | `[,(]\s*ssl\s*=\s*False\b` | HIGH | Python | SSL disabled in connector call (anchored to arg position to avoid matching `is_ssl_enabled = False`) |
174
+ | `ssl\.CERT_NONE` | HIGH | Python | TLS certificate verification disabled (anchored to `ssl.` module) |
175
+ | `check_hostname\s*=\s*False` | HIGH | Python | TLS hostname verification disabled |
176
+ | `urllib3\.disable_warnings` | WARN | Python | TLS warnings suppressed (urllib3) |
177
+ | `SECURE_SSL_REDIRECT\s*=\s*False` | WARN | Python | Django HTTPS redirect disabled (commonly False in dev settings — verify production config) |
178
+ | `NODE_TLS_REJECT_UNAUTHORIZED.*0` | HIGH | JS/TS | TLS rejection disabled globally |
168
179
 
169
180
  See: [reference/hipaa-rules.md](reference/hipaa-rules.md) §164.312(e)(1) for transmission security requirements.
170
181
 
@@ -194,13 +205,16 @@ See: [reference/phi-identifiers.md](reference/phi-identifiers.md) for the full l
194
205
 
195
206
  *Context-gated: scans PHI-adjacent files only. Heuristic — flags potential gaps.*
196
207
 
197
- **Auth keywords** (co-occurrence check): `auth`, `authenticate`, `requireAuth`, `isAuthenticated`, `protect`, `guard`, `Authorize`, `login_required`, `Permission`
208
+ **Auth keywords** (co-occurrence check): `auth`, `authenticate`, `requireAuth`, `isAuthenticated`, `protect`, `guard`, `Authorize`, `login_required`, `Permission`, `permission_required`, `LoginRequiredMixin`, `PermissionRequiredMixin`, `IsAuthenticated`, `Depends`, `Security`
198
209
 
199
- | Pattern | Severity | Description |
200
- |---------|----------|-------------|
201
- | PHI route file without any auth keywords in same file | WARN | POTENTIAL access control gap — verify auth middleware covers these routes (§164.312(d)) |
202
- | `Access-Control-Allow-Origin:\s*\*` or `origin:\s*(true\|\*)` in PHI-adjacent files | HIGH | Unrestricted cross-origin access to PHI endpoints |
203
- | Routes marked `public`, `noAuth`, `anonymous` exposing PHI keywords | HIGH | PHI must require authentication |
210
+ **Data operation patterns** (Python frameworks): `@app.route`, `@blueprint.route`, `@api_view`, `ViewSet`, `APIView`, `cursor.execute`, `\bsession.(query|execute)\b` (word-anchored — SQLAlchemy only)
211
+
212
+ | Pattern | Severity | Language | Description |
213
+ |---------|----------|----------|-------------|
214
+ | PHI route file without any auth keywords in same file | WARN | Any | POTENTIAL access control gap — verify auth middleware covers these routes (§164.312(d)) |
215
+ | `Access-Control-Allow-Origin:\s*\*` or `origin:\s*(true\|\*)` in PHI-adjacent files | HIGH | Any | Unrestricted cross-origin access to PHI endpoints |
216
+ | Routes marked `public`, `noAuth`, `anonymous` exposing PHI keywords | HIGH | Any | PHI must require authentication |
217
+ | `permission_classes\s*=.*AllowAny` | WARN | Python | DRF AllowAny — verify no PHI exposed |
204
218
 
205
219
  > **Note**: Auth middleware is commonly applied at router-level or app-level. The co-occurrence heuristic checks the same file only. False positives expected when auth is configured globally. Use `.hipaaignore` to suppress.
206
220
 
@@ -253,13 +267,15 @@ Instead of per-finding rows, emit a single **BAA Verification Checklist** in the
253
267
 
254
268
  Detects PHI storage patterns without encryption references. Per §164.312(a)(2)(iv), ePHI must be encrypted when stored.
255
269
 
256
- | Pattern | Severity | Description |
257
- |---------|----------|-------------|
258
- | `encrypt\s*[:=]\s*false` in database config files | HIGH | §164.312(a)(2)(iv) — Encryption explicitly disabled |
259
- | File write operations (`writeFile`, `fs.write`, `open(.*w`, `File.Create`) in PHI-adjacent code without encryption references | WARN | PHI written to disk may lack encryption at rest |
260
- | Database connection without `ssl`, `encrypt`, or `tls` keywords in PHI-adjacent config | WARN | Database storing PHI should enforce encrypted connections |
261
- | `localStorage.setItem` or `sessionStorage.setItem` with PHI keywords | HIGH | Browser storage is unencrypted — PHI must not be stored client-side without encryption |
262
- | `SharedPreferences` or `UserDefaults` with PHI keywords | HIGH | Mobile local storage is unencrypted by default |
270
+ | Pattern | Severity | Language | Description |
271
+ |---------|----------|----------|-------------|
272
+ | `encrypt\s*[:=]\s*false` in database config files | HIGH | Any | §164.312(a)(2)(iv) — Encryption explicitly disabled |
273
+ | File write operations (`writeFile`, `fs.write`, `open(.*w`, `File.Create`) in PHI-adjacent code without encryption references | WARN | Any | PHI written to disk may lack encryption at rest |
274
+ | Database connection without `ssl`, `encrypt`, or `tls` keywords in PHI-adjacent config | WARN | Any | Database storing PHI should enforce encrypted connections |
275
+ | `localStorage.setItem` or `sessionStorage.setItem` with PHI keywords | HIGH | JS/TS | Browser storage is unencrypted — PHI must not be stored client-side without encryption |
276
+ | `SharedPreferences` or `UserDefaults` with PHI keywords | HIGH | Java/Any | Mobile local storage is unencrypted by default |
277
+ | `pickle\.(dump\|dumps)\(` with PHI keywords | HIGH | Python | pickle serialization is unencrypted — PHI must be encrypted at rest |
278
+ | `shelve\.open\(` with PHI keywords | HIGH | Python | shelve storage is unencrypted — PHI must be encrypted at rest |
263
279
 
264
280
  See: [reference/hipaa-rules.md](reference/hipaa-rules.md) §164.312(a)(2)(iv) for encryption requirements.
265
281
 
@@ -62,6 +62,19 @@ LANGUAGE_INDICATORS = {
62
62
  "*.csproj": "csharp",
63
63
  }
64
64
 
65
+ # Map language tag to file extensions. Used by scan_patterns to avoid
66
+ # cross-language double-flagging when the same regex is valid for more
67
+ # than one language (e.g. `logger.info(...)` in Python vs Java).
68
+ LANG_EXTENSIONS = {
69
+ "js": {".js", ".jsx", ".mjs", ".cjs", ".ts", ".tsx"},
70
+ "ts": {".ts", ".tsx"},
71
+ "python": {".py", ".pyi"},
72
+ "java": {".java", ".kt", ".scala"},
73
+ "go": {".go"},
74
+ "ruby": {".rb", ".erb"},
75
+ "csharp": {".cs"},
76
+ }
77
+
65
78
  # ---------------------------------------------------------------------------
66
79
  # Pattern definitions per category
67
80
  # ---------------------------------------------------------------------------
@@ -72,9 +85,15 @@ CAT1_PATTERNS = [
72
85
  (r"console\.log\(.*patient", "HIGH", "js", "Patient data in console.log", "1"),
73
86
  (r"console\.\w+\(.*req\.body", "WARN", "js", "Raw request body may contain PHI", "1"),
74
87
  (r"JSON\.stringify\(.*patient", "WARN", "js", "Full patient object serialization", "1"),
75
- # Python
88
+ # Python (logger pattern covers logging.*, logger.*, and pprint.* in one regex
89
+ # to avoid overlapping findings and double-flag with the Java `logger.` pattern.
90
+ # Language is enforced by file extension via LANG_EXTENSIONS.)
76
91
  (r"print\(.*\b(patient|ssn|social.security)", "HIGH", "python", "PHI in print statement", "1"),
77
- (r"logging\.\w+\(.*\b(patient|ssn|mrn|dob)", "HIGH", "python", "PHI fields in logger", "1"),
92
+ (r"(logging|logger|pprint)\.\w+\(.*\b(patient|ssn|mrn|dob)", "HIGH", "python", "PHI in Python logger/pprint", "1"),
93
+ (r"print\(.*request\.(data|json|form|POST|body)", "WARN", "python", "Raw request body may contain PHI", "1"),
94
+ (r"(logging|logger)\.\w+\(.*request\.(data|json|form|POST|body)", "WARN", "python", "Raw request body in logger", "1"),
95
+ (r"\brepr\(.*\b(patient|ssn|mrn)", "WARN", "python", "repr() may expose PHI fields", "1"),
96
+ (r"\bvars\(.*\b(patient|ssn|mrn)", "WARN", "python", "vars() dumps all PHI fields", "1"),
78
97
  # Go
79
98
  (r"fmt\.Print.*\b(patient|ssn|mrn)", "HIGH", "go", "PHI in fmt output", "1"),
80
99
  (r"log\.\w+\(.*\b(patient|ssn|mrn)", "HIGH", "go", "PHI in log call", "1"),
@@ -101,6 +120,14 @@ CAT3_PATTERNS = [
101
120
  (r"NODE_TLS_REJECT_UNAUTHORIZED.*0", "HIGH", "js", "TLS rejection disabled globally", "3"),
102
121
  (r"verify\s*=\s*False", "HIGH", "python", "TLS verification disabled (requests)", "3"),
103
122
  (r"InsecureRequestWarning", "WARN", "python", "TLS warning suppressed", "3"),
123
+ # Anchored to argument position ([, or () to avoid matching `is_ssl_enabled = False`
124
+ (r"[,(]\s*ssl\s*=\s*False\b", "HIGH", "python", "SSL disabled in connector call", "3"),
125
+ (r"ssl\.CERT_NONE", "HIGH", "python", "TLS certificate verification disabled (ssl.CERT_NONE)", "3"),
126
+ (r"check_hostname\s*=\s*False", "HIGH", "python", "TLS hostname verification disabled", "3"),
127
+ (r"urllib3\.disable_warnings", "WARN", "python", "TLS warnings suppressed (urllib3)", "3"),
128
+ # WARN (not HIGH): commonly False in DEBUG/dev settings — compliance reviewer
129
+ # must confirm production config. Avoids flooding every Django project.
130
+ (r"SECURE_SSL_REDIRECT\s*=\s*False", "WARN", "python", "Django HTTPS redirect disabled (verify prod config)", "3"),
104
131
  ]
105
132
 
106
133
  # Category 4: Hardcoded PHI/Test Data
@@ -119,6 +146,9 @@ CAT7_PATTERNS = [
119
146
  (r"sessionStorage\.setItem\(.*\b(patient|ssn|mrn|phi|health)", "HIGH", "js", "PHI in session storage", "7"),
120
147
  (r"SharedPreferences.*\b(patient|ssn|mrn|phi|health)", "HIGH", "java", "PHI in unencrypted mobile storage", "7"),
121
148
  (r"UserDefaults.*\b(patient|ssn|mrn|phi|health)", "HIGH", "any", "PHI in unencrypted UserDefaults", "7"),
149
+ # Python
150
+ (r"pickle\.(dump|dumps)\(.*\b(patient|phi|health|ssn|mrn)", "HIGH", "python", "PHI in unencrypted pickle", "7"),
151
+ (r"shelve\.open\(.*\b(patient|phi|health|ssn|mrn)", "HIGH", "python", "PHI in unencrypted shelve storage", "7"),
122
152
  ]
123
153
 
124
154
  # Category 8: PHI Temp File Exposure
@@ -132,12 +162,17 @@ CAT8_PATTERNS = [
132
162
  CAT5_AUTH_KEYWORDS = [
133
163
  "auth", "authenticate", "requireAuth", "isAuthenticated",
134
164
  "protect", "guard", "Authorize", "login_required", "Permission",
165
+ # Python frameworks
166
+ "permission_required", "LoginRequiredMixin", "PermissionRequiredMixin",
167
+ "IsAuthenticated", "Depends", "Security",
135
168
  ]
136
169
 
137
170
  CAT5_PATTERNS = [
138
171
  (r"Access-Control-Allow-Origin:\s*\*", "HIGH", "any", "Unrestricted CORS on PHI endpoint", "5"),
139
172
  (r"origin:\s*(true|\*)", "HIGH", "any", "Unrestricted CORS origin", "5"),
140
173
  (r"\b(public|noAuth|anonymous)\b.*\b(patient|phi|health|medical)", "HIGH", "any", "Public route exposing PHI", "5"),
174
+ # Python
175
+ (r"permission_classes\s*=.*AllowAny", "WARN", "python", "DRF AllowAny — verify no PHI exposed", "5"),
141
176
  ]
142
177
 
143
178
  # HIPAA rule citations per category
@@ -284,7 +319,15 @@ def detect_languages(root: Path) -> set[str]:
284
319
 
285
320
  def scan_patterns(files: list[Path], patterns: list[tuple],
286
321
  languages: set[str], root: Path) -> list[dict]:
287
- """Run regex patterns against files, return findings."""
322
+ """Run regex patterns against files, return findings.
323
+
324
+ Language-tagged patterns fire only when:
325
+ 1. The project's detected languages include the tag, AND
326
+ 2. The file's extension matches that language (per LANG_EXTENSIONS).
327
+
328
+ This prevents cross-language double-flagging when two languages share
329
+ a regex (e.g. `logger.info(patient)` valid in both Python and Java).
330
+ """
288
331
  findings = []
289
332
  for fpath in files:
290
333
  try:
@@ -292,11 +335,16 @@ def scan_patterns(files: list[Path], patterns: list[tuple],
292
335
  except (OSError, PermissionError):
293
336
  continue
294
337
  rel = str(fpath.relative_to(root))
338
+ ext = fpath.suffix.lower()
295
339
 
296
340
  for line_num, line in enumerate(lines, 1):
297
341
  for pat, severity, lang, desc, cat in patterns:
298
- if lang != "any" and lang not in languages:
299
- continue
342
+ if lang != "any":
343
+ if lang not in languages:
344
+ continue
345
+ exts = LANG_EXTENSIONS.get(lang)
346
+ if exts and ext not in exts:
347
+ continue
300
348
  if re.search(pat, line, re.IGNORECASE):
301
349
  findings.append({
302
350
  "file": rel,
@@ -333,7 +381,12 @@ def scan_cat2_audit_gaps(phi_files: list[Path], root: Path) -> list[dict]:
333
381
  r"@(Request|Get|Post|Put|Delete)Mapping|"
334
382
  r"Model\.(find|save|update|delete)|"
335
383
  r"db\.(query|execute)|cursor\.execute|"
336
- r"repository\.|findBy|\.save\(|\.delete\()",
384
+ r"repository\.|findBy|\.save\(|\.delete\(|"
385
+ # Python frameworks (SQLAlchemy session methods only — avoids matching
386
+ # Express req.session.save/destroy which use different method names)
387
+ r"@app\.route|@blueprint\.route|"
388
+ r"@api_view|ViewSet|APIView|"
389
+ r"\bsession\.(query|add|execute|delete|merge)\b)",
337
390
  re.IGNORECASE,
338
391
  )
339
392
  audit_kw = re.compile(
@@ -382,7 +435,11 @@ def scan_cat5_access_gaps(phi_files: list[Path], languages: set[str],
382
435
  )
383
436
  data_ops = re.compile(
384
437
  r"(router|app\.(get|post|put|delete)|"
385
- r"@(Request|Get|Post|Put|Delete)Mapping)",
438
+ r"@(Request|Get|Post|Put|Delete)Mapping|"
439
+ # Python frameworks (session methods anchored to SQLAlchemy)
440
+ r"@app\.route|@blueprint\.route|"
441
+ r"@api_view|ViewSet|APIView|"
442
+ r"cursor\.execute|\bsession\.(query|execute)\b)",
386
443
  re.IGNORECASE,
387
444
  )
388
445
 
@@ -24,7 +24,7 @@ Reviews code changes for quality and issues.
24
24
  Before starting manual review, run the diff analyzer script to get a structured risk assessment:
25
25
 
26
26
  ```bash
27
- python3 "$(dirname "$0")/scripts/diff-analyzer.py" [base_branch]
27
+ python3 ${CLAUDE_SKILL_DIR}/scripts/diff-analyzer.py [base_branch]
28
28
  # Default base branch: main
29
29
  # Example: python3 scripts/diff-analyzer.py develop
30
30
  ```
@@ -90,11 +90,35 @@ After all reviewers complete:
90
90
  - [ ] No code duplication
91
91
  - [ ] Appropriate abstractions
92
92
 
93
- ### Security
94
- - [ ] No hardcoded secrets
95
- - [ ] Input validation
96
- - [ ] Proper auth checks
97
- - [ ] SQL injection prevention
93
+ ### Security (OWASP Top 10)
94
+ - [ ] A01: Proper auth/authorization on all endpoints
95
+ - [ ] A02: No weak crypto, HTTPS for external comms
96
+ - [ ] A03: Input validation, parameterized queries, output encoding (XSS)
97
+ - [ ] A04: Threat model assumptions documented for new features
98
+ - [ ] A05: No debug mode, default credentials, or verbose errors in prod config
99
+ - [ ] A06: Dependencies checked for known CVEs
100
+ - [ ] A07: No hardcoded secrets, session management correct
101
+ - [ ] A08: Integrity checks on deserialized data, CI/CD pipeline safety
102
+ - [ ] A09: Security-relevant events logged (without PII)
103
+ - [ ] A10: External URL handling validates scheme/host (SSRF prevention)
104
+
105
+ ### API / Contract Changes
106
+ - [ ] Backward compatibility preserved (no silent breaking changes)
107
+ - [ ] API versioning updated if contract changed
108
+ - [ ] Schema validation on request/response
109
+ - [ ] Error responses follow project convention
110
+
111
+ ### Concurrency / Async
112
+ - [ ] Shared mutable state protected (locks, atomics, channels)
113
+ - [ ] No fire-and-forget promises without error handling
114
+ - [ ] Database transactions scoped correctly (no long-held locks)
115
+ - [ ] Race condition risk assessed for concurrent access paths
116
+
117
+ ### Migrations / Schema Changes
118
+ - [ ] Migration is reversible (has rollback path)
119
+ - [ ] No table locks on large tables during peak hours
120
+ - [ ] Data backfill handles NULL/missing values
121
+ - [ ] Indexes added for new query patterns
98
122
 
99
123
  ### Performance
100
124
  - [ ] No N+1 queries