Codebase Design & Domain Modeling
Relevant source files
The following files were used as context for generating this wiki page:
Codebase Design and Domain Modeling represent the active discipline of sharpening a project's architecture and ubiquitous language. The primary objective is to create "deep modules" that encapsulate meaningful complexity behind small, stable interfaces, while ensuring that all terminology aligns with a strictly defined domain model.
This system relies on three pillars: a shared design vocabulary, a centralized domain glossary (CONTEXT.md), and recorded Architectural Decision Records (ADRs). These components work together to improve testability, AI-navigability, and maintainer locality.
Sources: skills/codebase-design/SKILL.md:1-10, skills/domain-modeling/SKILL.md:1-10
Core Design Vocabulary
The project uses a specific set of terms to describe architectural components. You must use these terms exactly to maintain consistency across refactor proposals and implementations.
| Term | Definition |
|---|---|
| Module | Any unit with an interface and implementation (function, class, package, or slice). |
| Interface | The full surface a caller must know, including types, invariants, error modes, and config. |
| Implementation | The internal code body of a module. |
| Depth | The amount of behavior a caller exercises per unit of interface learned (leverage). |
| Seam | The location where an interface lives; allows altering behavior without local edits. |
| Adapter | A concrete object that satisfies an interface at a specific seam. |
| Leverage | The benefit callers receive from a deep module (more capability for less learned interface). |
| Locality | The concentration of bugs, changes, and knowledge in a single place for maintainers. |
Sources: skills/codebase-design/SKILL.md:12-35, skills/improve-codebase-architecture/SKILL.md:11-20
Deep vs. Shallow Modules
The project prioritizes "Deep Modules" over "Shallow Modules." A deep module hides significant implementation complexity behind a small public interface. Conversely, a shallow module has an interface nearly as complex as its implementation, offering little leverage to callers.
This diagram illustrates the relationship between interface size and implementation complexity, where deep modules provide leverage and locality.
The Deletion Test
To identify a shallow module, apply the deletion test. If you imagine deleting the module and the overall system complexity vanishes, the module was likely a pass-through. If the complexity instead reappears across multiple callers, the module was successfully earning its keep.
Sources: skills/codebase-design/SKILL.md:37-55, skills/improve-codebase-architecture/SKILL.md:23-28
Domain Modeling Structure
Domain Modeling focuses on capturing terminology and decisions in a CONTEXT.md file and an ADR directory. The structure of these files depends on whether the repository uses a single or multi-context layout.
The diagram shows how CONTEXT.md and ADRs are distributed based on the presence of a CONTEXT-MAP.md.
Context and Glossary Rules
- Context Files:
CONTEXT.mdserves as a glossary of terms for domain experts. It must remain devoid of implementation details. - Lazy Creation: Do not create
CONTEXT.mdordocs/adr/until the first term or decision needs resolution. - Cross-Reference: When a domain relationship is discussed, you must check if the current code implementation agrees with the stated business rules.
Sources: skills/domain-modeling/SKILL.md:12-38, skills/setup-matt-pocock-skills/domain.md:5-25
Architectural Decision Records (ADR)
ADRs record the "why" behind significant architectural choices. They provide historical context to prevent future maintainers from re-litigating settled trade-offs.
Criteria for Creating an ADR
Only offer to create an ADR if all three conditions are met:
- Hard to reverse: Changing the decision later involves meaningful cost.
- Surprising without context: Future readers will not intuitively understand the reasoning.
- Real trade-off: The choice resulted from genuine alternatives.
ADR Document Format
Each ADR must follow a specific structure to ensure consistency:
- Status: (e.g., proposed, accepted, superseded)
- Context: The problem or requirement driving the decision.
- Decision: The specific path chosen.
- Consequences: The positive and negative results of the choice.
Sources: skills/domain-modeling/SKILL.md:58-65, skills/domain-modeling/ADR-FORMAT.md:1-20
The Grilling and Deepening Process
Improving architecture involves a "grilling" session where plans are challenged against the domain model.
This sequence diagram shows the iterative process of sharpening a domain model and architecture through active questioning.
Identifying Deepening Opportunities
Architectural friction is surfaced by looking for:
- Concepts that require jumping between many small modules to understand.
- Pure functions extracted solely for testability that lack locality for real bugs.
- Modules where the interface is nearly as complex as the implementation.
Sources: skills/grill-with-docs/SKILL.md:15-55, skills/improve-codebase-architecture/SKILL.md:32-60
Conclusion
Effective codebase design requires a disciplined adherence to deep module principles and a shared language. By maintaining a sharp domain model in CONTEXT.md and recording load-bearing decisions in ADRs, projects achieve high leverage for callers and clear locality for maintainers. Architecture should be deepened through active grilling sessions that challenge fuzzy terminology and seek to encapsulate complexity behind stable seams.