Checks that any component that is being used by another component is only accessed through the component's interface and does not interact directly with the struct.
Scanned 9/9/2026
Install to Claude Code
npx -y skills add AI-native-Systems-Research/ai-native-storage-certus --skill component-check-leakage --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Component Check Leakage?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/ai-native-systems-research-component-check-leakage-2c9cfe9a)More formats (shields.io, HTML) on the badges page.
---
name: component-check-leakage
description: Checks that any component that is being used by another component is only accessed through the component's interface and does not interact directly with the struct.
argument-hint: "[component-name, component-name, ...]"
---
# Component Leakage Check
This skill audits the codebase for **abstraction leakage** — cases where a component's concrete struct is used directly by another component instead of being accessed through its interface trait.
## The Rule
Each component in `components/` exposes:
- A **concrete struct** (e.g., `LoggerComponent`, `HelloWorldComponent`) — the implementation detail.
- An **interface trait** in `components/interfaces/` (e.g., `ILogger`, `IGreeter`) — the public contract.
When component A consumes component B, it must only interact through B's interface. Direct use of B's struct is leakage.
**Violation (leakage):**
```rust
use logger::LoggerComponent; // importing struct from another component
let logger = Arc::new(LoggerComponent::new_default()); // constructing it
let logger: Arc<LoggerComponent> = ...; // holding a typed reference to the struct
```
**Correct (interface only):**
```rust
use interfaces::ILogger;
// logger injected via receptacle, typed as Arc<dyn ILogger + Send + Sync>
```
## Scope and Exceptions
- **Components under `components/`** are subject to this rule (excluding `interfaces/` and `component-framework/`).
- **Apps under `apps/`** are wiring points — they legitimately instantiate concrete structs. Flag them only as a note, not a violation.
- **Unit test files** (`#[cfg(test)]` blocks and files in `tests/`) may use concrete structs for test fixtures. These are warnings, not errors.
- **A component's own source files** constructing its own struct are fine — a component knows its own type.
- **Dynamic loading entry points** (`extern "C" fn create_component`) constructing and returning the struct as a trait object are fine.
## Detection Strategy
For each component under investigation (all components if no `$ARGUMENTS`, otherwise only those named):
### Step 1 — Identify the component's concrete struct name
Read the `define_component!` macro invocation in the component's `src/lib.rs`. The struct name is the identifier immediately following `pub` in the macro body (e.g., `pub LoggerComponent { ... }`).
### Step 2 — Find all other components that list it as a Cargo dependency
Search all `Cargo.toml` files under `components/` and `apps/` for a dependency entry whose crate name matches the component being checked. Use the package name (hyphenated) from the component's `Cargo.toml` `[package]` section.
### Step 3 — Check each dependent crate's source for leakage
For each crate that lists the target component as a dependency, grep its source files (`src/**/*.rs`) for:
1. **Direct import of the struct:**
```
use <crate_name>::<StructName>
use <crate_name>::{..., <StructName>, ...}
```
2. **Qualified path usage:**
```
<crate_name>::<StructName>::
Arc<dyn ... | Arc<<StructName>> (type annotations containing the struct)
```
3. **Type annotations holding the struct** (not behind `dyn`):
```
: Arc<<StructName>>
: <StructName>
```
Exclude matches in:
- The component's own `src/` files (self-reference)
- Lines inside `#[cfg(test)]` modules and `tests/` directories (mark separately as warnings)
- `apps/` crates (mark separately as notes)
### Step 4 — Identify the correct interface
Cross-reference `components/interfaces/src/lib.rs` to find which interface trait(s) the component provides (look for `use <crate>::...; pub use` re-exports or the trait definitions). This helps frame the fix suggestion.
### Step 5 — Report
For each component checked, output a structured report:
```
## <ComponentName> (crate: <crate-name>)
### Violations (must fix)
- <file>:<line> — <dependent-crate> uses `<StructName>` directly
Fix: replace with `Arc<dyn <IInterface> + Send + Sync>` via receptacle
### Warnings (test code — consider fixing)
- <file>:<line> — test uses `<StructName>` directly
### Notes (apps — acceptable but review)
- <file>:<line> — app wiring uses `<StructName>` to construct and bind
### Clean ✓
No leakage found.
```
If `$ARGUMENTS` are provided, only check components whose names (case-insensitive, hyphen/underscore normalised) appear in the argument list. Otherwise check all components.
At the end, print a summary line: `N violation(s) across M component(s)`.
## Example Run
```
/component-check-leakage logger
```
Expected: finds that `gpu-services` uses `LoggerComponent` directly in `src/lib.rs` (tests) and `src/bin/p2p_server.rs` (main code), reports violations and suggests using `ILogger` via a receptacle instead.
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!