Design and review Rust FFI boundaries that keep raw declarations isolated behind safe ownership, lifetime, error, and cleanup wrappers.
SkillScore96Maintained
Automatic
◆Coding pack
Last verified 8/16/2026
What it changes
Passed 24 of 25 test cases with the skill, and 22 of 25 without it.
Without skill88%
With skill96%
Checks it passed that the model alone missed
Uses `unsafe extern "C"` blocks for foreign declarations.
Uses `unsafe extern "C"` blocks for foreign function declarations.
Imports C primitive types from `core::ffi` or `std::ffi` rather than `std::os::raw`.
2 fixed22 passed either way1 still failing0 broke
Pass-rate lift
+8 pp
Tokens
+15%
Agent turns
0%
Response time
-16%
Model gemini-3.6-flashMeasured 8/16/2026v124 of 25 cases passed with skill
Tokens, turns and time describe resource use, not a dollar price.
See it in action
One of 2 test cases the skill fixed. Same model, same prompt, with and without the skill.
1 of 2
Prompt
I have C header signatures for a graphics library that creates a context pointer, accepts configuration string parameters, and requires explicit destruction. Could you write a safe Rust wrapper module around these foreign function declarations? I need an idiomatic Rust interface that manages the handle lifetime, converts return error codes into standard Rust Results, and bridges string types safely.
What was checked, without and with the skill
Checked
Without skill
With skill
Uses `core::ffi` or `std::ffi` types instead of `std::os::raw` for C type declarations.
Passed
Passed
Uses `unsafe extern "C"` blocks for foreign function declarations.
Missed
Passed
Implements `Drop` on the handle wrapper type to call the foreign deallocator.
Passed
Passed
case-01 · gemini-3.6-flash · 8/16/2026 · answers are capped and redacted
What's inside
The instructions your model reads when the skill loads.
SKILL.md71 lines2 files
Rust FFI Safe Wrappers
Use this skill to wrap foreign interfaces in Rust APIs that make ownership,
lifetimes, errors, and cleanup explicit. FFI code should be unsafe at the raw
boundary and safe for normal Rust callers.
Core Workflow
Separate raw declarations from safe wrappers. Put raw unsafe extern
bindings in a small private module.
Verify ABI, type layout, calling convention, ownership, nullability,
threading, and error conventions against the foreign header or docs.
Use unsafe extern "C" blocks for modern Rust, especially Rust 2024 edition
code. Leave safety-conditional items unqualified or explicitly unsafe, and
mark individual extern items safe only when calling them is safe for all
Rust inputs.
Use #[repr(C)] for structs and enums that cross the ABI boundary. Do not
expose Rust-only layout types across C.
Use CString for owned nul-terminated strings sent to C and CStr for
borrowed C strings. Never treat arbitrary C memory as Rust-owned.
Wrap raw handles in Rust types with private fields and Drop cleanup using
the matching foreign deallocator.
Prevent Rust panics from crossing extern "C" boundaries. Catch panics or
expose an ABI that permits unwinding only when deliberately using
"C-unwind".
Wrapper Rules
Read references/ffi-boundary-patterns.md before adding or reviewing FFI
bindings.
Prefer core::ffi or std::ffi C types over guessing integer sizes.
Convert foreign error codes into Rust Result at the wrapper boundary.
Represent nullable handles as Option<NonNull<T>> internally when useful,
but expose safe Rust types to callers.
Tie borrowed values to owner lifetimes with normal references or
PhantomData when the compiler cannot see the relationship.
Make initialization and shutdown idempotent with OnceLock, LazyLock, or
Once when the foreign library requires process-wide setup.
Use bindgen for large or changing C headers and cbindgen when exporting a