一键导入
review-verification-protocol
Mandatory verification steps for all code reviews to reduce false positives. Load this skill before reporting ANY code review findings.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Mandatory verification steps for all code reviews to reduce false positives. Load this skill before reporting ANY code review findings.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Use when you need a bite-sized, TDD-driven implementation plan but do NOT have a brainstorm-beagle spec to plan against. quick-plan reconstructs intent from the current conversation, fans out domain-expert exploration subagents across the codebase, and synthesizes the same plan format write-plan produces — without requiring `.beagle/concepts/<slug>/spec.md`. Triggers on: "quick plan", "plan this out", "plan what we just discussed", "turn this into an implementation plan", "plan this without a spec", "I don't have a spec, just plan it", "write-plan but no spec". Make sure to use this skill whenever the user wants an implementation or TDD plan and there is no spec to plan against — even if they just say "plan it" after discussing a feature. Writes to `.beagle/plans/<slug>/plan.md`. If a finalized spec already exists at `.beagle/concepts/<slug>/spec.md`, prefer write-plan. Does NOT brainstorm specs, write code, or execute the plan — produces the plan document (and an optional handoff prompt) only.
Use when the user has a fuzzy idea and wants to shape it into a concrete project spec before planning or building. Triggers on: "brainstorm this", "I have an idea for...", "help me think through this project", "what should I build", "spec this out". Also catches vague feature descriptions needing structured questioning to clarify scope. Does NOT write code, plan implementation, review strategy docs, or run strategy interviews — produces a WHAT/WHY spec through dialogue, not a HOW plan.
Use as the follow-up to brainstorm-beagle when a spec has an Open Questions section (or quietly carries latent gaps) that need closing before planning or implementation can begin. Triggers on: "resolve the open questions", "close the gaps in this spec", "research the open items", "finalize my spec", "make this spec implementation-ready", "answer the TBDs". Also triggers whenever the user points at a brainstorm-beagle spec and asks for research, proposals, or answers to unresolved items. Orchestrates parallel research subagents when available (falls back to inline sequential research otherwise), proposes answers one at a time for user approval, then rewrites the spec in place so it arrives at planning with no known gaps. Does NOT write code, design implementation, or create plans — it only produces a complete spec.
Use when you have a finalized brainstorm-beagle spec at `.beagle/concepts/<slug>/spec.md` and need a bite-sized, TDD-driven implementation plan before any code is written. Triggers on: "write a plan", "plan this spec", "turn the spec into a plan", "now plan the implementation", "write-plan". Reads the spec, designs the file structure, decomposes work into 2-5 minute TDD steps with exact paths and commands, self-reviews against the spec, gets user approval, then writes to `.beagle/concepts/<slug>/plan.md` and offers to generate an execution handoff prompt via the subagent-prompt skill. Does NOT brainstorm specs, write code, or execute the plan — produces the plan document (and an optional handoff prompt) only.
Core technical documentation writing principles for voice, tone, structure, and LLM-friendly patterns. Use when writing or reviewing any documentation.
Generate first-draft technical documentation from code analysis
| name | review-verification-protocol |
| description | Mandatory verification steps for all code reviews to reduce false positives. Load this skill before reporting ANY code review findings. |
| user-invocable | false |
This protocol MUST be followed before reporting any code review finding. Skipping these steps leads to false positives that waste developer time and erode trust in reviews.
Before issuing any verdict — flag, reject, or downgrade a finding — you MUST echo the exact artifact you are judging, quoted from a source you read in this turn:
The artifact is the only source of truth. Never infer what you are reviewing from the branch name, the working directory, surrounding files, or recollection. If your mental model differs from the freshly read source, the source wins. A verdict issued without a same-turn echo of its target is invalid — emit the echo first, or do not emit the verdict.
This gate exists because an LLM under contextual priming will confidently flag code that is not in the file. It runs before the hard gates below.
Complete these in order before you add a finding. Skip a gate only when it clearly does not apply (e.g. skip the usages gate if the finding is not about dead code or “unused”).
impl, or macro_rules! block you read in full (not only a diff hunk or partial snippet).rg, IDE references, or equivalent) and either state zero matches for the symbol you call unused, or list each match and why it still supports the finding.#[cfg], or error propagation that could make the pattern intentional; note one concrete checked location (path + rough location) or state “none relevant after search.”Cargo.toml for the crate under review and either quote the [package] edition = "..." line or state the default edition applies and name the manifest path you checked.Before flagging ANY issue, verify:
Before flagging, you MUST:
pub and used by other crates in the workspace#[cfg])Common false positives:
#[cfg(test)] items only used in test buildsFrom/Into conversionsBefore flagging, you MUST:
?)unwrap() isn't in test code or after a safety-ensuring checkCommon false positives:
unwrap() in tests and examples (expected pattern)expect("reason") after validation (e.g., regex::Regex::new on a literal)? (the caller handles it)let _ = tx.send(...) — intentional when receiver may have droppedBefore flagging, you MUST:
Cargo.toml-> impl Trait captures ALL in-scope lifetimes by default+ use<'a> syntax, this is precise capture control, not a mistakeCommon false positives:
impl Trait — edition 2024 captures them implicitly+ use<'a, T> syntax — this is the new precise capturing syntax, not an errorBefore flagging, you MUST:
unsafe fnunsafe_op_in_unsafe_fn is deny-by-default — unsafe operations inside unsafe fn REQUIRE explicit unsafe {} blocksCommon false positives:
unsafe {} blocks inside unsafe fn — REQUIRED in edition 2024, not redundantunsafe extern "C" {} — REQUIRED in edition 2024, not optional#[unsafe(no_mangle)] / #[unsafe(export_name)] — REQUIRED in edition 2024Before flagging, you MUST:
Copy (clone on Copy types is a no-op)Common false positives:
Arc::clone(&arc) — this is the recommended explicit clone for Arctokio::spawn — required for 'static boundBefore flagging, you MUST:
Mutex, RwLock, or atomic operations protect the accessArc<Mutex<T>>)Common false positives:
Arc<Mutex<T>> — already thread-safestd::sync::atomic operations — designed for concurrent accessBefore flagging, you MUST:
Do NOT flag:
.collect() on small iteratorsONLY use for:
unsafe code with unsound invariantsUse for:
Use for:
String parameters where &str would work#[must_use] on functions with important return valuesUse for:
#[non_exhaustive]These are NOT review blockers.
if let vs match for single variant)| Pattern | Why It's Valid |
|---|---|
unwrap() in tests | Standard test behavior — panics on unexpected errors |
.clone() in test setup | Clarity over performance |
use super::* in test modules | Standard pattern for accessing parent items |
Box<dyn Error> in binaries | Not every app needs custom error types |
String fields in structs | Owned data is correct for struct fields |
Arc::clone(&x) | Explicit Arc cloning is idiomatic and recommended |
#[allow(clippy::...)] with reason | Intentional suppression is valid |
#[expect(lint)] instead of #[allow] | Self-cleaning suppression (stable since 1.81) — warns when lint no longer triggers |
unsafe {} inside unsafe fn | Required in edition 2024 (unsafe_op_in_unsafe_fn = deny) |
unsafe extern "C" {} | Required in edition 2024 for extern blocks |
#[unsafe(no_mangle)] | Required in edition 2024 for safety-relevant attributes |
#[unsafe(export_name = "...")] | Required in edition 2024 for safety-relevant attributes |
+ use<'a, T> on impl Trait returns | Precise capture syntax for edition 2024 RPIT |
r#gen as identifier | gen is reserved in edition 2024 |
LazyLock / LazyCell | Standard library replacements for once_cell/lazy_static (stable since 1.80) |
async fn in trait definitions | No longer needs async-trait crate (stable since 1.75) |
#[diagnostic::on_unimplemented] | Custom trait error messages (stable since 1.78) |
| Pattern | Why It's Valid |
|---|---|
std::sync::Mutex for short critical sections | Tokio docs recommend this for non-async locks |
tokio::spawn without join | Valid for background tasks with shutdown signaling |
select! with default branch | Non-blocking check, intentional pattern |
#[tokio::test] without multi_thread | Default single-thread is fine for most tests |
| Pattern | Why It's Valid |
|---|---|
expect() in tests | Acceptable for test setup/assertions |
#[should_panic] with expected | Valid for testing panic behavior |
| Large test functions | Integration tests can be long |
let _ = ... in test cleanup | Cleanup errors are often unactionable |
| Pattern | Why It's Valid |
|---|---|
todo!() in new code | Valid placeholder during development |
#[allow(dead_code)] during development | Common during iteration |
Multiple impl blocks for one type | Organized by trait or concern |
| Type aliases for complex types | Reduces boilerplate, improves readability |
Flag unnecessary .clone() ONLY IF:
Send/'static boundsCopyFlag missing error context ONLY IF:
? loses meaningful information about what operation failedFlag unsafe ONLY IF:
Edition 2024 unsafe changes — check Cargo.toml edition before flagging:
unsafe {} inside unsafe fn is required (not style) in edition 2024unsafe extern "C" {} is required in edition 2024 — bare extern "C" {} is a compile error#[unsafe(no_mangle)] and #[unsafe(export_name)] are required in edition 2024BEFORE flagging any edition-specific pattern, check Cargo.toml for the project's edition:
[package]
edition = "2024" # or "2021", "2018"
Edition 2024 changes that affect review findings:
| Change | Edition 2021 | Edition 2024 |
|---|---|---|
unsafe inside unsafe fn | Optional style | Required (unsafe_op_in_unsafe_fn = deny) |
extern "C" {} | Valid | Must be unsafe extern "C" {} |
#[no_mangle] | Valid | Must be #[unsafe(no_mangle)] |
#[export_name] | Valid | Must be #[unsafe(export_name)] |
-> impl Trait lifetime capture | Explicit only | Captures all in-scope lifetimes |
gen as identifier | Valid | Reserved keyword (use r#gen) |
! type fallback | Falls back to () | Falls back to ! |
if let temporaries | Dropped at end of block | Dropped earlier (end of if let) |
| Tail expression temporaries | Dropped after locals | Dropped before local variables |
Box<[T]> iteration | Needs explicit .iter() | Has IntoIterator impl |
If edition is not specified, Rust defaults to edition 2015. Most modern projects use 2021 or later.
Cross-reference: The rust-code-review and rust-best-practices skills provide edition-specific code review guidance and idiomatic patterns.
Before flagging, you MUST:
macro_rules!$crate is used correctly for exported macros (not crate or self)::core:: / ::alloc:: paths are needed (only for macros used in no_std contexts)#[macro_export]Common false positives:
$crate not used in macros that are only pub(crate) — $crate is for cross-crate usage::std:: in macros for std-only crates — only flag if crate supports no_stdBefore flagging, you MUST:
Cargo.toml for proc-macro = true)syn features are minimized (full syn with "full" feature vs selective features)Before flagging, you MUST:
:tt is intentionally used for flexibility (common in TT munching patterns):expr greediness issues actually manifest (test with the macro's actual call sites)Before flagging, you MUST:
#[repr(transparent)] wrapper insteadCommon false positives:
repr(C)repr(transparent) newtype wrappers — the wrapper handles layout*mut c_void) — no layout guarantee neededBefore flagging, you MUST:
Box::into_raw/Box::from_raw pairs)Common false positives:
extern "C" fn callbacks that never panic — catch_unwind not needed*const c_char from CStr::as_ptr() held within the same scope — lifetime is fineunsafe — bindgen output is inherently unsafe-heavy by designBefore flagging, you MUST:
Relaxed is sufficient (counters, flags with no dependent data)Acquire/Release vs SeqCst choice matters (most code doesn't need SeqCst)Common false positives:
Relaxed on simple counters/metrics — no ordering needed for independent valuesRelaxed on boolean flags polled in a loop — the loop provides eventual visibilitySeqCst used "for safety" — not wrong, just potentially over-synchronizedSubmission gate — Pass: Every finding uses [FILE:LINE] ISSUE_TITLE and includes the exact line (or minimal contiguous lines) that demonstrates the issue, so a reader can jump to the proof without trusting memory.
Final verification:
[FILE:LINE] ISSUE_TITLEIf uncertain about any finding, either: