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).
This commit is contained in:
1 parent
93fa05bdcc
commit
18fdff7d8c
15 files changed
+1973
No files matched your search
@@ -0,0 +1,192 @@
|
||||
---
|
||||
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
|
||||
Reference in new issue
Block a user