
Unsafe Checker
Review Rust unsafe blocks and public APIs against a prioritized rule set before merge or release.
Overview
Unsafe Checker is an agent skill most often used in Ship review (also Build backend) that audits Rust unsafe code against documented P- and G-level safety rules.
Install
npx skills add https://github.com/zhanghandong/rust-skills --skill unsafe-checkerWhat is this skill?
- 20+ rules across General Principles (3), Safety Abstraction (11), and Raw Pointers (6)
- Mandatory SAFETY comments before any unsafe block and docs safety sections for public unsafe functions
- Blocks exposing uninitialized memory or raw pointers in public APIs
- Panic-safety and double-free guidance for unsafe paths
- Prefer NonNull<T> over *mut T and PhantomData for variance and ownership
- 3 General Principles rules (general-01 through general-03)
- 11 Safety Abstraction rules (safety-01 through safety-11)
- 6 Raw Pointers rules (ptr-01 through ptr-06)
Adoption & trust: 678 installs on skills.sh; 1.2k GitHub stars; 3/3 security scanners passed (skills.sh audits).
What problem does it solve?
You added unsafe for speed but cannot tell if panics, aliases, or public raw pointers violate invariants your team never wrote down.
Who is it for?
Indie Rust authors maintaining FFI, allocators, or hot paths who want agent-driven review against a fixed unsafe rule catalog.
Skip if: Pure safe Rust crates with no unsafe keyword, or teams without any Rust codebase to scan.
When should I use this skill?
Any PR or module introduces or modifies unsafe, raw pointers, manual Auto trait impls, or public unsafe APIs.
What do I get? / Deliverables
After the skill runs, unsafe blocks and APIs are checked against categorized rules with explicit SAFETY documentation gaps called out for fix or block-merge.
- Rule-by-rule findings keyed to general, safety, and ptr IDs
- Action list for missing SAFETY comments, API exposure issues, and panic-safety gaps
Recommended Skills
Journey fit
Spans multiple journey phases - primary shelf plus alternate fits below.
Unsafe Rust review is shelved under Ship because it gates quality and safety before code leaves your hands. Review is the primary home for systematic unsafe audits, SAFETY comments, and API exposure checks.
Where it fits
Implement a custom allocator and run the checker so every unsafe block gets a SAFETY comment before you benchmark.
Scan a PR that adds pub unsafe fn helpers and verify public APIs do not leak uninitialized memory.
Audit thread sharing of raw pointers before shipping a concurrent Rust service edge case.
How it compares
Use as a rule-based unsafe linter mindset, not as a substitute for miri, cargo audit, or full formal verification.
Common Questions / FAQ
Who is unsafe-checker for?
Solo and small-team Rust developers who write or review unsafe and want agents to apply the same sectioned rule tables consistently.
When should I use unsafe-checker?
In Build backend while drafting unsafe modules, and in Ship review before merging PRs that touch unsafe, raw pointers, or public unsafe APIs.
Is unsafe-checker safe to install?
Check the Security Audits panel on this Prism page; the skill guides review only and does not replace running your own tests and miri where applicable.
SKILL.md
READMESKILL.md - Unsafe Checker
# Unsafe Checker - Quick Reference **Auto-generated from rules/** ## Rule Summary by Section ### General Principles (3 rules) | ID | Level | Title | |----|-------|-------| | general-01 | P | Do Not Abuse Unsafe to Escape Compiler Safety Checks | | general-02 | P | Do Not Blindly Use Unsafe for Performance | | general-03 | G | Do Not Create Aliases for Types/Methods Named "Unsafe" | ### Safety Abstraction (11 rules) | ID | Level | Title | |----|-------|-------| | safety-01 | P | Be Aware of Memory Safety Issues from Panics | | safety-02 | P | Unsafe Code Authors Must Verify Safety Invariants | | safety-03 | P | Do Not Expose Uninitialized Memory in Public APIs | | safety-04 | P | Avoid Double-Free from Panic Safety Issues | | safety-05 | P | Consider Safety When Manually Implementing Auto Traits | | safety-06 | P | Do Not Expose Raw Pointers in Public APIs | | safety-07 | P | Provide Unsafe Counterparts for Performance Alongside Safe Methods | | safety-08 | P | Mutable Return from Immutable Parameter is Wrong | | safety-09 | P | Add SAFETY Comment Before Any Unsafe Block | | safety-10 | G | Add Safety Section in Docs for Public Unsafe Functions | | safety-11 | G | Use assert! Instead of debug_assert! in Unsafe Functions | ### Raw Pointers (6 rules) | ID | Level | Title | |----|-------|-------| | ptr-01 | P | Do Not Share Raw Pointers Across Threads | | ptr-02 | P | Prefer NonNull<T> Over *mut T | | ptr-03 | P | Use PhantomData<T> for Variance and Ownership | | ptr-04 | G | Do Not Dereference Pointers Cast to Misaligned Types | | ptr-05 | G | Do Not Manually Convert Immutable Pointer to Mutable | | ptr-06 | G | Prefer pointer::cast Over `as` for Pointer Casting | ### Union (2 rules) | ID | Level | Title | |----|-------|-------| | union-01 | P | Avoid Union Except for C Interop | | union-02 | P | Do Not Use Union Variants Across Different Lifetimes | ### Memory Layout (6 rules) | ID | Level | Title | |----|-------|-------| | mem-01 | P | Choose Appropriate Data Layout for Struct/Tuple/Enum | | mem-02 | P | Do Not Modify Memory Variables of Other Processes | | mem-03 | P | Do Not Let String/Vec Auto-Drop Other Process's Memory | | mem-04 | P | Prefer Reentrant Versions of C-API or Syscalls | | mem-05 | P | Use Third-Party Crates for Bitfields | | mem-06 | G | Use MaybeUninit<T> for Uninitialized Memory | ### FFI (18 rules) | ID | Level | Title | |----|-------|-------| | ffi-01 | P | Avoid Passing Strings Directly to C | | ffi-02 | P | Read Documentation Carefully for std::ffi Types | | ffi-03 | P | Implement Drop for Wrapped C Pointers | | ffi-04 | P | Handle Panics When Crossing FFI Boundaries | | ffi-05 | P | Use Portable Type Aliases from std or libc | | ffi-06 | P | Ensure C-ABI String Compatibility | | ffi-07 | P | Do Not Implement Drop for Types Passed to External Code | | ffi-08 | P | Handle Errors Properly in FFI | | ffi-09 | P | Use References Instead of Raw Pointers in Safe Wrappers | | ffi-10 | P | Exported Functions Must Be Thread-Safe | | ffi-11 | P | Be Careful with repr(packed) Field References | | ffi-12 | P | Document Invariant Assumptions for C Parameters | | ffi-13 | P | Ensure Consistent Data Layout for Custom Types | | ffi-14 | P | Types in FFI Should Have Stable Layout | | ffi-15 | P | Validate Non-Robust External Values | | ffi-16 | P | Separate Data and Code for Closures to C | | ffi-17 | P | Use Opaque Types Instead of c_void | | ffi-18 | P | Avoid Passing Trait Objects to C | ### I/O Safety (1 rule) | ID | Level | Title | |----|-------|-------| | io-01 | P | Ensure I/O Safety When Using Raw Handles | ## Clippy Lint Mapping | Clippy Lint | Rule | Category | |-------------|------|----------| | `undocumented_unsafe_blocks` | safety-09 | SAFETY comments | | `missing_safety_doc` | safety-10 | Safety docs | | `panic_in_result_fn` | safety-01, ffi-04 | Panic safety | | `non_send_fields_in_send_ty` | safety-05 | Send/Sync | | `uninit_assumed_init` | safety-03 | Initialization | | `uninit_vec` | mem-06