@izkac/forgekit 0.1.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.
- package/bin/forge.mjs +100 -0
- package/bin/forgekit.mjs +84 -0
- package/bin/review.mjs +82 -0
- package/package.json +46 -0
- package/scripts/prepack.mjs +78 -0
- package/scripts/run-tests.mjs +43 -0
- package/src/adr.mjs +236 -0
- package/src/adr.test.mjs +170 -0
- package/src/change.mjs +234 -0
- package/src/change.test.mjs +83 -0
- package/src/cleanup-sessions.mjs +70 -0
- package/src/config.mjs +103 -0
- package/src/defer.mjs +75 -0
- package/src/doctor.mjs +341 -0
- package/src/doctor.test.mjs +114 -0
- package/src/init.mjs +575 -0
- package/src/install.mjs +777 -0
- package/src/install.test.mjs +104 -0
- package/src/integrity-check.mjs +58 -0
- package/src/integrity.mjs +317 -0
- package/src/integrity.test.mjs +296 -0
- package/src/lib/workspaces.mjs +55 -0
- package/src/lib.mjs +138 -0
- package/src/models.defaults.json +41 -0
- package/src/new-session.mjs +82 -0
- package/src/openspec-overlays/README.md +19 -0
- package/src/openspec-overlays/openspec-apply-change-footer.md +14 -0
- package/src/openspec-overlays/opsx-apply-completion-step.md +1 -0
- package/src/openspec-overlays/opsx-apply-implement-step.md +11 -0
- package/src/paths.mjs +92 -0
- package/src/plan-engine.mjs +260 -0
- package/src/plan-engine.test.mjs +245 -0
- package/src/preferences.defaults.json +78 -0
- package/src/preferences.mjs +438 -0
- package/src/preferences.test.mjs +174 -0
- package/src/record-evidence.mjs +204 -0
- package/src/record-evidence.test.mjs +260 -0
- package/src/resolve-model.mjs +312 -0
- package/src/resolve-model.test.mjs +194 -0
- package/src/review/carryforward.mjs +413 -0
- package/src/review/carryforward.test.mjs +587 -0
- package/src/review/cli.test.mjs +117 -0
- package/src/review/export.mjs +172 -0
- package/src/review/export.test.mjs +197 -0
- package/src/review/fixtures/valid-review.json +42 -0
- package/src/review/lib.mjs +894 -0
- package/src/review/lib.test.mjs +266 -0
- package/src/review/merge-tentative.mjs +292 -0
- package/src/review/merge-tentative.test.mjs +363 -0
- package/src/review/new-review.mjs +200 -0
- package/src/review/render.mjs +108 -0
- package/src/review/schema-consistency.test.mjs +83 -0
- package/src/review/schema.json +196 -0
- package/src/review/signals.mjs +144 -0
- package/src/review/signals.test.mjs +62 -0
- package/src/score-cli.mjs +68 -0
- package/src/score.mjs +489 -0
- package/src/score.test.mjs +253 -0
- package/src/session-reminder.mjs +168 -0
- package/src/session-status.mjs +70 -0
- package/src/set-models.mjs +186 -0
- package/src/set-phase.mjs +177 -0
- package/src/set-phase.test.mjs +317 -0
- package/src/set-prefs.mjs +294 -0
- package/src/spine.mjs +91 -0
- package/src/triage-prompt.mjs +175 -0
- package/src/triage-prompt.test.mjs +50 -0
- package/src/vendor-openspec-overlays.mjs +176 -0
- package/src/vendor-openspec-overlays.test.mjs +62 -0
- package/vendor/skills/archive-to-adr/SKILL.md +149 -0
- package/vendor/skills/forge/SKILL.md +136 -0
- package/vendor/skills/forge/phases/brainstorm.md +23 -0
- package/vendor/skills/forge/phases/finish.md +87 -0
- package/vendor/skills/forge/phases/implement.md +76 -0
- package/vendor/skills/forge/phases/plan-openspec.md +40 -0
- package/vendor/skills/forge/phases/plan-specs.md +97 -0
- package/vendor/skills/forge/phases/review.md +25 -0
- package/vendor/skills/forge/phases/verify.md +120 -0
- package/vendor/skills/forge/references/forge-layout.md +85 -0
- package/vendor/skills/forge/references/pace.md +115 -0
- package/vendor/skills/forge/references/plan-routing.md +51 -0
- package/vendor/skills/forge/references/runtime-integrity.md +157 -0
- package/vendor/skills/forge/references/substantial-work.md +37 -0
- package/vendor/skills/forge/references/tdd-core.md +29 -0
- package/vendor/skills/forge/references/test-evidence.md +30 -0
- package/vendor/skills/forge/references/test-strategy.md +68 -0
- package/vendor/skills/forge/skills/NOTICE.md +17 -0
- package/vendor/skills/forge/skills/brainstorming/SKILL.md +120 -0
- package/vendor/skills/forge/skills/requesting-code-review/SKILL.md +67 -0
- package/vendor/skills/forge/skills/requesting-code-review/code-reviewer.md +146 -0
- package/vendor/skills/forge/skills/subagent-driven-development/SKILL.md +87 -0
- package/vendor/skills/forge/skills/systematic-debugging/SKILL.md +234 -0
- package/vendor/skills/forge/skills/systematic-debugging/condition-based-waiting.md +115 -0
- package/vendor/skills/forge/skills/systematic-debugging/defense-in-depth.md +122 -0
- package/vendor/skills/forge/skills/systematic-debugging/find-polluter.sh +63 -0
- package/vendor/skills/forge/skills/systematic-debugging/root-cause-tracing.md +169 -0
- package/vendor/skills/forge/skills/test-driven-development/SKILL.md +290 -0
- package/vendor/skills/forge/skills/test-driven-development/testing-anti-patterns.md +299 -0
- package/vendor/skills/forge/skills/verification-before-completion/SKILL.md +59 -0
- package/vendor/skills/forge/subagents/final-reviewer-prompt.md +53 -0
- package/vendor/skills/forge/subagents/implementer-prompt.md +38 -0
- package/vendor/skills/forge/subagents/task-reviewer-prompt.md +61 -0
- package/vendor/skills/git-resolve-adr-conflict/SKILL.md +132 -0
- package/vendor/skills/thorough-code-review/SKILL.md +290 -0
- package/vendor/skills/thorough-code-review/examples/accepted-risks-janus.md +32 -0
- package/vendor/skills/thorough-code-review/examples.md +133 -0
- package/vendor/skills/thorough-code-review/reference/accepted-risks.md +26 -0
- package/vendor/skills/thorough-code-review/reference/lenses.md +96 -0
- package/vendor/skills/thorough-code-review/reference/phase1-scout.md +62 -0
- package/vendor/skills/thorough-code-review/reference/phase1c-coverage.md +44 -0
- package/vendor/skills/thorough-code-review/reference/phase2-skeptic.md +105 -0
- package/vendor/skills/thorough-code-review/reference/report-schema.json +222 -0
- package/vendor/skills/thorough-code-review/reference/report-template.md +115 -0
- package/vendor/skills/thorough-code-review/reference/severity-rubric.md +49 -0
- package/vendor/skills/thorough-code-review/reference/signals-preflight.md +55 -0
- package/vendor/templates/adr/README.md +7 -0
- package/vendor/templates/adr/decisions.md +141 -0
- package/vendor/templates/adr/hooks/check-pending-adrs.mjs +74 -0
- package/vendor/templates/adr/hooks/check-pending-adrs.sh +3 -0
- package/vendor/templates/adr/hooks/openspec-archive-agent-message.mjs +52 -0
- package/vendor/templates/adr/hooks/openspec-archive-agent-message.sh +3 -0
- package/vendor/templates/project/claude/commands/forge-apply.md +75 -0
- package/vendor/templates/project/claude/commands/forge-brainstorm.md +7 -0
- package/vendor/templates/project/claude/commands/forge-build.md +17 -0
- package/vendor/templates/project/claude/commands/forge-plan.md +12 -0
- package/vendor/templates/project/claude/commands/forge-skip.md +14 -0
- package/vendor/templates/project/claude/commands/forge-status.md +16 -0
- package/vendor/templates/project/claude/commands/forge.md +16 -0
- package/vendor/templates/project/claude/hooks/forge-prompt-hook.mjs +73 -0
- package/vendor/templates/project/claude/hooks/forge-session-start.mjs +19 -0
- package/vendor/templates/project/claude/hooks/forge-triage-hook.mjs +77 -0
- package/vendor/templates/project/claude/rules/forge.md +16 -0
- package/vendor/templates/project/codex/rules/forge.md +10 -0
- package/vendor/templates/project/cursor/commands/forge-apply.md +75 -0
- package/vendor/templates/project/cursor/commands/forge-brainstorm.md +10 -0
- package/vendor/templates/project/cursor/commands/forge-build.md +17 -0
- package/vendor/templates/project/cursor/commands/forge-plan.md +15 -0
- package/vendor/templates/project/cursor/commands/forge-skip.md +14 -0
- package/vendor/templates/project/cursor/commands/forge-status.md +16 -0
- package/vendor/templates/project/cursor/commands/forge.md +16 -0
- package/vendor/templates/project/cursor/hooks/forge-session-start.mjs +30 -0
- package/vendor/templates/project/cursor/hooks/forge-session-start.sh +3 -0
- package/vendor/templates/project/cursor/rules/forge.mdc +21 -0
|
@@ -0,0 +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 forgekit `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
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# Accepted risks digest — Janus example
|
|
2
|
+
|
|
3
|
+
Filled-in digest from the **Janus** monorepo (originating project). Copy patterns into your product's `reference/accepted-risks.md`; do not treat Janus ADRs as applicable outside that repo.
|
|
4
|
+
|
|
5
|
+
Distilled from `docs/adr/` so review subagents don't re-discover — and don't re-escalate — risks Janus has formally accepted. **Do not flag these as findings** unless a listed re-open trigger has fired; cite the ADR instead. If a claim isn't covered here, check `docs/adr/` before confirming a security finding.
|
|
6
|
+
|
|
7
|
+
**Maintenance:** update this file whenever an ADR that accepts, changes, or re-opens a risk is created (part of the archive-to-adr step).
|
|
8
|
+
|
|
9
|
+
## ADR-0048 — inter-service HMAC is LAN-internal (the big one)
|
|
10
|
+
|
|
11
|
+
The HMAC-gated APIs of CDP, Mercury, and Persona are **never published through Traefik**; all callers are first-party apps on a trusted overlay. Accepted, NOT findings:
|
|
12
|
+
|
|
13
|
+
- **HMAC signs body only** — no method/path binding, no timestamp/nonce, replayable. Accepted; hardening is formally out of scope.
|
|
14
|
+
- **Persona any-app→any-subject profile read/write** — load-bearing (CLM territory assignment, Mercury billing reads); writes are already self-disciplined via session-pinned `:sub` proxies.
|
|
15
|
+
- **CDP actor-header trust** — CLM binds actor headers server-side from a signed JWT; CDP resolves the role from its own `users` table. Forging requires the CLM HMAC secret.
|
|
16
|
+
- **Mercury VAT reverse-charge** — gated by Mercury's own `vat_verifications` VIES cache (fail-safe to standard VAT); TopBrands server re-verifies at source. Client cannot self-assert `valid`.
|
|
17
|
+
|
|
18
|
+
**Re-open triggers** (if any is true in the code under review, escalate freely): an HMAC route becomes internet-reachable (Traefik `Host()` router without `PathPrefix`), the overlay becomes untrusted/multi-tenant/unencrypted-sniffable, or a non-first-party app is onboarded.
|
|
19
|
+
|
|
20
|
+
## Other standing decisions reviews keep tripping on
|
|
21
|
+
|
|
22
|
+
- **CDP GDPR forget is PII-only** (ADR-0056) — behavioral events survive erasure by design; only PII fields are scrubbed. Not a leak.
|
|
23
|
+
- **Redaction contract** (ADR-0058) — loggers censor via `@janus/pii` taxonomy with literal `"[redacted]"`; a field passing through the shared logger is not automatically a PII leak.
|
|
24
|
+
- **Stripe card rail: Stripe totals are authoritative** (ADR-0059) — Mercury mirroring Stripe-computed totals on the card rail is intended, not a trust bug.
|
|
25
|
+
- **Control Center deploy actions** (ADR-0068/0073) — TEST-channel-only, flag-off by default, confirm+audit, registry-bound argv arrays. The execFile shelling is the reviewed design, not command injection.
|
|
26
|
+
- **Cross-rep contact visibility in CLM** — intended product behavior (`all_leads`), not IDOR (ADR-0048 §5 note).
|
|
27
|
+
|
|
28
|
+
## Cross-cutting patterns to check (not accepted risks — real find material)
|
|
29
|
+
|
|
30
|
+
- Idempotency middleware must reserve-before-execute and never cache errors.
|
|
31
|
+
- Every service keeps an OpenAPI route-parity test alive (mounted routes vs registry).
|
|
32
|
+
- Nullable-unique Mongo fields need partial `$type` indexes, not sparse (E11000 class).
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
# Thorough code review — examples
|
|
2
|
+
|
|
3
|
+
## 1. Full review (all lenses, branch diff)
|
|
4
|
+
|
|
5
|
+
**User:** "Review my branch before I open a PR."
|
|
6
|
+
|
|
7
|
+
**Agent:**
|
|
8
|
+
|
|
9
|
+
1. Ask scope → user picks "Branch vs main".
|
|
10
|
+
2. Scaffold: `review new mercury-vat --type branch` (captures id, timestamp, base/head SHAs).
|
|
11
|
+
3. Signals pre-flight: `review signals --type branch` → run the listed typecheck/test commands; 1 grounded finding from a failing test.
|
|
12
|
+
4. All lenses active; dedupe pre-flight (smells).
|
|
13
|
+
5. Scout → 8 tentative findings (small scope, single pass).
|
|
14
|
+
6. Coverage pass → confirms `performance` lens clean (no loops/queries added); records ledger.
|
|
15
|
+
7. Eight parallel skeptic subagents; one Critical `false_positive` triggers a second skeptic (agrees).
|
|
16
|
+
8. Fill JSON → `review render` → `review export`.
|
|
17
|
+
|
|
18
|
+
**Excerpt — executive summary (`summary.headline`):**
|
|
19
|
+
|
|
20
|
+
```markdown
|
|
21
|
+
Reviewed 4 files on `feature/vat` vs `main`. 8 tentative → 3 confirmed, 2 downgraded,
|
|
22
|
+
3 false positives. No open critical. Top action: add test for zero-rate edge case.
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## 2. Security-only narrow review
|
|
26
|
+
|
|
27
|
+
**User:** "Run a security review on `services/persona/src/routes/profile.ts` --security"
|
|
28
|
+
|
|
29
|
+
**Agent:**
|
|
30
|
+
|
|
31
|
+
1. Scope: single path (no ask needed — explicit).
|
|
32
|
+
2. Lenses: `security` only — skip dedupe pre-flight.
|
|
33
|
+
3. Scout with security checklist + project accepted-risks digest (if any).
|
|
34
|
+
4. Severity-routed skeptic dispatch (dedicated for critical, batched/inline otherwise; within budget).
|
|
35
|
+
5. Report: `.reviews/20260605T162000Z-persona-profile-security-review.json`
|
|
36
|
+
|
|
37
|
+
## 3. Fix verification after patches
|
|
38
|
+
|
|
39
|
+
**User:** "I fixed the findings — re-verify."
|
|
40
|
+
|
|
41
|
+
**Agent:**
|
|
42
|
+
|
|
43
|
+
1. Load `.reviews/20260605T161200Z-mercury-vat-review.json`.
|
|
44
|
+
2. Three findings were `confirmed` or `downgraded`.
|
|
45
|
+
3. `--verify-fixes` flow: skeptics with `MODE=reverify`, severity-routed and batched like initial mode.
|
|
46
|
+
4. Write `.reviews/20260605T170000Z-mercury-vat-reverify.json`:
|
|
47
|
+
|
|
48
|
+
```json
|
|
49
|
+
{
|
|
50
|
+
"review_id": "20260605T170000Z-mercury-vat-reverify",
|
|
51
|
+
"kind": "reverify",
|
|
52
|
+
"parent_report": "20260605T161200Z-mercury-vat-review",
|
|
53
|
+
"findings": [
|
|
54
|
+
{
|
|
55
|
+
"id": "F-002",
|
|
56
|
+
"verdict": "resolved",
|
|
57
|
+
"verdict_reason": "Guard added at line 88; test added in vat-verify.test.ts"
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
"id": "F-005",
|
|
61
|
+
"verdict": "still_open",
|
|
62
|
+
"verdict_reason": "Error path still swallows exception at line 102"
|
|
63
|
+
}
|
|
64
|
+
]
|
|
65
|
+
}
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## 4. CI usage
|
|
69
|
+
|
|
70
|
+
After a review completes:
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
# Validate latest report
|
|
74
|
+
review export
|
|
75
|
+
|
|
76
|
+
# Pin specific report in CI
|
|
77
|
+
review export --file .reviews/20260605T161200Z-mercury-vat-review.json
|
|
78
|
+
|
|
79
|
+
# Fail pipeline on open critical
|
|
80
|
+
review export --file .reviews/20260605T161200Z-mercury-vat-review.json --fail-on critical
|
|
81
|
+
|
|
82
|
+
# Copy artefacts for upload
|
|
83
|
+
review export --out ./ci-artifacts/review
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
**GitHub Actions sketch:**
|
|
87
|
+
|
|
88
|
+
```yaml
|
|
89
|
+
- name: Validate code review report
|
|
90
|
+
run: review export --file .reviews/pr-review.json --fail-on critical
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
## 5. Skeptic false-positive example
|
|
94
|
+
|
|
95
|
+
**Scout F-003:** "Race condition in idempotency check-then-act."
|
|
96
|
+
|
|
97
|
+
**Skeptic verdict:** `false_positive`
|
|
98
|
+
|
|
99
|
+
**Reason:** "Handler uses unique index `create` collision path; integration test `idempotency.test.ts` asserts single side effect under concurrent requests. Non-atomic window exists but duplicate work is prevented at persistence layer."
|
|
100
|
+
|
|
101
|
+
→ Appears in Appendix A, not main findings.
|
|
102
|
+
|
|
103
|
+
## 6. Dedupe pre-flight example
|
|
104
|
+
|
|
105
|
+
**Scope:** `services/*/src/middleware/idempotency.ts` (smells in "all" review)
|
|
106
|
+
|
|
107
|
+
**Pre-flight dup-001:** Same idempotency middleware copied in cdp, mercury, persona.
|
|
108
|
+
|
|
109
|
+
→ Merged as tentative `dup-001` / smells / Important → skeptic confirms → main report suggests shared package extraction.
|
|
110
|
+
|
|
111
|
+
## 7. Signals pre-flight grounds the scout
|
|
112
|
+
|
|
113
|
+
**User:** "Review `services/persona` --tests --contracts"
|
|
114
|
+
|
|
115
|
+
**Agent:**
|
|
116
|
+
|
|
117
|
+
```bash
|
|
118
|
+
review signals --paths services/persona
|
|
119
|
+
# Workspaces: your-workspace
|
|
120
|
+
# npm run typecheck --workspace=your-workspace
|
|
121
|
+
# npm run test --workspace=your-workspace
|
|
122
|
+
# Notes: Contract/route files touched — verify OpenAPI route-parity (contracts lens).
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
`npm run test --workspace=your-workspace` fails one route-parity case → grounded `F-001` / contracts / Important, `confidence: high`, tool output as evidence. Recorded in JSON `signals.tools`.
|
|
126
|
+
|
|
127
|
+
## 8. Risk-weighted second skeptic
|
|
128
|
+
|
|
129
|
+
**Scout F-002:** "IDOR on `GET /profile/:id`" — `severity: critical`, `phase1_confidence: high`.
|
|
130
|
+
|
|
131
|
+
**Skeptic 1 verdict:** `false_positive` ("CLM binds actor server-side").
|
|
132
|
+
|
|
133
|
+
→ Dangerous quadrant (critical + high-confidence dismissed). A **second independent skeptic** is dispatched blind. It also returns `false_positive`, citing ADR-0048 and the signed-JWT actor binding. `second_opinion.agrees: true` → finding stays in Appendix A, now with two concurring dismissals. Had they disagreed, it would route to `needs_decision`.
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# Accepted risks digest (inject into every scout & skeptic packet)
|
|
2
|
+
|
|
3
|
+
Project-specific list of risks that ADRs (or equivalent) have **formally accepted**. Inject into every scout and skeptic packet so subagents do not re-escalate them.
|
|
4
|
+
|
|
5
|
+
**Do not flag these as findings** unless a listed re-open trigger has fired; cite the decision record instead. If a claim is not covered here, check the project's ADR / decision docs before confirming a security finding.
|
|
6
|
+
|
|
7
|
+
**Maintenance:** update whenever a decision that accepts, changes, or re-opens a risk is recorded.
|
|
8
|
+
|
|
9
|
+
## Template
|
|
10
|
+
|
|
11
|
+
```markdown
|
|
12
|
+
## DEC-NNNN — short title
|
|
13
|
+
|
|
14
|
+
Accepted, NOT findings:
|
|
15
|
+
- …
|
|
16
|
+
|
|
17
|
+
**Re-open triggers:** …
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Cross-cutting patterns to check (not accepted risks)
|
|
21
|
+
|
|
22
|
+
List project invariants that *are* fair game for findings (idempotency, route-parity tests, index rules, etc.).
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
See [examples/accepted-risks-janus.md](../examples/accepted-risks-janus.md) for a filled-in digest from the originating monorepo.
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
# Review lenses
|
|
2
|
+
|
|
3
|
+
Load **only** the sections matching active lenses. Default invocation uses all sections.
|
|
4
|
+
|
|
5
|
+
**Ground first.** Before hand-reading for any lens, ingest the [signals pre-flight](signals-preflight.md) — typecheck, lint, and test output convert directly into grounded findings (especially for smells, contracts, tests, and errors).
|
|
6
|
+
|
|
7
|
+
## security
|
|
8
|
+
|
|
9
|
+
- AuthN/AuthZ: who can call this? Is identity bound to the credential?
|
|
10
|
+
- Injection: SQL, NoSQL, command, path, template, XSS (if user-facing output)
|
|
11
|
+
- Secrets: hardcoded keys, logs, error messages, env leakage
|
|
12
|
+
- Crypto: constant-time compare, algorithm choice, key rotation surface
|
|
13
|
+
- Input validation at trust boundaries
|
|
14
|
+
- SSRF, open redirects, CORS misconfiguration
|
|
15
|
+
- Dependency vulnerabilities in changed manifests (note only; do not auto-audit whole tree unless scope includes lockfiles)
|
|
16
|
+
- Example (HMAC): body-only signatures without method/path binding? Idempotency caches errors? Headers outside signed envelope?
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
## correctness
|
|
20
|
+
|
|
21
|
+
- Logic errors, off-by-one, wrong operator, inverted conditions
|
|
22
|
+
- Null/undefined/empty handling
|
|
23
|
+
- Race conditions, check-then-act, missing transactions
|
|
24
|
+
- Idempotency and retry semantics
|
|
25
|
+
- Money: integer cents, rounding, currency conversion
|
|
26
|
+
- Date/time/timezone handling
|
|
27
|
+
- Error paths that leave inconsistent state
|
|
28
|
+
|
|
29
|
+
## smells
|
|
30
|
+
|
|
31
|
+
**Pre-flight (before this checklist):** the dedupe scan is the smells-lens arm of the [signals pre-flight](signals-preflight.md). Read the project `dedupe` skill and run a **read-only** duplicate scan scoped to the review target. Emit `dup-###` tentative findings; include summary in report appendix. Do not edit code.
|
|
32
|
+
|
|
33
|
+
Then apply:
|
|
34
|
+
|
|
35
|
+
- Copy-paste blocks (rule of three)
|
|
36
|
+
- Near-identical functions differing only by parameter
|
|
37
|
+
- Magic numbers/strings repeated across files
|
|
38
|
+
- Dead code, unused exports, unreachable branches
|
|
39
|
+
- Overly long functions/files **introduced or grown by this change**
|
|
40
|
+
- Parallel switch/if chains that could share structure
|
|
41
|
+
|
|
42
|
+
## architecture
|
|
43
|
+
|
|
44
|
+
- Single responsibility per module
|
|
45
|
+
- Layer violations (domain importing transport, etc.)
|
|
46
|
+
- Coupling across service boundaries
|
|
47
|
+
- Hidden dependencies, global mutable state
|
|
48
|
+
- Does design match existing patterns in the repo?
|
|
49
|
+
- Scope creep beyond stated goal
|
|
50
|
+
|
|
51
|
+
## performance
|
|
52
|
+
|
|
53
|
+
- N+1 queries or sequential remote calls in loops
|
|
54
|
+
- Unbounded memory (loading full collections)
|
|
55
|
+
- Missing indexes for new query patterns
|
|
56
|
+
- Hot-path allocations or sync I/O
|
|
57
|
+
- Missing pagination on list endpoints
|
|
58
|
+
|
|
59
|
+
## tests
|
|
60
|
+
|
|
61
|
+
- Do tests assert behaviour, not implementation details?
|
|
62
|
+
- Mock-heavy tests that don't catch real regressions
|
|
63
|
+
- Missing cases for new branches or error paths
|
|
64
|
+
- Flaky patterns (timing, ordering assumptions)
|
|
65
|
+
- Integration coverage where unit tests insufficient
|
|
66
|
+
- Tests excluded from runner (wrong vitest `include` path)
|
|
67
|
+
|
|
68
|
+
## contracts
|
|
69
|
+
|
|
70
|
+
- OpenAPI/registry drift vs mounted routes
|
|
71
|
+
- Breaking API or shared package export changes
|
|
72
|
+
- Versioning and migration notes
|
|
73
|
+
- Client packages updated when server contract changes
|
|
74
|
+
|
|
75
|
+
## errors
|
|
76
|
+
|
|
77
|
+
- Swallowed errors (empty catch, ignored return)
|
|
78
|
+
- Wrong error type or status code mapping
|
|
79
|
+
- Leaking internal details to clients
|
|
80
|
+
- Missing error logging with correlation context
|
|
81
|
+
|
|
82
|
+
## maintainability
|
|
83
|
+
|
|
84
|
+
- Naming clarity and consistency with codebase
|
|
85
|
+
- Comment quality (why, not what)
|
|
86
|
+
- File organization and import hygiene
|
|
87
|
+
- Type safety gaps (if typed language)
|
|
88
|
+
- Documentation for non-obvious public behaviour
|
|
89
|
+
|
|
90
|
+
## Project hooks (all lenses)
|
|
91
|
+
|
|
92
|
+
When reviewing a project with agent docs / ADRs:
|
|
93
|
+
|
|
94
|
+
1. Read project agent instructions (`AGENTS.md` or equivalent) for coding guidelines
|
|
95
|
+
2. Check ADRs / [accepted-risks.md](accepted-risks.md) before confirming security findings
|
|
96
|
+
3. Note cross-package impact if shared libraries change
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# Phase 1 — Scout pass
|
|
2
|
+
|
|
3
|
+
You are the **scout** for a thorough code review. Discovery only — no fix suggestions yet.
|
|
4
|
+
|
|
5
|
+
## Input packet
|
|
6
|
+
|
|
7
|
+
- **Scope:** {SCOPE_TYPE} — {SCOPE_DESCRIPTION}
|
|
8
|
+
- **Lenses:** {LENS_LIST}
|
|
9
|
+
- **Git range / paths:** {SCOPE_DETAIL}
|
|
10
|
+
- **Accepted risks:** {ACCEPTED_RISKS_DIGEST} <!-- contents of reference/accepted-risks.md — do not raise findings it covers unless a re-open trigger fired -->
|
|
11
|
+
|
|
12
|
+
## Steps
|
|
13
|
+
|
|
14
|
+
1. Ingest the **signals pre-flight** results ([signals-preflight.md](signals-preflight.md)) — tool-confirmed failures are grounded findings; start from them.
|
|
15
|
+
2. Read the files in scope (`git diff`, paths, or commits as applicable). **Partition large scopes** — see below.
|
|
16
|
+
3. If **smells** lens is active: run dedupe pre-flight (read `dedupe` skill; report-only scan on scope).
|
|
17
|
+
4. For each active lens, read the checklist from [lenses.md](lenses.md) and inspect code.
|
|
18
|
+
5. Emit **tentative findings** — de-duplicate overlapping claims before handing off.
|
|
19
|
+
6. Do **not** assign final verdicts; Phase 2 skeptics do that. The coverage pass ([phase1c-coverage.md](phase1c-coverage.md)) runs after you to catch misses.
|
|
20
|
+
|
|
21
|
+
## Scaling — partition large scopes
|
|
22
|
+
|
|
23
|
+
A single scout reading every file degrades once the scope is large (context pressure → shallow reads → missed findings).
|
|
24
|
+
|
|
25
|
+
- **Small scope** (≲10 files / ≲800 changed lines): one scout pass.
|
|
26
|
+
- **Large scope:** split into reviewable **units** — by module/directory, or by lens — and run one scout subagent per unit **in parallel**, capped at **4 scouts** (grow the unit size, not the scout count). Each unit owns a slice; none needs the whole tree in context. Each scout writes its findings to `.reviews/<id>-tentative/<scout-name>.json` (`{ "findings": [...] }`).
|
|
27
|
+
- **Merge:** `review merge --dir .reviews/<id>-tentative` — dedupes overlapping claims (same file, line ±5, same lens; keeps the stronger finding, records merged ids in `related`) and renumbers `F-###` deterministically into `merged.json`.
|
|
28
|
+
|
|
29
|
+
## Tentative finding format
|
|
30
|
+
|
|
31
|
+
Each finding MUST include all fields:
|
|
32
|
+
|
|
33
|
+
```
|
|
34
|
+
id: F-001 # or dup-001 from pre-flight
|
|
35
|
+
lens: security
|
|
36
|
+
location: services/foo/src/bar.ts:42
|
|
37
|
+
claim: One-sentence description of the suspected issue
|
|
38
|
+
evidence: |
|
|
39
|
+
```42:48:services/foo/src/bar.ts
|
|
40
|
+
// cited lines
|
|
41
|
+
```
|
|
42
|
+
context: | # ±30 lines around the citation — lets the skeptic verdict without re-discovering the file
|
|
43
|
+
...
|
|
44
|
+
related: [] # callers, test files, ADR paths — you already found these; hand them over
|
|
45
|
+
tentative_severity: critical | important | minor
|
|
46
|
+
confidence: low | medium | high
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
The `context` and `related` fields are what keep Phase 2 cheap: you already read this code — package it so the skeptic doesn't have to rediscover it.
|
|
50
|
+
|
|
51
|
+
## Rules
|
|
52
|
+
|
|
53
|
+
- Every finding needs `file:line` (or line range) and a code citation.
|
|
54
|
+
- Prefer fewer, higher-quality findings over laundry lists.
|
|
55
|
+
- "Might be wrong" is fine — skeptics verify. Mark `confidence: low` when unsure.
|
|
56
|
+
- Check ADRs for accepted-risk patterns before claiming security issues.
|
|
57
|
+
- Record scope and lens list for the synthesis report header.
|
|
58
|
+
|
|
59
|
+
## Handoff
|
|
60
|
+
|
|
61
|
+
1. Run the **coverage pass** ([phase1c-coverage.md](phase1c-coverage.md)) on the merged tentative list — it may add follow-up findings and records the `coverage` ledger.
|
|
62
|
+
2. Pass the full tentative list (scout + coverage) to Phase 2. Skeptic dispatch is severity-routed and budgeted (see SKILL.md) using [phase2-skeptic.md](phase2-skeptic.md) — not one subagent per finding.
|