| name | design-doc-low-level |
| description | Generate a low-level design specification from requirements and high-level design documents. Covers class diagrams, package structure, class interactions, and testing strategy — the bridge between architecture and implementation. |
| argument-hint | [prefix] [focus areas or constraints, or leave blank] |
Generate a low-level design specification that bridges the high-level architecture and actual implementation. This document answers "how exactly will we structure and test the code?"
Given the requirements and high-level design, this skill produces class diagrams, package/module structures, class interactions, and a comprehensive testing strategy — enough detail for an implementer to begin writing code without ambiguity.
Input
The user may provide: $ARGUMENTS (design prefix, specific focus areas, language idioms, or constraints)
Expected Folder Structure
design/
├── {prefix}-requirements.md # Input: must exist
├── {prefix}-high-level-design.md # Input: must exist
└── {prefix}-low-level-design.md # Output: this skill creates this
Process
Phase 1: Locate and Read Prerequisite Documents
- If $ARGUMENTS provides a prefix, look for
design/{prefix}-requirements.md and design/{prefix}-high-level-design.md
- Otherwise, scan
design/ for files matching *-requirements.md and *-high-level-design.md (also check for unprefixed requirements.md and high-level-design.md for backwards compatibility)
- If exactly one match: use it and infer the prefix from the filename (e.g.,
client-requirements.md means the prefix is client)
- If multiple matches: use AskUserQuestion to list all discovered options and ask which design to work with
- If no matches: use AskUserQuestion to ask the user where to find the documents
- Once a prefix is established from one file, use it to find the other (e.g., if
client-requirements.md is found, look for client-high-level-design.md)
- If no prefix was determined yet (e.g., unprefixed files were found, or the user provided a custom path), use AskUserQuestion to ask: "What design prefix should be used? This allows multiple designs to coexist (e.g., 'client', 'server', 'auth')."
- If either prerequisite is missing: Use AskUserQuestion to ask the user where to find it. Do NOT proceed without both documents.
- Read and understand both thoroughly — the low-level design must be consistent with the architectural decisions and must address every functional requirement.
Phase 2: Clarify Implementation Approach
Ask the user about implementation-level decisions using AskUserQuestion. Adapt questions to the language and platform chosen in the high-level design. Ask questions liberally — it is better to over-clarify than to make assumptions at this level of detail. Common areas:
Code Organization
- How should the project be divided into packages/modules/crates? (e.g., for Rust: how many Cargo packages in the workspace, and what are their dependency relationships?)
- Monorepo vs. multi-repo?
- Where do shared types live?
Class/Type Design
- Preferred patterns? (e.g., trait-based abstraction in Rust, interface-heavy in Java, protocol-oriented in Swift)
- Error handling strategy? (result types, exceptions, error codes)
- How opinionated should types be? (newtype wrappers, strong typing vs. primitives)
Data Access Patterns
- ORM vs. raw SQL vs. query builder?
- Repository pattern, active record, or direct access?
- Connection pooling strategy?
- Migration tool preference?
Dependency Injection & Wiring
- Constructor injection, framework-based DI, or module-level wiring?
- How are runtime dependencies (DB connections, HTTP clients, config) threaded through the code?
Concurrency Model (if applicable)
- Async runtime? (tokio, async-std, asyncio, etc.)
- Thread pool sizing?
- Shared state strategy? (locks, channels, actors)
Testing Philosophy
- Unit test framework preference?
- Integration test infrastructure? (testcontainers, docker-compose, in-memory fakes)
- What level of coverage is expected?
- Are there specific requirements from the requirements doc that need dedicated integration tests?
Ask 2-4 focused questions at a time. Continue until you have enough clarity for all implementation decisions. When in doubt, ask — do not assume.
Phase 3: Generate Low-Level Design
Create design/{prefix}-low-level-design.md using the template in template.md with these sections:
-
Overview — Brief summary of scope and relationship to high-level design
-
Package/Module Structure — Complete breakdown of how the codebase is organized. For each package/module:
- Name and purpose
- Public interface (what it exports)
- Dependencies on other internal packages
- Mermaid diagram showing package dependency graph
-
Class Diagrams — For each major package/module, a Mermaid classDiagram showing:
- Classes/structs/traits/interfaces
- Key methods and fields
- Inheritance/implementation relationships
- Associations and dependencies between classes
-
Class Interactions — How classes collaborate for key operations:
- Mermaid
sequenceDiagram for important workflows
- Which class is responsible for what in each flow
- Error propagation paths
-
Data Access Layer — Detailed design of how data is stored and retrieved:
- Repository/DAO interfaces
- Query patterns
- Transaction boundaries
- Connection management
-
Error Handling Strategy — Concrete error types, how they propagate, and how they map to user-facing responses
-
Configuration & Wiring — How the application bootstraps:
- Dependency graph at startup
- Configuration loading
- Service initialization order
-
Testing Strategy — This section is critical and should be thorough:
Unit Tests (per class/module):
- For each class with significant logic, list the protocol tests needed
- Protocol tests should verify the class honors its contract as defined by the requirements
- Group tests by the requirement IDs (FR-x.x.x) they verify
Integration Tests:
- For each functional requirement in the requirements doc, identify which integration tests are needed to verify it end-to-end
- Describe what each integration test sets up, exercises, and asserts
- Identify shared test fixtures or utilities needed
Test Infrastructure:
- What test doubles are needed (mocks, fakes, stubs)?
- How are integration test dependencies managed (testcontainers, docker-compose, etc.)?
- Any performance or load testing considerations?
-
Open Questions — Implementation-level decisions still unresolved
Design Principles:
- Every class/module must have a clear single responsibility
- The design must trace back to requirements — every FR should be coverable by the testing strategy
- Favor explicitness over magic
- Document non-obvious decisions with rationale
- No implementation code. The low-level design may describe API surface areas (function signatures, return types, exceptions) and provide guidelines on what to do or not do, but it must never include implementation code examples. Implementation decisions belong to the implementation agent.
Conventions:
- Use Mermaid diagrams —
classDiagram, sequenceDiagram, flowchart, graph
- Tables for structured data (test matrices, package summaries)
- Requirement ID cross-references (FR-x.x.x) throughout
- API surface areas are acceptable (function signatures, return types, possible exceptions) but never include implementation code. The low-level design describes what each component's interface looks like and guidelines for how it should behave — it must leave actual implementation to the implementation agent. Use prose, tables, and diagrams to convey design intent rather than code examples.
Mermaid Diagram Rules (required for renderer compatibility — GitLab, GitHub, VS Code use older Mermaid.js):
- Always quote flowchart node labels:
A["Start here"] not A[Start here]
- Always quote decision nodes:
B{"Is it ready?"} not B{Is it ready?}
- Always quote subgraph titles:
subgraph sg["My Group"] not subgraph sg[My Group]
- Prefer
A -- "label" --> B link syntax over A -->|"label"| B
- Use plain text participant aliases in sequence diagrams:
participant SVC as my-service
- Keep labels short — move detail into surrounding prose
- NO
<br/> in any label or node text
- NO
par / and blocks in sequence diagrams — use Note over A,B: description instead
- NO
<--> bidirectional arrows — use two separate directed arrows
- NO
}o--|| at start of erDiagram lines — reverse to ||--o{
- NO special characters in state/flowchart labels:
() . / → __ — use plain words
Phase 4: Solicit Feedback
After generating the low-level design, summarize:
- Package/module structure and rationale
- Key class design decisions
- Testing coverage relative to requirements
- Open questions
Invite the user to review and provide feedback. Iterate on the document based on their input.
Phase 5: Sync to Grimoire
After writing the local file, sync it to the grimoire so it's searchable and accessible across projects.
-
Derive the project name from the project context:
- Check
design/{prefix}-requirements.md title or the project's root directory name
- Use a short, lowercase, hyphenated name (e.g.,
my-api-server, data-pipeline)
- If unclear, use AskUserQuestion to ask the user what to call this project
-
Write the file to the grimoire:
~/.grimoire/files/technical-designs/{project-name}/{prefix}-low-level-design.md
Copy the full contents of design/{prefix}-low-level-design.md to this path.
-
Register metadata using the grimoire-cli CLI:
grimoire-cli create-file-metadata \
--file "files/technical-designs/{project-name}/{prefix}-low-level-design.md" \
--source-agent "design-doc-low-level" \
--tags "type/low-level-design,project/{project-name},topic/technical-design" \
--summary "Low-level design specification for {project name}"
If the file already exists in the grimoire, use update-file-metadata instead.
-
If the grimoire CLI is not available (command not found), skip this phase silently — the local file is the primary output.
Output
Create design/{prefix}-low-level-design.md (create design/ directory if needed).
Also synced to ~/.grimoire/files/technical-designs/{project-name}/{prefix}-low-level-design.md if the grimoire is available.
The low-level design should be:
- Implementation-ready: Enough detail to begin coding without architectural ambiguity
- Traceable: Every requirement ID from the requirements doc should appear in the testing strategy
- Testable: Clear testing strategy with specific test cases tied to requirements
- Consistent: All decisions must align with the high-level design document