@rune-kit/rune 2.3.3 → 2.6.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.
Files changed (77) hide show
  1. package/README.md +86 -17
  2. package/compiler/__tests__/pack-split.test.js +141 -1
  3. package/compiler/__tests__/parser.test.js +147 -55
  4. package/compiler/__tests__/scripts-bundling.test.js +283 -0
  5. package/compiler/__tests__/skill-index.test.js +218 -0
  6. package/compiler/__tests__/tier-override.test.js +41 -0
  7. package/compiler/adapters/antigravity.js +71 -53
  8. package/compiler/adapters/codex.js +4 -0
  9. package/compiler/adapters/cursor.js +4 -0
  10. package/compiler/adapters/generic.js +4 -0
  11. package/compiler/adapters/openclaw.js +4 -0
  12. package/compiler/adapters/opencode.js +4 -0
  13. package/compiler/adapters/windsurf.js +4 -0
  14. package/compiler/bin/rune.js +355 -355
  15. package/compiler/doctor.js +11 -1
  16. package/compiler/emitter.js +678 -386
  17. package/compiler/parser.js +267 -247
  18. package/compiler/transforms/scripts-path.js +18 -0
  19. package/extensions/zalo/PACK.md +20 -1
  20. package/extensions/zalo/references/conversation-management.md +214 -0
  21. package/extensions/zalo/references/eval-scenarios.md +157 -0
  22. package/extensions/zalo/references/listen-mode.md +237 -0
  23. package/extensions/zalo/references/mcp-production.md +274 -0
  24. package/extensions/zalo/references/multi-account-proxy.md +224 -0
  25. package/extensions/zalo/references/vietqr-banking.md +160 -0
  26. package/hooks/hooks.json +12 -0
  27. package/hooks/intent-router/index.cjs +108 -0
  28. package/hooks/pre-tool-guard/index.cjs +177 -68
  29. package/package.json +63 -64
  30. package/skills/brainstorm/SKILL.md +2 -0
  31. package/skills/cook/SKILL.md +661 -648
  32. package/skills/debug/SKILL.md +394 -392
  33. package/skills/deploy/SKILL.md +2 -0
  34. package/skills/fix/SKILL.md +283 -281
  35. package/skills/marketing/SKILL.md +3 -0
  36. package/skills/onboard/SKILL.md +7 -0
  37. package/skills/plan/SKILL.md +344 -342
  38. package/skills/preflight/SKILL.md +362 -360
  39. package/skills/review/SKILL.md +491 -489
  40. package/skills/scout/SKILL.md +1 -0
  41. package/skills/sentinel/SKILL.md +319 -296
  42. package/skills/sentinel/references/auth-crypto-reference.md +192 -0
  43. package/skills/sentinel/references/desktop-security.md +201 -0
  44. package/skills/sentinel/references/supply-chain.md +160 -0
  45. package/skills/session-bridge/SKILL.md +1 -0
  46. package/skills/slides/SKILL.md +142 -0
  47. package/skills/slides/scripts/build-deck.js +158 -0
  48. package/skills/team/SKILL.md +1 -0
  49. package/skills/test/SKILL.md +587 -585
  50. package/skills/verification/SKILL.md +1 -0
  51. package/skills/watchdog/SKILL.md +2 -0
  52. package/docs/ANTIGRAVITY-GAP-ANALYSIS.md +0 -369
  53. package/docs/ARCHITECTURE.md +0 -332
  54. package/docs/COMMUNITY-PACKS.md +0 -109
  55. package/docs/CONTRIBUTING-L4.md +0 -215
  56. package/docs/CROSS-IDE-ANALYSIS.md +0 -164
  57. package/docs/EXTENSION-TEMPLATE.md +0 -126
  58. package/docs/MESH-RULES.md +0 -34
  59. package/docs/MULTI-PLATFORM.md +0 -804
  60. package/docs/SKILL-DEPTH-AUDIT.md +0 -191
  61. package/docs/SKILL-TEMPLATE.md +0 -118
  62. package/docs/TRADE-MATRIX.md +0 -327
  63. package/docs/VERSIONING.md +0 -91
  64. package/docs/VISION.md +0 -263
  65. package/docs/assets/demo-subtitles.srt +0 -215
  66. package/docs/assets/end-card.html +0 -276
  67. package/docs/assets/mesh-diagram.html +0 -654
  68. package/docs/assets/thumbnail.html +0 -295
  69. package/docs/guides/cli.md +0 -403
  70. package/docs/guides/index.html +0 -1450
  71. package/docs/index.html +0 -1005
  72. package/docs/references/claudekit-analysis.md +0 -414
  73. package/docs/references/voltagent-analysis.md +0 -189
  74. package/docs/script.js +0 -495
  75. package/docs/skills/index.html +0 -832
  76. package/docs/style.css +0 -958
  77. package/docs/video-demo-plan.md +0 -172
@@ -1,489 +1,491 @@
1
- ---
2
- name: review
3
- description: Code quality review — patterns, security, performance, correctness. Finds bugs, suggests improvements, triggers fix for issues found. Escalates to opus for security-critical code.
4
- metadata:
5
- author: runedev
6
- version: "0.5.0"
7
- layer: L2
8
- model: sonnet
9
- group: development
10
- tools: "Read, Glob, Grep"
11
- ---
12
-
13
- # review
14
-
15
- ## Purpose
16
-
17
- Code quality analysis. Review finds bugs, bad patterns, security issues, and untested code. It does NOT fix anything — it reports findings and delegates: bugs go to rune:fix, untested code goes to rune:test, security-critical code goes to rune:sentinel.
18
-
19
- <HARD-GATE>
20
- A review that says "LGTM" or "code looks good" without specific file:line references is NOT a review.
21
- Every review MUST cite at least one specific concern, suggestion, or explicit approval per file changed.
22
- </HARD-GATE>
23
-
24
- ## Triggers
25
-
26
- - Called by `cook` Phase 5 REVIEW — after implementation complete
27
- - Called by `fix` for self-review on complex fixes
28
- - `/rune review` — manual code review
29
- - Auto-trigger: when PR is created or significant code changes committed
30
-
31
- ## Calls (outbound)
32
-
33
- - `scout` (L2): find related code for fuller context during review
34
- - `test` (L2): when untested edge cases found — write tests for them
35
- - `fix` (L2): when bugs found during review trigger fix
36
- - `sentinel` (L2): when security-critical code detected (auth, input, crypto)
37
- - `docs-seeker` (L3): verify API usage is current and correct
38
- - `hallucination-guard` (L3): verify imports and API calls in reviewed code
39
- - `design` (L2): when UI anti-patterns suggest missing design system — recommend design skill invocation
40
- - `perf` (L2): when performance patterns detected in frontend diff
41
- - `review-intake` (L2): structured intake for complex multi-file reviews
42
- - `sast` (L3): static analysis security scan on reviewed code
43
- - L4 extension packs: domain-specific review patterns when context matches (e.g., @rune/ui for frontend, @rune/security for auth code)
44
- - `neural-memory` | After review complete | Capture code quality insight
45
-
46
- ## Called By (inbound)
47
-
48
- - `cook` (L1): Phase 5 REVIEW — post-implementation quality check
49
- - `fix` (L2): complex fix requests self-review
50
- - User: `/rune review` direct invocation
51
- - `surgeon` (L2): review refactored code quality
52
- - `rescue` (L1): review refactored code quality
53
-
54
- ## Cross-Hub Connections
55
-
56
- - `review` → `test` — untested edge case found → test writes it
57
- - `review` → `fix` — bug found during review → fix applies correction
58
- - `review` → `scout` — needs more contextscout finds related code
59
- - `review` `fix` — complex fix requests self-review
60
- - `review` → `sentinel` — security-critical codesentinel deep scan
61
-
62
- ## Execution
63
-
64
- ### Step 1: Scope
65
-
66
- Determine what to review.
67
-
68
- - If triggered by a commit or PR: use `Bash` with `git diff main...HEAD` or `git diff HEAD~1` to see exactly what changed
69
- - If triggered by a specific file or feature: use `Read` on each named file
70
- - If context is unclear: use `rune:scout` to identify all files touched by the change
71
- - List every file in scope before proceeding do not review files outside the stated scope
72
-
73
- ### Step 1.5: Blast Radius Assessment
74
-
75
- For each modified function/class, estimate its blast radius before reviewing.
76
-
77
- ```
78
- Use Grep to count direct callers/importers of each modified symbol:
79
- blast_radius = count(files importing or calling this symbol)
80
- ```
81
-
82
- | Blast Radius | Risk | Review Depth |
83
- |-------------|------|-------------|
84
- | 1-5 callers | Low | Standard review |
85
- | 6-20 callers | Medium | Check all callers for compatibility |
86
- | 21-50 callers | High | Thorough review + regression test check |
87
- | 50+ callers | Critical | MUST escalate to adversarial analysis (rune:adversary) even in quick triage |
88
-
89
- <HARD-GATE>
90
- Modifying a symbol with 50+ callers + HIGH severity change (logic, types, behavior) → adversarial analysis REQUIRED. Quick review is NOT sufficient for high-blast-radius changes.
91
- </HARD-GATE>
92
-
93
- ### Step 2: Logic Check (Production-Critical Focus)
94
-
95
- Read each changed file. Prioritize bugs that **pass CI but break production** — these are the highest-value findings because linters and type checkers already catch the rest.
96
-
97
- - Use `Read` on every file in scope
98
- - **Race conditions**: async operations without proper sequencing, shared mutable state, missing locks
99
- - **State corruption**: mutations that affect other consumers, cache invalidation gaps, stale closures
100
- - **Silent failures**: caught errors that swallow context, empty catch blocks, promises without rejection handling
101
- - **Data loss paths**: write operations without confirmation, delete without soft-delete, truncation without backup
102
- - **Edge cases**: empty input, null/undefined, zero, negative numbers, empty arrays, Unicode, timezone boundaries
103
- - Check for: logic errors, off-by-one errors, incorrect conditionals, broken async/await patterns
104
- - Flag each finding with file path, line number, and severity
105
-
106
- **Common patterns to flag:**
107
-
108
- ```typescript
109
- // BAD — missing await causes race condition
110
- async function saveUser(data) {
111
- db.users.create(data); // caller proceeds before save completes
112
- return { success: true };
113
- }
114
- // GOOD
115
- async function saveUser(data) {
116
- await db.users.create(data);
117
- return { success: true };
118
- }
119
- ```
120
-
121
- ```typescript
122
- // BAD — null deref crash
123
- function getUsername(user) {
124
- return user.profile.name.toUpperCase(); // crashes if profile or name is null
125
- }
126
- // GOOD safe access
127
- function getUsername(user) {
128
- return user?.profile?.name?.toUpperCase() ?? 'Anonymous';
129
- }
130
- ```
131
-
132
- ### Step 3: Pattern Check
133
-
134
- Check consistency with project conventions.
135
-
136
- - Compare naming against existing codebase patterns (use `Grep` to sample similar code)
137
- - Check file structure: is it in the right layer/directory per project conventions?
138
- - Check for mutations all state changes should use immutable patterns
139
- - Check for hardcoded values that should be constants or config
140
- - Check TypeScript: no `any`, full type coverage, no non-null assertions without justification
141
- - Flag inconsistencies as MEDIUM or LOW depending on impact
142
-
143
- **Common patterns to flag:**
144
-
145
- ```typescript
146
- // BAD — mutation
147
- function addItem(cart, item) {
148
- cart.items.push(item); // mutates in place
149
- return cart;
150
- }
151
- // GOOD — immutable
152
- function addItem(cart, item) {
153
- return { ...cart, items: [...cart.items, item] };
154
- }
155
- ```
156
-
157
- ```typescript
158
- // BAD — any defeats TypeScript's purpose
159
- function process(data: any): any {
160
- return data.items.map((i: any) => i.value);
161
- }
162
- // GOOD typed
163
- function process(data: { items: Array<{ value: string }> }): string[] {
164
- return data.items.map(i => i.value);
165
- }
166
- ```
167
-
168
- ### Step 4: Security Check
169
-
170
- Check for security-relevant issues.
171
-
172
- - Scan for: hardcoded secrets, API keys, passwords in code or comments
173
- - Scan for: unvalidated user input passed to queries, file paths, or shell commands
174
- - Scan for: missing authentication checks on new routes or functions
175
- - Scan for: XSS vectors (unsanitized HTML output), CSRF exposure, open redirects
176
- - If any security-sensitive code found (auth logic, input handling, crypto, payment): call `rune:sentinel` for deep scan
177
- - Sentinel escalation is mandatory do not skip it for auth or crypto code
178
-
179
- ### Step 4.5: API Pit-of-Success Check
180
-
181
- For code that exposes APIs, shared utilities, or reusable interfaces, evaluate through 3 adversary personas:
182
-
183
- | Adversary | Mindset | What They Reveal |
184
- |-----------|---------|-----------------|
185
- | **The Scoundrel** | Malicious — controls config, crafts inputs, exploits edge cases | Security holes, privilege escalation, injection surfaces |
186
- | **The Lazy Developer** | Copy-pastes from docs, skips error handling, uses defaults | Unsafe defaults, missing validation, footgun APIs |
187
- | **The Confused Developer** | Misunderstands API semantics, passes wrong types, ignores return values | Ambiguous interfaces, poor naming, missing type safety |
188
-
189
- **Pit-of-Success principle**: Secure, correct usage should be the path of least resistance. If the API makes it EASIER to use it wrong than right → WARN.
190
-
191
- Check: Does the API have sensible defaults? Does misuse fail loudly (not silently)? Is the happy path obvious from the signature?
192
-
193
- **Skip if**: Code is internal-only (no external consumers), single-use utility, or test-only.
194
-
195
- ### Step 5: Test Coverage
196
-
197
- Identify gaps in test coverage.
198
-
199
- - Use `Bash` to check if a test file exists for each changed file
200
- - Use `Glob` to find test files: `**/*.test.ts`, `**/*.spec.ts`, `**/__tests__/**`
201
- - Read the test file and verify: are the new functions covered? are edge cases tested?
202
- - If untested code found: call `rune:test` with specific instructions on what to test
203
- - Flag as HIGH if business logic is untested, MEDIUM if utility code is untested
204
-
205
- ### Step 5.5: Two-Stage Review Gate
206
-
207
- Separate spec compliance from code quality. Most reviews conflate both — this gate forces the distinction.
208
-
209
- **Stage 1Spec Compliance (check FIRST)**
210
-
211
- Before evaluating code quality, verify the implementation matches what was asked:
212
-
213
- - Load the originating plan, task, ticket, or `requirements.md` if available
214
- - Does the implementation cover every acceptance criterion? Check each one explicitly
215
- - Is there **under-engineering** requirements stated but not implemented?
216
- - Is there **over-engineering** abstractions, generalization, or features beyond scope?
217
- - Does the file/function structure match what the plan specified?
218
-
219
- Flag spec deviations as HIGH clean code that misses requirements ships broken products.
220
-
221
- ```
222
- # Spec Compliance Checklist
223
- [ ] All acceptance criteria from plan/ticket covered
224
- [ ] No stated requirements missing from implementation
225
- [ ] No unrequested features added (scope creep)
226
- [ ] API surface matches what was specified (signatures, endpoints, return types)
227
- [ ] File structure matches plan (no renamed or relocated files without justification)
228
- ```
229
-
230
- If spec violations found: document them separately from code quality findings in the report. Label as `SPEC-MISS` or `SPEC-CREEP`.
231
-
232
- **Stage 2 Code Quality**
233
-
234
- Proceed to Step 6 only after Stage 1 passes. Code quality findings (bugs, patterns, security, coverage) are the existing Steps 2–5 above.
235
-
236
- The review report MUST show both stages: spec compliance verdict first, then code quality findings.
237
-
238
- ### Step 6: Report
239
-
240
- Produce a structured severity-ranked report.
241
-
242
- **Before reporting, apply confidence filter:**
243
- - Only report findings with >80% confidence it is a real issue
244
- - Consolidate similar issues: "8 functions missing error handling in src/services/" — not 8 separate findings
245
- - Skip stylistic preferences unless they violate conventions found in `.eslintrc`, `CLAUDE.md`, or `CONTRIBUTING.md`
246
- - Adapt to project type: a `console.log` in a CLI tool is fine; in a production API handler it is not
247
-
248
- - Group findings by severity: CRITICAL HIGH MEDIUM LOW
249
- - Include file path and line number for every finding
250
- - Include a Positive Notes section (good patterns observed)
251
- - Include a Verdict: APPROVE | REQUEST CHANGES | NEEDS DISCUSSION
252
-
253
- After reporting:
254
- - If any CRITICAL findings: call `rune:fix` immediately with the finding details
255
- - If any HIGH findings: call `rune:fix` with the finding details
256
- - If untested code: call `rune:test` with specific coverage gaps identified
257
- - Call `neural-memory` (Capture Mode) to save any novel code quality patterns or recurring issues found.
258
-
259
- ## Framework-Specific Checks
260
-
261
- Apply **only** if the framework is detected in the changed files. Skip if not relevant.
262
-
263
- **React / Next.js** (detect: `import React` or `.tsx` files)
264
- - `useEffect` with missing dependencies (stale closure) → flag HIGH
265
- - List items using index as key on reorderable lists: `key={i}` flag MEDIUM
266
- - Props drilled through 3+ levels without Context or composition → flag MEDIUM
267
- - Client-side hooks (`useState`, `useEffect`) in Server Components (Next.js App Router) → flag HIGH
268
-
269
- **Node.js / Express** (detect: `import express` or `require('express')`)
270
- - Missing rate limiting on public endpoints → flag MEDIUM
271
- - `req.body` passed directly to DB without validation schema → flag HIGH
272
- - Synchronous operations blocking the event loop inside async handlers → flag HIGH
273
-
274
- **Python** (detect: `.py` files with `django`, `flask`, or `fastapi` imports)
275
- - `except:` bare catch without specific exception type → flag MEDIUM
276
- - Mutable default arguments: `def func(items=[])` flag HIGH
277
- - Missing type hints on public functions (if project uses mypy/pyright) → flag LOW
278
-
279
- ## UI/UX Anti-Pattern Checks
280
-
281
- Apply **only** when `.tsx`, `.jsx`, `.svelte`, `.vue`, or `.html` files are in the diff. Skip for backend-only changes.
282
-
283
- These are the **"AI UI signature"** patterns that make AI-generated frontends visually identifiable as non-human-designed. Flag each as MEDIUM severity.
284
-
285
- **AI_ANTIPATTERNPurple/indigo default accent with no domain justification:**
286
- ```tsx
287
- // BAD: LLM default color bias signals "AI-generated" to experienced designers
288
- className="bg-indigo-600 text-white" // every button/CTA is indigo
289
- // GOOD: domain-appropriate trading neutral dark, healthcare trust blue,
290
- // e-commerce → conversion-optimized warm. Purple is only appropriate for
291
- // AI-native tools and creative platforms.
292
- ```
293
-
294
- **AI_ANTIPATTERN — Card-grid monotony (every section is 3-col cards, zero layout variation):**
295
- ```tsx
296
- // BAD: every section uses the same grid pattern
297
- <div className="grid grid-cols-3 gap-6"> // features
298
- <div className="grid grid-cols-3 gap-6"> // testimonials
299
- <div className="grid grid-cols-3 gap-6"> // pricing
300
- // GOOD: mix layouts — split sections, bento grids, full-bleed hero, list+detail
301
- ```
302
-
303
- **AI_ANTIPATTERN — Centeritis (everything centered, no directional flow):**
304
- ```tsx
305
- // BAD: no visual tension, no reading direction
306
- <div className="text-center flex flex-col items-center"> // hero
307
- <div className="text-center"> // every feature section
308
- // GOOD: left-align body copy, use centering intentionally for hero/CTAs only
309
- ```
310
-
311
- **AI_ANTIPATTERN — Numeric/financial values in non-monospace font:**
312
- ```tsx
313
- // BAD: prices, stats, metrics in Inter/Roboto
314
- <span className="text-2xl font-bold">${price}</span>
315
- // GOOD: monospace for all numbers that need alignment
316
- <span className="font-mono text-2xl font-bold">${price}</span>
317
- ```
318
-
319
- **AI_ANTIPATTERN — Missing UI states (only happy path rendered):**
320
- ```tsx
321
- // BAD: data rendering without empty/error/loading states
322
- {data.map(item => <Card key={item.id} {...item} />)}
323
- // GOOD: all 4 states covered
324
- {isLoading && <CardSkeleton />}
325
- {error && <ErrorState message={error.message} />}
326
- {!data.length && <EmptyState />}
327
- {data.map(item => <Card key={item.id} {...item} />)}
328
- ```
329
-
330
- **Accessibility — flag as HIGH (these are WCAG 2.2 failures):**
331
- ```tsx
332
- // BAD: icon button with no accessible name
333
- <button onClick={close}><XIcon /></button>
334
- // GOOD
335
- <button onClick={close} aria-label="Close dialog"><XIcon aria-hidden="true" /></button>
336
-
337
- // BAD: placeholder as label
338
- <input placeholder="Email address" type="email" />
339
- // GOOD
340
- <label htmlFor="email">Email address</label>
341
- <input id="email" type="email" />
342
-
343
- // BAD: removes focus ring without replacement
344
- className="focus:outline-none"
345
- // GOOD: must have focus-visible replacement
346
- className="focus:outline-none focus-visible:ring-2 focus-visible:ring-blue-500"
347
-
348
- // BAD: color as sole information conveyor
349
- <span className="text-red-500">{errorMessage}</span>
350
- // GOOD: icon + color + text
351
- <span className="text-red-500 flex gap-1"><ErrorIcon aria-hidden />Error: {errorMessage}</span>
352
- ```
353
-
354
- **WCAG 2.2 New Rules — flag as MEDIUM:**
355
- - `position: sticky` or `position: fixed` header/footer without `scroll-padding-top` → Focus Not Obscured (2.4.11)
356
- - Interactive elements with `width < 24px` or `height < 24px` without 8px spacing → Target Size (2.5.8)
357
- - Multi-step form re-asking for previously entered dataRedundant Entry (3.3.7)
358
-
359
- **Platform-Specific flag as MEDIUM when platform is detectable:**
360
- - iOS target: solid-background cards (iOS 26 Liquid Glass deprecates this visual language) — should use translucent/blur surfaces
361
- - Android target: hardcoded hex colors instead of `MaterialTheme.colorScheme` tokens → not adaptive to dynamic color
362
-
363
- ## Weighted Composite Scoring
364
-
365
- When a review is part of a recurring quality-gate cycle (e.g., sprint review, pre-release gate), produce a **composite quality score** alongside the findings list. This makes review output numeric and comparable across runs.
366
-
367
- ### Formula
368
-
369
- ```
370
- Quality Score = (Correctness × 0.35) + (Security × 0.30) + (Test Coverage × 0.20) + (Conventions × 0.15)
371
- ```
372
-
373
- Each dimension is scored 0–100 based on findings count and severity:
374
- - 0 CRITICAL/HIGH findings → 100 for that dimension
375
- - 1 CRITICAL dimension capped at 40
376
- - 1 HIGH → dimension capped at 70
377
- - Each additional MEDIUM subtract 5 (floor: 50)
378
-
379
- ### Grade Thresholds
380
-
381
- | Score | Grade | Verdict |
382
- |-------|-------|---------|
383
- | 90–100 | Excellent | APPROVE |
384
- | 75–89 | Good | APPROVE with notes |
385
- | 6074 | Fair | REQUEST CHANGES (MEDIUM issues) |
386
- | 4059 | Poor | REQUEST CHANGES (HIGH issues present) |
387
- | 039 | Critical | REQUEST CHANGES (CRITICAL present) |
388
-
389
- **When to include**: Only when `mode: "scored"` is passed by the caller, or when invoked by `audit`. Default review output uses the standard severity-ranked report without the score.
390
-
391
-
392
- ## Severity Levels
393
-
394
- ```
395
- CRITICAL — security vulnerability, data loss risk, crash bug
396
- HIGH — logic error, missing validation, broken edge case
397
- MEDIUM code smell, performance issue, missing error handling
398
- LOW style inconsistency, naming suggestion, minor refactor opportunity
399
- ```
400
-
401
- ## Output Format
402
-
403
- ```
404
- ## Code Review Report
405
- - **Files Reviewed**: [count]
406
- - **Findings**: [count by severity]
407
- - **Review Commit**: [git hash at time of review]
408
- - **Overall**: APPROVE | REQUEST CHANGES | NEEDS DISCUSSION
409
-
410
- ### Spec Compliance
411
- - [PASS/FAIL]: [acceptance criteria coverage]
412
-
413
- ### CRITICAL
414
- - `path/to/file.ts:42` — [description of critical issue]
415
-
416
- ### HIGH
417
- - `path/to/file.ts:85` — [description of high-severity issue]
418
-
419
- ### MEDIUM
420
- - `path/to/file.ts:120` — [description of medium issue]
421
-
422
- ### Blast Radius
423
- - [High-impact symbols with caller counts]
424
-
425
- ### Positive Notes
426
- - [good patterns observed]
427
-
428
- ### Verdict
429
- [Summary and recommendation]
430
- ```
431
-
432
- ### Review Staleness Detection
433
-
434
- Track the git commit hash at review time. If code changes after review → review is STALE.
435
-
436
- ```
437
- Review commit: abc123 → Code changed to def456 → Review is STALE, re-review required
438
- ```
439
-
440
- When `cook` or `ship` checks review status: compare review commit hash with current HEAD. If different → WARN: "Review is stale — code changed since last review."
441
-
442
-
443
- ## Constraints
444
-
445
- 1. MUST read the full diff — not just the files the user pointed at
446
- 2. MUST reference specific file:line for every finding
447
- 3. MUST NOT rubber-stamp with generic praise ("well-structured", "clean code") without evidence
448
- 4. MUST check: correctness, security, performance, conventions, test coverage
449
- 5. MUST categorize findings: CRITICAL (blocks commit) / HIGH / MEDIUM / LOW
450
- 6. MUST escalate to sentinel if auth/crypto/secrets code is touched
451
- 7. MUST flag untested code paths and recommend tests via rune:test
452
-
453
- ## Returns
454
-
455
- | Artifact | Format | Location |
456
- |----------|--------|----------|
457
- | Code review report | Markdown | inline (chat output) |
458
- | Severity-ranked findings | Markdown table | inline |
459
- | Spec compliance verdict | Markdown | inline |
460
- | Composite quality score | Markdown table | inline (when `mode: "scored"`) |
461
- | Blast radius assessment | Markdown table | inline |
462
-
463
- ## Sharp Edges
464
-
465
- | Failure Mode | Severity | Mitigation |
466
- |---|---|---|
467
- | Finding flood — 20+ findings overwhelm developer | MEDIUM | Confidence filter: only >80% confidence, consolidate similar issues per file |
468
- | "LGTM" without file:line evidence | HIGH | HARD-GATE blocks this — cite at least one specific item per changed file |
469
- | Expanding review scope beyond the diff | MEDIUM | Limit to `git diff` scope do not creep into adjacent unchanged files |
470
- | Security finding without sentinel escalation | HIGH | Any auth/crypto/payment code touched MUST call rune:sentinel |
471
- | Skipping UI anti-pattern checks for frontend changes | MEDIUM | Any .tsx/.jsx/.svelte/.vue in diff MUST run UI/UX Anti-Pattern Checks section |
472
- | Skipping spec compliance check (Step 5.5 Stage 1) | HIGH | Code quality without spec check ships clean code that does the wrong thing — always load the plan/ticket before reviewing quality |
473
- | Treating purple/indigo accent as "just a color choice" | MEDIUM | It is a documented AI-generated UI signature always flag for domain justification |
474
- | Suggesting "add X" without checking if X is used | MEDIUM | YAGNI pushback: grep codebase for the suggested feature if uncalled anywhere respond "Not called anywhere. Remove? (YAGNI)". Valid pushback, not laziness |
475
- | Adding abstractions "for future flexibility" | MEDIUM | Three similar lines > premature abstraction. Only abstract when there are 3+ concrete callers today |
476
- | Missing cross-phase integration check at phase boundary | MEDIUM | When reviewing a phase completion: check orphaned exports, uncalled routes, auth gaps, E2E flow continuity. Delegate to completion-gate Step 4.5 |
477
-
478
- ## Done When
479
-
480
- - All changed files in the diff read and analyzed
481
- - Every finding references specific file:line with severity label
482
- - Security-critical code escalated to sentinel (or confirmed not present)
483
- - Test coverage gaps identified and documented
484
- - UI anti-pattern checks ran for any frontend files in diff (or confirmed not applicable)
485
- - Structured report emitted with APPROVE / REQUEST CHANGES / NEEDS DISCUSSION verdict
486
-
487
- ## Cost Profile
488
-
489
- ~3000-6000 tokens input, ~1000-2000 tokens output. Sonnet default, opus for security-critical reviews. Runs once per implementation cycle.
1
+ ---
2
+ name: review
3
+ description: Code quality review — patterns, security, performance, correctness. Finds bugs, suggests improvements, triggers fix for issues found. Escalates to opus for security-critical code.
4
+ metadata:
5
+ author: runedev
6
+ version: "0.5.0"
7
+ layer: L2
8
+ model: sonnet
9
+ group: development
10
+ tools: "Read, Glob, Grep"
11
+ emit: review.complete, review.issues
12
+ listen: code.changed
13
+ ---
14
+
15
+ # review
16
+
17
+ ## Purpose
18
+
19
+ Code quality analysis. Review finds bugs, bad patterns, security issues, and untested code. It does NOT fix anything — it reports findings and delegates: bugs go to rune:fix, untested code goes to rune:test, security-critical code goes to rune:sentinel.
20
+
21
+ <HARD-GATE>
22
+ A review that says "LGTM" or "code looks good" without specific file:line references is NOT a review.
23
+ Every review MUST cite at least one specific concern, suggestion, or explicit approval per file changed.
24
+ </HARD-GATE>
25
+
26
+ ## Triggers
27
+
28
+ - Called by `cook` Phase 5 REVIEW after implementation complete
29
+ - Called by `fix` for self-review on complex fixes
30
+ - `/rune review` — manual code review
31
+ - Auto-trigger: when PR is created or significant code changes committed
32
+
33
+ ## Calls (outbound)
34
+
35
+ - `scout` (L2): find related code for fuller context during review
36
+ - `test` (L2): when untested edge cases found write tests for them
37
+ - `fix` (L2): when bugs found during review trigger fix
38
+ - `sentinel` (L2): when security-critical code detected (auth, input, crypto)
39
+ - `docs-seeker` (L3): verify API usage is current and correct
40
+ - `hallucination-guard` (L3): verify imports and API calls in reviewed code
41
+ - `design` (L2): when UI anti-patterns suggest missing design system — recommend design skill invocation
42
+ - `perf` (L2): when performance patterns detected in frontend diff
43
+ - `review-intake` (L2): structured intake for complex multi-file reviews
44
+ - `sast` (L3): static analysis security scan on reviewed code
45
+ - L4 extension packs: domain-specific review patterns when context matches (e.g., @rune/ui for frontend, @rune/security for auth code)
46
+ - `neural-memory` | After review complete | Capture code quality insight
47
+
48
+ ## Called By (inbound)
49
+
50
+ - `cook` (L1): Phase 5 REVIEW — post-implementation quality check
51
+ - `fix` (L2): complex fix requests self-review
52
+ - User: `/rune review` direct invocation
53
+ - `surgeon` (L2): review refactored code quality
54
+ - `rescue` (L1): review refactored code quality
55
+
56
+ ## Cross-Hub Connections
57
+
58
+ - `review` → `test` — untested edge case found test writes it
59
+ - `review` `fix` — bug found during review → fix applies correction
60
+ - `review` → `scout` — needs more context scout finds related code
61
+ - `review` ← `fix` — complex fix requests self-review
62
+ - `review` → `sentinel` — security-critical code → sentinel deep scan
63
+
64
+ ## Execution
65
+
66
+ ### Step 1: Scope
67
+
68
+ Determine what to review.
69
+
70
+ - If triggered by a commit or PR: use `Bash` with `git diff main...HEAD` or `git diff HEAD~1` to see exactly what changed
71
+ - If triggered by a specific file or feature: use `Read` on each named file
72
+ - If context is unclear: use `rune:scout` to identify all files touched by the change
73
+ - List every file in scope before proceeding — do not review files outside the stated scope
74
+
75
+ ### Step 1.5: Blast Radius Assessment
76
+
77
+ For each modified function/class, estimate its blast radius before reviewing.
78
+
79
+ ```
80
+ Use Grep to count direct callers/importers of each modified symbol:
81
+ blast_radius = count(files importing or calling this symbol)
82
+ ```
83
+
84
+ | Blast Radius | Risk | Review Depth |
85
+ |-------------|------|-------------|
86
+ | 1-5 callers | Low | Standard review |
87
+ | 6-20 callers | Medium | Check all callers for compatibility |
88
+ | 21-50 callers | High | Thorough review + regression test check |
89
+ | 50+ callers | Critical | MUST escalate to adversarial analysis (rune:adversary) even in quick triage |
90
+
91
+ <HARD-GATE>
92
+ Modifying a symbol with 50+ callers + HIGH severity change (logic, types, behavior) → adversarial analysis REQUIRED. Quick review is NOT sufficient for high-blast-radius changes.
93
+ </HARD-GATE>
94
+
95
+ ### Step 2: Logic Check (Production-Critical Focus)
96
+
97
+ Read each changed file. Prioritize bugs that **pass CI but break production** — these are the highest-value findings because linters and type checkers already catch the rest.
98
+
99
+ - Use `Read` on every file in scope
100
+ - **Race conditions**: async operations without proper sequencing, shared mutable state, missing locks
101
+ - **State corruption**: mutations that affect other consumers, cache invalidation gaps, stale closures
102
+ - **Silent failures**: caught errors that swallow context, empty catch blocks, promises without rejection handling
103
+ - **Data loss paths**: write operations without confirmation, delete without soft-delete, truncation without backup
104
+ - **Edge cases**: empty input, null/undefined, zero, negative numbers, empty arrays, Unicode, timezone boundaries
105
+ - Check for: logic errors, off-by-one errors, incorrect conditionals, broken async/await patterns
106
+ - Flag each finding with file path, line number, and severity
107
+
108
+ **Common patterns to flag:**
109
+
110
+ ```typescript
111
+ // BAD missing await causes race condition
112
+ async function saveUser(data) {
113
+ db.users.create(data); // caller proceeds before save completes
114
+ return { success: true };
115
+ }
116
+ // GOOD
117
+ async function saveUser(data) {
118
+ await db.users.create(data);
119
+ return { success: true };
120
+ }
121
+ ```
122
+
123
+ ```typescript
124
+ // BAD null deref crash
125
+ function getUsername(user) {
126
+ return user.profile.name.toUpperCase(); // crashes if profile or name is null
127
+ }
128
+ // GOOD safe access
129
+ function getUsername(user) {
130
+ return user?.profile?.name?.toUpperCase() ?? 'Anonymous';
131
+ }
132
+ ```
133
+
134
+ ### Step 3: Pattern Check
135
+
136
+ Check consistency with project conventions.
137
+
138
+ - Compare naming against existing codebase patterns (use `Grep` to sample similar code)
139
+ - Check file structure: is it in the right layer/directory per project conventions?
140
+ - Check for mutations all state changes should use immutable patterns
141
+ - Check for hardcoded values that should be constants or config
142
+ - Check TypeScript: no `any`, full type coverage, no non-null assertions without justification
143
+ - Flag inconsistencies as MEDIUM or LOW depending on impact
144
+
145
+ **Common patterns to flag:**
146
+
147
+ ```typescript
148
+ // BAD mutation
149
+ function addItem(cart, item) {
150
+ cart.items.push(item); // mutates in place
151
+ return cart;
152
+ }
153
+ // GOOD immutable
154
+ function addItem(cart, item) {
155
+ return { ...cart, items: [...cart.items, item] };
156
+ }
157
+ ```
158
+
159
+ ```typescript
160
+ // BAD any defeats TypeScript's purpose
161
+ function process(data: any): any {
162
+ return data.items.map((i: any) => i.value);
163
+ }
164
+ // GOOD typed
165
+ function process(data: { items: Array<{ value: string }> }): string[] {
166
+ return data.items.map(i => i.value);
167
+ }
168
+ ```
169
+
170
+ ### Step 4: Security Check
171
+
172
+ Check for security-relevant issues.
173
+
174
+ - Scan for: hardcoded secrets, API keys, passwords in code or comments
175
+ - Scan for: unvalidated user input passed to queries, file paths, or shell commands
176
+ - Scan for: missing authentication checks on new routes or functions
177
+ - Scan for: XSS vectors (unsanitized HTML output), CSRF exposure, open redirects
178
+ - If any security-sensitive code found (auth logic, input handling, crypto, payment): call `rune:sentinel` for deep scan
179
+ - Sentinel escalation is mandatory — do not skip it for auth or crypto code
180
+
181
+ ### Step 4.5: API Pit-of-Success Check
182
+
183
+ For code that exposes APIs, shared utilities, or reusable interfaces, evaluate through 3 adversary personas:
184
+
185
+ | Adversary | Mindset | What They Reveal |
186
+ |-----------|---------|-----------------|
187
+ | **The Scoundrel** | Malicious controls config, crafts inputs, exploits edge cases | Security holes, privilege escalation, injection surfaces |
188
+ | **The Lazy Developer** | Copy-pastes from docs, skips error handling, uses defaults | Unsafe defaults, missing validation, footgun APIs |
189
+ | **The Confused Developer** | Misunderstands API semantics, passes wrong types, ignores return values | Ambiguous interfaces, poor naming, missing type safety |
190
+
191
+ **Pit-of-Success principle**: Secure, correct usage should be the path of least resistance. If the API makes it EASIER to use it wrong than right WARN.
192
+
193
+ Check: Does the API have sensible defaults? Does misuse fail loudly (not silently)? Is the happy path obvious from the signature?
194
+
195
+ **Skip if**: Code is internal-only (no external consumers), single-use utility, or test-only.
196
+
197
+ ### Step 5: Test Coverage
198
+
199
+ Identify gaps in test coverage.
200
+
201
+ - Use `Bash` to check if a test file exists for each changed file
202
+ - Use `Glob` to find test files: `**/*.test.ts`, `**/*.spec.ts`, `**/__tests__/**`
203
+ - Read the test file and verify: are the new functions covered? are edge cases tested?
204
+ - If untested code found: call `rune:test` with specific instructions on what to test
205
+ - Flag as HIGH if business logic is untested, MEDIUM if utility code is untested
206
+
207
+ ### Step 5.5: Two-Stage Review Gate
208
+
209
+ Separate spec compliance from code quality. Most reviews conflate both this gate forces the distinction.
210
+
211
+ **Stage 1 Spec Compliance (check FIRST)**
212
+
213
+ Before evaluating code quality, verify the implementation matches what was asked:
214
+
215
+ - Load the originating plan, task, ticket, or `requirements.md` if available
216
+ - Does the implementation cover every acceptance criterion? Check each one explicitly
217
+ - Is there **under-engineering** requirements stated but not implemented?
218
+ - Is there **over-engineering** — abstractions, generalization, or features beyond scope?
219
+ - Does the file/function structure match what the plan specified?
220
+
221
+ Flag spec deviations as HIGH — clean code that misses requirements ships broken products.
222
+
223
+ ```
224
+ # Spec Compliance Checklist
225
+ [ ] All acceptance criteria from plan/ticket covered
226
+ [ ] No stated requirements missing from implementation
227
+ [ ] No unrequested features added (scope creep)
228
+ [ ] API surface matches what was specified (signatures, endpoints, return types)
229
+ [ ] File structure matches plan (no renamed or relocated files without justification)
230
+ ```
231
+
232
+ If spec violations found: document them separately from code quality findings in the report. Label as `SPEC-MISS` or `SPEC-CREEP`.
233
+
234
+ **Stage 2 Code Quality**
235
+
236
+ Proceed to Step 6 only after Stage 1 passes. Code quality findings (bugs, patterns, security, coverage) are the existing Steps 2–5 above.
237
+
238
+ The review report MUST show both stages: spec compliance verdict first, then code quality findings.
239
+
240
+ ### Step 6: Report
241
+
242
+ Produce a structured severity-ranked report.
243
+
244
+ **Before reporting, apply confidence filter:**
245
+ - Only report findings with >80% confidence it is a real issue
246
+ - Consolidate similar issues: "8 functions missing error handling in src/services/" not 8 separate findings
247
+ - Skip stylistic preferences unless they violate conventions found in `.eslintrc`, `CLAUDE.md`, or `CONTRIBUTING.md`
248
+ - Adapt to project type: a `console.log` in a CLI tool is fine; in a production API handler it is not
249
+
250
+ - Group findings by severity: CRITICAL HIGH → MEDIUM → LOW
251
+ - Include file path and line number for every finding
252
+ - Include a Positive Notes section (good patterns observed)
253
+ - Include a Verdict: APPROVE | REQUEST CHANGES | NEEDS DISCUSSION
254
+
255
+ After reporting:
256
+ - If any CRITICAL findings: call `rune:fix` immediately with the finding details
257
+ - If any HIGH findings: call `rune:fix` with the finding details
258
+ - If untested code: call `rune:test` with specific coverage gaps identified
259
+ - Call `neural-memory` (Capture Mode) to save any novel code quality patterns or recurring issues found.
260
+
261
+ ## Framework-Specific Checks
262
+
263
+ Apply **only** if the framework is detected in the changed files. Skip if not relevant.
264
+
265
+ **React / Next.js** (detect: `import React` or `.tsx` files)
266
+ - `useEffect` with missing dependencies (stale closure) → flag HIGH
267
+ - List items using index as key on reorderable lists: `key={i}` → flag MEDIUM
268
+ - Props drilled through 3+ levels without Context or composition → flag MEDIUM
269
+ - Client-side hooks (`useState`, `useEffect`) in Server Components (Next.js App Router) → flag HIGH
270
+
271
+ **Node.js / Express** (detect: `import express` or `require('express')`)
272
+ - Missing rate limiting on public endpoints → flag MEDIUM
273
+ - `req.body` passed directly to DB without validation schema → flag HIGH
274
+ - Synchronous operations blocking the event loop inside async handlers → flag HIGH
275
+
276
+ **Python** (detect: `.py` files with `django`, `flask`, or `fastapi` imports)
277
+ - `except:` bare catch without specific exception type → flag MEDIUM
278
+ - Mutable default arguments: `def func(items=[])` → flag HIGH
279
+ - Missing type hints on public functions (if project uses mypy/pyright) flag LOW
280
+
281
+ ## UI/UX Anti-Pattern Checks
282
+
283
+ Apply **only** when `.tsx`, `.jsx`, `.svelte`, `.vue`, or `.html` files are in the diff. Skip for backend-only changes.
284
+
285
+ These are the **"AI UI signature"** patterns that make AI-generated frontends visually identifiable as non-human-designed. Flag each as MEDIUM severity.
286
+
287
+ **AI_ANTIPATTERN Purple/indigo default accent with no domain justification:**
288
+ ```tsx
289
+ // BAD: LLM default color bias signals "AI-generated" to experienced designers
290
+ className="bg-indigo-600 text-white" // every button/CTA is indigo
291
+ // GOOD: domain-appropriate trading neutral dark, healthcare → trust blue,
292
+ // e-commerce → conversion-optimized warm. Purple is only appropriate for
293
+ // AI-native tools and creative platforms.
294
+ ```
295
+
296
+ **AI_ANTIPATTERN Card-grid monotony (every section is 3-col cards, zero layout variation):**
297
+ ```tsx
298
+ // BAD: every section uses the same grid pattern
299
+ <div className="grid grid-cols-3 gap-6"> // features
300
+ <div className="grid grid-cols-3 gap-6"> // testimonials
301
+ <div className="grid grid-cols-3 gap-6"> // pricing
302
+ // GOOD: mix layouts — split sections, bento grids, full-bleed hero, list+detail
303
+ ```
304
+
305
+ **AI_ANTIPATTERN Centeritis (everything centered, no directional flow):**
306
+ ```tsx
307
+ // BAD: no visual tension, no reading direction
308
+ <div className="text-center flex flex-col items-center"> // hero
309
+ <div className="text-center"> // every feature section
310
+ // GOOD: left-align body copy, use centering intentionally for hero/CTAs only
311
+ ```
312
+
313
+ **AI_ANTIPATTERN Numeric/financial values in non-monospace font:**
314
+ ```tsx
315
+ // BAD: prices, stats, metrics in Inter/Roboto
316
+ <span className="text-2xl font-bold">${price}</span>
317
+ // GOOD: monospace for all numbers that need alignment
318
+ <span className="font-mono text-2xl font-bold">${price}</span>
319
+ ```
320
+
321
+ **AI_ANTIPATTERN Missing UI states (only happy path rendered):**
322
+ ```tsx
323
+ // BAD: data rendering without empty/error/loading states
324
+ {data.map(item => <Card key={item.id} {...item} />)}
325
+ // GOOD: all 4 states covered
326
+ {isLoading && <CardSkeleton />}
327
+ {error && <ErrorState message={error.message} />}
328
+ {!data.length && <EmptyState />}
329
+ {data.map(item => <Card key={item.id} {...item} />)}
330
+ ```
331
+
332
+ **Accessibility flag as HIGH (these are WCAG 2.2 failures):**
333
+ ```tsx
334
+ // BAD: icon button with no accessible name
335
+ <button onClick={close}><XIcon /></button>
336
+ // GOOD
337
+ <button onClick={close} aria-label="Close dialog"><XIcon aria-hidden="true" /></button>
338
+
339
+ // BAD: placeholder as label
340
+ <input placeholder="Email address" type="email" />
341
+ // GOOD
342
+ <label htmlFor="email">Email address</label>
343
+ <input id="email" type="email" />
344
+
345
+ // BAD: removes focus ring without replacement
346
+ className="focus:outline-none"
347
+ // GOOD: must have focus-visible replacement
348
+ className="focus:outline-none focus-visible:ring-2 focus-visible:ring-blue-500"
349
+
350
+ // BAD: color as sole information conveyor
351
+ <span className="text-red-500">{errorMessage}</span>
352
+ // GOOD: icon + color + text
353
+ <span className="text-red-500 flex gap-1"><ErrorIcon aria-hidden />Error: {errorMessage}</span>
354
+ ```
355
+
356
+ **WCAG 2.2 New Rules flag as MEDIUM:**
357
+ - `position: sticky` or `position: fixed` header/footer without `scroll-padding-top` Focus Not Obscured (2.4.11)
358
+ - Interactive elements with `width < 24px` or `height < 24px` without 8px spacing → Target Size (2.5.8)
359
+ - Multi-step form re-asking for previously entered data → Redundant Entry (3.3.7)
360
+
361
+ **Platform-Specific flag as MEDIUM when platform is detectable:**
362
+ - iOS target: solid-background cards (iOS 26 Liquid Glass deprecates this visual language) — should use translucent/blur surfaces
363
+ - Android target: hardcoded hex colors instead of `MaterialTheme.colorScheme` tokens → not adaptive to dynamic color
364
+
365
+ ## Weighted Composite Scoring
366
+
367
+ When a review is part of a recurring quality-gate cycle (e.g., sprint review, pre-release gate), produce a **composite quality score** alongside the findings list. This makes review output numeric and comparable across runs.
368
+
369
+ ### Formula
370
+
371
+ ```
372
+ Quality Score = (Correctness × 0.35) + (Security × 0.30) + (Test Coverage × 0.20) + (Conventions × 0.15)
373
+ ```
374
+
375
+ Each dimension is scored 0–100 based on findings count and severity:
376
+ - 0 CRITICAL/HIGH findings 100 for that dimension
377
+ - 1 CRITICALdimension capped at 40
378
+ - 1 HIGH → dimension capped at 70
379
+ - Each additional MEDIUM → subtract 5 (floor: 50)
380
+
381
+ ### Grade Thresholds
382
+
383
+ | Score | Grade | Verdict |
384
+ |-------|-------|---------|
385
+ | 90100 | Excellent | APPROVE |
386
+ | 7589 | Good | APPROVE with notes |
387
+ | 6074 | Fair | REQUEST CHANGES (MEDIUM issues) |
388
+ | 40–59 | Poor | REQUEST CHANGES (HIGH issues present) |
389
+ | 0–39 | Critical | REQUEST CHANGES (CRITICAL present) |
390
+
391
+ **When to include**: Only when `mode: "scored"` is passed by the caller, or when invoked by `audit`. Default review output uses the standard severity-ranked report without the score.
392
+
393
+
394
+ ## Severity Levels
395
+
396
+ ```
397
+ CRITICAL security vulnerability, data loss risk, crash bug
398
+ HIGH logic error, missing validation, broken edge case
399
+ MEDIUM — code smell, performance issue, missing error handling
400
+ LOW — style inconsistency, naming suggestion, minor refactor opportunity
401
+ ```
402
+
403
+ ## Output Format
404
+
405
+ ```
406
+ ## Code Review Report
407
+ - **Files Reviewed**: [count]
408
+ - **Findings**: [count by severity]
409
+ - **Review Commit**: [git hash at time of review]
410
+ - **Overall**: APPROVE | REQUEST CHANGES | NEEDS DISCUSSION
411
+
412
+ ### Spec Compliance
413
+ - [PASS/FAIL]: [acceptance criteria coverage]
414
+
415
+ ### CRITICAL
416
+ - `path/to/file.ts:42` — [description of critical issue]
417
+
418
+ ### HIGH
419
+ - `path/to/file.ts:85` — [description of high-severity issue]
420
+
421
+ ### MEDIUM
422
+ - `path/to/file.ts:120` — [description of medium issue]
423
+
424
+ ### Blast Radius
425
+ - [High-impact symbols with caller counts]
426
+
427
+ ### Positive Notes
428
+ - [good patterns observed]
429
+
430
+ ### Verdict
431
+ [Summary and recommendation]
432
+ ```
433
+
434
+ ### Review Staleness Detection
435
+
436
+ Track the git commit hash at review time. If code changes after review → review is STALE.
437
+
438
+ ```
439
+ Review commit: abc123 → Code changed to def456 → Review is STALE, re-review required
440
+ ```
441
+
442
+ When `cook` or `ship` checks review status: compare review commit hash with current HEAD. If different → WARN: "Review is stale — code changed since last review."
443
+
444
+
445
+ ## Constraints
446
+
447
+ 1. MUST read the full diff not just the files the user pointed at
448
+ 2. MUST reference specific file:line for every finding
449
+ 3. MUST NOT rubber-stamp with generic praise ("well-structured", "clean code") without evidence
450
+ 4. MUST check: correctness, security, performance, conventions, test coverage
451
+ 5. MUST categorize findings: CRITICAL (blocks commit) / HIGH / MEDIUM / LOW
452
+ 6. MUST escalate to sentinel if auth/crypto/secrets code is touched
453
+ 7. MUST flag untested code paths and recommend tests via rune:test
454
+
455
+ ## Returns
456
+
457
+ | Artifact | Format | Location |
458
+ |----------|--------|----------|
459
+ | Code review report | Markdown | inline (chat output) |
460
+ | Severity-ranked findings | Markdown table | inline |
461
+ | Spec compliance verdict | Markdown | inline |
462
+ | Composite quality score | Markdown table | inline (when `mode: "scored"`) |
463
+ | Blast radius assessment | Markdown table | inline |
464
+
465
+ ## Sharp Edges
466
+
467
+ | Failure Mode | Severity | Mitigation |
468
+ |---|---|---|
469
+ | Finding flood 20+ findings overwhelm developer | MEDIUM | Confidence filter: only >80% confidence, consolidate similar issues per file |
470
+ | "LGTM" without file:line evidence | HIGH | HARD-GATE blocks this cite at least one specific item per changed file |
471
+ | Expanding review scope beyond the diff | MEDIUM | Limit to `git diff` scope do not creep into adjacent unchanged files |
472
+ | Security finding without sentinel escalation | HIGH | Any auth/crypto/payment code touched MUST call rune:sentinel |
473
+ | Skipping UI anti-pattern checks for frontend changes | MEDIUM | Any .tsx/.jsx/.svelte/.vue in diff MUST run UI/UX Anti-Pattern Checks section |
474
+ | Skipping spec compliance check (Step 5.5 Stage 1) | HIGH | Code quality without spec check ships clean code that does the wrong thing always load the plan/ticket before reviewing quality |
475
+ | Treating purple/indigo accent as "just a color choice" | MEDIUM | It is a documented AI-generated UI signature always flag for domain justification |
476
+ | Suggesting "add X" without checking if X is used | MEDIUM | YAGNI pushback: grep codebase for the suggested feature → if uncalled anywhere respond "Not called anywhere. Remove? (YAGNI)". Valid pushback, not laziness |
477
+ | Adding abstractions "for future flexibility" | MEDIUM | Three similar lines > premature abstraction. Only abstract when there are 3+ concrete callers today |
478
+ | Missing cross-phase integration check at phase boundary | MEDIUM | When reviewing a phase completion: check orphaned exports, uncalled routes, auth gaps, E2E flow continuity. Delegate to completion-gate Step 4.5 |
479
+
480
+ ## Done When
481
+
482
+ - All changed files in the diff read and analyzed
483
+ - Every finding references specific file:line with severity label
484
+ - Security-critical code escalated to sentinel (or confirmed not present)
485
+ - Test coverage gaps identified and documented
486
+ - UI anti-pattern checks ran for any frontend files in diff (or confirmed not applicable)
487
+ - Structured report emitted with APPROVE / REQUEST CHANGES / NEEDS DISCUSSION verdict
488
+
489
+ ## Cost Profile
490
+
491
+ ~3000-6000 tokens input, ~1000-2000 tokens output. Sonnet default, opus for security-critical reviews. Runs once per implementation cycle.