execute-review-findings
Use when you have code review findings, PR comments, or review reports that need to be systematically addressed — especially when there are multiple findings across different files and severities
safe-over-unsafe
Use when designing safe public APIs that wrap unsafe Rust code, adding unsafe blocks to existing types, reviewing unsafe code for soundness, or creating new types backed by raw pointers, MaybeUninit, or FFI
Full skill instructions
Module privacy is the soundness boundary — not the unsafe keyword. The
unsafe {} block is a syntax marker; the real safety mechanism is private
fields behind a safe public API, within a module (or crate) where all code
is trusted.
MaybeUninit, raw pointers, or FFIunsafe blocks to existing code for performanceSend/Sync/Drop for types with unsafe internalsFollow every step. Skipping any step is how soundness bugs happen.
< to <= in
a safe bounds check can make all unsafe blocks unsound.#![forbid(unsafe_code)]; unsafe lives in a dedicated crate.#![deny(unsafe_op_in_unsafe_fn)]
#![deny(clippy::undocumented_unsafe_blocks)]
Two kinds of invariants exist — conflating them causes bugs:
bool must be 0 or 1.)Vec's len <= cap.)Document both in a module-level //! or struct-level /// doc comment:
/// # Invariants
/// - `len <= CAPACITY` (safety)
/// - Slots `[head..head+len)` (mod cap) are initialized (safety)
/// - Initialized slots contain valid `T` values (validity)
Every invariant should be evaluated: can this be a const assertion, a NonZero type, or a typestate transition instead of a runtime check?
const { assert!(N > 0 && N.is_power_of_two()) }; // compile-time
Compile-time enforcement eliminates entire bug classes. Runtime
debug_assert! is the fallback — use assert! in public API
preconditions that guard unsafe code in the implementation.
Every // SAFETY: comment must argue invariant preservation, not just
state a fact. Use this structure:
// SAFETY: [what unsafe operation is being performed]
// Invariant: [which safety invariant holds here — and WHY from the code path]
// Implies: [which validity invariant this satisfies for the unsafe op]
// Preserved: [what invariants remain intact after this operation]
Bad: // SAFETY: index is in bounds
Good: // SAFETY: physical = idx & MASK, so physical < CAPACITY (mask clears // high bits). The element is initialized because idx < self.len, and our // safety invariant guarantees slots [head..head+len) are initialized. // This satisfies assume_init_ref's requirement that the value is valid T.
For unsafe fn, use # Safety doc sections documenting caller obligations.
Incorrect Send/Sync is the #1 real-world unsafe soundness bug (tokio RUSTSEC-2025-0023, lock_api RUSTSEC-2020-0070, windows RUSTSEC-2022-0008).
| Situation | Action |
|---|---|
Type uses [MaybeUninit<T>; N] | Auto-derive is correct. No PhantomData needed. |
| Type uses raw pointers | Add PhantomData<T> for owned data (covariant, correct Send/Sync). |
| Need manual Send/Sync | Red flag. Bound generics: unsafe impl<T: Send + Sync> Sync for MyType<T> {} |
| Unsure about variance | If the type owns T, it should be covariant (like Vec). Use PhantomData<T>. |
Always prefer auto-derivation. Add compile-time assertions:
const _: () = {
fn assert_send<T: Send>() { fn requires_send<S: Send>() {} requires_send::<MyType<T>>(); }
fn assert_sync<T: Sync>() { fn requires_sync<S: Sync>() {} requires_sync::<MyType<T>>(); }
};
If an operation modifies state in multiple steps and any step can panic
(e.g., T::drop(), T::clone()), use the decrement-before-drop or
guard pattern:
// Decrement-before-drop: len reflects reality even if drop panics
while self.len > 0 {
self.len -= 1;
unsafe { self.buf[self.len].assume_init_drop(); }
}
Test with a deliberately-panicking Drop impl via catch_unwind.
Unsafe code cannot trust safe trait implementations. T::drop() can
panic. T::clone() can panic. Ord impls can be inconsistent. Write
defensively so broken trait impls cause wrong results, never UB.
All three are required. No single tool is sufficient.
| Layer | Tool | What It Catches | Required |
|---|---|---|---|
| Dynamic UB | cargo +nightly miri test | Aliasing, uninit, alignment, use-after-free | Every test run |
| Aliasing model | MIRIFLAGS="-Zmiri-tree-borrows" cargo +nightly miri test | Tree Borrows violations | CI |
| Reference model | proptest vs known-correct safe impl (e.g., VecDeque) | Logic errors, edge cases | Every test run |
| Drop correctness | DropTracker with Arc<AtomicUsize> | Double-drop, leaks | Every test run |
| Bounded proof | Kani proof harnesses | Exhaustive invariant verification | Critical code |
Before declaring unsafe code "done," verify each:
unsafe impl Send/Sync without restrictive bounds on genericsMaybeUninit: using write() for init, tracking init state, never mem::uninitializedlen/capacity updated atomically with the memory operationassert! (not just debug_assert!)| Pattern | When to Use | Exemplar |
|---|---|---|
| Private fields + safe API | Always | std Vec |
Crate-level #![forbid(unsafe_code)] | Multi-crate projects | Fuchsia, gossip-rs |
| Compile-time const assertions | Numeric invariants | RingBuffer power-of-2 |
MaybeUninit + init tracking | Uninitialized storage | std MaybeUninit docs |
| PhantomData for variance | Raw pointer containers | Rustonomicon Vec |
| Guard struct for panic safety | Multi-step mutations | hashbrown HashMap |
| Typestate (generic state param) | State-dependent operations | serde Serializer |
| Sealed trait | Fixed impl set | zerocopy |
unsafe trait as capability gate | External impls needed | bytemuck Pod |
| Lifetime-encoded validity | Temporal access control | crossbeam-epoch Guard |
Use when you have code review findings, PR comments, or review reports that need to be systematically addressed — especially when there are multiple findings across different files and severities
Deep research before design — 3-5 parallel research agents survey papers, production systems, failure modes, and prior art, then a synthesizer compiles evidence, and an integrator maps findings to a concrete codebase plan with citations
Performance regression testing workflow for hot path changes
Use when creating any beads task — auto-researches the codebase, links related tasks, and produces a rich self-contained description from a structured template. Accepts minimal intent and outputs a complete task ready for agent implementation.
Deep Linux perf profiling — PMU counters, topdown analysis, flamegraphs, and annotated hotspot drill-down on ARM/Graviton
Write-then-verify documentation pipeline. Use when a user asks to
Review and tune SQLite schemas, queries, indexes, and pragmas. Connects to the actual database to gather concrete evidence (EXPLAIN QUERY PLAN, page counts, table stats) before recommending changes.
Parallel specialist code review — 6 focused agents (correctness, design, performance, safety, docs, complexity) diverge independently, then a single ranker merges findings into an importance-ranked report with confidence scores
Run deterministic simulation tests with progressive difficulty levels (sunny/stormy/radioactive) inspired by TigerBeetle VOPR — orchestrates seed management, workload selection, and invariant verification
Use when the user wants a minimal source-only archive for upload or checkpoint. Creates a tar.gz with just src/ and tests/ directories.
Audit memory safety and security in unsafe code blocks, buffer handling, and security-sensitive operations
Scaffold simulation-testable modules with sans-IO pattern, proptest state machine tests, and fault injection points — prevents retrofitting costs by making code DST-ready from the start
Generate, edit, and beat-sync AI video with leading models in one workspace.
The world's fastest calendar for remote work
Transform Your Design with AI Designer by ImgCreator.ai
Revolutionizing Video Production with AI-Powered Creativity
Extend an image past the frame and let AI fill the new aspect ratio.
Discover your celebrity doppelgänger with StarByFace!
ChainClarity explains 700+ crypto whitepapers in plain English, with layered summaries, comparisons, research tools, alerts, and a $4.99 Pro plan.
Opus.ai: Revolutionize Your Web Experience