@rune-kit/rune 2.10.0 → 2.12.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 (240) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +65 -6
  3. package/commands/rune.md +168 -168
  4. package/compiler/__tests__/detect-invariants.test.js +136 -0
  5. package/compiler/__tests__/doctor-mesh.test.js +229 -0
  6. package/compiler/__tests__/hook-dispatch.test.js +91 -0
  7. package/compiler/__tests__/hooks-antigravity.test.js +118 -0
  8. package/compiler/__tests__/hooks-cursor.test.js +139 -0
  9. package/compiler/__tests__/hooks-install.test.js +305 -0
  10. package/compiler/__tests__/hooks-merge.test.js +204 -0
  11. package/compiler/__tests__/hooks-tiers.test.js +519 -0
  12. package/compiler/__tests__/hooks-windsurf.test.js +115 -0
  13. package/compiler/__tests__/inject-claude-md.test.js +152 -0
  14. package/compiler/__tests__/load-invariants.test.js +408 -0
  15. package/compiler/__tests__/onboard-invariants.test.js +240 -0
  16. package/compiler/adapters/hooks/antigravity.js +140 -0
  17. package/compiler/adapters/hooks/claude.js +166 -0
  18. package/compiler/adapters/hooks/cursor.js +191 -0
  19. package/compiler/adapters/hooks/index.js +82 -0
  20. package/compiler/adapters/hooks/tier-emitter.js +182 -0
  21. package/compiler/adapters/hooks/windsurf.js +202 -0
  22. package/compiler/bin/rune.js +196 -6
  23. package/compiler/commands/hook-dispatch.js +87 -0
  24. package/compiler/commands/hooks/install.js +120 -0
  25. package/compiler/commands/hooks/merge.js +211 -0
  26. package/compiler/commands/hooks/presets.js +116 -0
  27. package/compiler/commands/hooks/status.js +112 -0
  28. package/compiler/commands/hooks/tiers.js +221 -0
  29. package/compiler/commands/hooks/uninstall.js +94 -0
  30. package/compiler/doctor.js +236 -0
  31. package/contexts/dev.md +34 -34
  32. package/contexts/research.md +43 -43
  33. package/contexts/review.md +55 -55
  34. package/extensions/ai-ml/PACK.md +88 -88
  35. package/extensions/ai-ml/skills/ai-agents.md +172 -172
  36. package/extensions/ai-ml/skills/code-sandbox.md +187 -187
  37. package/extensions/ai-ml/skills/deep-research.md +146 -146
  38. package/extensions/ai-ml/skills/embedding-search.md +66 -66
  39. package/extensions/ai-ml/skills/fine-tuning-guide.md +74 -74
  40. package/extensions/ai-ml/skills/llm-architect.md +125 -125
  41. package/extensions/ai-ml/skills/llm-integration.md +64 -64
  42. package/extensions/ai-ml/skills/prompt-patterns.md +72 -72
  43. package/extensions/ai-ml/skills/rag-patterns.md +66 -66
  44. package/extensions/ai-ml/skills/web-extraction.md +114 -114
  45. package/extensions/analytics/PACK.md +92 -92
  46. package/extensions/analytics/skills/ab-testing.md +72 -72
  47. package/extensions/analytics/skills/dashboard-patterns.md +83 -83
  48. package/extensions/analytics/skills/data-validation.md +68 -68
  49. package/extensions/analytics/skills/funnel-analysis.md +81 -81
  50. package/extensions/analytics/skills/sql-patterns.md +57 -57
  51. package/extensions/analytics/skills/statistical-analysis.md +79 -79
  52. package/extensions/analytics/skills/tracking-setup.md +71 -71
  53. package/extensions/backend/PACK.md +104 -104
  54. package/extensions/backend/skills/api-patterns.md +84 -84
  55. package/extensions/backend/skills/async-pipeline.md +193 -193
  56. package/extensions/backend/skills/auth-patterns.md +97 -97
  57. package/extensions/backend/skills/background-jobs.md +133 -133
  58. package/extensions/backend/skills/caching-patterns.md +108 -108
  59. package/extensions/backend/skills/cli-generation.md +133 -133
  60. package/extensions/backend/skills/database-patterns.md +87 -87
  61. package/extensions/backend/skills/middleware-patterns.md +104 -104
  62. package/extensions/chrome-ext/PACK.md +93 -93
  63. package/extensions/chrome-ext/skills/cws-preflight.md +143 -143
  64. package/extensions/chrome-ext/skills/cws-publish.md +104 -104
  65. package/extensions/chrome-ext/skills/ext-ai-integration.md +251 -251
  66. package/extensions/chrome-ext/skills/ext-messaging.md +139 -139
  67. package/extensions/chrome-ext/skills/ext-storage.md +133 -133
  68. package/extensions/chrome-ext/skills/mv3-scaffold.md +164 -164
  69. package/extensions/content/PACK.md +96 -96
  70. package/extensions/content/skills/blog-patterns.md +88 -88
  71. package/extensions/content/skills/cms-integration.md +131 -131
  72. package/extensions/content/skills/content-scoring.md +107 -107
  73. package/extensions/content/skills/i18n.md +83 -83
  74. package/extensions/content/skills/mdx-authoring.md +137 -137
  75. package/extensions/content/skills/reference.md +1014 -1014
  76. package/extensions/content/skills/seo-patterns.md +67 -67
  77. package/extensions/content/skills/video-repurpose.md +153 -153
  78. package/extensions/devops/PACK.md +101 -101
  79. package/extensions/devops/skills/chaos-testing.md +67 -67
  80. package/extensions/devops/skills/ci-cd.md +75 -75
  81. package/extensions/devops/skills/docker.md +58 -58
  82. package/extensions/devops/skills/edge-serverless.md +163 -163
  83. package/extensions/devops/skills/infra-as-code.md +158 -158
  84. package/extensions/devops/skills/kubernetes.md +110 -110
  85. package/extensions/devops/skills/monitoring.md +57 -57
  86. package/extensions/devops/skills/server-setup.md +64 -64
  87. package/extensions/devops/skills/ssl-domain.md +42 -42
  88. package/extensions/ecommerce/PACK.md +116 -116
  89. package/extensions/ecommerce/skills/cart-system.md +79 -79
  90. package/extensions/ecommerce/skills/inventory-mgmt.md +102 -102
  91. package/extensions/ecommerce/skills/order-management.md +126 -126
  92. package/extensions/ecommerce/skills/payment-integration.md +472 -472
  93. package/extensions/ecommerce/skills/shopify-dev.md +69 -69
  94. package/extensions/ecommerce/skills/subscription-billing.md +93 -93
  95. package/extensions/ecommerce/skills/tax-compliance.md +117 -117
  96. package/extensions/gamedev/PACK.md +142 -142
  97. package/extensions/gamedev/skills/asset-pipeline.md +74 -74
  98. package/extensions/gamedev/skills/audio-system.md +129 -129
  99. package/extensions/gamedev/skills/camera-system.md +87 -87
  100. package/extensions/gamedev/skills/ecs.md +98 -98
  101. package/extensions/gamedev/skills/game-loops.md +72 -72
  102. package/extensions/gamedev/skills/input-system.md +199 -199
  103. package/extensions/gamedev/skills/multiplayer.md +180 -180
  104. package/extensions/gamedev/skills/particles.md +105 -105
  105. package/extensions/gamedev/skills/physics-engine.md +89 -89
  106. package/extensions/gamedev/skills/scene-management.md +146 -146
  107. package/extensions/gamedev/skills/threejs-patterns.md +90 -90
  108. package/extensions/gamedev/skills/webgl.md +71 -71
  109. package/extensions/mobile/PACK.md +106 -106
  110. package/extensions/mobile/skills/app-store-connect.md +152 -152
  111. package/extensions/mobile/skills/app-store-prep.md +66 -66
  112. package/extensions/mobile/skills/deep-linking.md +109 -109
  113. package/extensions/mobile/skills/flutter.md +60 -60
  114. package/extensions/mobile/skills/ios-build-pipeline.md +142 -142
  115. package/extensions/mobile/skills/native-bridge.md +66 -66
  116. package/extensions/mobile/skills/ota-updates.md +97 -97
  117. package/extensions/mobile/skills/push-notifications.md +111 -111
  118. package/extensions/mobile/skills/react-native.md +82 -82
  119. package/extensions/saas/PACK.md +116 -116
  120. package/extensions/saas/skills/billing-integration.md +200 -200
  121. package/extensions/saas/skills/feature-flags.md +130 -130
  122. package/extensions/saas/skills/multi-tenant.md +103 -103
  123. package/extensions/saas/skills/onboarding-flow.md +139 -139
  124. package/extensions/saas/skills/subscription-flow.md +95 -95
  125. package/extensions/saas/skills/team-management.md +144 -144
  126. package/extensions/security/PACK.md +99 -99
  127. package/extensions/security/skills/api-security.md +140 -140
  128. package/extensions/security/skills/compliance.md +68 -68
  129. package/extensions/security/skills/owasp-audit.md +64 -64
  130. package/extensions/security/skills/pentest-patterns.md +77 -77
  131. package/extensions/security/skills/secret-mgmt.md +65 -65
  132. package/extensions/security/skills/supply-chain.md +65 -65
  133. package/extensions/trading/PACK.md +80 -80
  134. package/extensions/trading/skills/chart-components.md +55 -55
  135. package/extensions/trading/skills/experiment-loop.md +125 -125
  136. package/extensions/trading/skills/fintech-patterns.md +47 -47
  137. package/extensions/trading/skills/indicator-library.md +58 -58
  138. package/extensions/trading/skills/quant-analysis.md +111 -111
  139. package/extensions/trading/skills/realtime-data.md +58 -58
  140. package/extensions/trading/skills/trade-logic.md +104 -104
  141. package/extensions/ui/PACK.md +130 -130
  142. package/extensions/ui/skills/a11y-audit.md +91 -91
  143. package/extensions/ui/skills/animation-patterns.md +127 -127
  144. package/extensions/ui/skills/component-patterns.md +100 -100
  145. package/extensions/ui/skills/design-decision.md +108 -108
  146. package/extensions/ui/skills/design-system.md +68 -68
  147. package/extensions/ui/skills/landing-patterns.md +155 -155
  148. package/extensions/ui/skills/palette-picker.md +173 -173
  149. package/extensions/ui/skills/react-health.md +90 -90
  150. package/extensions/ui/skills/type-system.md +125 -125
  151. package/extensions/ui/skills/web-vitals.md +153 -153
  152. package/extensions/zalo/PACK.md +145 -145
  153. package/extensions/zalo/skills/zalo-oa-mcp.md +317 -317
  154. package/extensions/zalo/skills/zalo-oa-messaging.md +429 -429
  155. package/extensions/zalo/skills/zalo-oa-setup.md +236 -236
  156. package/extensions/zalo/skills/zalo-oa-webhook.md +189 -189
  157. package/extensions/zalo/skills/zalo-personal-messaging.md +194 -194
  158. package/extensions/zalo/skills/zalo-personal-setup.md +153 -153
  159. package/extensions/zalo/skills/zalo-rate-guard.md +219 -219
  160. package/hooks/auto-format/index.cjs +48 -48
  161. package/hooks/hooks.json +111 -111
  162. package/hooks/post-session-reflect/index.cjs +189 -189
  163. package/hooks/pre-compact/index.cjs +95 -95
  164. package/hooks/run-hook.cmd +1 -1
  165. package/hooks/secrets-scan/index.cjs +100 -100
  166. package/hooks/session-start/index.cjs +71 -71
  167. package/hooks/typecheck/index.cjs +65 -65
  168. package/package.json +63 -63
  169. package/references/ui-pro-max-data/LICENSE-UI-PRO-MAX +21 -21
  170. package/references/ui-pro-max-data/charts.csv +26 -26
  171. package/references/ui-pro-max-data/colors.csv +161 -161
  172. package/references/ui-pro-max-data/styles.csv +68 -68
  173. package/references/ui-pro-max-data/typography.csv +74 -74
  174. package/references/ui-pro-max-data/ui-reasoning.csv +162 -162
  175. package/references/ui-pro-max-data/ux-guidelines.csv +99 -99
  176. package/skills/adversary/SKILL.md +283 -283
  177. package/skills/asset-creator/SKILL.md +157 -157
  178. package/skills/audit/SKILL.md +147 -2
  179. package/skills/autopsy/SKILL.md +335 -335
  180. package/skills/ba/SKILL.md +85 -1
  181. package/skills/brainstorm/SKILL.md +380 -342
  182. package/skills/browser-pilot/SKILL.md +169 -168
  183. package/skills/constraint-check/SKILL.md +165 -165
  184. package/skills/context-engine/SKILL.md +408 -404
  185. package/skills/cook/SKILL.md +917 -863
  186. package/skills/db/SKILL.md +273 -273
  187. package/skills/debug/SKILL.md +465 -465
  188. package/skills/dependency-doctor/SKILL.md +265 -235
  189. package/skills/deploy/SKILL.md +274 -231
  190. package/skills/design/DESIGN-REFERENCE.md +365 -365
  191. package/skills/design/SKILL.md +590 -589
  192. package/skills/doc-processor/SKILL.md +254 -254
  193. package/skills/docs/SKILL.md +374 -374
  194. package/skills/docs-seeker/SKILL.md +178 -177
  195. package/skills/fix/SKILL.md +332 -330
  196. package/skills/git/SKILL.md +339 -339
  197. package/skills/hallucination-guard/SKILL.md +220 -219
  198. package/skills/incident/SKILL.md +254 -253
  199. package/skills/integrity-check/SKILL.md +169 -169
  200. package/skills/journal/SKILL.md +241 -240
  201. package/skills/launch/SKILL.md +344 -344
  202. package/skills/logic-guardian/SKILL.md +269 -251
  203. package/skills/marketing/SKILL.md +351 -289
  204. package/skills/mcp-builder/SKILL.md +425 -425
  205. package/skills/neural-memory/SKILL.md +359 -362
  206. package/skills/onboard/SKILL.md +432 -403
  207. package/skills/onboard/references/invariants-template.md +76 -0
  208. package/skills/onboard/scripts/detect-invariants.js +439 -0
  209. package/skills/onboard/scripts/inject-claude-md.js +150 -0
  210. package/skills/onboard/scripts/onboard-invariants.js +194 -0
  211. package/skills/perf/SKILL.md +347 -346
  212. package/skills/plan/SKILL.md +435 -428
  213. package/skills/preflight/SKILL.md +415 -415
  214. package/skills/problem-solver/SKILL.md +380 -284
  215. package/skills/rescue/SKILL.md +474 -474
  216. package/skills/research/SKILL.md +4 -0
  217. package/skills/retro/SKILL.md +3 -1
  218. package/skills/review/SKILL.md +614 -588
  219. package/skills/review-intake/SKILL.md +249 -249
  220. package/skills/safeguard/SKILL.md +200 -200
  221. package/skills/sast/SKILL.md +190 -190
  222. package/skills/scaffold/SKILL.md +328 -287
  223. package/skills/scope-guard/SKILL.md +183 -180
  224. package/skills/scout/SKILL.md +269 -263
  225. package/skills/sentinel/SKILL.md +384 -381
  226. package/skills/sentinel-env/SKILL.md +254 -254
  227. package/skills/sequential-thinking/SKILL.md +234 -234
  228. package/skills/session-bridge/SKILL.md +595 -543
  229. package/skills/session-bridge/scripts/load-invariants.js +397 -0
  230. package/skills/skill-forge/SKILL.md +581 -581
  231. package/skills/skill-router/SKILL.md +3 -0
  232. package/skills/slides/SKILL.md +19 -0
  233. package/skills/surgeon/SKILL.md +215 -215
  234. package/skills/team/SKILL.md +557 -537
  235. package/skills/test/SKILL.md +620 -614
  236. package/skills/trend-scout/SKILL.md +145 -145
  237. package/skills/verification/SKILL.md +334 -326
  238. package/skills/video-creator/SKILL.md +201 -201
  239. package/skills/watchdog/SKILL.md +168 -168
  240. package/skills/worktree/SKILL.md +140 -140
@@ -1,588 +1,614 @@
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.8.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, docs.updated
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 contextscout finds related code
61
- - `review` `fix` — complex fix requests self-review
62
- - `review` → `sentinel` — security-critical codesentinel 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
- #### Per-Function Test Gap Analysis
208
-
209
- Go beyond "test file exists" check coverage at function granularity:
210
-
211
- 1. **Extract changed functions** from the diff, list every function/method that was added or modified (name + file:line)
212
- 2. **Map to test assertions** — for each changed function, Grep the test file for its name. Count distinct test cases (look for `it(`, `test(`, `describe(` blocks that reference the function)
213
- 3. **Classify gap severity**:
214
-
215
- | Function Type | 0 tests | 1 test | 2+ tests |
216
- |--------------|---------|--------|----------|
217
- | Business logic (money, auth, state) | BLOCK | WARN: "only happy path" | PASS |
218
- | Data transform (parse, format, map) | HIGH | PASS | PASS |
219
- | Event handler (onClick, onSubmit) | MEDIUM | PASS | PASS |
220
- | Pure utility (string, math, date) | MEDIUM | PASS | PASS |
221
-
222
- 4. **Output per-function table** in review report:
223
-
224
- ```
225
- ### Test Gap Analysis
226
- | Function | File | Tests Found | Verdict |
227
- |----------|------|-------------|---------|
228
- | calculateTotal | src/billing.ts:42 | 3 (happy, zero, overflow) | PASS |
229
- | processRefund | src/billing.ts:89 | 0 | BLOCK business logic untested |
230
- | formatCurrency | src/utils.ts:12 | 1 | PASS |
231
- ```
232
-
233
- 5. **Flag untested edge cases** — for functions with only 1 test, check if the test covers: empty/null input, boundary values, error path. If only happy path → WARN: "only happy path tested for {function}"
234
-
235
- **Skip if**: Diff only touches config, docs, styles, or test files themselves.
236
-
237
- ### Step 5.5: Two-Stage Review Gate
238
-
239
- Separate spec compliance from code quality. Most reviews conflate both — this gate forces the distinction.
240
-
241
- **Stage 1 Spec Compliance (check FIRST)**
242
-
243
- Before evaluating code quality, verify the implementation matches what was asked:
244
-
245
- - Load the originating plan, task, ticket, or `requirements.md` if available
246
- - Does the implementation cover every acceptance criterion? Check each one explicitly
247
- - Is there **under-engineering** — requirements stated but not implemented?
248
- - Is there **over-engineering** abstractions, generalization, or features beyond scope?
249
- - Does the file/function structure match what the plan specified?
250
-
251
- Flag spec deviations as HIGH — clean code that misses requirements ships broken products.
252
-
253
- ```
254
- # Spec Compliance Checklist
255
- [ ] All acceptance criteria from plan/ticket covered
256
- [ ] No stated requirements missing from implementation
257
- [ ] No unrequested features added (scope creep)
258
- [ ] API surface matches what was specified (signatures, endpoints, return types)
259
- [ ] File structure matches plan (no renamed or relocated files without justification)
260
- ```
261
-
262
- If spec violations found: document them separately from code quality findings in the report. Label as `SPEC-MISS` or `SPEC-CREEP`.
263
-
264
- **Stage 2 — Code Quality**
265
-
266
- Proceed to Step 6 only after Stage 1 passes. Code quality findings (bugs, patterns, security, coverage) are the existing Steps 2–5 above.
267
-
268
- The review report MUST show both stages: spec compliance verdict first, then code quality findings.
269
-
270
- ### Step 6: Report
271
-
272
- Produce a structured severity-ranked report.
273
-
274
- **Before reporting, apply confidence filter:**
275
- - Only report findings with >80% confidence it is a real issue
276
- - Consolidate similar issues: "8 functions missing error handling in src/services/" — not 8 separate findings
277
- - Skip stylistic preferences unless they violate conventions found in `.eslintrc`, `CLAUDE.md`, or `CONTRIBUTING.md`
278
- - Adapt to project type: a `console.log` in a CLI tool is fine; in a production API handler it is not
279
-
280
- - Group findings by severity: CRITICAL → HIGH → MEDIUM → LOW
281
- - Include file path and line number for every finding
282
- - Include a Positive Notes section (good patterns observed)
283
- - Include a Verdict: APPROVE | REQUEST CHANGES | NEEDS DISCUSSION
284
-
285
- ### Step 6.5: Fix-First Triage
286
-
287
- > From gstack (garrytan/gstack, 50.9k★): "Reviews that produce 20 findings and delegate all to the user waste everyone's time."
288
-
289
- Classify each finding as **AUTO-FIX** or **ASK** before reporting:
290
-
291
- | Category | Auto-Fix? | Examples |
292
- |----------|-----------|---------|
293
- | Dead imports, unused variables | AUTO-FIX | `import { foo } from './bar'` where foo is never used |
294
- | Missing error handling on obvious paths | AUTO-FIX | `await fetch()` without try/catch in production code |
295
- | Console.log in production code | AUTO-FIX | Remove `console.log` from non-CLI production files |
296
- | Architectural concern, trade-off | ASK | "This bypasses the auth middleware — intentional?" |
297
- | Ambiguous intent | ASK | "Is this fallback behavior correct for null users?" |
298
- | Style/convention disagreement | ASK | "Project uses camelCase but this file uses snake_case" |
299
-
300
- **After classification:**
301
- - Apply AUTO-FIX findings directly via `rune:fix` include all in a single batch
302
- - Collect ASK findings into ONE `AskUserQuestion` — not 5 separate questions
303
- - Report both: "Auto-fixed 4 issues. 2 findings need your input: [...]"
304
-
305
- **Rationalization prevention**: "This looks fine" is NOT acceptable without evidence. If you can't cite a specific file:line or convention that justifies the code, flag it as UNVERIFIED — don't rationalize away uncertainty.
306
-
307
- ### Step 6.6: Scope Drift Detection
308
-
309
- > From gstack (garrytan/gstack, 50.9k★): "Intent vs diff catches scope creep that plan-based guards miss."
310
-
311
- After reviewing code, compare **stated intent** vs **actual diff**:
312
-
313
- 1. Read the originating source: TODO list, PR description, commit messages, or plan file
314
- 2. Extract stated intent: "what was this change supposed to do?"
315
- 3. Run `git diff --stat` to see actual file changes
316
- 4. Compare:
317
-
318
- | Result | Meaning | Action |
319
- |--------|---------|--------|
320
- | **CLEAN** | All changed files serve the stated intent | Note in report |
321
- | **DRIFT** | 1-2 files changed that don't relate to stated intent | WARN — "These files were modified but aren't mentioned in the task: [list]" |
322
- | **REQUIREMENTS_MISSING** | Stated intent mentions files/features not in the diff | WARN — "Task mentions X but it's not in the diff" |
323
-
324
- **This is informational, not blocking.** Scope drift is common and sometimes intentional — but making it visible prevents silent creep.
325
-
326
- After reporting:
327
- - If any CRITICAL findings: call `rune:fix` immediately with the finding details
328
- - If any HIGH findings: call `rune:fix` with the finding details
329
- - If untested code: call `rune:test` with specific coverage gaps identified
330
- - Call `neural-memory` (Capture Mode) to save any novel code quality patterns or recurring issues found.
331
-
332
- ## Framework-Specific Checks
333
-
334
- Apply **only** if the framework is detected in the changed files. Skip if not relevant.
335
-
336
- **React / Next.js** (detect: `import React` or `.tsx` files)
337
- - `useEffect` with missing dependencies (stale closure) flag HIGH
338
- - List items using index as key on reorderable lists: `key={i}` → flag MEDIUM
339
- - Props drilled through 3+ levels without Context or composition flag MEDIUM
340
- - Client-side hooks (`useState`, `useEffect`) in Server Components (Next.js App Router) → flag HIGH
341
-
342
- **Node.js / Express** (detect: `import express` or `require('express')`)
343
- - Missing rate limiting on public endpoints → flag MEDIUM
344
- - `req.body` passed directly to DB without validation schema → flag HIGH
345
- - Synchronous operations blocking the event loop inside async handlers → flag HIGH
346
-
347
- **Python** (detect: `.py` files with `django`, `flask`, or `fastapi` imports)
348
- - `except:` bare catch without specific exception type flag MEDIUM
349
- - Mutable default arguments: `def func(items=[])` → flag HIGH
350
- - Missing type hints on public functions (if project uses mypy/pyright) flag LOW
351
-
352
- ## UI/UX Anti-Pattern Checks
353
-
354
- Apply **only** when `.tsx`, `.jsx`, `.svelte`, `.vue`, or `.html` files are in the diff. Skip for backend-only changes.
355
-
356
- These are the **"AI UI signature"** patterns that make AI-generated frontends visually identifiable as non-human-designed. Flag each as MEDIUM severity.
357
-
358
- **AI_ANTIPATTERN Purple/indigo default accent with no domain justification:**
359
- ```tsx
360
- // BAD: LLM default color bias signals "AI-generated" to experienced designers
361
- className="bg-indigo-600 text-white" // every button/CTA is indigo
362
- // GOOD: domain-appropriate trading neutral dark, healthcare → trust blue,
363
- // e-commerce conversion-optimized warm. Purple is only appropriate for
364
- // AI-native tools and creative platforms.
365
- ```
366
-
367
- **AI_ANTIPATTERN — Card-grid monotony (every section is 3-col cards, zero layout variation):**
368
- ```tsx
369
- // BAD: every section uses the same grid pattern
370
- <div className="grid grid-cols-3 gap-6"> // features
371
- <div className="grid grid-cols-3 gap-6"> // testimonials
372
- <div className="grid grid-cols-3 gap-6"> // pricing
373
- // GOOD: mix layouts split sections, bento grids, full-bleed hero, list+detail
374
- ```
375
-
376
- **AI_ANTIPATTERN Centeritis (everything centered, no directional flow):**
377
- ```tsx
378
- // BAD: no visual tension, no reading direction
379
- <div className="text-center flex flex-col items-center"> // hero
380
- <div className="text-center"> // every feature section
381
- // GOOD: left-align body copy, use centering intentionally for hero/CTAs only
382
- ```
383
-
384
- **AI_ANTIPATTERN — Numeric/financial values in non-monospace font:**
385
- ```tsx
386
- // BAD: prices, stats, metrics in Inter/Roboto
387
- <span className="text-2xl font-bold">${price}</span>
388
- // GOOD: monospace for all numbers that need alignment
389
- <span className="font-mono text-2xl font-bold">${price}</span>
390
- ```
391
-
392
- **AI_ANTIPATTERN — Missing UI states (only happy path rendered):**
393
- ```tsx
394
- // BAD: data rendering without empty/error/loading states
395
- {data.map(item => <Card key={item.id} {...item} />)}
396
- // GOOD: all 4 states covered
397
- {isLoading && <CardSkeleton />}
398
- {error && <ErrorState message={error.message} />}
399
- {!data.length && <EmptyState />}
400
- {data.map(item => <Card key={item.id} {...item} />)}
401
- ```
402
-
403
- **Accessibility — flag as HIGH (these are WCAG 2.2 failures):**
404
- ```tsx
405
- // BAD: icon button with no accessible name
406
- <button onClick={close}><XIcon /></button>
407
- // GOOD
408
- <button onClick={close} aria-label="Close dialog"><XIcon aria-hidden="true" /></button>
409
-
410
- // BAD: placeholder as label
411
- <input placeholder="Email address" type="email" />
412
- // GOOD
413
- <label htmlFor="email">Email address</label>
414
- <input id="email" type="email" />
415
-
416
- // BAD: removes focus ring without replacement
417
- className="focus:outline-none"
418
- // GOOD: must have focus-visible replacement
419
- className="focus:outline-none focus-visible:ring-2 focus-visible:ring-blue-500"
420
-
421
- // BAD: color as sole information conveyor
422
- <span className="text-red-500">{errorMessage}</span>
423
- // GOOD: icon + color + text
424
- <span className="text-red-500 flex gap-1"><ErrorIcon aria-hidden />Error: {errorMessage}</span>
425
- ```
426
-
427
- **WCAG 2.2 New Rules — flag as MEDIUM:**
428
- - `position: sticky` or `position: fixed` header/footer without `scroll-padding-top` → Focus Not Obscured (2.4.11)
429
- - Interactive elements with `width < 24px` or `height < 24px` without 8px spacing → Target Size (2.5.8)
430
- - Multi-step form re-asking for previously entered data → Redundant Entry (3.3.7)
431
-
432
- **Platform-Specific flag as MEDIUM when platform is detectable:**
433
- - iOS target: solid-background cards (iOS 26 Liquid Glass deprecates this visual language) — should use translucent/blur surfaces
434
- - Android target: hardcoded hex colors instead of `MaterialTheme.colorScheme` tokens → not adaptive to dynamic color
435
-
436
- ## Weighted Composite Scoring
437
-
438
- 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.
439
-
440
- ### Formula
441
-
442
- ```
443
- Quality Score = (Correctness × 0.35) + (Security × 0.30) + (Test Coverage × 0.20) + (Conventions × 0.15)
444
- ```
445
-
446
- Each dimension is scored 0–100 based on findings count and severity:
447
- - 0 CRITICAL/HIGH findings 100 for that dimension
448
- - 1 CRITICAL → dimension capped at 40
449
- - 1 HIGH dimension capped at 70
450
- - Each additional MEDIUM → subtract 5 (floor: 50)
451
-
452
- ### Grade Thresholds
453
-
454
- | Score | Grade | Verdict |
455
- |-------|-------|---------|
456
- | 90–100 | Excellent | APPROVE |
457
- | 75–89 | Good | APPROVE with notes |
458
- | 60–74 | Fair | REQUEST CHANGES (MEDIUM issues) |
459
- | 40–59 | Poor | REQUEST CHANGES (HIGH issues present) |
460
- | 0–39 | Critical | REQUEST CHANGES (CRITICAL present) |
461
-
462
- **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.
463
-
464
-
465
- ## Severity Levels
466
-
467
- ```
468
- CRITICAL — security vulnerability, data loss risk, crash bug
469
- HIGH — logic error, missing validation, broken edge case
470
- MEDIUM — code smell, performance issue, missing error handling
471
- LOW — style inconsistency, naming suggestion, minor refactor opportunity
472
- ```
473
-
474
- ## Output Format
475
-
476
- ```
477
- ## Code Review Report
478
- - **Files Reviewed**: [count]
479
- - **Findings**: [count by severity]
480
- - **Review Commit**: [git hash at time of review]
481
- - **Overall**: APPROVE | REQUEST CHANGES | NEEDS DISCUSSION
482
-
483
- ### Spec Compliance
484
- - [PASS/FAIL]: [acceptance criteria coverage]
485
-
486
- ### CRITICAL
487
- - `path/to/file.ts:42` — [description of critical issue]
488
-
489
- ### HIGH
490
- - `path/to/file.ts:85` — [description of high-severity issue]
491
-
492
- ### MEDIUM
493
- - `path/to/file.ts:120` — [description of medium issue]
494
-
495
- ### Blast Radius
496
- - [High-impact symbols with caller counts]
497
-
498
- ### Positive Notes
499
- - [good patterns observed]
500
-
501
- ### Verdict
502
- [Summary and recommendation]
503
- ```
504
-
505
- ### Review Staleness Detection
506
-
507
- Track the git commit hash at review time. If code changes after review → review is STALE.
508
-
509
- ```
510
- Review commit: abc123 Code changed to def456 → Review is STALE, re-review required
511
- ```
512
-
513
- 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."
514
-
515
-
516
- ## Constraints
517
-
518
- 1. MUST read the full diff — not just the files the user pointed at
519
- 2. MUST reference specific file:line for every finding
520
- 3. MUST NOT rubber-stamp with generic praise ("well-structured", "clean code") without evidence
521
- 4. MUST check: correctness, security, performance, conventions, test coverage
522
- 5. MUST categorize findings: CRITICAL (blocks commit) / HIGH / MEDIUM / LOW
523
- 6. MUST escalate to sentinel if auth/crypto/secrets code is touched
524
- 7. MUST flag untested code paths and recommend tests via rune:test
525
-
526
- ## Returns
527
-
528
- | Artifact | Format | Location |
529
- |----------|--------|----------|
530
- | Code review report | Markdown | inline (chat output) |
531
- | Severity-ranked findings | Markdown table | inline |
532
- | Spec compliance verdict | Markdown | inline |
533
- | Composite quality score | Markdown table | inline (when `mode: "scored"`) |
534
- | Blast radius assessment | Markdown table | inline |
535
-
536
- ## Chain Metadata
537
-
538
- Append to Code Review Report when invoked standalone. Suppress when called as sub-skill inside an L1 orchestrator (cook, team, etc.) — the orchestrator emits a consolidated block. See `docs/references/chain-metadata.md`.
539
-
540
- ```yaml
541
- chain_metadata:
542
- skill: "rune:review"
543
- version: "0.8.0"
544
- status: "[DONE | DONE_WITH_CONCERNS]"
545
- domain: "[area reviewed]"
546
- files_changed: [] # review doesn't change files
547
- exports:
548
- findings_count: { critical: [N], high: [N], medium: [N], low: [N] }
549
- findings:
550
- - { severity: "[level]", file: "[path]", line: [N], message: "[issue]" }
551
- verdict: "[APPROVE | REQUEST_CHANGES | NEEDS_DISCUSSION]"
552
- quality_score: [0-100] # when mode: "scored"
553
- suggested_next:
554
- - skill: "rune:fix"
555
- reason: "[grounded in findings — e.g., '2 HIGH findings in api/users.ts need remediation']"
556
- consumes: ["findings"]
557
- ```
558
-
559
- ## Sharp Edges
560
-
561
- | Failure Mode | Severity | Mitigation |
562
- |---|---|---|
563
- | Finding flood — 20+ findings overwhelm developer | MEDIUM | Confidence filter: only >80% confidence, consolidate similar issues per file |
564
- | "LGTM" without file:line evidence | HIGH | HARD-GATE blocks this cite at least one specific item per changed file |
565
- | Expanding review scope beyond the diff | MEDIUM | Limit to `git diff` scope — do not creep into adjacent unchanged files |
566
- | Security finding without sentinel escalation | HIGH | Any auth/crypto/payment code touched → MUST call rune:sentinel |
567
- | Skipping UI anti-pattern checks for frontend changes | MEDIUM | Any .tsx/.jsx/.svelte/.vue in diff → MUST run UI/UX Anti-Pattern Checks section |
568
- | 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 |
569
- | Treating purple/indigo accent as "just a color choice" | MEDIUM | It is a documented AI-generated UI signature — always flag for domain justification |
570
- | 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 |
571
- | Adding abstractions "for future flexibility" | MEDIUM | Three similar lines > premature abstraction. Only abstract when there are 3+ concrete callers today |
572
- | 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 |
573
- | Review loop exceeds 3 iterations without resolution | MEDIUM | Cap at 3 review loops. After 3rd iteration with unresolved findings → surface to user with "these findings persist after 3 fix attempts — needs human decision" |
574
- | Auto-fixing something that should have been ASK | HIGH | When in doubt, ASK. AUTO-FIX only for mechanical issues (dead imports, console.log). Anything involving intent or trade-offs = ASK |
575
- | Scope drift flagged on intentional refactoring | LOW | Scope drift is informational, not blocking. User can override with "intentional" — don't re-flag after override |
576
-
577
- ## Done When
578
-
579
- - All changed files in the diff read and analyzed
580
- - Every finding references specific file:line with severity label
581
- - Security-critical code escalated to sentinel (or confirmed not present)
582
- - Test coverage gaps identified and documented
583
- - UI anti-pattern checks ran for any frontend files in diff (or confirmed not applicable)
584
- - Structured report emitted with APPROVE / REQUEST CHANGES / NEEDS DISCUSSION verdict
585
-
586
- ## Cost Profile
587
-
588
- ~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: "1.0.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, docs.updated
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
+ - `design` (L2): review UI/design implementation quality
56
+ - `graft` (L2): review grafted code integration
57
+
58
+ ## Cross-Hub Connections
59
+
60
+ - `review` → `test` — untested edge case found test writes it
61
+ - `review` `fix` — bug found during review → fix applies correction
62
+ - `review` → `scout` — needs more context scout finds related code
63
+ - `review` ← `fix` — complex fix requests self-review
64
+ - `review` → `sentinel` — security-critical code → sentinel deep scan
65
+
66
+ ## Execution
67
+
68
+ ### Step 1: Scope
69
+
70
+ Determine what to review.
71
+
72
+ - If triggered by a commit or PR: use `Bash` with `git diff main...HEAD` or `git diff HEAD~1` to see exactly what changed
73
+ - If triggered by a specific file or feature: use `Read` on each named file
74
+ - If context is unclear: use `rune:scout` to identify all files touched by the change
75
+ - List every file in scope before proceeding — do not review files outside the stated scope
76
+
77
+ ### Step 1.5: Blast Radius Assessment
78
+
79
+ For each modified function/class, estimate its blast radius before reviewing.
80
+
81
+ ```
82
+ Use Grep to count direct callers/importers of each modified symbol:
83
+ blast_radius = count(files importing or calling this symbol)
84
+ ```
85
+
86
+ | Blast Radius | Risk | Review Depth |
87
+ |-------------|------|-------------|
88
+ | 1-5 callers | Low | Standard review |
89
+ | 6-20 callers | Medium | Check all callers for compatibility |
90
+ | 21-50 callers | High | Thorough review + regression test check |
91
+ | 50+ callers | Critical | MUST escalate to adversarial analysis (rune:adversary) even in quick triage |
92
+
93
+ <HARD-GATE>
94
+ 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.
95
+ </HARD-GATE>
96
+
97
+ ### Step 2: Logic Check (Production-Critical Focus)
98
+
99
+ 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.
100
+
101
+ - Use `Read` on every file in scope
102
+ - **Race conditions**: async operations without proper sequencing, shared mutable state, missing locks
103
+ - **State corruption**: mutations that affect other consumers, cache invalidation gaps, stale closures
104
+ - **Silent failures**: caught errors that swallow context, empty catch blocks, promises without rejection handling
105
+ - **Data loss paths**: write operations without confirmation, delete without soft-delete, truncation without backup
106
+ - **Edge cases**: empty input, null/undefined, zero, negative numbers, empty arrays, Unicode, timezone boundaries
107
+ - Check for: logic errors, off-by-one errors, incorrect conditionals, broken async/await patterns
108
+ - Flag each finding with file path, line number, and severity
109
+
110
+ **Common patterns to flag:**
111
+
112
+ ```typescript
113
+ // BAD missing await causes race condition
114
+ async function saveUser(data) {
115
+ db.users.create(data); // caller proceeds before save completes
116
+ return { success: true };
117
+ }
118
+ // GOOD
119
+ async function saveUser(data) {
120
+ await db.users.create(data);
121
+ return { success: true };
122
+ }
123
+ ```
124
+
125
+ ```typescript
126
+ // BAD null deref crash
127
+ function getUsername(user) {
128
+ return user.profile.name.toUpperCase(); // crashes if profile or name is null
129
+ }
130
+ // GOOD safe access
131
+ function getUsername(user) {
132
+ return user?.profile?.name?.toUpperCase() ?? 'Anonymous';
133
+ }
134
+ ```
135
+
136
+ ### Step 3: Pattern Check
137
+
138
+ Check consistency with project conventions.
139
+
140
+ - Compare naming against existing codebase patterns (use `Grep` to sample similar code)
141
+ - Check file structure: is it in the right layer/directory per project conventions?
142
+ - Check for mutations all state changes should use immutable patterns
143
+ - Check for hardcoded values that should be constants or config
144
+ - Check TypeScript: no `any`, full type coverage, no non-null assertions without justification
145
+ - Flag inconsistencies as MEDIUM or LOW depending on impact
146
+
147
+ **Common patterns to flag:**
148
+
149
+ ```typescript
150
+ // BAD mutation
151
+ function addItem(cart, item) {
152
+ cart.items.push(item); // mutates in place
153
+ return cart;
154
+ }
155
+ // GOOD immutable
156
+ function addItem(cart, item) {
157
+ return { ...cart, items: [...cart.items, item] };
158
+ }
159
+ ```
160
+
161
+ ```typescript
162
+ // BAD any defeats TypeScript's purpose
163
+ function process(data: any): any {
164
+ return data.items.map((i: any) => i.value);
165
+ }
166
+ // GOOD typed
167
+ function process(data: { items: Array<{ value: string }> }): string[] {
168
+ return data.items.map(i => i.value);
169
+ }
170
+ ```
171
+
172
+ ### Step 4: Security Check
173
+
174
+ Check for security-relevant issues.
175
+
176
+ - Scan for: hardcoded secrets, API keys, passwords in code or comments
177
+ - Scan for: unvalidated user input passed to queries, file paths, or shell commands
178
+ - Scan for: missing authentication checks on new routes or functions
179
+ - Scan for: XSS vectors (unsanitized HTML output), CSRF exposure, open redirects
180
+ - If any security-sensitive code found (auth logic, input handling, crypto, payment): call `rune:sentinel` for deep scan
181
+ - Sentinel escalation is mandatory — do not skip it for auth or crypto code
182
+
183
+ ### Step 4.5: API Pit-of-Success Check
184
+
185
+ For code that exposes APIs, shared utilities, or reusable interfaces, evaluate through 3 adversary personas:
186
+
187
+ | Adversary | Mindset | What They Reveal |
188
+ |-----------|---------|-----------------|
189
+ | **The Scoundrel** | Malicious controls config, crafts inputs, exploits edge cases | Security holes, privilege escalation, injection surfaces |
190
+ | **The Lazy Developer** | Copy-pastes from docs, skips error handling, uses defaults | Unsafe defaults, missing validation, footgun APIs |
191
+ | **The Confused Developer** | Misunderstands API semantics, passes wrong types, ignores return values | Ambiguous interfaces, poor naming, missing type safety |
192
+
193
+ **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.
194
+
195
+ Check: Does the API have sensible defaults? Does misuse fail loudly (not silently)? Is the happy path obvious from the signature?
196
+
197
+ **Skip if**: Code is internal-only (no external consumers), single-use utility, or test-only.
198
+
199
+ ### Step 4.7: API Contract / Breaking Change Check
200
+
201
+ For any change that modifies exported functions, REST endpoints, event schemas, or shared types, check for backward-compatibility violations before proceeding.
202
+
203
+ **Breaking change signals** flag any of these as HIGH:
204
+
205
+ | Signal | Example | Why it Breaks |
206
+ |--------|---------|---------------|
207
+ | Removed export | `export function getUser` deleted | Callers crash at import |
208
+ | Renamed parameter | `id: string` → `userId: string` | Named-argument callers break |
209
+ | Narrowed return type | `User \| null` `User` (null removed) | Callers that handle null crash |
210
+ | Required arg added | `fn(a)` → `fn(a, b: string)` | All existing callers missing `b` |
211
+ | Status code changed | 200 204 on success | Clients checking for body break |
212
+ | Event schema changed | `{ userId }` `{ user_id }` | Consumers miss the field |
213
+ | Endpoint path renamed | `/users/:id` → `/users/:userId` | All client URLs broken |
214
+
215
+ **Versioning check:**
216
+ 1. Run `git diff main...HEAD` — list every changed exported symbol
217
+ 2. For each changed export: check if old signature still exists as an alias or overload
218
+ 3. If breaking and no version bump WARN: "Breaking change detected in [symbol] — needs CHANGELOG entry and version bump"
219
+ 4. If `CHANGELOG.md` found: check that breaking changes are documented in the current version entry
220
+
221
+ **Skip if**: Change is internal-only (no exports changed, no public API surface affected), or in test files only.
222
+
223
+ ### Step 5: Test Coverage
224
+
225
+ Identify gaps in test coverage.
226
+
227
+ - Use `Bash` to check if a test file exists for each changed file
228
+ - Use `Glob` to find test files: `**/*.test.ts`, `**/*.spec.ts`, `**/__tests__/**`
229
+ - Read the test file and verify: are the new functions covered? are edge cases tested?
230
+ - If untested code found: call `rune:test` with specific instructions on what to test
231
+ - Flag as HIGH if business logic is untested, MEDIUM if utility code is untested
232
+
233
+ #### Per-Function Test Gap Analysis
234
+
235
+ Go beyond "test file exists" check coverage at function granularity:
236
+
237
+ 1. **Extract changed functions** from the diff, list every function/method that was added or modified (name + file:line)
238
+ 2. **Map to test assertions** — for each changed function, Grep the test file for its name. Count distinct test cases (look for `it(`, `test(`, `describe(` blocks that reference the function)
239
+ 3. **Classify gap severity**:
240
+
241
+ | Function Type | 0 tests | 1 test | 2+ tests |
242
+ |--------------|---------|--------|----------|
243
+ | Business logic (money, auth, state) | BLOCK | WARN: "only happy path" | PASS |
244
+ | Data transform (parse, format, map) | HIGH | PASS | PASS |
245
+ | Event handler (onClick, onSubmit) | MEDIUM | PASS | PASS |
246
+ | Pure utility (string, math, date) | MEDIUM | PASS | PASS |
247
+
248
+ 4. **Output per-function table** in review report:
249
+
250
+ ```
251
+ ### Test Gap Analysis
252
+ | Function | File | Tests Found | Verdict |
253
+ |----------|------|-------------|---------|
254
+ | calculateTotal | src/billing.ts:42 | 3 (happy, zero, overflow) | PASS |
255
+ | processRefund | src/billing.ts:89 | 0 | BLOCK — business logic untested |
256
+ | formatCurrency | src/utils.ts:12 | 1 | PASS |
257
+ ```
258
+
259
+ 5. **Flag untested edge cases** for functions with only 1 test, check if the test covers: empty/null input, boundary values, error path. If only happy path → WARN: "only happy path tested for {function}"
260
+
261
+ **Skip if**: Diff only touches config, docs, styles, or test files themselves.
262
+
263
+ ### Step 5.5: Two-Stage Review Gate
264
+
265
+ Separate spec compliance from code quality. Most reviews conflate both — this gate forces the distinction.
266
+
267
+ **Stage 1 — Spec Compliance (check FIRST)**
268
+
269
+ Before evaluating code quality, verify the implementation matches what was asked:
270
+
271
+ - Load the originating plan, task, ticket, or `requirements.md` if available
272
+ - Does the implementation cover every acceptance criterion? Check each one explicitly
273
+ - Is there **under-engineering** — requirements stated but not implemented?
274
+ - Is there **over-engineering** — abstractions, generalization, or features beyond scope?
275
+ - Does the file/function structure match what the plan specified?
276
+
277
+ Flag spec deviations as HIGH clean code that misses requirements ships broken products.
278
+
279
+ ```
280
+ # Spec Compliance Checklist
281
+ [ ] All acceptance criteria from plan/ticket covered
282
+ [ ] No stated requirements missing from implementation
283
+ [ ] No unrequested features added (scope creep)
284
+ [ ] API surface matches what was specified (signatures, endpoints, return types)
285
+ [ ] File structure matches plan (no renamed or relocated files without justification)
286
+ ```
287
+
288
+ If spec violations found: document them separately from code quality findings in the report. Label as `SPEC-MISS` or `SPEC-CREEP`.
289
+
290
+ **Stage 2 — Code Quality**
291
+
292
+ Proceed to Step 6 only after Stage 1 passes. Code quality findings (bugs, patterns, security, coverage) are the existing Steps 2–5 above.
293
+
294
+ The review report MUST show both stages: spec compliance verdict first, then code quality findings.
295
+
296
+ ### Step 6: Report
297
+
298
+ Produce a structured severity-ranked report.
299
+
300
+ **Before reporting, apply confidence filter:**
301
+ - Only report findings with >80% confidence it is a real issue
302
+ - Consolidate similar issues: "8 functions missing error handling in src/services/" — not 8 separate findings
303
+ - Skip stylistic preferences unless they violate conventions found in `.eslintrc`, `CLAUDE.md`, or `CONTRIBUTING.md`
304
+ - Adapt to project type: a `console.log` in a CLI tool is fine; in a production API handler it is not
305
+
306
+ - Group findings by severity: CRITICAL → HIGH → MEDIUM → LOW
307
+ - Include file path and line number for every finding
308
+ - Include a Positive Notes section (good patterns observed)
309
+ - Include a Verdict: APPROVE | REQUEST CHANGES | NEEDS DISCUSSION
310
+
311
+ ### Step 6.5: Fix-First Triage
312
+
313
+ > From gstack (garrytan/gstack, 50.9k★): "Reviews that produce 20 findings and delegate all to the user waste everyone's time."
314
+
315
+ Classify each finding as **AUTO-FIX** or **ASK** before reporting:
316
+
317
+ | Category | Auto-Fix? | Examples |
318
+ |----------|-----------|---------|
319
+ | Dead imports, unused variables | AUTO-FIX | `import { foo } from './bar'` where foo is never used |
320
+ | Missing error handling on obvious paths | AUTO-FIX | `await fetch()` without try/catch in production code |
321
+ | Console.log in production code | AUTO-FIX | Remove `console.log` from non-CLI production files |
322
+ | Architectural concern, trade-off | ASK | "This bypasses the auth middlewareintentional?" |
323
+ | Ambiguous intent | ASK | "Is this fallback behavior correct for null users?" |
324
+ | Style/convention disagreement | ASK | "Project uses camelCase but this file uses snake_case" |
325
+
326
+ **After classification:**
327
+ - Apply AUTO-FIX findings directly via `rune:fix` include all in a single batch
328
+ - Collect ASK findings into ONE `AskUserQuestion` not 5 separate questions
329
+ - Report both: "Auto-fixed 4 issues. 2 findings need your input: [...]"
330
+
331
+ **Rationalization prevention**: "This looks fine" is NOT acceptable without evidence. If you can't cite a specific file:line or convention that justifies the code, flag it as UNVERIFIED — don't rationalize away uncertainty.
332
+
333
+ ### Step 6.6: Scope Drift Detection
334
+
335
+ > From gstack (garrytan/gstack, 50.9k★): "Intent vs diff catches scope creep that plan-based guards miss."
336
+
337
+ After reviewing code, compare **stated intent** vs **actual diff**:
338
+
339
+ 1. Read the originating source: TODO list, PR description, commit messages, or plan file
340
+ 2. Extract stated intent: "what was this change supposed to do?"
341
+ 3. Run `git diff --stat` to see actual file changes
342
+ 4. Compare:
343
+
344
+ | Result | Meaning | Action |
345
+ |--------|---------|--------|
346
+ | **CLEAN** | All changed files serve the stated intent | Note in report |
347
+ | **DRIFT** | 1-2 files changed that don't relate to stated intent | WARN — "These files were modified but aren't mentioned in the task: [list]" |
348
+ | **REQUIREMENTS_MISSING** | Stated intent mentions files/features not in the diff | WARN — "Task mentions X but it's not in the diff" |
349
+
350
+ **This is informational, not blocking.** Scope drift is common and sometimes intentional but making it visible prevents silent creep.
351
+
352
+ After reporting:
353
+ - If any CRITICAL findings: call `rune:fix` immediately with the finding details
354
+ - If any HIGH findings: call `rune:fix` with the finding details
355
+ - If untested code: call `rune:test` with specific coverage gaps identified
356
+ - Call `neural-memory` (Capture Mode) to save any novel code quality patterns or recurring issues found.
357
+
358
+ ## Framework-Specific Checks
359
+
360
+ Apply **only** if the framework is detected in the changed files. Skip if not relevant.
361
+
362
+ **React / Next.js** (detect: `import React` or `.tsx` files)
363
+ - `useEffect` with missing dependencies (stale closure) flag HIGH
364
+ - List items using index as key on reorderable lists: `key={i}` → flag MEDIUM
365
+ - Props drilled through 3+ levels without Context or composition → flag MEDIUM
366
+ - Client-side hooks (`useState`, `useEffect`) in Server Components (Next.js App Router) → flag HIGH
367
+
368
+ **Node.js / Express** (detect: `import express` or `require('express')`)
369
+ - Missing rate limiting on public endpoints flag MEDIUM
370
+ - `req.body` passed directly to DB without validation schema → flag HIGH
371
+ - Synchronous operations blocking the event loop inside async handlers → flag HIGH
372
+
373
+ **Python** (detect: `.py` files with `django`, `flask`, or `fastapi` imports)
374
+ - `except:` bare catch without specific exception type → flag MEDIUM
375
+ - Mutable default arguments: `def func(items=[])` → flag HIGH
376
+ - Missing type hints on public functions (if project uses mypy/pyright) → flag LOW
377
+
378
+ ## UI/UX Anti-Pattern Checks
379
+
380
+ Apply **only** when `.tsx`, `.jsx`, `.svelte`, `.vue`, or `.html` files are in the diff. Skip for backend-only changes.
381
+
382
+ These are the **"AI UI signature"** — patterns that make AI-generated frontends visually identifiable as non-human-designed. Flag each as MEDIUM severity.
383
+
384
+ **AI_ANTIPATTERN — Purple/indigo default accent with no domain justification:**
385
+ ```tsx
386
+ // BAD: LLM default color bias — signals "AI-generated" to experienced designers
387
+ className="bg-indigo-600 text-white" // every button/CTA is indigo
388
+ // GOOD: domain-appropriate trading neutral dark, healthcare → trust blue,
389
+ // e-commerce → conversion-optimized warm. Purple is only appropriate for
390
+ // AI-native tools and creative platforms.
391
+ ```
392
+
393
+ **AI_ANTIPATTERN — Card-grid monotony (every section is 3-col cards, zero layout variation):**
394
+ ```tsx
395
+ // BAD: every section uses the same grid pattern
396
+ <div className="grid grid-cols-3 gap-6"> // features
397
+ <div className="grid grid-cols-3 gap-6"> // testimonials
398
+ <div className="grid grid-cols-3 gap-6"> // pricing
399
+ // GOOD: mix layouts — split sections, bento grids, full-bleed hero, list+detail
400
+ ```
401
+
402
+ **AI_ANTIPATTERN — Centeritis (everything centered, no directional flow):**
403
+ ```tsx
404
+ // BAD: no visual tension, no reading direction
405
+ <div className="text-center flex flex-col items-center"> // hero
406
+ <div className="text-center"> // every feature section
407
+ // GOOD: left-align body copy, use centering intentionally for hero/CTAs only
408
+ ```
409
+
410
+ **AI_ANTIPATTERN Numeric/financial values in non-monospace font:**
411
+ ```tsx
412
+ // BAD: prices, stats, metrics in Inter/Roboto
413
+ <span className="text-2xl font-bold">${price}</span>
414
+ // GOOD: monospace for all numbers that need alignment
415
+ <span className="font-mono text-2xl font-bold">${price}</span>
416
+ ```
417
+
418
+ **AI_ANTIPATTERN Missing UI states (only happy path rendered):**
419
+ ```tsx
420
+ // BAD: data rendering without empty/error/loading states
421
+ {data.map(item => <Card key={item.id} {...item} />)}
422
+ // GOOD: all 4 states covered
423
+ {isLoading && <CardSkeleton />}
424
+ {error && <ErrorState message={error.message} />}
425
+ {!data.length && <EmptyState />}
426
+ {data.map(item => <Card key={item.id} {...item} />)}
427
+ ```
428
+
429
+ **Accessibility flag as HIGH (these are WCAG 2.2 failures):**
430
+ ```tsx
431
+ // BAD: icon button with no accessible name
432
+ <button onClick={close}><XIcon /></button>
433
+ // GOOD
434
+ <button onClick={close} aria-label="Close dialog"><XIcon aria-hidden="true" /></button>
435
+
436
+ // BAD: placeholder as label
437
+ <input placeholder="Email address" type="email" />
438
+ // GOOD
439
+ <label htmlFor="email">Email address</label>
440
+ <input id="email" type="email" />
441
+
442
+ // BAD: removes focus ring without replacement
443
+ className="focus:outline-none"
444
+ // GOOD: must have focus-visible replacement
445
+ className="focus:outline-none focus-visible:ring-2 focus-visible:ring-blue-500"
446
+
447
+ // BAD: color as sole information conveyor
448
+ <span className="text-red-500">{errorMessage}</span>
449
+ // GOOD: icon + color + text
450
+ <span className="text-red-500 flex gap-1"><ErrorIcon aria-hidden />Error: {errorMessage}</span>
451
+ ```
452
+
453
+ **WCAG 2.2 New Rules — flag as MEDIUM:**
454
+ - `position: sticky` or `position: fixed` header/footer without `scroll-padding-top` → Focus Not Obscured (2.4.11)
455
+ - Interactive elements with `width < 24px` or `height < 24px` without 8px spacing → Target Size (2.5.8)
456
+ - Multi-step form re-asking for previously entered data → Redundant Entry (3.3.7)
457
+
458
+ **Platform-Specific flag as MEDIUM when platform is detectable:**
459
+ - iOS target: solid-background cards (iOS 26 Liquid Glass deprecates this visual language) — should use translucent/blur surfaces
460
+ - Android target: hardcoded hex colors instead of `MaterialTheme.colorScheme` tokens → not adaptive to dynamic color
461
+
462
+ ## Weighted Composite Scoring
463
+
464
+ 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.
465
+
466
+ ### Formula
467
+
468
+ ```
469
+ Quality Score = (Correctness × 0.35) + (Security × 0.30) + (Test Coverage × 0.20) + (Conventions × 0.15)
470
+ ```
471
+
472
+ Each dimension is scored 0–100 based on findings count and severity:
473
+ - 0 CRITICAL/HIGH findings → 100 for that dimension
474
+ - 1 CRITICAL → dimension capped at 40
475
+ - 1 HIGH → dimension capped at 70
476
+ - Each additional MEDIUM → subtract 5 (floor: 50)
477
+
478
+ ### Grade Thresholds
479
+
480
+ | Score | Grade | Verdict |
481
+ |-------|-------|---------|
482
+ | 90–100 | Excellent | APPROVE |
483
+ | 75–89 | Good | APPROVE with notes |
484
+ | 60–74 | Fair | REQUEST CHANGES (MEDIUM issues) |
485
+ | 40–59 | Poor | REQUEST CHANGES (HIGH issues present) |
486
+ | 0–39 | Critical | REQUEST CHANGES (CRITICAL present) |
487
+
488
+ **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.
489
+
490
+
491
+ ## Severity Levels
492
+
493
+ ```
494
+ CRITICAL — security vulnerability, data loss risk, crash bug
495
+ HIGH — logic error, missing validation, broken edge case
496
+ MEDIUM — code smell, performance issue, missing error handling
497
+ LOW — style inconsistency, naming suggestion, minor refactor opportunity
498
+ ```
499
+
500
+ ## Output Format
501
+
502
+ ```
503
+ ## Code Review Report
504
+ - **Files Reviewed**: [count]
505
+ - **Findings**: [count by severity]
506
+ - **Review Commit**: [git hash at time of review]
507
+ - **Overall**: APPROVE | REQUEST CHANGES | NEEDS DISCUSSION
508
+
509
+ ### Spec Compliance
510
+ - [PASS/FAIL]: [acceptance criteria coverage]
511
+
512
+ ### CRITICAL
513
+ - `path/to/file.ts:42`[description of critical issue]
514
+
515
+ ### HIGH
516
+ - `path/to/file.ts:85` — [description of high-severity issue]
517
+
518
+ ### MEDIUM
519
+ - `path/to/file.ts:120` [description of medium issue]
520
+
521
+ ### Blast Radius
522
+ - [High-impact symbols with caller counts]
523
+
524
+ ### Positive Notes
525
+ - [good patterns observed]
526
+
527
+ ### Verdict
528
+ [Summary and recommendation]
529
+ ```
530
+
531
+ ### Review Staleness Detection
532
+
533
+ Track the git commit hash at review time. If code changes after review → review is STALE.
534
+
535
+ ```
536
+ Review commit: abc123 → Code changed to def456 → Review is STALE, re-review required
537
+ ```
538
+
539
+ 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."
540
+
541
+
542
+ ## Constraints
543
+
544
+ 1. MUST read the full diff — not just the files the user pointed at
545
+ 2. MUST reference specific file:line for every finding
546
+ 3. MUST NOT rubber-stamp with generic praise ("well-structured", "clean code") without evidence
547
+ 4. MUST check: correctness, security, performance, conventions, test coverage
548
+ 5. MUST categorize findings: CRITICAL (blocks commit) / HIGH / MEDIUM / LOW
549
+ 6. MUST escalate to sentinel if auth/crypto/secrets code is touched
550
+ 7. MUST flag untested code paths and recommend tests via rune:test
551
+
552
+ ## Returns
553
+
554
+ | Artifact | Format | Location |
555
+ |----------|--------|----------|
556
+ | Code review report | Markdown | inline (chat output) |
557
+ | Severity-ranked findings | Markdown table | inline |
558
+ | Spec compliance verdict | Markdown | inline |
559
+ | Composite quality score | Markdown table | inline (when `mode: "scored"`) |
560
+ | Blast radius assessment | Markdown table | inline |
561
+
562
+ ## Chain Metadata
563
+
564
+ Append to Code Review Report when invoked standalone. Suppress when called as sub-skill inside an L1 orchestrator (cook, team, etc.) the orchestrator emits a consolidated block. See `docs/references/chain-metadata.md`.
565
+
566
+ ```yaml
567
+ chain_metadata:
568
+ skill: "rune:review"
569
+ version: "1.0.0"
570
+ status: "[DONE | DONE_WITH_CONCERNS]"
571
+ domain: "[area reviewed]"
572
+ files_changed: [] # review doesn't change files
573
+ exports:
574
+ findings_count: { critical: [N], high: [N], medium: [N], low: [N] }
575
+ findings:
576
+ - { severity: "[level]", file: "[path]", line: [N], message: "[issue]" }
577
+ verdict: "[APPROVE | REQUEST_CHANGES | NEEDS_DISCUSSION]"
578
+ quality_score: [0-100] # when mode: "scored"
579
+ suggested_next:
580
+ - skill: "rune:fix"
581
+ reason: "[grounded in findings e.g., '2 HIGH findings in api/users.ts need remediation']"
582
+ consumes: ["findings"]
583
+ ```
584
+
585
+ ## Sharp Edges
586
+
587
+ | Failure Mode | Severity | Mitigation |
588
+ |---|---|---|
589
+ | Finding flood — 20+ findings overwhelm developer | MEDIUM | Confidence filter: only >80% confidence, consolidate similar issues per file |
590
+ | "LGTM" without file:line evidence | HIGH | HARD-GATE blocks this — cite at least one specific item per changed file |
591
+ | Expanding review scope beyond the diff | MEDIUM | Limit to `git diff` scope — do not creep into adjacent unchanged files |
592
+ | Security finding without sentinel escalation | HIGH | Any auth/crypto/payment code touched → MUST call rune:sentinel |
593
+ | Skipping UI anti-pattern checks for frontend changes | MEDIUM | Any .tsx/.jsx/.svelte/.vue in diff → MUST run UI/UX Anti-Pattern Checks section |
594
+ | 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 |
595
+ | Treating purple/indigo accent as "just a color choice" | MEDIUM | It is a documented AI-generated UI signature — always flag for domain justification |
596
+ | 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 |
597
+ | Adding abstractions "for future flexibility" | MEDIUM | Three similar lines > premature abstraction. Only abstract when there are 3+ concrete callers today |
598
+ | 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 |
599
+ | Review loop exceeds 3 iterations without resolution | MEDIUM | Cap at 3 review loops. After 3rd iteration with unresolved findings → surface to user with "these findings persist after 3 fix attempts — needs human decision" |
600
+ | Auto-fixing something that should have been ASK | HIGH | When in doubt, ASK. AUTO-FIX only for mechanical issues (dead imports, console.log). Anything involving intent or trade-offs = ASK |
601
+ | Scope drift flagged on intentional refactoring | LOW | Scope drift is informational, not blocking. User can override with "intentional" — don't re-flag after override |
602
+
603
+ ## Done When
604
+
605
+ - All changed files in the diff read and analyzed
606
+ - Every finding references specific file:line with severity label
607
+ - Security-critical code escalated to sentinel (or confirmed not present)
608
+ - Test coverage gaps identified and documented
609
+ - UI anti-pattern checks ran for any frontend files in diff (or confirmed not applicable)
610
+ - Structured report emitted with APPROVE / REQUEST CHANGES / NEEDS DISCUSSION verdict
611
+
612
+ ## Cost Profile
613
+
614
+ ~3000-6000 tokens input, ~1000-2000 tokens output. Sonnet default, opus for security-critical reviews. Runs once per implementation cycle.