@izkac/forgekit 0.3.11 → 0.3.13

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 (116) hide show
  1. package/bin/forge.mjs +107 -107
  2. package/bin/forgekit.mjs +83 -83
  3. package/bin/review.mjs +81 -81
  4. package/package.json +1 -1
  5. package/scripts/prepack.mjs +78 -78
  6. package/scripts/run-tests.mjs +50 -50
  7. package/src/adr.mjs +236 -236
  8. package/src/adr.test.mjs +170 -170
  9. package/src/change.mjs +327 -234
  10. package/src/change.test.mjs +145 -83
  11. package/src/cleanup-sessions.mjs +84 -84
  12. package/src/config.mjs +103 -103
  13. package/src/defer.mjs +75 -75
  14. package/src/doctor.mjs +350 -341
  15. package/src/doctor.test.mjs +114 -114
  16. package/src/init.mjs +680 -621
  17. package/src/install.mjs +815 -815
  18. package/src/install.test.mjs +180 -180
  19. package/src/integrity-check.mjs +60 -60
  20. package/src/integrity.mjs +682 -682
  21. package/src/integrity.test.mjs +566 -566
  22. package/src/lib.mjs +143 -143
  23. package/src/models.defaults.json +41 -41
  24. package/src/new-session.mjs +99 -99
  25. package/src/openspec-overlays/README.md +19 -19
  26. package/src/openspec-overlays/openspec-apply-change-footer.md +14 -14
  27. package/src/openspec-overlays/opsx-apply-completion-step.md +1 -1
  28. package/src/openspec-overlays/opsx-apply-implement-step.md +11 -11
  29. package/src/paths.mjs +92 -92
  30. package/src/plan-engine.mjs +321 -278
  31. package/src/plan-engine.test.mjs +447 -283
  32. package/src/preferences.defaults.json +78 -78
  33. package/src/preferences.mjs +438 -438
  34. package/src/preferences.test.mjs +174 -174
  35. package/src/record-evidence.mjs +204 -204
  36. package/src/resolve-model.mjs +312 -312
  37. package/src/resolve-model.test.mjs +194 -194
  38. package/src/review/cli.test.mjs +117 -117
  39. package/src/review/export.mjs +172 -172
  40. package/src/review/export.test.mjs +197 -197
  41. package/src/review/fixtures/valid-review.json +42 -42
  42. package/src/review/lib.mjs +894 -894
  43. package/src/review/lib.test.mjs +266 -266
  44. package/src/review/schema.json +196 -196
  45. package/src/review/signals.test.mjs +62 -62
  46. package/src/score-cli.mjs +68 -68
  47. package/src/score.mjs +568 -566
  48. package/src/score.test.mjs +366 -340
  49. package/src/session-reminder.mjs +207 -207
  50. package/src/session-status.mjs +70 -70
  51. package/src/set-models.mjs +186 -186
  52. package/src/set-phase.mjs +205 -205
  53. package/src/set-prefs.mjs +294 -294
  54. package/src/specs-sync.mjs +234 -0
  55. package/src/specs-sync.test.mjs +114 -0
  56. package/src/spine.mjs +93 -93
  57. package/src/triage-prompt.mjs +175 -175
  58. package/src/triage-prompt.test.mjs +50 -50
  59. package/src/vendor-openspec-overlays.mjs +176 -176
  60. package/src/vendor-openspec-overlays.test.mjs +62 -62
  61. package/vendor/skills/archive-to-adr/SKILL.md +149 -149
  62. package/vendor/skills/forge/SKILL.md +136 -136
  63. package/vendor/skills/forge/docs/forge.md +650 -647
  64. package/vendor/skills/forge/phases/brainstorm.md +23 -23
  65. package/vendor/skills/forge/phases/finish.md +90 -87
  66. package/vendor/skills/forge/phases/implement.md +77 -77
  67. package/vendor/skills/forge/phases/plan-openspec.md +60 -60
  68. package/vendor/skills/forge/phases/plan-specs.md +163 -117
  69. package/vendor/skills/forge/phases/review.md +25 -25
  70. package/vendor/skills/forge/phases/verify.md +124 -124
  71. package/vendor/skills/forge/references/forge-layout.md +85 -85
  72. package/vendor/skills/forge/references/pace.md +115 -115
  73. package/vendor/skills/forge/references/plan-routing.md +52 -51
  74. package/vendor/skills/forge/references/runtime-integrity.md +232 -225
  75. package/vendor/skills/forge/references/substantial-work.md +37 -37
  76. package/vendor/skills/forge/references/test-evidence.md +30 -30
  77. package/vendor/skills/forge/references/test-strategy.md +68 -68
  78. package/vendor/skills/forge/skills/subagent-driven-development/SKILL.md +87 -87
  79. package/vendor/skills/forge/subagents/final-reviewer-prompt.md +56 -56
  80. package/vendor/skills/forge/subagents/implementer-prompt.md +38 -38
  81. package/vendor/skills/git-resolve-adr-conflict/SKILL.md +132 -132
  82. package/vendor/skills/thorough-code-review/SKILL.md +290 -290
  83. package/vendor/skills/thorough-code-review/examples.md +133 -133
  84. package/vendor/skills/thorough-code-review/reference/accepted-risks.md +26 -26
  85. package/vendor/skills/thorough-code-review/reference/lenses.md +96 -96
  86. package/vendor/skills/thorough-code-review/reference/phase1-scout.md +62 -62
  87. package/vendor/skills/thorough-code-review/reference/phase2-skeptic.md +105 -105
  88. package/vendor/skills/thorough-code-review/reference/report-schema.json +222 -222
  89. package/vendor/skills/thorough-code-review/reference/report-template.md +115 -115
  90. package/vendor/skills/thorough-code-review/reference/severity-rubric.md +49 -49
  91. package/vendor/skills/thorough-code-review/reference/signals-preflight.md +55 -55
  92. package/vendor/templates/adr/README.md +7 -7
  93. package/vendor/templates/adr/decisions.md +141 -141
  94. package/vendor/templates/adr/hooks/check-pending-adrs.mjs +74 -74
  95. package/vendor/templates/adr/hooks/check-pending-adrs.sh +3 -3
  96. package/vendor/templates/adr/hooks/openspec-archive-agent-message.mjs +52 -52
  97. package/vendor/templates/adr/hooks/openspec-archive-agent-message.sh +3 -3
  98. package/vendor/templates/project/claude/commands/forge-apply.md +75 -75
  99. package/vendor/templates/project/claude/commands/forge-brainstorm.md +7 -7
  100. package/vendor/templates/project/claude/commands/forge-build.md +17 -17
  101. package/vendor/templates/project/claude/commands/forge-plan.md +12 -12
  102. package/vendor/templates/project/claude/commands/forge-skip.md +14 -14
  103. package/vendor/templates/project/claude/commands/forge-status.md +16 -16
  104. package/vendor/templates/project/claude/commands/forge.md +16 -16
  105. package/vendor/templates/project/claude/hooks/forge-prompt-hook.mjs +73 -73
  106. package/vendor/templates/project/claude/hooks/forge-session-start.mjs +19 -19
  107. package/vendor/templates/project/claude/hooks/forge-triage-hook.mjs +77 -77
  108. package/vendor/templates/project/cursor/commands/forge-apply.md +75 -75
  109. package/vendor/templates/project/cursor/commands/forge-brainstorm.md +10 -10
  110. package/vendor/templates/project/cursor/commands/forge-build.md +17 -17
  111. package/vendor/templates/project/cursor/commands/forge-plan.md +15 -15
  112. package/vendor/templates/project/cursor/commands/forge-skip.md +14 -14
  113. package/vendor/templates/project/cursor/commands/forge-status.md +16 -16
  114. package/vendor/templates/project/cursor/commands/forge.md +16 -16
  115. package/vendor/templates/project/cursor/hooks/forge-session-start.mjs +30 -30
  116. package/vendor/templates/project/cursor/hooks/forge-session-start.sh +3 -3
@@ -1,290 +1,290 @@
1
- ---
2
- name: thorough-code-review
3
- description: >-
4
- Performs two-phase code review with adversarial false-positive verification across
5
- security, correctness, smells, architecture, performance, tests, contracts, errors,
6
- and maintainability. Grounds findings in a signals pre-flight, balances precision with
7
- a recall/coverage pass, and risk-weights skeptic verification. JSON is the source of
8
- truth; the Markdown is generated from it. Writes reports to .reviews/. Supports lens
9
- narrowing, dedupe pre-flight, fix re-verification, and CI export. Use when the user
10
- asks for code review, thorough review, security review, PR review, /review, or
11
- --verify-fixes / re-verify findings.
12
- disable-model-invocation: true
13
- ---
14
-
15
- # Thorough Code Review
16
-
17
- Two-phase review: **scout** discovers tentative issues; **skeptic** subagents attempt to disprove each claim. Skeptic dispatch is severity-routed and budgeted — it is **not** one subagent per finding. Only verified findings appear in the main report.
18
-
19
- Three properties keep it honest:
20
-
21
- - **Grounded** — a signals pre-flight runs real tools (typecheck, lint, tests) so findings start from fact, not guesswork.
22
- - **Complete** — a recall/coverage pass balances the skeptic's precision by checking what the scout *missed*.
23
- - **Risk-weighted** — the dangerous quadrant (a high-severity finding one skeptic wants to dismiss) gets a second, independent skeptic before it vanishes.
24
-
25
- ## When to use
26
-
27
- - Pre-merge or pre-hand-off review
28
- - Security or correctness audit of a diff, path, or service
29
- - Re-verification after fixes (`--verify-fixes`)
30
- - CI validation via `review export`
31
-
32
- **Not** a replacement for Forge `requesting-code-review` — invoke this skill explicitly.
33
-
34
- ## Scope resolution
35
-
36
- **If the user did not specify a target, ask** which scope applies:
37
-
38
- | Option | How to read |
39
- | ------ | ----------- |
40
- | Uncommitted | `git diff` + untracked in scope |
41
- | Branch vs main | `git diff main...HEAD` (or repo default branch) |
42
- | Paths / services | User-provided paths |
43
- | Commit range | `git diff BASE..HEAD` |
44
- | Single file | Deep read of one file |
45
-
46
- ## Lens narrowing
47
-
48
- Default: **all lenses**. User may narrow with flags or phrases:
49
-
50
- | Flag | Lens |
51
- | ---- | ---- |
52
- | `--security` | AuthZ, injection, secrets, crypto |
53
- | `--correctness` | Logic, races, edge cases, idempotency |
54
- | `--smells` | Duplication, complexity, dead code |
55
- | `--architecture` | Boundaries, coupling, layering |
56
- | `--performance` | N+1, hot paths, allocations |
57
- | `--tests` | Coverage, mock-heavy tests |
58
- | `--contracts` | OpenAPI drift, breaking changes |
59
- | `--errors` | Silent failures, propagation |
60
- | `--maintainability` | Readability, file size |
61
-
62
- Read only matching sections from [reference/lenses.md](reference/lenses.md).
63
-
64
- ## Workflow overview
65
-
66
- ```
67
- Scaffold report → review new <slug> --type <t>
68
- Resolve scope + lenses
69
- → Prior-report carry-forward (inherit verdicts for unchanged code)
70
- → Signals pre-flight (run grounding tools; seed grounded findings)
71
- → [if smells] Dedupe pre-flight (read-only)
72
- → Phase 1: Scout (partition + parallel scouts when scope is large)
73
- → De-duplicate tentative findings
74
- → Phase 1.5: Coverage pass (recall — what did the scout miss? orchestrator-inline)
75
- → Phase 2: Skeptic (severity-routed + budgeted: dedicated for critical; batched for
76
- important/minor; inline verdicts for cheap cases; second skeptic
77
- for the dangerous quadrant)
78
- → Phase 3: Synthesis (edit JSON → review:render → review:export)
79
- ```
80
-
81
- ### Scaffold first
82
-
83
- Generate the report skeleton up front so the timestamp, review id, scope slug, and git SHAs are captured deterministically (never hand-author these):
84
-
85
- ```bash
86
- review new mercury-vat --type branch
87
- review new persona-profile --type paths --paths services/persona --lenses security,correctness
88
- ```
89
-
90
- This writes `.reviews/<id>-review.json` with empty findings. You fill findings into the JSON as you work, then render and export.
91
-
92
- ### Prior-report carry-forward
93
-
94
- Don't re-litigate verdicts the last review already earned. Before scouting:
95
-
96
- 1. Find the most recent `.reviews/*-review.json` whose scope overlaps this one (same service/paths). None → skip this step.
97
- 2. Run the script — it copies each verdicted finding whose file is unchanged since the parent's recorded SHA into the new report (verdict preserved, reason cites the parent + SHA), skips the rest with reasons, and refuses to write an invalid report:
98
-
99
- ```bash
100
- review carryforward --parent <prior-review-id> --file .reviews/<new-id>-review.json
101
- # add --dry-run to preview
102
- ```
103
-
104
- 3. List carried-forward false positives in the scout packet as "known false positives — do not re-raise". Findings whose file changed are fair game — the scout re-examines them fresh.
105
-
106
- ### Signals pre-flight
107
-
108
- Ground the scout in real tool output before reading code by hand. Run [reference/signals-preflight.md](reference/signals-preflight.md):
109
-
110
- 1. `review signals --type branch` (or `--paths a,b`) prints the typecheck/lint/test commands for exactly the workspaces in scope.
111
- 2. Run them; convert genuine failures into **grounded** tentative findings (`confidence: high`).
112
- 3. Record what ran in the JSON `signals` object.
113
-
114
- Grounded findings below `important` **skip Phase 2** — a compiler or test failure is already tool-proven; the orchestrator just checks it isn't intentional WIP (recent commit message, TODO, user context) and records the verdict directly. Grounded findings at `critical`/`important` still get a skeptic.
115
-
116
- The dedupe pre-flight (below) is the smells-lens special case of this pattern.
117
-
118
- #### Dedupe pre-flight (smells lens only)
119
-
120
- When `smells` is active (including "all"):
121
-
122
- 1. Read the project `dedupe` skill.
123
- 2. Run a **read-only** duplicate scan on the review scope only.
124
- 3. Emit `dup-###` tentative findings; merge into Phase 1 list.
125
- 4. Include `dedupe_preflight` in JSON and Appendix B in the rendered markdown.
126
- 5. **Do not edit code** during review.
127
-
128
- ### Phase 1 — Scout
129
-
130
- Follow [reference/phase1-scout.md](reference/phase1-scout.md).
131
-
132
- **Scale by partitioning.** A single scout reading every file degrades on large scopes. When the scope exceeds ~10 files or ~800 changed lines, split it into reviewable units (by module, or by lens) and run **parallel scout subagents** — capped at **4 scouts**; for bigger scopes make the units larger rather than the scout count higher. Each scout writes its tentative findings to `.reviews/<id>-tentative/<scout-name>.json` (`{ "findings": [...] }` in the scout format); then merge + dedupe + renumber deterministically:
133
-
134
- ```bash
135
- review merge --dir .reviews/<id>-tentative
136
- ```
137
-
138
- Small scopes stay a single pass (no tentative dir needed).
139
-
140
- Output tentative findings with: `id`, `lens`, `location`, `claim`, `evidence`, `tentative_severity`, `confidence`. Calibrate severity using [reference/severity-rubric.md](reference/severity-rubric.md).
141
-
142
- ### Phase 1.5 — Coverage pass (recall)
143
-
144
- The skeptic optimizes precision; nothing else guards against silent misses. After scout, run the coverage critic in [reference/phase1c-coverage.md](reference/phase1c-coverage.md). The orchestrator does this pass **inline** (no subagent) — it already holds the scope and the merged finding list; dispatch a single coverage subagent only when the scope was partitioned across scouts and the file list is too large to re-check in context:
145
-
146
- - Which in-scope files received **zero** findings — actually clean, or skipped?
147
- - Which active lens produced **zero** findings — real, or not exercised?
148
- - Emit any follow-up tentative findings (they go through Phase 2 like the rest).
149
- - Record the ledger in the JSON `coverage` object (`files_reviewed`, `files_skipped`, `lenses_without_findings` with a reason each).
150
-
151
- ### Phase 2 — Skeptic
152
-
153
- Dispatch skeptic subagents (Task tool) with **no chat history**, filling [reference/phase2-skeptic.md](reference/phase2-skeptic.md) placeholders. Mode `initial` for full reviews.
154
-
155
- **Cheap verdicts first — a subagent is the last resort, not the default.** Before dispatching anything, drain the no-dispatch paths:
156
-
157
- 1. **Carry-forward** — verdict inherited from a prior report (see above).
158
- 2. **Grounded skip** — tool-proven findings below `important` skip Phase 2 entirely (see signals pre-flight).
159
- 3. **Inline verdict** — `minor` findings with `confidence: high` whose scout packet (`context` + `related`) already contains everything needed: the orchestrator runs the disproof checklist itself, records the verdict with evidence, and counts it under `stats.inline_verdicts`. No subagent. If the checklist turns up anything non-local (unclear callers, possible mitigation elsewhere), promote it to a batched dispatch instead.
160
-
161
- Route the remainder by severity:
162
-
163
- - **`critical`** — one **dedicated** skeptic per finding.
164
- - **`important`** — batch findings **sharing a file** (or tight module) into one skeptic dispatch, cap ~4 per batch; an important finding alone in its file gets a dedicated dispatch.
165
- - **`minor`** — batch by file, cap ~6 per batch.
166
- - Every batched skeptic reads the file once and returns an **independent verdict block per finding** — never let one verdict color another.
167
-
168
- **Dispatch budget.** Default cap: **~12 skeptic dispatches** per review (dedicated + batched + second opinions combined); the user can raise it (`--budget N`) or lift it ("no budget"). When the tentative list would exceed the budget:
169
-
170
- 1. Sort by severity, then by scout confidence (low confidence first — those need verification most).
171
- 2. Batch more aggressively (merge adjacent-file batches into module batches) before dropping anything.
172
- 3. Move remaining `minor` findings to inline verdicts.
173
- 4. Never leave a finding unverdicted, and never silently drop one — if the budget genuinely cannot cover a finding, report it with verdict `needs_decision` and a reason noting it was not adversarially verified.
174
-
175
- Dangerous-quadrant second opinions count against the budget and are capped at **3 per review**, highest severity first.
176
-
177
- **Hard rules:**
178
-
179
- - Steelman the claim first.
180
- - Every verdict needs `verdict_reason` with evidence.
181
- - `false_positive` findings go to the report appendix, not the main body.
182
-
183
- **Risk-weighted dispatch.** Spend the adversarial budget where a wrong call is most costly. A finding is in the **dangerous quadrant** when:
184
-
185
- - it is `critical`/`important` and a single skeptic returns `false_positive` (risk: dismissing a real bug), or
186
- - `phase1_confidence: high` but the skeptic returns `false_positive` (scout/skeptic disagreement), or
187
- - `phase1_confidence: low` and `severity: critical` (high-stakes, low-certainty).
188
-
189
- For these, dispatch a **second independent skeptic** (no history, no knowledge of the first verdict). Record it in the finding's `second_opinion` object. If the two disagree, keep the higher-severity outcome or route to `needs_decision` — never silently drop it.
190
-
191
- ### Phase 3 — Synthesis
192
-
193
- **JSON is the single source of truth. The Markdown is generated from it — never hand-author the `.md`.**
194
-
195
- 1. Fill findings, `summary` (with `headline` and `top_actions`), `coverage`, `signals`, and `stats` (dispatch counters: `scouts`, `skeptics_dedicated`, `skeptics_batched`, `inline_verdicts`, `grounded_skips`, `carried_forward`, `second_opinions`) into the scaffolded `.reviews/<id>-review.json`.
196
- 2. Generate the paired markdown: `review render --file .reviews/<id>-review.json`.
197
- 3. Validate + summarize: `review export` (add `--fail-on critical|important` for a CI gate).
198
-
199
- The summary verdict counts must reconcile with the findings — `review:export` rejects a report whose summary disagrees with its own body, so let render/export own the counts.
200
-
201
- ## Fix verification (`--verify-fixes`)
202
-
203
- When the user fixed issues or asks to re-verify:
204
-
205
- 1. Scaffold a reverify report: `review new <slug> --kind reverify --parent <review_id>`.
206
- 2. Load prior report JSON (user path, or latest `*-review.json` in `.reviews/`).
207
- 3. Filter findings where prior `verdict` was `confirmed` or `downgraded`.
208
- 4. Phase 2 only: skeptics with `MODE=reverify` in [reference/phase2-skeptic.md](reference/phase2-skeptic.md) — same severity routing, batching, budget, and model tiers as initial mode.
209
- 5. Verdicts: `resolved` | `still_open` | `partially_fixed` | `regressed`.
210
- 6. Also scout the **fix diff itself** for regressions a per-finding recheck would miss, then `review:render` + `review:export`.
211
-
212
- `new-review --kind reverify` sets `kind: reverify` and `parent_report` for you.
213
-
214
- ## CI export
215
-
216
- ```bash
217
- review export
218
- review export --file .reviews/<id>-review.json
219
- review export --render-md # regenerate .md from JSON first
220
- review export --out ./ci-artifacts --fail-on important
221
- ```
222
-
223
- Validates the report, prints a summary, optionally copies artefacts and fails on open findings at/above a severity level.
224
-
225
- ## Project-specific hooks
226
-
227
- When reviewing a project that documents accepted risks:
228
-
229
- - If the skill’s [reference/accepted-risks.md](reference/accepted-risks.md) (or the project’s ADR digest) applies, inject it into **every scout and skeptic packet**. Full ADRs are the fallback for claims the digest does not cover. Customize `accepted-risks.md` per product as needed.
230
- - Scouts also honor project agent guidelines and any cross-cutting patterns listed in the digest.
231
-
232
- ## Model selection for subagents
233
-
234
- **Choose the model tier per dispatch — never default to the most capable (priciest) model.** Match the tier to the judgment the role actually needs. Map roles to Forge capability tiers (`fast` / `standard` / `capable`) and resolve via `forge resolve-model --tier <…>` so billing stays on the **`included`** (subscription) lane unless the user explicitly asks for metered/API models — see forge skill [docs/forge.md](../forge/docs/forge.md) § Subagent model.
235
-
236
- | Role | Tier | Why |
237
- | ---- | ---- | --- |
238
- | Scout (any partition) | `standard` | Checklist-driven scanning; breadth over depth |
239
- | Coverage pass | none (orchestrator-inline) | Bookkeeping over the tentative list; subagent only if the scope is very large |
240
- | Skeptic — `minor` batch | `standard` | Verdicts need judgment, but stakes are low; never the *cheapest* tier |
241
- | Skeptic — `important` | `standard` | Escalate to `capable` only when the claim needs subtle non-local reasoning (races, authz chains, crypto) |
242
- | Skeptic — `critical` | `capable` | A wrong verdict here is the costliest outcome |
243
- | Second opinion (dangerous quadrant) | `capable` | Exists precisely to catch a wrong dismissal |
244
-
245
- Honor resolver JSON: if `omitModel` is true, pass no explicit `model` to the Task tool; otherwise pass `model` exactly. Do not invent frontier/API slugs. If the session is *already* on the strongest included model, escalation to `capable` may be a no-op — don't pay for it twice by picking a metered slug.
246
-
247
- ## Subagent dispatch template
248
-
249
- ```
250
- Task (generalPurpose or explore):
251
- Prompt from reference/phase2-skeptic.md with finding packet filled in.
252
- Model tier per the model-selection table above.
253
- Read files needed to verify — no session history.
254
- Return one verdict YAML block per finding in the packet.
255
- ```
256
-
257
- Dispatch independent scouts and skeptics in parallel; barrier only where you must merge across the whole set (dedupe, coverage).
258
-
259
- ## Quality bar
260
-
261
- Before finishing:
262
-
263
- - [ ] Report scaffolded with `review:new` (deterministic id/timestamp/SHAs)
264
- - [ ] Prior-report carry-forward checked; carried verdicts cite the prior report id + SHA
265
- - [ ] Signals pre-flight run; `signals` recorded
266
- - [ ] Scope and lenses recorded
267
- - [ ] Coverage pass run; `coverage` ledger recorded
268
- - [ ] Every tentative finding has a verdict: dedicated skeptic (critical), batched skeptic (important/minor), inline verdict, grounded-skip, or carry-forward; dangerous-quadrant findings got a second skeptic (≤3)
269
- - [ ] Skeptic dispatches stayed within budget (~12 default); model tier chosen per the model-selection table, not defaulted to the most capable
270
- - [ ] `stats` dispatch counters recorded (scouts, skeptics, inline verdicts, skips, carry-forwards)
271
- - [ ] Markdown **generated** via `review:render` (not hand-written)
272
- - [ ] JSON validates via `review export`
273
- - [ ] False positives documented in the appendix with reasons
274
-
275
- ## Human documentation
276
-
277
- - forgekit `docs/thorough-code-review.md` — overview, invocation, CI usage
278
- - project agent docs (if any)
279
-
280
- ## Additional resources
281
-
282
- - [reference/lenses.md](reference/lenses.md) — per-lens checklists
283
- - [reference/signals-preflight.md](reference/signals-preflight.md) — grounding tools → findings
284
- - [reference/phase1-scout.md](reference/phase1-scout.md) — scout prompt (+ partitioning)
285
- - [reference/phase1c-coverage.md](reference/phase1c-coverage.md) — recall / coverage pass
286
- - [reference/phase2-skeptic.md](reference/phase2-skeptic.md) — skeptic prompt (+ risk-weighting)
287
- - [reference/severity-rubric.md](reference/severity-rubric.md) — severity calibration
288
- - [reference/report-template.md](reference/report-template.md) — markdown structure (generated)
289
- - [reference/report-schema.json](reference/report-schema.json) — JSON sidecar schema
290
- - [examples.md](examples.md) — invocation examples
1
+ ---
2
+ name: thorough-code-review
3
+ description: >-
4
+ Performs two-phase code review with adversarial false-positive verification across
5
+ security, correctness, smells, architecture, performance, tests, contracts, errors,
6
+ and maintainability. Grounds findings in a signals pre-flight, balances precision with
7
+ a recall/coverage pass, and risk-weights skeptic verification. JSON is the source of
8
+ truth; the Markdown is generated from it. Writes reports to .reviews/. Supports lens
9
+ narrowing, dedupe pre-flight, fix re-verification, and CI export. Use when the user
10
+ asks for code review, thorough review, security review, PR review, /review, or
11
+ --verify-fixes / re-verify findings.
12
+ disable-model-invocation: true
13
+ ---
14
+
15
+ # Thorough Code Review
16
+
17
+ Two-phase review: **scout** discovers tentative issues; **skeptic** subagents attempt to disprove each claim. Skeptic dispatch is severity-routed and budgeted — it is **not** one subagent per finding. Only verified findings appear in the main report.
18
+
19
+ Three properties keep it honest:
20
+
21
+ - **Grounded** — a signals pre-flight runs real tools (typecheck, lint, tests) so findings start from fact, not guesswork.
22
+ - **Complete** — a recall/coverage pass balances the skeptic's precision by checking what the scout *missed*.
23
+ - **Risk-weighted** — the dangerous quadrant (a high-severity finding one skeptic wants to dismiss) gets a second, independent skeptic before it vanishes.
24
+
25
+ ## When to use
26
+
27
+ - Pre-merge or pre-hand-off review
28
+ - Security or correctness audit of a diff, path, or service
29
+ - Re-verification after fixes (`--verify-fixes`)
30
+ - CI validation via `review export`
31
+
32
+ **Not** a replacement for Forge `requesting-code-review` — invoke this skill explicitly.
33
+
34
+ ## Scope resolution
35
+
36
+ **If the user did not specify a target, ask** which scope applies:
37
+
38
+ | Option | How to read |
39
+ | ------ | ----------- |
40
+ | Uncommitted | `git diff` + untracked in scope |
41
+ | Branch vs main | `git diff main...HEAD` (or repo default branch) |
42
+ | Paths / services | User-provided paths |
43
+ | Commit range | `git diff BASE..HEAD` |
44
+ | Single file | Deep read of one file |
45
+
46
+ ## Lens narrowing
47
+
48
+ Default: **all lenses**. User may narrow with flags or phrases:
49
+
50
+ | Flag | Lens |
51
+ | ---- | ---- |
52
+ | `--security` | AuthZ, injection, secrets, crypto |
53
+ | `--correctness` | Logic, races, edge cases, idempotency |
54
+ | `--smells` | Duplication, complexity, dead code |
55
+ | `--architecture` | Boundaries, coupling, layering |
56
+ | `--performance` | N+1, hot paths, allocations |
57
+ | `--tests` | Coverage, mock-heavy tests |
58
+ | `--contracts` | OpenAPI drift, breaking changes |
59
+ | `--errors` | Silent failures, propagation |
60
+ | `--maintainability` | Readability, file size |
61
+
62
+ Read only matching sections from [reference/lenses.md](reference/lenses.md).
63
+
64
+ ## Workflow overview
65
+
66
+ ```
67
+ Scaffold report → review new <slug> --type <t>
68
+ Resolve scope + lenses
69
+ → Prior-report carry-forward (inherit verdicts for unchanged code)
70
+ → Signals pre-flight (run grounding tools; seed grounded findings)
71
+ → [if smells] Dedupe pre-flight (read-only)
72
+ → Phase 1: Scout (partition + parallel scouts when scope is large)
73
+ → De-duplicate tentative findings
74
+ → Phase 1.5: Coverage pass (recall — what did the scout miss? orchestrator-inline)
75
+ → Phase 2: Skeptic (severity-routed + budgeted: dedicated for critical; batched for
76
+ important/minor; inline verdicts for cheap cases; second skeptic
77
+ for the dangerous quadrant)
78
+ → Phase 3: Synthesis (edit JSON → review:render → review:export)
79
+ ```
80
+
81
+ ### Scaffold first
82
+
83
+ Generate the report skeleton up front so the timestamp, review id, scope slug, and git SHAs are captured deterministically (never hand-author these):
84
+
85
+ ```bash
86
+ review new mercury-vat --type branch
87
+ review new persona-profile --type paths --paths services/persona --lenses security,correctness
88
+ ```
89
+
90
+ This writes `.reviews/<id>-review.json` with empty findings. You fill findings into the JSON as you work, then render and export.
91
+
92
+ ### Prior-report carry-forward
93
+
94
+ Don't re-litigate verdicts the last review already earned. Before scouting:
95
+
96
+ 1. Find the most recent `.reviews/*-review.json` whose scope overlaps this one (same service/paths). None → skip this step.
97
+ 2. Run the script — it copies each verdicted finding whose file is unchanged since the parent's recorded SHA into the new report (verdict preserved, reason cites the parent + SHA), skips the rest with reasons, and refuses to write an invalid report:
98
+
99
+ ```bash
100
+ review carryforward --parent <prior-review-id> --file .reviews/<new-id>-review.json
101
+ # add --dry-run to preview
102
+ ```
103
+
104
+ 3. List carried-forward false positives in the scout packet as "known false positives — do not re-raise". Findings whose file changed are fair game — the scout re-examines them fresh.
105
+
106
+ ### Signals pre-flight
107
+
108
+ Ground the scout in real tool output before reading code by hand. Run [reference/signals-preflight.md](reference/signals-preflight.md):
109
+
110
+ 1. `review signals --type branch` (or `--paths a,b`) prints the typecheck/lint/test commands for exactly the workspaces in scope.
111
+ 2. Run them; convert genuine failures into **grounded** tentative findings (`confidence: high`).
112
+ 3. Record what ran in the JSON `signals` object.
113
+
114
+ Grounded findings below `important` **skip Phase 2** — a compiler or test failure is already tool-proven; the orchestrator just checks it isn't intentional WIP (recent commit message, TODO, user context) and records the verdict directly. Grounded findings at `critical`/`important` still get a skeptic.
115
+
116
+ The dedupe pre-flight (below) is the smells-lens special case of this pattern.
117
+
118
+ #### Dedupe pre-flight (smells lens only)
119
+
120
+ When `smells` is active (including "all"):
121
+
122
+ 1. Read the project `dedupe` skill.
123
+ 2. Run a **read-only** duplicate scan on the review scope only.
124
+ 3. Emit `dup-###` tentative findings; merge into Phase 1 list.
125
+ 4. Include `dedupe_preflight` in JSON and Appendix B in the rendered markdown.
126
+ 5. **Do not edit code** during review.
127
+
128
+ ### Phase 1 — Scout
129
+
130
+ Follow [reference/phase1-scout.md](reference/phase1-scout.md).
131
+
132
+ **Scale by partitioning.** A single scout reading every file degrades on large scopes. When the scope exceeds ~10 files or ~800 changed lines, split it into reviewable units (by module, or by lens) and run **parallel scout subagents** — capped at **4 scouts**; for bigger scopes make the units larger rather than the scout count higher. Each scout writes its tentative findings to `.reviews/<id>-tentative/<scout-name>.json` (`{ "findings": [...] }` in the scout format); then merge + dedupe + renumber deterministically:
133
+
134
+ ```bash
135
+ review merge --dir .reviews/<id>-tentative
136
+ ```
137
+
138
+ Small scopes stay a single pass (no tentative dir needed).
139
+
140
+ Output tentative findings with: `id`, `lens`, `location`, `claim`, `evidence`, `tentative_severity`, `confidence`. Calibrate severity using [reference/severity-rubric.md](reference/severity-rubric.md).
141
+
142
+ ### Phase 1.5 — Coverage pass (recall)
143
+
144
+ The skeptic optimizes precision; nothing else guards against silent misses. After scout, run the coverage critic in [reference/phase1c-coverage.md](reference/phase1c-coverage.md). The orchestrator does this pass **inline** (no subagent) — it already holds the scope and the merged finding list; dispatch a single coverage subagent only when the scope was partitioned across scouts and the file list is too large to re-check in context:
145
+
146
+ - Which in-scope files received **zero** findings — actually clean, or skipped?
147
+ - Which active lens produced **zero** findings — real, or not exercised?
148
+ - Emit any follow-up tentative findings (they go through Phase 2 like the rest).
149
+ - Record the ledger in the JSON `coverage` object (`files_reviewed`, `files_skipped`, `lenses_without_findings` with a reason each).
150
+
151
+ ### Phase 2 — Skeptic
152
+
153
+ Dispatch skeptic subagents (Task tool) with **no chat history**, filling [reference/phase2-skeptic.md](reference/phase2-skeptic.md) placeholders. Mode `initial` for full reviews.
154
+
155
+ **Cheap verdicts first — a subagent is the last resort, not the default.** Before dispatching anything, drain the no-dispatch paths:
156
+
157
+ 1. **Carry-forward** — verdict inherited from a prior report (see above).
158
+ 2. **Grounded skip** — tool-proven findings below `important` skip Phase 2 entirely (see signals pre-flight).
159
+ 3. **Inline verdict** — `minor` findings with `confidence: high` whose scout packet (`context` + `related`) already contains everything needed: the orchestrator runs the disproof checklist itself, records the verdict with evidence, and counts it under `stats.inline_verdicts`. No subagent. If the checklist turns up anything non-local (unclear callers, possible mitigation elsewhere), promote it to a batched dispatch instead.
160
+
161
+ Route the remainder by severity:
162
+
163
+ - **`critical`** — one **dedicated** skeptic per finding.
164
+ - **`important`** — batch findings **sharing a file** (or tight module) into one skeptic dispatch, cap ~4 per batch; an important finding alone in its file gets a dedicated dispatch.
165
+ - **`minor`** — batch by file, cap ~6 per batch.
166
+ - Every batched skeptic reads the file once and returns an **independent verdict block per finding** — never let one verdict color another.
167
+
168
+ **Dispatch budget.** Default cap: **~12 skeptic dispatches** per review (dedicated + batched + second opinions combined); the user can raise it (`--budget N`) or lift it ("no budget"). When the tentative list would exceed the budget:
169
+
170
+ 1. Sort by severity, then by scout confidence (low confidence first — those need verification most).
171
+ 2. Batch more aggressively (merge adjacent-file batches into module batches) before dropping anything.
172
+ 3. Move remaining `minor` findings to inline verdicts.
173
+ 4. Never leave a finding unverdicted, and never silently drop one — if the budget genuinely cannot cover a finding, report it with verdict `needs_decision` and a reason noting it was not adversarially verified.
174
+
175
+ Dangerous-quadrant second opinions count against the budget and are capped at **3 per review**, highest severity first.
176
+
177
+ **Hard rules:**
178
+
179
+ - Steelman the claim first.
180
+ - Every verdict needs `verdict_reason` with evidence.
181
+ - `false_positive` findings go to the report appendix, not the main body.
182
+
183
+ **Risk-weighted dispatch.** Spend the adversarial budget where a wrong call is most costly. A finding is in the **dangerous quadrant** when:
184
+
185
+ - it is `critical`/`important` and a single skeptic returns `false_positive` (risk: dismissing a real bug), or
186
+ - `phase1_confidence: high` but the skeptic returns `false_positive` (scout/skeptic disagreement), or
187
+ - `phase1_confidence: low` and `severity: critical` (high-stakes, low-certainty).
188
+
189
+ For these, dispatch a **second independent skeptic** (no history, no knowledge of the first verdict). Record it in the finding's `second_opinion` object. If the two disagree, keep the higher-severity outcome or route to `needs_decision` — never silently drop it.
190
+
191
+ ### Phase 3 — Synthesis
192
+
193
+ **JSON is the single source of truth. The Markdown is generated from it — never hand-author the `.md`.**
194
+
195
+ 1. Fill findings, `summary` (with `headline` and `top_actions`), `coverage`, `signals`, and `stats` (dispatch counters: `scouts`, `skeptics_dedicated`, `skeptics_batched`, `inline_verdicts`, `grounded_skips`, `carried_forward`, `second_opinions`) into the scaffolded `.reviews/<id>-review.json`.
196
+ 2. Generate the paired markdown: `review render --file .reviews/<id>-review.json`.
197
+ 3. Validate + summarize: `review export` (add `--fail-on critical|important` for a CI gate).
198
+
199
+ The summary verdict counts must reconcile with the findings — `review:export` rejects a report whose summary disagrees with its own body, so let render/export own the counts.
200
+
201
+ ## Fix verification (`--verify-fixes`)
202
+
203
+ When the user fixed issues or asks to re-verify:
204
+
205
+ 1. Scaffold a reverify report: `review new <slug> --kind reverify --parent <review_id>`.
206
+ 2. Load prior report JSON (user path, or latest `*-review.json` in `.reviews/`).
207
+ 3. Filter findings where prior `verdict` was `confirmed` or `downgraded`.
208
+ 4. Phase 2 only: skeptics with `MODE=reverify` in [reference/phase2-skeptic.md](reference/phase2-skeptic.md) — same severity routing, batching, budget, and model tiers as initial mode.
209
+ 5. Verdicts: `resolved` | `still_open` | `partially_fixed` | `regressed`.
210
+ 6. Also scout the **fix diff itself** for regressions a per-finding recheck would miss, then `review:render` + `review:export`.
211
+
212
+ `new-review --kind reverify` sets `kind: reverify` and `parent_report` for you.
213
+
214
+ ## CI export
215
+
216
+ ```bash
217
+ review export
218
+ review export --file .reviews/<id>-review.json
219
+ review export --render-md # regenerate .md from JSON first
220
+ review export --out ./ci-artifacts --fail-on important
221
+ ```
222
+
223
+ Validates the report, prints a summary, optionally copies artefacts and fails on open findings at/above a severity level.
224
+
225
+ ## Project-specific hooks
226
+
227
+ When reviewing a project that documents accepted risks:
228
+
229
+ - If the skill’s [reference/accepted-risks.md](reference/accepted-risks.md) (or the project’s ADR digest) applies, inject it into **every scout and skeptic packet**. Full ADRs are the fallback for claims the digest does not cover. Customize `accepted-risks.md` per product as needed.
230
+ - Scouts also honor project agent guidelines and any cross-cutting patterns listed in the digest.
231
+
232
+ ## Model selection for subagents
233
+
234
+ **Choose the model tier per dispatch — never default to the most capable (priciest) model.** Match the tier to the judgment the role actually needs. Map roles to Forge capability tiers (`fast` / `standard` / `capable`) and resolve via `forge resolve-model --tier <…>` so billing stays on the **`included`** (subscription) lane unless the user explicitly asks for metered/API models — see forge skill [docs/forge.md](../forge/docs/forge.md) § Subagent model.
235
+
236
+ | Role | Tier | Why |
237
+ | ---- | ---- | --- |
238
+ | Scout (any partition) | `standard` | Checklist-driven scanning; breadth over depth |
239
+ | Coverage pass | none (orchestrator-inline) | Bookkeeping over the tentative list; subagent only if the scope is very large |
240
+ | Skeptic — `minor` batch | `standard` | Verdicts need judgment, but stakes are low; never the *cheapest* tier |
241
+ | Skeptic — `important` | `standard` | Escalate to `capable` only when the claim needs subtle non-local reasoning (races, authz chains, crypto) |
242
+ | Skeptic — `critical` | `capable` | A wrong verdict here is the costliest outcome |
243
+ | Second opinion (dangerous quadrant) | `capable` | Exists precisely to catch a wrong dismissal |
244
+
245
+ Honor resolver JSON: if `omitModel` is true, pass no explicit `model` to the Task tool; otherwise pass `model` exactly. Do not invent frontier/API slugs. If the session is *already* on the strongest included model, escalation to `capable` may be a no-op — don't pay for it twice by picking a metered slug.
246
+
247
+ ## Subagent dispatch template
248
+
249
+ ```
250
+ Task (generalPurpose or explore):
251
+ Prompt from reference/phase2-skeptic.md with finding packet filled in.
252
+ Model tier per the model-selection table above.
253
+ Read files needed to verify — no session history.
254
+ Return one verdict YAML block per finding in the packet.
255
+ ```
256
+
257
+ Dispatch independent scouts and skeptics in parallel; barrier only where you must merge across the whole set (dedupe, coverage).
258
+
259
+ ## Quality bar
260
+
261
+ Before finishing:
262
+
263
+ - [ ] Report scaffolded with `review:new` (deterministic id/timestamp/SHAs)
264
+ - [ ] Prior-report carry-forward checked; carried verdicts cite the prior report id + SHA
265
+ - [ ] Signals pre-flight run; `signals` recorded
266
+ - [ ] Scope and lenses recorded
267
+ - [ ] Coverage pass run; `coverage` ledger recorded
268
+ - [ ] Every tentative finding has a verdict: dedicated skeptic (critical), batched skeptic (important/minor), inline verdict, grounded-skip, or carry-forward; dangerous-quadrant findings got a second skeptic (≤3)
269
+ - [ ] Skeptic dispatches stayed within budget (~12 default); model tier chosen per the model-selection table, not defaulted to the most capable
270
+ - [ ] `stats` dispatch counters recorded (scouts, skeptics, inline verdicts, skips, carry-forwards)
271
+ - [ ] Markdown **generated** via `review:render` (not hand-written)
272
+ - [ ] JSON validates via `review export`
273
+ - [ ] False positives documented in the appendix with reasons
274
+
275
+ ## Human documentation
276
+
277
+ - forgekit `docs/thorough-code-review.md` — overview, invocation, CI usage
278
+ - project agent docs (if any)
279
+
280
+ ## Additional resources
281
+
282
+ - [reference/lenses.md](reference/lenses.md) — per-lens checklists
283
+ - [reference/signals-preflight.md](reference/signals-preflight.md) — grounding tools → findings
284
+ - [reference/phase1-scout.md](reference/phase1-scout.md) — scout prompt (+ partitioning)
285
+ - [reference/phase1c-coverage.md](reference/phase1c-coverage.md) — recall / coverage pass
286
+ - [reference/phase2-skeptic.md](reference/phase2-skeptic.md) — skeptic prompt (+ risk-weighting)
287
+ - [reference/severity-rubric.md](reference/severity-rubric.md) — severity calibration
288
+ - [reference/report-template.md](reference/report-template.md) — markdown structure (generated)
289
+ - [reference/report-schema.json](reference/report-schema.json) — JSON sidecar schema
290
+ - [examples.md](examples.md) — invocation examples