一键导入
usual-suspects
Fan out all relevant review agents in parallel against a plan or implementation, then consolidate into a single triageable report
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Fan out all relevant review agents in parallel against a plan or implementation, then consolidate into a single triageable report
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Start work in an ISOLATED git worktree (the exception path — use only when two envs must be live at once, the work is multi-day and main must stay shippable meanwhile, or it's a throwaway spike). Creates the branch + worktree + venv + frontend build + smoke test + BRANCHES.md entry. For ordinary work, use /new-feature (trunk) instead. Any Kind — captured in Step 3.5. The `--from-cloud` flag instead ADOPTS an existing `origin/claude/*` cloud branch (built on phone/cloud, never compiled): fetch → build the Mac env → run the tests the cloud couldn't → preview the merge against main.
End-of-session ritual — verify, document for humans and robots, commit, close out
Ship a release — bump version, finalise changelog/readme, tag, push, and verify PyPI. The ONLY workflow command that touches public distribution (PyPI, Homebrew, the public changelog, the tag). Evening window on weekdays. Supports --dry-run.
Finish a piece of trunk work on main — runs tests + lint, surfaces human-QA checks, trues docs, adds a changelog line, marks the 100days item done, and commits. No merge (you're already on main). If you're on a branch, it offers to close the branch properly instead.
Archive a merged feature branch — stale marker, detach worktree, update BRANCHES.md (preserves local directory)
Start a piece of work on main (trunk — the DEFAULT path). Loads the plan / 100days item, checks recent history, agrees a plan, and records the task. No branch, no worktree, no env setup. For work that needs an isolated live environment, use /new-branch instead.
| name | usual-suspects |
| description | Fan out all relevant review agents in parallel against a plan or implementation, then consolidate into a single triageable report |
| user-invocable | true |
| allowed-tools | Bash, Read, Glob, Grep, Agent, TodoWrite |
Run all relevant review agents in parallel against the current work (plan or implementation), then consolidate their findings into a single triageable list.
The user decides what to act on, park for later, or ignore. Your job is to present clear findings, not to gatekeep.
Determine whether this is a plan review or an implementation review:
Plan review — if any of these are true:
docs/design-*.md file was recently created/modifiedImplementation review — if any of these are true:
Determine scope:
git diff --stat (staged + unstaged) or a git rangeIf ambiguous, ask: "Plan or implementation? And what's the scope?"
Determine the design doc and slice (the two dimensions of continuity):
The doc identifies the review log file. The slice is a tag inside it.
Doc slug — autodetected, in order:
--doc <slug>, use that.docs/design-*.md referenced in the conversation or recently
modified — derive the slug by stripping design- and .md
(e.g. docs/design-cost-forecast-phase1.md → cost-forecast-phase1).Slice tag — autodetected, in order:
--slice <name>, use that (e.g. --slice "Slice 2").What slice + pass type? (e.g. "Slice 2 impl-review").The review log lives at docs/private/reviews/<doc-slug>.md (gitignored
— strategic context stays local). Auto-create the directory if it does not
exist. One log per design doc; every pass across every slice appends to
the same file.
No design doc and no --doc slug? Do not silently skip the log — that's
a quiet-failure mode where findings accumulate nowhere. Prompt the user once:
No design doc detected. Pick one:
- Pass
--doc <slug>— log goes todocs/private/reviews/<slug>.md. Use this for sliced work without a design doc (e.g.react-migration-step-11).- One-off review — no log. Confirm and I'll proceed.
Default to (2) on no response after one prompt. Record the choice in the final report header so future passes know whether a missing log is by-design or an oversight.
Handoff docs (e.g. docs/private/<slice>-handoff.md) describe intent for
the next slice — what the next session should read first, what's in scope,
working agreements. The review log captures findings raised by review
agents and their disposition. Boundary rule:
When a handoff doc would otherwise repeat a "Decisions taken — don't
relitigate" block, replace it with a one-line link to the review log
(e.g. See parked findings 3–7 in docs/private/reviews/<slug>.md). One
canonical home per piece of information.
Check which areas are touched (file extensions, directory prefixes, content):
| Condition | Agent |
|---|---|
| Always | code-review |
.ts/.tsx/.css files, or UI/frontend mentioned | ux-critique |
bristlenose/locales/, t() calls, i18n mentioned | i18n-review |
| Security-sensitive (auth, tokens, PII, file access, bridge) | security-review |
| HTML/React components with interactive elements | a11y-review |
desktop/, .swift files, macOS/HIG mentioned | what-would-gruber-say |
.ts/.tsx/.css, package.json, server, pipeline, perf-sensitive, or .swift (concurrency/cancellation) | perf-review |
Test files touched, new public API without tests, or any .swift change | what-would-james-bach-say (see three-way selector below) |
| try/except or catch blocks, fallback logic, subprocess/shellouts, JSON serialization, or E2E/Playwright specs touched | silent-failure-hunter |
.github/workflows/** or other CI/release config touched | security-review + silent-failure-hunter (CI workflow lens — see below) |
code-review always runs. The others run only if their area is touched.
The Bach reviewer (what-would-james-bach-say) is testing-taste-specific.
Run a finer decision than the binary table above:
Auto-call Bach when ANY of:
*test*, *Tests.swift, tests/, e2e/, or frontend/src/**/*.test.{ts,tsx}bristlenose/,
frontend/src/, or desktop/Bristlenose/Bristlenose/ without
corresponding test changes.swift change (Swift is the under-served layer per
docs/design-test-philosophy.md — Bach has the most to say there)Skip Bach silently when ALL of:
docs/**/*.md, README.md, CHANGELOG.md)Prompt the user when:
Prompt format: one-liner — "Bach selector is grey: . Call Bach? (y/n)" — keep it tight, don't break flow.
CI config rarely changes but is high-blast-radius, and the project's CI has a
documented fragility history (docs/design-ci.md § Fragility classes). When a
diff touches .github/workflows/** (or release/CI config), this lens ensures
the two reviewers who own those failure modes both fire, and points them at the
charter's invariants:
security-review — the supply-chain + least-privilege invariants: every
third-party action SHA-pinned, every workflow carries a permissions: block
scoped to the minimum, no secret widened in reach. Ref: docs/design-ci.md
§ Least privilege and supply-chain pinning.silent-failure-hunter — the false-green invariants: no new
continue-on-error swallowing a real failure, non-success conclusions
still treated as non-green, no bounded step that fails open. Ref:
docs/design-ci.md § Standing audit targets.what-would-james-bach-say — add only if the change alters what gets
tested (matrix cells, test invocation, markers), not just infra plumbing.This is a routing lens over existing reviewers, not a new agent. There is
deliberately no standalone CI-audit mode: the Rule of Three isn't met (one
steward use-case, not three), so the lens runs only as part of a normal
/usual-suspects pass on a diff that touches CI.
Sunset. Remove this lens row when either holds: (a) the invariants are enforced mechanically in CI (an actionlint / pinned-SHA / permissions-check job — at which point human review is redundant), or (b) a post-TestFlight retro confirms two consecutive quarters with no new fragility-class incident and no unreviewed workflow regression. Re-evaluate at the first post-TF retro; don't let this lens ossify unexamined.
Announce which agents you're launching and why:
Calling the usual suspects:
- code-review (always)
- ux-critique (frontend components changed)
- i18n-review (locale files touched)
- what-would-james-bach-say (Swift change + no test updates)
Skipping: security-review, a11y-review, what-would-gruber-say (not in scope)
If docs/private/reviews/<doc-slug>.md exists, read it whole before launching
agents. This is the memory of every finding raised across every prior pass —
both earlier slices and earlier passes within the current slice.
Pass the file's contents to every agent you launch (Step 3) inside a
## Prior findings (do not relitigate) block, along with the current slice +
pass tag (e.g. "Current pass: Slice 2 impl-review"). Instruct each agent to
tag every finding it returns with exactly one of these four bracket tags
(quote them verbatim — do not paraphrase):
[NEW]— not in the prior log.[SAME-SLICE]— already flagged in this slice's earlier pass; cite prior Finding N. Do not re-raise unless evidence changed.[PARK→OPEN]— finding parked in a prior slice, now relevant because the parking condition changed; cite Finding N and explain what changed.[REGRESSION]— finding markedresolvedin a prior slice has reappeared; cite Finding N, the resolution commit, and the regressing change.Do not re-raise
parkedfindings unless the parking condition actually changed. Do not re-raiseresolvedfindings unless you can show the resolution was reverted or undermined. Do not re-raise findings whose status isignored— those were explicitly dismissed.
If the file does not exist, proceed without prior context — note this in the
final output (First pass for this doc — no prior log.).
Spawn all selected agents simultaneously in a single message with multiple Agent tool calls. Each agent gets the same scope description:
For plan review, tell each agent:
Review this plan: <path to plan file or design doc>
Mode: plan review
Scope: <list of files/areas the plan affects>
For implementation review, tell each agent:
Review these changes: <git range or "staged + unstaged changes">
Mode: implementation review
Scope: <list of changed files from git diff --stat>
When .swift files or desktop/ are in scope, the SwiftUI-aware agents
(what-would-gruber-say, code-review, what-would-james-bach-say) get an
extra line telling them to consult the vendored swiftui-pro skill:
For generic SwiftUI craft (deprecated API, view composition, data flow,
navigation, performance, hygiene), read the relevant reference files under
.claude/skills/swiftui-pro/references/*.md before flagging. It is iOS-first:
project hard rules (MEMORY.md / CLAUDE.md) and macOS idiom win on any conflict.
swiftui-pro is a knowledge source, not a reviewer persona — it does not
fan out as its own agent and does not appear in the agent-selection table. It
informs the agents that already run. (Review subagents can't invoke skills, so
they Read the reference files directly — that's why this is a per-agent
instruction, not a Skill call.) It also auto-triggers in the main conversation
when authoring SwiftUI. See .claude/skills/swiftui-pro/VENDORED.md.
Adjudication. swiftui-pro is evidence, not a vote. If a finding cites a swiftui-pro reference and an agent's hunch disagrees on a pure SwiftUI fact (deprecated API, property-wrapper choice), trust swiftui-pro. If swiftui-pro's iOS-flavoured advice collides with a Mac-platform concern or a documented project decision, the project/Mac side wins. William does not adjudicate SwiftUI correctness — his Step 4.6 pass is scope/proportion only. A swiftui-pro-backed finding that is real but over-engineered still gets William's "real problem, smaller fix" treatment like any other.
Once all agents return, produce a single consolidated report. This is the hard part — don't just concatenate. Do this:
Deduplicate — if two agents flag the same issue (e.g. code-review and ux-critique both notice a missing keyboard handler), merge into one finding and note which agents flagged it.
Resolve contradictions — if agents disagree (e.g. security-review wants stricter validation, code-review questions whether it's needed), present both views honestly with the tradeoff. Don't pick a winner.
Categorise — group findings into:
Tag each finding by kind in addition to severity. Kinds:
[technical] — best-practice / correctness / perf / security. Some the
user adjudicates; others want zoom-out (see rule below).[product] — UX, naming, behaviour. User's call; agents propose, user
disposes.[niggle] — small, low-risk, mechanical. Often fixed inline on the same
turn.[needs-zoom-out] — answer is outside the codebase (Apple HIG, Mac indie
norms, accessibility standards, academic methodology, etc.). Flag
explicitly so the user can ask for prior-art research before triage,
not after.Number everything — each finding gets a number for easy reference when the user triages ("act on 1, 3, 7; park 4, 5; ignore 2, 6").
Apply the merge rule for findings already in the log:
parked findings are advisory: re-surface as [PARK→OPEN] when code
reality shows higher severity than the park decision had access to, OR
when you suspect bandwidth-pressure triage. Frame as "you said X, here's
what changed / what I now see — worth reconsidering?"ignored is sacred — never re-raise.After consolidation but before showing the report to the user, append every
[NEW] finding from this pass to docs/private/reviews/<doc-slug>.md.
Continue numbering from the highest existing Finding N (never renumber).
New findings start at status open. For findings tagged [SAME-SLICE],
[REGRESSION], or [PARK→OPEN], do not duplicate the entry — instead append
a status-update bullet under the existing Finding N capturing what this pass
observed. Do not write triage outcomes (resolved, parked, ignored)
yourself — those are the user's call, applied in Step 5.
If the file does not yet exist, create it with the header from the schema below.
Before showing the report to the user, run the consolidated finding list
through the what-would-william-of-ockham-say agent in adjudicator mode
(Mode A). Spawn it via Agent with subagent_type: "what-would-william-of-ockham-say" and pass the consolidated report as
input.
William's job at this stage is to:
real / edge / speculative —
shrinking the user's triage list from "everything every agent
raised" to "the things actually worth deciding on."William returns an annotated version of the consolidated list (per-finding annotation + a short summary). Show the annotated version to the user in Step 5, not the raw consolidated list — one report, not two.
Skip William when: only one agent ran (nothing to adjudicate), the
consolidated list has fewer than 3 findings (no signal worth filtering),
or the user explicitly invoked --no-william. Note the skip in the
report header so future passes know whether William's absence was
deliberate.
William is a signal, not a gate. The user still decides what to act on, park, or ignore — William's annotations are pre-triage advice, not verdicts.
After showing the report, the user triages by finding number ("act on 1, 3, 7; park 4, 5; ignore 2, 6; supersede 8 by 11"). Apply the dispositions to the log immediately, in the same turn:
resolved, append bullet
<YYYY-MM-DD> **resolved** by <commit-sha> — <one-line note>parked, append bullet
<YYYY-MM-DD> **parked** — <reason>ignored, append bullet
<YYYY-MM-DD> **ignored** — <reason or "no reason given">. Distinct from
parked: ignored findings are exempt from [PARK→OPEN] resurrection.superseded, append bullet
<YYYY-MM-DD> **superseded** by Finding M — <why>If the user states dispositions clearly, apply them in the same turn; otherwise prompt them once.
# Review log — <doc-slug>
One log per design doc. All slices, all passes, append here.
Findings numbered sequentially across the whole doc; never renumber.
Status flags: `open`, `parked`, `ignored`, `resolved`, `superseded`.
(`ignored` is distinct from `parked` — exempt from `[PARK→OPEN]`.)
---
## Finding <N> — <one-line summary>
- **Pass:** <YYYY-MM-DD> <Slice tag> <plan-review|impl-review>
- **Agents:** code-review, security-review
- **Severity:** HIGH|MEDIUM|LOW|question
- **Where:** `path/to/file.py:123` (or "design doc §X")
- **Status:** open
- **Detail:** <2–4 sentences. The finding itself, plus enough context that
a future pass understands what was claimed and why.>
<!-- Status updates appended below as they happen — one bullet per event,
chronological, including observations from later passes. -->
- <YYYY-MM-DD> **resolved** by `<commit-sha>` — <one-line resolution note>
- <YYYY-MM-DD> **parked** — <reason>
- <YYYY-MM-DD> **carried to Slice N** — <why it must be enforced later>
- <YYYY-MM-DD> **observed in <Slice tag> impl-review** — <still open / verified>
- <YYYY-MM-DD> **superseded** by Finding <M> — <why>
The schema is intentionally markdown (not YAML/JSON) — humans skim this file during slice transitions. Keep entries terse.
# Review — [plan title or "recent changes"]
**Pass:** Slice 2 plan-review (or "Slice 2 impl-review", etc.)
**Doc:** <doc-slug> — `docs/private/reviews/<doc-slug>.md` (or "none — no continuity log")
**Scope:** <summary>
**Agents called:** code-review, ux-critique, i18n-review (3 of 8)
**Prior log:** N findings carried in (X open, Y parked, Z resolved) — or "first pass for this doc"
## Bugs / Errors
1. [HIGH][technical][NEW] `file:line` — description (flagged by: code-review)
<!-- Each finding gets THREE tag groups:
Severity: [HIGH] | [MEDIUM] | [LOW] | [question]
Kind: [technical] | [product] | [niggle] | [needs-zoom-out]
Continuity: [NEW] | [SAME-SLICE] (Finding 7) | [PARK→OPEN] (Finding 4
— what changed) | [REGRESSION] (Finding 12 — resolved by
abc123, broken by def456) -->
2. [MEDIUM] `file:line` — description (flagged by: code-review, a11y-review)
## Convention Violations
3. `file:line` — description. Ref: CLAUDE.md rule (flagged by: code-review)
4. `locale/key` — description (flagged by: i18n-review)
## Performance
5. [MEDIUM — bundle] `package.json` — description (flagged by: perf-review)
## Design Questions
6. Description of tradeoff. Two views: (a) ... (b) ...
(raised by: code-review, ux-critique)
7. Description of tradeoff. (raised by: security-review)
## Improvements
8. `file:line` — suggestion (flagged by: ux-critique)
---
Your call — which to act on, park, or ignore?
[SAME-SLICE] with a one-line "see Finding 7" reference beats a
re-explained finding — the prior log already has the detail.[needs-zoom-out]. When a finding's answer is outside
the codebase (HIG, accessibility, Mac indie norms, academic methodology),
say so and offer to fetch prior art before triage. Don't introspect
deeper into the repo when the answer isn't there.The first few times this skill runs in a new session or worktree where it has prior log data to compare against, narrate the merge process in the final report:
Read prior log: 7 findings (1 open, 5 parked, 1 resolved).
Carried forward to this pass:
- Finding 1 (open) → Slice 2 impl-review must verify; mapped to current
Finding 1 [SAME-SLICE]
- Findings 3, 4, 5, 6 (parked) → no condition change observed; skipped
- Finding 7 (parked → Slice 3 deferred) → not yet relevant; skipped
Genuinely new this pass: Findings 8, 9, 10
This is so the user can feel how the comparison and merge are working. Drop the narration once the user says they understand the rhythm — typically after 2–3 invocations on a doc with non-trivial prior log content.