Files
marvin 18fdff7d8c Import 13 skills from the old opencode setup into turnstone
skills/ carries the SKILL.md files; scripts/import_skills.py runs
inside the VM via turnstone's own storage layer (SKILL.md parser +
risk scanner) so rows match what the console admin API would write.
Server must be restarted after import (stale WAL snapshot).
2026-09-28 20:24:47 +02:00

193 lines
6.0 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
name: code-review
description: >
Multi-stage code review pipeline — 4 parallel finders (bug, security,
performance, quality) → verify → dedupe → synthesize → final markdown
report. Load into a workstream to review a diff; the model orchestrates
the pipeline by spawning sub-skills as task calls.
---
# Code Review — multi-stage pipeline
You are the **orchestrator** of a multi-stage code review pipeline. Your job
is to coordinate the stages below and produce a final markdown report.
## Pipeline
find-bug ─┐
find-security ─┤
├──► verify ──► dedupe ──► synthesize ──► final markdown
find-performance ─┤ (claim (merge + (fix-verify
find-quality ─┘ check) filter) + render)
(parallel)
## Step 1 — Determine scope
Figure out what to review. Options:
- **Uncommitted changes** — run `git diff` in the repo root
- **Branch range** — `git diff origin/master..HEAD`
- **Specific files** — read them directly
If the user didn't specify, default to uncommitted changes + last commit.
Ask for clarification only if it's truly ambiguous.
Compute the diff once and write it to a temp file (e.g. `git diff origin/main..HEAD > /tmp/review.diff`)
so all finders operate on the same bytes.
## Step 2 — Spawn the four finders in parallel
**In a single message, make four concurrent subagents using `task` calls** -
one per finder, each prompted with its finder skill. Parallel invocation is
the key to wall-clock speed; serial spawning defeats the design.
Prompt: minimal; the path to the diff file (e.g. `/tmp/review.diff`),
the skill to use (e.g. `code-review-find-bug`), plus a one-paragraph
context block about what the change is trying to accomplish. The skill
body itself carries the search protocol, severity calibration, lane rules,
and JSON output schema — don't re-state them in the prompt.
Example prompt:
Load the `code-review-find-bug` skill and review `/tmp/review.diff`.
The change adds feature XYZ, and does blah blah blah.
| Finder | Skill |
|--------|------------------|
| Bug | `code-review-find-bug` |
| Security | `code-review-find-security` |
| Performance | `code-review-find-performance` |
| Quality | `code-review-find-quality` |
Do NOT tell a finder what the other finders are doing. Each works in
isolation; the dedupe stage handles overlap.
Do NOT load the skills yourself.
## Step 3 — Merge finder output
Each finder returns a JSON object:
{
"finder": "bug|security|performance|quality",
"findings": [
{"id": "...", "severity": "...", "location": "...",
"claim": "...", "evidence": "...", "fix": "..."}
]
}
Build the combined list: concatenate all four `findings` arrays, stamping each
entry with its finder name. Ids are already namespaced (`bug-N`, `sec-N`,
`perf-N`, `q-N`) — no renumbering.
If a finder returned an empty string, malformed JSON or errored, this is a BUG.
Run it again, but if it fails a second time, abort the entire review process.
If the combined list is empty (all finders returned `{"findings": []}`),
skip steps 4–6 and emit a short “Approve — no issues found” report directly.
## Step 4 — Spawn verify (serial)
One `task` call with skill `code-review-verify`. Pass the skill and the merged
findings list as JSON in the prompt. The skill body carries the verifier’s
identity and instructions. Example prompt:
Load the `code-review-verify` skill.
---
{
"findings": [
/* findings goes here */
]
}
The verifier returns:
{
"verified": [
{"id": "...", "verdict": "confirmed|refuted|uncertain",
"reason": "...", "severity_override": "..."}
]
}
## Step 5 — Spawn dedupe (serial)
One `task` call with skill `code-review-dedupe`. Pass BOTH the
original merged findings AND the verifier’s verdicts in the prompt as a
single JSON object with `findings` and `verdicts` keys. Example:
Load the `code-review-dedupe` skill.
---
/* json goes here */
Dedupe drops refuted findings, merges overlap, applies severity overrides,
and emits:
{
"deduped": [
{
"ids": ["bug-1", "sec-1"],
"dimensions": ["bug", "security"],
"severity": "critical",
"location": "...",
"claim": "...",
"evidence": "...",
"fix": "...",
"verdict": "confirmed|uncertain",
"uncertain_reason": null
}
],
"stats": {
"input_findings": 12,
"refuted": 4,
"after_clustering": 6,
"by_severity": {"critical": 1, "major": 2, "minor": 2, "nit": 1},
"uncertain": 1,
"finder_failures": []
}
}
## Step 6 — Spawn synthesize (serial)
One `task` call with skill `code-review-sanity`. Pass dedupe’s JSON
output verbatim in the prompt.
Synthesize re-reads source for each finding’s `fix`, marks each as
`unchanged` / `refined` / `unverifiable`, then renders the final user-facing
markdown.
## Step 7 — Return the report
Emit synthesize’s markdown verbatim to the user. Do NOT wrap it in commentary
— the report is self-contained.
If synthesize itself errored or returned nothing, fall back to a minimal
report built from dedupe’s JSON, prepended with:
> ⚠ Pipeline note: synthesize did not complete normally; the report below
> skips fix-verification.
## Parallelism and cost
* Wall clock ≈ max(finders) + verify + dedupe + synthesize. Finders run in
parallel; the rest is serial.
* Token cost ≈ 6–8× a single-pass review. Deliberate — verify removes
hallucinated claims, synthesize tightens fixes before they reach the user.
* If the diff is tiny (≤50 lines, single file, no security/perf surface) the
full pipeline is overkill; in that case spawn only `find-bug` +
`find-quality` and still run verify + dedupe + synthesize. Default to the
full pipeline when in doubt.
## Short pipeline variant
When the diff is small (≤50 lines, single file, no security/perf surface):
* Spawn only `find-bug` + `find-quality` in parallel
* Still run verify + dedupe + synthesize
* Half the token cost, same rigor on the dimensions that matter for small
changes