/audit-ports-adapters
Audit Ports and Adapters (Hexagonal Architecture) pattern implementation in Rust codebases
$ npx -y skills add qdhenry/Claude-Command-Suite --agent claude-codeHow it fires
How this command gets triggered: by you, by Claude, or both.
- Fires itselfClaude auto-loads it when your prompt matches the work.
- You can call itInvoke it directly when you want it.
- Slash command
/audit-ports-adapters
Context preview
What this command does when you run it.
Audit Ports and Adapters (Hexagonal Architecture) pattern implementation in Rust codebases
Command definition
audit-ports-adapters.mdname: rust:audit-ports-adapters
description: Audit Ports and Adapters (Hexagonal Architecture) pattern implementation in Rust codebases
allowed-tools: Read, Grep, Glob, Bash
author: Quintin Henry (https://github.com/qdhenry/)
Audit Ports & Adapters Pattern
Analyze the implementation of the Ports & Adapters (Hexagonal Architecture) pattern in a Rust codebase, checking for proper trait definitions, dependency inversion, and adapter implementations.
Instructions
Audit ports and adapters implementation: **$ARGUMENTS**
> **Note:** `$ARGUMENTS` can specify focus areas. > Examples: > - `/rust:audit-ports-adapters` - Full audit > - `/rust:audit-ports-adapters repositories` - Focus on repository ports
---
Ports & Adapters Concept
┌─────────────────────┐
│ Application │
│ │
┌───────────────┤ ┌─────────────┐ ├───────────────┐
│ │ │ Use Cases │ │ │
│ Driving │ │ │ │ Driven │
│ Adapters │ │ ┌───────┐ │ │ Adapters │
│ │ │ │ Ports │ │ │ │
│ (HTTP, CLI, │──│──│(traits)│──│───│ (DB, APIs, │
│ gRPC, etc.) │ │ └───────┘ │ │ Email, etc.)│
│ │ │ │ │ │
└───────────────┤ └─────────────┘ ├───────────────┘
│ │
└─────────────────────┘
Ports = Trait definitions in Application layer
Adapters = Implementations of those traits**Key Principle:** Use cases depend on PORT TRAITS, not concrete adapters.
---
Phase 1: Port Discovery
1.1 Find Port Trait Definitions
Ports should be defined in the application layer:
# Find async traits (common for ports)
grep -rn "#\[async_trait\]" src/ --include="*.rs"
# Find trait definitions in application layer
grep -rn "^pub trait\|^trait" src/application/ 2>/dev/null
# Common port naming patterns
grep -rn "trait.*Repository\|trait.*Service\|trait.*Port\|trait.*Gateway" src/ --include="*.rs"
1.2 Port Location Audit
**Ports MUST be defined in the application layer, NOT in adapters:**
# CORRECT: Ports in application
grep -rn "^pub trait" src/application/ 2>/dev/null
# VIOLATION: Ports defined in adapters
grep -rn "^pub trait" src/adapters/ 2>/dev/null
1.3 Document Discovered Ports
## Discovered Ports
| Port Trait | Location | Purpose | Status |
|------------|----------|---------|--------|
| `UserRepository` | `src/application/ports/` | User persistence | ✓ Correct |
| `PasswordHasher` | `src/application/ports/` | Cryptography | ✓ Correct |
| `EmailService` | `src/adapters/email/` | Email sending | Wrong location |
---
Phase 2: Port Quality Analysis
2.1 Check Port Trait Design
Good ports should:
- Use domain types in signatures
- Be async for I/O operations
- Have clear, focused responsibilities
# Extract port trait definitions
grep -A20 "^pub trait.*Repository\|^pub trait.*Service\|^pub trait.*Port" src/application/ 2>/dev/null
2.2 Port Design Checklist
| Criteria | Status | Notes | |----------|--------|-------| | Uses domain types (not DTOs) | | | | Async for I/O operations | | | | Single responsibility | | | | No framework types in signature | | | | Error types are domain/app errors | | |
2.3 Good vs Bad Port Examples
// GOOD PORT: Uses domain types, async, focused
#[async_trait]
pub trait UserRepository: Send + Sync {
async fn save(&self, user: &User) -> Result<(), RepositoryError>;
async fn find_by_id(&self, id: Uuid) -> Result<Option<User>, RepositoryError>;
}
// BAD PORT: Framework types, too broad
pub trait UserRepository {
fn save(&self, pool: &PgPool, user: Json<UserDto>) -> HttpResult<()>; // Framework leakage!
fn find_by_id(&self, ...) -> ...;
fn delete(&self, ...) -> ...;
fn update(&self, ...) -> ...;
fn list_all(&self, ...) -> ...; // Too many responsibilities?
}---
Phase 3: Adapter Discovery
3.1 Find Adapter Implementations
# Find trait implementations in adapters
grep -rn "impl.*for" src/adapters/ 2>/dev/null
# Specifically find port implementations
grep -rn "impl.*Repository.*for\|impl.*Service.*for\|impl.*Port.*for\|impl.*Gateway.*for" src/adapters/ 2>/dev/null
3.2 Map Ports to Adapters
## Port-Adapter Mapping
| Port | Adapter(s) | Location | Status |
|------|-----------|----------|--------|
| `UserRepository` | `PostgresUserRepository` | `src/adapters/persistence/` | ✓ |
| `UserRepository` | `InMemoryUserRepository` | `src/adapters/persistence/` | ✓ (testing) |
| `PasswordHasher` | `Argon2Hasher` | `src/adapters/crypto/` | ✓ |
| `EmailService` | ??? | ??? | No adapter found |
3.3 Check Adapter Completeness
# For each port, verify an adapter exists
for port in $(grep -roh "trait \w*Repository\|trait \w*Service\|trait \w*Port" src/application/ 2>/dev/null | cut -d' ' -f2); do
echo "Port: $port"
impl_count=$(grep -rn "impl.*$port.*for" src/adapters/ 2>/dev/null | wc -l)
echo " Implementations found: $impl_count"
done
---
Phase 4: Dependency Inversion Check
4.1 Use Case Dependency Analysis
Use cases should depend on trait objects, not concrete types:
# Find use case structs
grep -A10 "^pub struct.*UseCase\|^pub struct.*Service\|^struct.*UseCase" src/application/ 2>/dev/null
# Look for Arc<dyn Trait> patterns (good)
grep -rn "Arc<dyn" src/application/ 2>/dev/null
# Look for concrete adapter types (bad)
grep -rn "Postgres\|Mysql\|Redis\|Argon2\|Bcrypt" src/application/ 2>/dev/null
4.2 Dependency Inversion Checklist
| Use Case | Dependencies | Inverted? | |----------|-------------|-----------| | `RegisterUser` | `Arc<dyn UserRepository>` | ✓ Yes | | `LoginUser` | `PostgresUserRepository` | No - concrete! |
4.3 Good vs Bad Dependency Injection
Read more
name: rust:audit-ports-adapters description: Audit Ports and Adapters (Hexagonal Architecture) pattern implementation in Rust codebases allowed-tools: Read, Grep, Glob, Bash author: Quintin Henry (https://github.com/qdhenry/)
Audit Ports & Adapters Pattern
Analyze the implementation of the Ports & Adapters (Hexagonal Architecture) pattern in a Rust codebase, checking for proper trait definitions, dependency inversion, and adapter implementations.
Instructions
Audit ports and adapters implementation: **$ARGUMENTS**
> **Note:** `$ARGUMENTS` can specify focus areas. > Examples: > - `/rust:audit-ports-adapters` - Full audit > - `/rust:audit-ports-adapters repositories` - Focus on repository ports
---
Ports & Adapters Concept
┌─────────────────────┐
│ Application │
│ │
┌───────────────┤ ┌─────────────┐ ├───────────────┐
│ │ │ Use Cases │ │ │
│ Driving │ │ │ │ Driven │
│ Adapters │ │ ┌───────┐ │ │ Adapters │
│ │ │ │ Ports │ │ │ │
│ (HTTP, CLI, │──│──│(traits)│──│───│ (DB, APIs, │
│ gRPC, etc.) │ │ └───────┘ │ │ Email, etc.)│
│ │ │ │ │ │
└───────────────┤ └─────────────┘ ├───────────────┘
│ │
└─────────────────────┘
Ports = Trait definitions in Application layer
Adapters = Implementations of those traits**Key Principle:** Use cases depend on PORT TRAITS, not concrete adapters.
---
Phase 1: Port Discovery
1.1 Find Port Trait Definitions
Ports should be defined in the application layer:
# Find async traits (common for ports) grep -rn "#\[async_trait\]" src/ --include="*.rs" # Find trait definitions in application layer grep -rn "^pub trait\|^trait" src/application/ 2>/dev/null # Common port naming patterns grep -rn "trait.*Repository\|trait.*Service\|trait.*Port\|trait.*Gateway" src/ --include="*.rs"
1.2 Port Location Audit
**Ports MUST be defined in the application layer, NOT in adapters:**
# CORRECT: Ports in application grep -rn "^pub trait" src/application/ 2>/dev/null # VIOLATION: Ports defined in adapters grep -rn "^pub trait" src/adapters/ 2>/dev/null
1.3 Document Discovered Ports
## Discovered Ports | Port Trait | Location | Purpose | Status | |------------|----------|---------|--------| | `UserRepository` | `src/application/ports/` | User persistence | ✓ Correct | | `PasswordHasher` | `src/application/ports/` | Cryptography | ✓ Correct | | `EmailService` | `src/adapters/email/` | Email sending | Wrong location |
---
Phase 2: Port Quality Analysis
2.1 Check Port Trait Design
Good ports should:
- Use domain types in signatures
- Be async for I/O operations
- Have clear, focused responsibilities
# Extract port trait definitions grep -A20 "^pub trait.*Repository\|^pub trait.*Service\|^pub trait.*Port" src/application/ 2>/dev/null
2.2 Port Design Checklist
| Criteria | Status | Notes | |----------|--------|-------| | Uses domain types (not DTOs) | | | | Async for I/O operations | | | | Single responsibility | | | | No framework types in signature | | | | Error types are domain/app errors | | |
2.3 Good vs Bad Port Examples
// GOOD PORT: Uses domain types, async, focused
#[async_trait]
pub trait UserRepository: Send + Sync {
async fn save(&self, user: &User) -> Result<(), RepositoryError>;
async fn find_by_id(&self, id: Uuid) -> Result<Option<User>, RepositoryError>;
}
// BAD PORT: Framework types, too broad
pub trait UserRepository {
fn save(&self, pool: &PgPool, user: Json<UserDto>) -> HttpResult<()>; // Framework leakage!
fn find_by_id(&self, ...) -> ...;
fn delete(&self, ...) -> ...;
fn update(&self, ...) -> ...;
fn list_all(&self, ...) -> ...; // Too many responsibilities?
}---
Phase 3: Adapter Discovery
3.1 Find Adapter Implementations
# Find trait implementations in adapters grep -rn "impl.*for" src/adapters/ 2>/dev/null # Specifically find port implementations grep -rn "impl.*Repository.*for\|impl.*Service.*for\|impl.*Port.*for\|impl.*Gateway.*for" src/adapters/ 2>/dev/null
3.2 Map Ports to Adapters
## Port-Adapter Mapping | Port | Adapter(s) | Location | Status | |------|-----------|----------|--------| | `UserRepository` | `PostgresUserRepository` | `src/adapters/persistence/` | ✓ | | `UserRepository` | `InMemoryUserRepository` | `src/adapters/persistence/` | ✓ (testing) | | `PasswordHasher` | `Argon2Hasher` | `src/adapters/crypto/` | ✓ | | `EmailService` | ??? | ??? | No adapter found |
3.3 Check Adapter Completeness
# For each port, verify an adapter exists for port in $(grep -roh "trait \w*Repository\|trait \w*Service\|trait \w*Port" src/application/ 2>/dev/null | cut -d' ' -f2); do echo "Port: $port" impl_count=$(grep -rn "impl.*$port.*for" src/adapters/ 2>/dev/null | wc -l) echo " Implementations found: $impl_count" done
---
Phase 4: Dependency Inversion Check
4.1 Use Case Dependency Analysis
Use cases should depend on trait objects, not concrete types:
# Find use case structs grep -A10 "^pub struct.*UseCase\|^pub struct.*Service\|^struct.*UseCase" src/application/ 2>/dev/null # Look for Arc<dyn Trait> patterns (good) grep -rn "Arc<dyn" src/application/ 2>/dev/null # Look for concrete adapter types (bad) grep -rn "Postgres\|Mysql\|Redis\|Argon2\|Bcrypt" src/application/ 2>/dev/null
4.2 Dependency Inversion Checklist
| Use Case | Dependencies | Inverted? | |----------|-------------|-----------| | `RegisterUser` | `Arc<dyn UserRepository>` | ✓ Yes | | `LoginUser` | `PostgresUserRepository` | No - concrete! |
4.3 Good vs Bad Dependency Injection
A comprehensive development toolkit designed following Anthropic's Claude Code Best Practices for AI-assisted software development.
Repo: qdhenry/Claude-Command-Suite
Other commands on claude-command-suite.
- /boundary-bbcr-fallback
Execute automatic BBCR (Collapse-Rebirth Correction) when knowledge boundaries are exceeded or reasoning fails.
Open command - /boundary-detect
Analyze semantic position relative to knowledge boundaries to prevent hallucination and identify uncertainty zones.
Open command - /boundary-heatmap
Generate a visual heatmap of knowledge boundaries showing safe zones, risk areas, and semantic coverage.
Open command - /boundary-risk-assess
Evaluate the current risk level and provide detailed analysis of potential hallucination or reasoning failure.
Open command - /boundary-safe-bridge
Find and construct semantic bridges to safely navigate from current position to target concept without crossing dangerous boundaries.
Open command - /optimize-prompt
Takes an input prompt and returns ONLY a token-optimized version that preserves meaning while minimizing token count. Based on LLM tokenization principles: common words tokenize more efficiently, unusual words break into more tokens, and conciseness reduces cost.
Open command

