codebase-spec
Use this skill whenever the user wants to reverse-engineer, document, or migrate a codebase. Triggers include: "write a spec for this codebase", "document this project", "I want to migrate this to ano
SKILL.mdskills/codebase-spec/SKILL.md
GitHubCodebase Spec Skill
Reads a codebase and produces a multi-document specification suite — thorough enough that an engineer (or an AI agent) can reimplement the entire codebase in a different language from the docs alone, with no access to the original source.
Phase 0: Orientation
Before reading any code, build a map of the codebase:
find . -type f | sort # full file list
cat README* 2>/dev/null # top-level readme
cat package.json / pyproject.toml / Cargo.toml / go.mod / pom.xml 2>/dev/null # manifest
ls -la # root structure
From this, identify:
- Language(s) and runtime
- Top-level modules / packages — these become your doc units
- Entry points (main files, CLI scripts, server startup, index files)
- Config and environment (
.env, config files, secrets patterns) - External dependencies (libraries, APIs, databases, queues)
- Test suite location and framework
- Build / deploy artifacts (Dockerfile, CI config, Makefile, etc.)
Announce your findings to the user in a short summary before proceeding:
"I've mapped the codebase. Found X modules, written in Y, with Z external dependencies. Here's my plan for the spec docs: [list]. Starting with [module]. Let me know if you want a different order."
Phase 1: Ambiguity Protocol
Always ask before proceeding when you encounter:
- Code whose purpose is genuinely unclear after reading the surrounding context
- Magic values, undocumented constants, or non-obvious algorithms
- Implicit contracts between modules that aren't expressed in types or comments
- Behavior that appears to be a bug but might be intentional
- Environment-specific logic that can't be inferred statically (feature flags, runtime config)
Format ambiguity questions clearly and batch them — don't ask one at a time if you have several for the same module:
Ambiguity check — [ModuleName] Before I document this module, I need to clarify a few things:
RETRY_LIMIT = 7— is this a business rule or an arbitrary default?process_event()callslegacy_handler()only on Tuesdays (line 84). Is this intentional?- The
UserCacheclass appears unused. Should I document it or skip it?Please answer all three before I continue.
Wait for the user's response. Don't proceed with guesses on flagged ambiguities — mark them [UNRESOLVED - awaiting clarification] if you somehow move on.
Phase 2: Module-by-Module Analysis
Work through each module/layer identified in Phase 0. For each module, read its files fully before writing anything.
Capture for each module:
- Purpose: What problem does this module solve?
- Public interface: Every function, class, method, or route that other modules depend on
- Internal logic: Key algorithms, data transformations, state machines, business rules
- Data structures: All significant structs, schemas, models, or types — with field names, types, and semantics
- Dependencies: What it imports from inside the codebase; what it imports from outside
- Side effects: I/O, DB writes, network calls, file system, external API calls
- Error handling: How errors are raised, caught, propagated, or swallowed
- Configuration: What env vars or config keys does it read, and what are the defaults?
- Invariants and assumptions: What must be true for this module to work correctly?
- Known limitations: Hard-coded limits, unhandled cases, TODO comments, deprecated paths
For large modules (>20 files), break them into sub-sections.
Phase 3: Cross-Cutting Concerns
After all modules are documented, write a Cross-Cutting Concerns doc covering:
- Authentication & authorization: How identity flows through the system
- Error and exception strategy: Global error handling patterns
- Logging and observability: What gets logged, at what level, where it goes
- Concurrency and threading model: Async patterns, thread pools, queues, locks
- Data validation: Where and how inputs are validated
- Security patterns: Sanitization, secrets management, network boundaries
- Performance assumptions: Caching strategy, batch sizes, rate limits, timeouts
Phase 4: Output Documents
Produce the following files in a spec/ directory at the codebase root (or output path if specified):
spec/
├── 00_overview.md ← Architecture, tech stack, entry points, system diagram
├── 01_requirements.md ← Functional and non-functional requirements inferred from code
├── 02_assumptions.md ← What the code assumes to be true about its environment/inputs
├── 03_limitations.md ← Hard limits, known gaps, unhandled edge cases, TODOs
├── 04_data_models.md ← All significant data structures, schemas, enums, types
├── 05_api_contracts.md ← All public interfaces (REST routes, function signatures, events, queues)
├── 06_<module_name>.md ← One file per major module (repeat as needed)
├── ...
└── NN_cross_cutting.md ← Auth, error handling, logging, concurrency, security
Read the Document Templates reference file before writing any doc:
→ references/doc-templates.md
Reimplementation Completeness Test
Before finalizing, ask yourself: "If someone burned the original codebase and only had these docs, could they rebuild it correctly in a different language?"
Check that the docs collectively answer:
- What does the system do at a high level?
- What are the inputs and outputs of every public interface?
- What are the data models and their field semantics?
- What external services/APIs does it integrate with, and how?
- What are the business rules and invariants?
- What are the known bugs, limitations, and TODOs?
- What configuration is required to run this?
- What does the test suite cover (and what does it miss)?
If any box is unchecked, fill the gap before delivering the docs.
Phase 5: Delivery
When all docs are written:
- Present the full
spec/directory to the user - Give a one-paragraph summary: what the codebase does, key architectural decisions, and any unresolved ambiguities still marked
[UNRESOLVED] - Explicitly flag anything that would block a clean reimplementation
Tone and Style
- Write for an engineer who has never seen this codebase and may be working in a different language
- Avoid source-language idioms — describe behavior, not syntax (say "iterates over all users" not "for user in users")
- Use tables for data models and API signatures
- Use numbered lists for ordered processes; bullet lists for unordered properties
- Mark all uncertainty explicitly:
[INFERRED],[UNRESOLVED],[ASSUMED] - Never invent behavior — if you don't know, say so
Reference Files
references/doc-templates.md— Exact templates for each output document. Read this before writing any spec doc.