About rust-unsafe-boundaries
A skill for Rust developers that guides the design and review of small, documented, testable unsafe-code boundaries, with emphasis on invariants, safety contracts, and edge-case testing.
Key features
- 01Try safe Rust designs first
- 02Document invariants and safety contracts
- 03Keep unsafe blocks small
- 04Test panic, boundary, and drop paths
- 05Use Miri when supported
Use cases
- 01Reviewing proposed unsafe Rust code
- 02Encapsulating unsafe internals behind safe APIs
- 03Testing initialization and ownership edge cases
Install
Copy the command and run it in a terminal.
$
npx skills add https:/ / github.com/ lvtd-llc/ skills --skill rust-unsafe-boundariesAfter installing, type/rust-unsafe-boundariesin Claude Code to confirm it loaded.
Bundled filesagents/openai.yamlreferences/safety-invariants.md
Details
From the project READMERust Unsafe Boundaries
Use this skill to isolate unsafe Rust behind small, documented, testable boundaries. Unsafe code is acceptable only when a safe API cannot express the needed operation with acceptable correctness and performance.
Core Workflow
- Try the safe design first. Check standard APIs, ownership restructuring, iterators, synchronization primitives, and existing crates.
- State the invariant that safe Rust cannot prove. If the invariant cannot be written down, do not write unsafe code yet.
- Keep unsafe blocks tiny. Put runtime checks and setup in safe code before the block.
- Add a
// SAFETY:comment immediately before each unsafe block explaining why every unsafe operation inside is valid. - Mark a function
unsafe fnonly when callers must uphold extra conditions. Document those conditions in a# Safetysection. - Enable or respect
unsafe_op_in_unsafe_fn; unsafe operations inside unsafe functions should still be wrapped in explicit unsafe blocks. - Test normal behavior, boundary cases, panic paths, and drop behavior. Run Miri when the project supports it.
Boundary Rules
Read references/safety-invariants.md before adding or approving unsafe code.
- Prefer private unsafe internals plus a safe public wrapper.
- Prefer
MaybeUninit<T>over deprecated or ad hoc uninitialized memory patterns. - Never create references from raw pointers unless validity, alignment, initialization, aliasing, and lifetime are all proven.
- Do not use
set_len, pointer arithmetic, orfrom_raw_partswithout proving capacity, initialization, and ownership. - Make panic safety explicit when partially initialized values, manual drops, or length changes are involved.
- Avoid
static mut; preferOnceLock,LazyLock, atomics, or locked state.
Documentation Pattern
/// # Safety
///
/// `ptr` must be non-null, aligned for `T`, initialized, and valid for reads
/// for the returned lifetime. No mutable reference may alias the same value.
pub unsafe fn read_ref<'a, T>(ptr: *const T) -> &'a T {
// SAFETY: The caller guarantees `ptr` satisfies the documented contract.
unsafe { &*ptr }
}
Review Checklist
- Every unsafe block has a local
SAFETYexplanation. - Every
unsafe fnor unsafe trait has a# Safetycontract. - Public safe APIs cannot be used to violate internal invariants.
- Drop, panic, and early-return paths preserve initialization and ownership.
- Tests or Miri cover the dangerous edge, not only the happy path.
Comments
Markdown supported