skills/design/SKILL.md
Plan architecture and components for a single user story. Use after spec phase to create a technical design before implementation. Produces design documents that guide stubs and implementation.
npx skillsauth add sofer/.agents designInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Plan the architecture and components for implementing a user story.
Expect from orchestrator:
Review the specification:
Examine the codebase:
Choose an appropriate pattern based on:
Common patterns:
Document rationale for selection.
For each component:
components:
- name: "UserController"
type: "controller"
responsibility: "Handle HTTP requests for user operations"
location: "src/controllers/user.controller.ts"
dependencies:
- "UserService"
- "ValidationMiddleware"
public_interface:
- "POST /users → createUser()"
- "GET /users/:id → getUser()"
- name: "UserService"
type: "service"
responsibility: "Orchestrate user business logic"
location: "src/services/user.service.ts"
dependencies:
- "UserRepository"
- "EventPublisher"
public_interface:
- "createUser(input: CreateUserInput): Promise<User>"
- "findById(id: string): Promise<User | null>"
- name: "UserRepository"
type: "repository"
responsibility: "Persist and retrieve user data"
location: "src/repositories/user.repository.ts"
dependencies:
- "Database"
public_interface:
- "save(user: User): Promise<User>"
- "findByEmail(email: string): Promise<User | null>"
Specify precise interface definitions:
interfaces:
- name: "CreateUserInput"
location: "src/types/user.types.ts"
definition: |
interface CreateUserInput {
email: string;
name: string;
}
- name: "UserService"
location: "src/services/user.service.ts"
definition: |
interface UserService {
createUser(input: CreateUserInput): Promise<User>;
findById(id: string): Promise<User | null>;
findByEmail(email: string): Promise<User | null>;
}
Document how data moves through the system:
data_flow:
scenario: "User registration"
steps:
- step: 1
component: "UserController"
action: "Receives POST /users request"
data_in: "HTTP request body"
data_out: "CreateUserInput"
- step: 2
component: "ValidationMiddleware"
action: "Validates input schema"
data_in: "CreateUserInput"
data_out: "Validated CreateUserInput or ValidationError"
- step: 3
component: "UserService"
action: "Orchestrates user creation"
data_in: "CreateUserInput"
data_out: "User or DuplicateEmailError"
- step: 4
component: "UserRepository"
action: "Persists user to database"
data_in: "User entity"
data_out: "Persisted User with ID"
- step: 5
component: "EventPublisher"
action: "Publishes UserCreated event"
data_in: "User"
data_out: "Event published confirmation"
Define error handling strategy:
error_handling:
strategy: "Propagate domain errors, transform at boundaries"
errors:
- error: "DuplicateEmailError"
origin: "UserRepository"
propagation: "UserService → UserController"
http_mapping: "409 Conflict"
- error: "ValidationError"
origin: "ValidationMiddleware"
propagation: "Caught at controller"
http_mapping: "400 Bad Request"
- error: "DatabaseError"
origin: "UserRepository"
propagation: "Wrap in ServiceError"
http_mapping: "500 Internal Server Error"
Record architectural decisions:
decisions:
- decision: "Use repository pattern for data access"
rationale: "Enables testing service logic without database"
alternatives:
- "Direct database access in service"
- "Active Record pattern"
trade_offs: "Additional abstraction layer, but improved testability"
- decision: "Publish events after successful persistence"
rationale: "Ensures events only fire for committed changes"
alternatives:
- "Publish before persistence"
- "Use transactional outbox"
trade_offs: "Simpler but no guaranteed delivery; consider outbox for critical events"
Save design to .sdlc/stories/{story-id}/design.md:
# Design: US-001 - User Registration
## Architecture
Pattern: Layered (Controller → Service → Repository)
Rationale: Matches existing codebase patterns, provides clear separation
## Components
[Component details]
## Interfaces
[Interface definitions]
## Data flow
[Flow diagrams/descriptions]
## Error handling
[Error strategy]
## Decisions
[ADRs - Architecture Decision Records]
## File changes
New files:
- src/controllers/user.controller.ts
- src/services/user.service.ts
- src/repositories/user.repository.ts
- src/types/user.types.ts
Modified files:
- src/routes/index.ts (add user routes)
Update manifest:
stories:
US-001:
artifacts:
design: ".sdlc/stories/US-001/design.md"
decisions:
- phase: "design"
decision: "Using layered architecture"
rationale: "Matches existing patterns"
Before completing:
When used outside the orchestrated pipeline (e.g., via /feature), design can work with inline context instead of manifest spec:
Inline mode input:
feature: "Add logout button to user menu"
codebase_context:
architecture: "React + Redux"
related_modules: ["src/components/UserMenu.tsx", "src/store/authSlice.ts"]
patterns: ["Functional components", "Redux Toolkit"]
Inline mode output:
design:
approach: "Add logout action to slice, expose via hook, add button to menu"
components: [...]
data_flow: [...]
decisions:
- "Use existing auth slice rather than new module"
tools
Check whether Claude and Codex have equivalent access to shared agent resources, skills, hooks, plugins, MCP servers, permissions, startup behaviour, and provider-specific adapter config. Use when comparing agent environments, debugging missing capabilities after restart, or deciding whether to symlink a resource or configure a runtime.
testing
Record substantive skill use in an append-only local log. Use after choosing or invoking a non-system skill for real work, when a skill is inspected but not used, or when a skill fails to apply. Do not use for routine system skills or incidental file reads.
testing
Turn a vague or underspecified request into a self-contained problem statement. Use when the user has a rough idea, when a request would fail if handed directly to an agent, or before non-trivial work that needs shared understanding.
data-ai
Append a one-line learning to ~/.agents/learning-log.md. Use when the user types /learning, or when something genuinely worth remembering surfaced during work and the user confirms it should be captured.