@nano-step/skill-manager 5.6.1 → 5.7.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 (39) hide show
  1. package/dist/utils.d.ts +1 -1
  2. package/dist/utils.js +1 -1
  3. package/package.json +1 -1
  4. package/private-catalog.json +7 -2
  5. package/skills/deep-design/SKILL.md +402 -0
  6. package/skills/deep-design/evals/evals.json +23 -0
  7. package/skills/deep-design/skill.json +7 -0
  8. package/skills/feature-analysis/SKILL.md +290 -0
  9. package/skills/feature-analysis/skill.json +15 -0
  10. package/skills/nano-brain/skill.json +7 -0
  11. package/skills/pr-code-reviewer/CHANGELOG.md +329 -0
  12. package/skills/pr-code-reviewer/RESEARCH.md +60 -0
  13. package/skills/pr-code-reviewer/SKILL.md +537 -0
  14. package/skills/pr-code-reviewer/assets/config.json +60 -0
  15. package/skills/pr-code-reviewer/checklists/backend-express.md +357 -0
  16. package/skills/pr-code-reviewer/checklists/ci-cd.md +428 -0
  17. package/skills/pr-code-reviewer/checklists/consumer-search-matrix.md +339 -0
  18. package/skills/pr-code-reviewer/checklists/database.md +382 -0
  19. package/skills/pr-code-reviewer/checklists/frontend-vue-nuxt.md +426 -0
  20. package/skills/pr-code-reviewer/checklists/review-checklist.md +149 -0
  21. package/skills/pr-code-reviewer/references/checkpoint-system.md +58 -0
  22. package/skills/pr-code-reviewer/references/confidence-scoring.md +98 -0
  23. package/skills/pr-code-reviewer/references/framework-rules/express.md +39 -0
  24. package/skills/pr-code-reviewer/references/framework-rules/nestjs.md +41 -0
  25. package/skills/pr-code-reviewer/references/framework-rules/nextjs.md +58 -0
  26. package/skills/pr-code-reviewer/references/framework-rules/prisma.md +54 -0
  27. package/skills/pr-code-reviewer/references/framework-rules/react.md +61 -0
  28. package/skills/pr-code-reviewer/references/framework-rules/typeorm.md +52 -0
  29. package/skills/pr-code-reviewer/references/framework-rules/typescript.md +50 -0
  30. package/skills/pr-code-reviewer/references/framework-rules/vue-nuxt.md +53 -0
  31. package/skills/pr-code-reviewer/references/nano-brain-integration.md +46 -0
  32. package/skills/pr-code-reviewer/references/performance-patterns.md +26 -0
  33. package/skills/pr-code-reviewer/references/quality-patterns.md +25 -0
  34. package/skills/pr-code-reviewer/references/report-template.md +172 -0
  35. package/skills/pr-code-reviewer/references/security-patterns.md +31 -0
  36. package/skills/pr-code-reviewer/references/setup-wizard.md +207 -0
  37. package/skills/pr-code-reviewer/references/subagent-prompts.md +344 -0
  38. package/skills/pr-code-reviewer/references/verification-protocol.md +56 -0
  39. package/skills/pr-code-reviewer/skill.json +15 -0
@@ -0,0 +1,426 @@
1
+ # Frontend Vue/Nuxt Checklist
2
+
3
+ Comprehensive review checklist for Vue 3/Nuxt 3 frontend PRs (tradeit, tradeit-admin, audit-dashboard-frontend, etc.)
4
+
5
+ ---
6
+
7
+ ## 1. State Management
8
+
9
+ ### CRITICAL - Must Check
10
+
11
+ | Check | Pattern | Why |
12
+ |-------|---------|-----|
13
+ | Vuex vs Pinia correct | `rootState.x` vs `useXStore()` | Vuex can't access Pinia |
14
+ | Store registered | Module in `store/index.js` | Undefined state |
15
+ | Computed get/set pattern | `computed({ get, set })` | Two-way binding |
16
+ | storeToRefs for destructuring | `storeToRefs(store)` | Maintains reactivity |
17
+
18
+ ### Detection Patterns
19
+
20
+ ```javascript
21
+ // CRITICAL: Vuex accessing Pinia store (will be undefined)
22
+ // In Vuex action:
23
+ const rate = rootState.currency.selectedRate // currency is Pinia!
24
+
25
+ // SECURE: Use Pinia directly
26
+ import { useCurrencyStore } from '~/store/useCurrencyStore'
27
+ const currencyStore = useCurrencyStore()
28
+ const rate = currencyStore.selectedRate
29
+
30
+ // CRITICAL: Store not registered
31
+ // store/index.js missing:
32
+ modules: {
33
+ // currency: currencyModule // MISSING!
34
+ }
35
+
36
+ // WARNING: Destructuring loses reactivity
37
+ const { items, loading } = useInventoryStore() // Not reactive!
38
+
39
+ // SECURE: Use storeToRefs
40
+ const store = useInventoryStore()
41
+ const { items, loading } = storeToRefs(store)
42
+
43
+ // CRITICAL: Direct mutation (Vuex)
44
+ state.items.push(newItem) // Mutation outside mutation handler!
45
+
46
+ // SECURE: Use mutation
47
+ commit('ADD_ITEM', newItem)
48
+ ```
49
+
50
+ ---
51
+
52
+ ## 2. Reactivity
53
+
54
+ ### CRITICAL - Must Check
55
+
56
+ | Check | Pattern | Why |
57
+ |-------|---------|-----|
58
+ | ref() for primitives | `ref(0)` not `reactive(0)` | reactive() doesn't work on primitives |
59
+ | .value in script | `count.value++` | Required for refs in script |
60
+ | toRefs for destructuring | `toRefs(props)` | Maintains reactivity |
61
+ | No direct prop mutation | `emit('update:x', newVal)` | One-way data flow |
62
+
63
+ ### Detection Patterns
64
+
65
+ ```javascript
66
+ // WARNING: reactive() on primitive
67
+ const count = reactive(0) // Won't work!
68
+
69
+ // SECURE: ref() for primitives
70
+ const count = ref(0)
71
+
72
+ // CRITICAL: Missing .value in script
73
+ const count = ref(0)
74
+ count++ // Wrong! count is a ref object
75
+
76
+ // SECURE: Use .value
77
+ count.value++
78
+
79
+ // CRITICAL: Mutating prop directly
80
+ props.items.push(newItem) // Mutating parent state!
81
+
82
+ // SECURE: Emit event
83
+ emit('add-item', newItem)
84
+
85
+ // WARNING: Destructuring props loses reactivity
86
+ const { modelValue } = defineProps(['modelValue'])
87
+ watch(modelValue, ...) // Won't trigger!
88
+
89
+ // SECURE: Use toRefs or computed
90
+ const props = defineProps(['modelValue'])
91
+ watch(() => props.modelValue, ...)
92
+ ```
93
+
94
+ ---
95
+
96
+ ## 3. Network Calls
97
+
98
+ ### CRITICAL - Must Check
99
+
100
+ | Check | Pattern | Why |
101
+ |-------|---------|-----|
102
+ | Use getAxiosInstance() | Not raw axios | Includes auth, base URL |
103
+ | Error handling | try/catch or .catch() | User feedback |
104
+ | Loading state managed | `loading.value = true/false` | UX |
105
+ | Response fields validated | Check before access | Defensive coding |
106
+
107
+ ### Detection Patterns
108
+
109
+ ```javascript
110
+ // WARNING: Raw axios
111
+ import axios from 'axios'
112
+ const { data } = await axios.get('/api/user')
113
+
114
+ // SECURE: Use instance
115
+ import { getAxiosInstance } from '~/network/axiosInstance'
116
+ const axios = getAxiosInstance()
117
+ const { data } = await axios.get('/api/user')
118
+
119
+ // CRITICAL: No error handling
120
+ const fetchData = async () => {
121
+ const { data } = await axios.get('/api/items')
122
+ items.value = data.items
123
+ }
124
+
125
+ // SECURE: With error handling
126
+ const fetchData = async () => {
127
+ try {
128
+ loading.value = true
129
+ const { data } = await axios.get('/api/items')
130
+ items.value = data.items
131
+ } catch (e) {
132
+ error.value = e.message
133
+ } finally {
134
+ loading.value = false
135
+ }
136
+ }
137
+
138
+ // CRITICAL: Assuming response field exists (PR #1101 issue!)
139
+ const imgUrl = item.imgURL // undefined if backend changed!
140
+
141
+ // SECURE: Defensive access
142
+ const imgUrl = item.imgURL ?? getFallbackImage(item.groupId)
143
+ ```
144
+
145
+ ---
146
+
147
+ ## 4. Component Patterns
148
+
149
+ ### CRITICAL - Must Check
150
+
151
+ | Check | Pattern | Why |
152
+ |-------|---------|-----|
153
+ | Props typed | `defineProps<{ x: string }>()` | Type safety |
154
+ | Emits declared | `defineEmits(['update:x'])` | Documentation |
155
+ | v-if/v-for not on same element | Use template wrapper | Vue limitation |
156
+ | Key on v-for | `:key="item.id"` | Efficient updates |
157
+
158
+ ### Detection Patterns
159
+
160
+ ```vue
161
+ <!-- CRITICAL: v-if and v-for on same element -->
162
+ <div v-for="item in items" v-if="item.active"> <!-- Wrong! -->
163
+
164
+ <!-- SECURE: Use template -->
165
+ <template v-for="item in items" :key="item.id">
166
+ <div v-if="item.active">...</div>
167
+ </template>
168
+
169
+ <!-- WARNING: Missing key -->
170
+ <div v-for="item in items"> <!-- No key! -->
171
+
172
+ <!-- SECURE: With key -->
173
+ <div v-for="item in items" :key="item.id">
174
+
175
+ <!-- WARNING: Untyped props -->
176
+ const props = defineProps(['modelValue', 'items'])
177
+
178
+ <!-- SECURE: Typed props -->
179
+ interface Props {
180
+ modelValue: string
181
+ items: Item[]
182
+ }
183
+ const props = defineProps<Props>()
184
+ ```
185
+
186
+ ---
187
+
188
+ ## 5. Composables
189
+
190
+ ### CRITICAL - Must Check
191
+
192
+ | Check | Pattern | Why |
193
+ |-------|---------|-----|
194
+ | Returns reactive refs | `return { items, loading }` | Reactivity preserved |
195
+ | No `this` usage | Composables don't have `this` | Runtime error |
196
+ | Cleanup on unmount | `onUnmounted(() => ...)` | Memory leaks |
197
+ | Named exports | `export function useX()` | Tree shaking |
198
+
199
+ ### Detection Patterns
200
+
201
+ ```javascript
202
+ // CRITICAL: Using this in composable
203
+ export function useInventory() {
204
+ this.items = [] // TypeError! No 'this' in composables
205
+ }
206
+
207
+ // SECURE: Use refs
208
+ export function useInventory() {
209
+ const items = ref([])
210
+ return { items }
211
+ }
212
+
213
+ // WARNING: Not returning reactive
214
+ export function useCounter() {
215
+ let count = 0 // Not reactive!
216
+ return { count }
217
+ }
218
+
219
+ // SECURE: Return refs
220
+ export function useCounter() {
221
+ const count = ref(0)
222
+ return { count }
223
+ }
224
+
225
+ // WARNING: No cleanup
226
+ export function useWebSocket() {
227
+ const ws = new WebSocket(url)
228
+ // Never closed!
229
+ }
230
+
231
+ // SECURE: Cleanup on unmount
232
+ export function useWebSocket() {
233
+ const ws = new WebSocket(url)
234
+ onUnmounted(() => ws.close())
235
+ return { ws }
236
+ }
237
+ ```
238
+
239
+ ---
240
+
241
+ ## 6. Nuxt-Specific
242
+
243
+ ### CRITICAL - Must Check
244
+
245
+ | Check | Pattern | Why |
246
+ |-------|---------|-----|
247
+ | Client-only code guarded | `import.meta.client` | SSR errors |
248
+ | Auto-imports from composables/ | Not utils/ | Only composables auto-imported |
249
+ | useFetch for SSR data | Not axios in setup | SSR hydration |
250
+ | definePageMeta for layouts | `definePageMeta({ layout: 'x' })` | Nuxt convention |
251
+
252
+ ### Detection Patterns
253
+
254
+ ```javascript
255
+ // CRITICAL: Browser API in SSR
256
+ const width = window.innerWidth // ReferenceError on server!
257
+
258
+ // SECURE: Guard with import.meta.client
259
+ const width = import.meta.client ? window.innerWidth : 0
260
+
261
+ // Or use onMounted
262
+ onMounted(() => {
263
+ width.value = window.innerWidth
264
+ })
265
+
266
+ // CRITICAL: Using function from utils/ without import
267
+ // In component:
268
+ stripImageSizeFromUrl(url) // undefined! utils/ not auto-imported
269
+
270
+ // SECURE: Import explicitly
271
+ import { stripImageSizeFromUrl } from '~/utils/helpers'
272
+
273
+ // WARNING: axios in setup (SSR issues)
274
+ const { data } = await axios.get('/api/items')
275
+
276
+ // SECURE: useFetch for SSR
277
+ const { data } = await useFetch('/api/items')
278
+ ```
279
+
280
+ ---
281
+
282
+ ## 7. i18n / Localization
283
+
284
+ ### WARNING - Should Check
285
+
286
+ | Check | Pattern | Why |
287
+ |-------|---------|-----|
288
+ | No hardcoded strings | Use `$t('key')` | Localization |
289
+ | Keys exist in locale files | Check en.js | Runtime errors |
290
+ | Interpolation correct | `$t('key', { name })` | Dynamic content |
291
+
292
+ ### Detection Patterns
293
+
294
+ ```vue
295
+ <!-- WARNING: Hardcoded string -->
296
+ <button>Submit</button>
297
+
298
+ <!-- SECURE: Use i18n -->
299
+ <button>{{ $t('common.submit') }}</button>
300
+
301
+ <!-- WARNING: Missing interpolation -->
302
+ <p>{{ $t('welcome') }}</p> <!-- "Welcome, {name}" shows literally -->
303
+
304
+ <!-- SECURE: With interpolation -->
305
+ <p>{{ $t('welcome', { name: user.name }) }}</p>
306
+ ```
307
+
308
+ ---
309
+
310
+ ## 8. Images & CDN
311
+
312
+ ### CRITICAL - Must Check
313
+
314
+ | Check | Pattern | Why |
315
+ |-------|---------|-----|
316
+ | Use useCDNImage() | Not raw URLs | CDN optimization |
317
+ | ImageWithFallback component | For item images | Handles missing images |
318
+ | Lazy loading | `loading="lazy"` | Performance |
319
+
320
+ ### Detection Patterns
321
+
322
+ ```vue
323
+ <!-- WARNING: Raw image URL -->
324
+ <img :src="item.imgURL"> <!-- No fallback if undefined! -->
325
+
326
+ <!-- SECURE: Use ImageWithFallback -->
327
+ <ImageWithFallback :src="item.imgURL" :fallback="getFallback(item)" />
328
+
329
+ <!-- WARNING: No lazy loading -->
330
+ <img :src="url">
331
+
332
+ <!-- SECURE: Lazy load -->
333
+ <img :src="url" loading="lazy">
334
+ ```
335
+
336
+ ---
337
+
338
+ ## 9. Breaking Change Detection
339
+
340
+ ### Auto-Flag These Changes
341
+
342
+ | Signal | Severity | Action |
343
+ |--------|----------|--------|
344
+ | Store module removed | CRITICAL | Search all consumers |
345
+ | Composable return value changed | CRITICAL | Search all usages |
346
+ | Network function signature changed | CRITICAL | Search all callers |
347
+ | Component prop removed | WARNING | Search all usages |
348
+ | Emit event renamed | WARNING | Search parent listeners |
349
+
350
+ ### Consumer Search Required
351
+
352
+ ```bash
353
+ # For store changes
354
+ grep -rn "useXStore" ./
355
+ grep -rn "rootState.x" ./
356
+
357
+ # For composable changes
358
+ grep -rn "useComposable" ./
359
+
360
+ # For component changes
361
+ grep -rn "<ComponentName" ./
362
+ ```
363
+
364
+ ---
365
+
366
+ ## 10. Performance Checks
367
+
368
+ ### WARNING - Should Check
369
+
370
+ | Check | Pattern | Why |
371
+ |-------|---------|-----|
372
+ | Large lists virtualized | `vue-virtual-scroller` | Memory |
373
+ | Computed for derived state | Not methods | Caching |
374
+ | v-once for static content | `<div v-once>` | Skip re-renders |
375
+ | Async components for heavy | `defineAsyncComponent` | Code splitting |
376
+
377
+ ---
378
+
379
+ ## Quick Checklist
380
+
381
+ Copy this for PR reviews:
382
+
383
+ ```markdown
384
+ ## Vue/Nuxt Frontend Review
385
+
386
+ ### State Management
387
+ - [ ] Vuex/Pinia used correctly (not mixed)
388
+ - [ ] Store modules registered
389
+ - [ ] storeToRefs used for destructuring
390
+ - [ ] No direct state mutation
391
+
392
+ ### Reactivity
393
+ - [ ] ref() for primitives, reactive() for objects
394
+ - [ ] .value used in script
395
+ - [ ] Props not mutated directly
396
+
397
+ ### Network
398
+ - [ ] getAxiosInstance() used (not raw axios)
399
+ - [ ] Error handling present
400
+ - [ ] Loading states managed
401
+ - [ ] Response fields validated (defensive)
402
+
403
+ ### Components
404
+ - [ ] Props typed with TypeScript
405
+ - [ ] Emits declared
406
+ - [ ] v-if/v-for not on same element
407
+ - [ ] Keys on v-for
408
+
409
+ ### Nuxt-Specific
410
+ - [ ] Client-only code guarded (import.meta.client)
411
+ - [ ] Auto-imports only from composables/
412
+ - [ ] useFetch for SSR data
413
+
414
+ ### i18n
415
+ - [ ] No hardcoded user-facing strings
416
+ - [ ] $t() keys exist in locale files
417
+
418
+ ### Images
419
+ - [ ] useCDNImage() or ImageWithFallback used
420
+ - [ ] Fallbacks for missing images
421
+
422
+ ### Breaking Changes
423
+ - [ ] No store modules removed without consumer check
424
+ - [ ] No composable signatures changed without search
425
+ - [ ] No component props removed without search
426
+ ```
@@ -0,0 +1,149 @@
1
+ # PR Review Checklist
2
+
3
+ Use this checklist for every PR review. Check off each item as you complete it.
4
+
5
+ ## Setup Check (Phase -2)
6
+
7
+ - [ ] Check if `.opencode/code-reviewer.json` exists
8
+ - [ ] If exists: read `stack` field → resolve framework rule files → store as `$FRAMEWORK_RULES`
9
+ - [ ] If exists: read `agents` field → validate workspace_root, AGENTS.md, .agents/ dirs exist
10
+ - [ ] If missing (or `/review --setup`): read `references/setup-wizard.md`, run wizard, write config
11
+ - [ ] Confirm which framework rule files will be loaded (only stack-matching files)
12
+ - [ ] Confirm agents knowledge base paths (workspace_root + which dirs found)
13
+
14
+ ## Resume Detection (Phase -1)
15
+
16
+ - [ ] Look for existing checkpoint: `find /tmp -maxdepth 1 -type d -name "pr-review-${repo}-${pr_number}-*"`
17
+ - [ ] If found: read `manifest.json` from `.checkpoints/`
18
+ - [ ] Validate checkpoint: check PR number and head SHA match
19
+ - [ ] Ask user: "Resume from phase {next_phase}? (y/n)"
20
+ - [ ] If yes: load manifest + phase files, jump to `next_phase`
21
+ - [ ] If no or invalid: delete old directory, start fresh from Phase 0
22
+
23
+ ## Pre-Review (Phase 0)
24
+
25
+ - [ ] Extract repo info: `owner/repo`, `pr_number`, `head_branch`
26
+ - [ ] Create unique temp dir: `/tmp/pr-review-{repo}-{pr}-{timestamp}`
27
+ - [ ] Clone repo to temp dir (shallow clone with `--depth=1`)
28
+ - [ ] Verify correct branch is checked out (`git log --oneline -1`)
29
+ - [ ] Record `$REVIEW_DIR` path for all subsequent phases
30
+ - [ ] Print confirmation with path and branch name
31
+ - [ ] Save checkpoint: `.checkpoints/phase-0-clone.json`
32
+ - [ ] Update manifest: `completed_phase: 0`, `next_phase: 1`
33
+
34
+ ## Context Gathering (Phase 1)
35
+
36
+ - [ ] Read `{workspace_root}/AGENTS.md` → identify PR repo's domain
37
+ - [ ] Read `.agents/_repos/{repo-name}.md` → repo-specific context
38
+ - [ ] Read `.agents/_domains/{domain}.md` → domain context
39
+ - [ ] Store combined as `$AGENTS_CONTEXT`
40
+ - [ ] Get PR metadata: title, description, author, base branch
41
+ - [ ] Get changed files with diff
42
+ - [ ] Read full file context from `$REVIEW_DIR` (not workspace repo)
43
+ - [ ] Classify each file: LOGIC / DELETION / STYLE / REFACTOR / NEW
44
+ - [ ] Query nano-brain for past context on changed modules
45
+ - [ ] Save checkpoint: `.checkpoints/phase-1-context.json`
46
+ - [ ] Update manifest: `completed_phase: 1`, `next_phase: 1.5`
47
+
48
+ ## Linear Ticket Context (Phase 1.5)
49
+
50
+ - [ ] Extract ticket ID from branch name, PR description, or PR title
51
+ - [ ] If found: `linear_get_issue(id)` → fetch ticket details
52
+ - [ ] If found: `linear_list_comments(issueId)` → fetch discussion
53
+ - [ ] Extract acceptance criteria from ticket description
54
+ - [ ] If images in description: `linear_extract_images(description)`
55
+ - [ ] If not found: skip silently, continue without ticket context
56
+ - [ ] Save checkpoint: `.checkpoints/phase-1.5-linear.json`
57
+ - [ ] Update manifest: `completed_phase: 1.5`, `next_phase: 2`
58
+
59
+ ## Smart Tracing (Phase 2)
60
+
61
+ - [ ] LOGIC changes: trace callers, callees, tests, types, data flow
62
+ - [ ] STYLE changes: verify no hidden logic changes
63
+ - [ ] REFACTOR changes: verify behavior preservation
64
+ - [ ] Query nano-brain for known issues on changed functions
65
+ - [ ] Save checkpoint: `.checkpoints/phase-2-tracing.json`
66
+ - [ ] Update manifest: `completed_phase: 2`, `next_phase: 2.5`
67
+
68
+ ## PR Summary (Phase 2.5)
69
+
70
+ - [ ] Write "What This PR Does" (1-3 sentences)
71
+ - [ ] Categorize key changes (Feature/Bugfix/Refactor/etc.)
72
+ - [ ] File-by-file summary with line numbers
73
+ - [ ] Save checkpoint: `.checkpoints/phase-2.5-summary.json`
74
+ - [ ] Update manifest: `completed_phase: 2.5`, `next_phase: 3`
75
+
76
+ ## Subagent Execution (Phase 3)
77
+
78
+ - [ ] Include `$REVIEW_DIR` path in ALL subagent prompts
79
+ - [ ] Launch Code Quality agent (explore)
80
+ - [ ] After Code Quality completes: update `.checkpoints/phase-3-subagents.json` + manifest subagent_status
81
+ - [ ] Launch Security & Logic agent (oracle)
82
+ - [ ] After Security & Logic completes: update `.checkpoints/phase-3-subagents.json` + manifest subagent_status
83
+ - [ ] Launch Docs & Best Practices agent (librarian)
84
+ - [ ] After Docs & Best Practices completes: update `.checkpoints/phase-3-subagents.json` + manifest subagent_status
85
+ - [ ] Launch Tests & Integration agent (general/quick)
86
+ - [ ] After Tests & Integration completes: update `.checkpoints/phase-3-subagents.json` + manifest subagent_status
87
+ - [ ] Collect ALL results (especially Oracle — never skip)
88
+ - [ ] Update manifest: `completed_phase: 3`, `next_phase: 4`
89
+
90
+ ## Refinement (Phase 4)
91
+
92
+ - [ ] Merge and deduplicate findings across agents
93
+ - [ ] Consensus scoring: 2+ agents flagged same issue → boost confidence to high
94
+ - [ ] Auto-downgrade: single agent + no evidence + critical/warning → suggestion
95
+ - [ ] Apply severity filter (critical/warning keep, suggestion count-only)
96
+ - [ ] Gap analysis — any subagent fail? Unreviewed files?
97
+ - [ ] Second pass on gaps if needed
98
+ - [ ] Save checkpoint: `.checkpoints/phase-4-refined.json`
99
+ - [ ] Update manifest: `completed_phase: 4`, `next_phase: 4.5`
100
+
101
+ ## Verification Spot-Check (Phase 4.5)
102
+
103
+ - [ ] Read `references/verification-protocol.md`
104
+ - [ ] For each critical/warning finding: read cited code at evidence file:line in `$REVIEW_DIR`
105
+ - [ ] Mark each: `verified:true` (keep) | `verified:false` (drop) | `verified:unverifiable` (downgrade to suggestion)
106
+ - [ ] If no critical/warning findings: skip to Phase 4.6
107
+ - [ ] Save checkpoint: `.checkpoints/phase-4.5-verification.json`
108
+ - [ ] Update manifest: `completed_phase: 4.5`, `next_phase: 4.6`
109
+
110
+ ## Confidence Scoring (Phase 4.6)
111
+
112
+ - [ ] Read `references/confidence-scoring.md`
113
+ - [ ] Compute accuracy_rate, consensus_rate, evidence_rate
114
+ - [ ] Compute overall score (0–100)
115
+ - [ ] Apply gate: < 60 → add 🔴 warning, 60–79 → add ⚠️ warning, 80+ → proceed normally
116
+ - [ ] Save checkpoint: `.checkpoints/phase-4.6-confidence.json`
117
+ - [ ] Update manifest: `completed_phase: 4.6`, `next_phase: 5`
118
+
119
+ ## Report (Phase 5)
120
+
121
+ - [ ] Save to `.opencode/reviews/{type}_{identifier}_{date}.md`
122
+ - [ ] TL;DR with verdict and counts
123
+ - [ ] Critical issues with full detail
124
+ - [ ] Warnings with full detail
125
+ - [ ] Improvements as one-liners
126
+ - [ ] File summary table
127
+ - [ ] Save checkpoint: `.checkpoints/phase-5-report.md`
128
+ - [ ] Update manifest: `completed_phase: 5`, `next_phase: 5.5`
129
+
130
+ ## Save to Memory (Phase 5.5)
131
+
132
+ - [ ] Write key findings to nano-brain with tags: review, {repo}
133
+ - [ ] Verify searchable (`curl -s localhost:3100/api/search -d '{"query":"PR {number}"}'`)
134
+ - [ ] Update manifest: `completed_phase: 5.5`, `next_phase: 6`
135
+
136
+ ## Cleanup (Phase 6)
137
+
138
+ - [ ] Show temp folder path and size to user
139
+ - [ ] **ASK user** before removing (NEVER auto-delete)
140
+ - [ ] If user confirms → `rm -rf "$REVIEW_DIR"` (also removes `.checkpoints/`)
141
+ - [ ] If user declines → remind them to clean up later
142
+ - [ ] For multiple PRs: ask about each temp folder individually
143
+ - [ ] Note: Checkpoints auto-removed with clone dir (PR reviews) or remain in `.checkpoints/` (local reviews)
144
+
145
+ ## Final Notification
146
+
147
+ - [ ] Report path shown to user
148
+ - [ ] Issue counts (critical/warning/suggestion) displayed
149
+ - [ ] Temp folder cleanup status communicated
@@ -0,0 +1,58 @@
1
+ # Checkpoint System
2
+
3
+ Reviews are resumable via checkpoints saved at each phase. If the agent crashes mid-review, you can resume from the last completed phase instead of starting over.
4
+
5
+ ## Checkpoint Directory
6
+
7
+ **For PR Reviews:** `$REVIEW_DIR/.checkpoints/` (inside the temp clone directory)
8
+ **For Local Reviews (`--staged`):** `{current_working_directory}/.checkpoints/`
9
+
10
+ Checkpoints are automatically removed when the clone directory is deleted (Phase 6 cleanup).
11
+
12
+ ## Checkpoint Files
13
+
14
+ | File | Content | Updated When |
15
+ |------|---------|--------------|
16
+ | `manifest.json` | Master state tracker | After every phase |
17
+ | `phase-0-clone.json` | Clone metadata (clone_dir, branches, head_sha, files_changed) | Phase 0 |
18
+ | `phase-1-context.json` | PR metadata, file classifications | Phase 1 |
19
+ | `phase-1.5-linear.json` | Linear ticket context, acceptance criteria | Phase 1.5 |
20
+ | `phase-2-tracing.json` | Smart tracing results per file | Phase 2 |
21
+ | `phase-2.5-summary.json` | PR summary text | Phase 2.5 |
22
+ | `phase-3-subagents.json` | Subagent findings (updated after EACH subagent completes) | Phase 3 |
23
+ | `phase-4-refined.json` | Deduplicated/filtered findings | Phase 4 |
24
+ | `phase-4.5-verification.json` | Verification results (verified/false/unverifiable counts, dropped/downgraded findings) | Phase 4.5 |
25
+ | `phase-4.6-confidence.json` | Result confidence score, per-finding confidence, gate action | Phase 4.6 |
26
+ | `phase-5-report.md` | Copy of final report | Phase 5 |
27
+
28
+ ## Manifest Schema
29
+
30
+ ```json
31
+ {
32
+ "version": "1.0",
33
+ "pr": { "repo": "owner/repo", "number": 123, "url": "..." },
34
+ "clone_dir": "/tmp/pr-review-...",
35
+ "started_at": "ISO-8601",
36
+ "last_updated": "ISO-8601",
37
+ "completed_phase": 2,
38
+ "next_phase": 2.5,
39
+ "phase_status": {
40
+ "0": "complete", "1": "complete", "1.5": "complete",
41
+ "2": "complete", "2.5": "pending", "3": "pending",
42
+ "4": "pending", "4.5": "pending", "4.6": "pending", "5": "pending"
43
+ },
44
+ "subagent_status": {
45
+ "explore": "pending", "oracle": "pending",
46
+ "librarian": "pending", "general": "pending"
47
+ }
48
+ }
49
+ ```
50
+
51
+ ## Phase 3 Special Handling
52
+
53
+ Phase 3 runs 4 parallel subagents. After **EACH** subagent completes:
54
+ 1. Update `phase-3-subagents.json` with that subagent's findings and status
55
+ 2. Update `manifest.json` subagent_status to `"complete"` for that subagent
56
+ 3. On resume: only run subagents with status != `"complete"`
57
+
58
+ This allows resuming mid-Phase-3 if only some subagents completed before a crash.