Skillscodebase-design
C

codebase-design

Shared vocabulary for designing deep modules. Use when the user wants to design or improve a module's interface, find deepening opportunities, decide where a seam goes, make code more testable or AI-navigable, or when another skill needs the deep-module vocabulary.

Codebase Design: A Shared Vocabulary for Designing Deep Modules

Skill Overview

Codebase Design is a shared vocabulary for discussing the design of “deep modules.” It gives concepts such as interfaces, implementations, depth, seams, and adapters consistent meanings across a team, thereby consolidating a large amount of behavior behind a small, stable interface.

Applicable Scenarios

  1. Designing or improving a module’s interface: When you need to decide what a module should expose and what it should hide, or when an existing interface has too many methods and parameters and is difficult for callers to learn, this vocabulary helps focus the discussion on the interface itself rather than implementation details.

  2. Determining where to place seams and where further deepening is possible: When refactoring legacy code, the hardest part is not making the changes but finding the right point of entry. This skill provides ways to evaluate that choice, such as the “delete the tests” test—imagine deleting the module: if the complexity disappears, it was merely a pass-through; if the complexity reappears at N call sites, the module is creating value.

  3. Making code easier to test and easier for AI to understand and modify: When unit tests are difficult to write and you can only test internal implementation by bypassing the interface, it usually indicates that the module has the wrong shape. The testability principles provided by this skill—injecting dependencies from outside, returning results instead of creating side effects, and reducing interface surface area—also help AI programming assistants locate and modify code more accurately.

Core Features

  1. A precise glossary for unifying team language. The skill clearly defines Module, Interface, Implementation, Depth, Seam, Adapter, Leverage, and Locality, and specifies when each term should and should not be used. For example, “module” is deliberately independent of scale: it may be a function, a class, a package, or a cross-layer slice; an “interface” is far more than a type signature—it also includes the invariants, ordering constraints, error modes, and performance characteristics that callers must know.

  2. Actionable principles for designing depth. Depth is a property of the interface, not the implementation: a deep module may be composed internally of small, mockable, replaceable parts, but those parts simply do not belong to the interface. The skill also provides three evaluation criteria: delete the tests; the interface is the test surface (callers and tests pass through the same seam); and one adapter indicates only a hypothetical seam, whereas two adapters indicate a real seam.

  3. A testability design checklist and further reading. Three practical rules are provided: accept dependencies instead of creating them, return results instead of producing side effects, and reduce interface surface area. For further study, the skill points to two companion documents: DEEPENING.md, which explains how to deepen a set of modules given a fixed set of dependencies, and DESIGN-IT-TWICE.md, which explains how to use parallel subagents to design the same interface in several radically different ways and then compare the results.

Frequently Asked Questions

What is a deep module? How do you distinguish deep and shallow modules?

Depth refers to the leverage provided by an interface: how much behavior a caller (or a test) can affect for each unit of interface it must learn. When a large amount of behavior is hidden behind a small interface, the module is deep; when interface complexity is roughly comparable to implementation complexity, the module is shallow. Note that this skill does not use an algorithm such as “implementation lines ÷ interface lines”—that would encourage padding the implementation. What matters here is leverage, not the ratio of line counts.

Are an interface and an API the same thing? Why use “seam” instead of “boundary”?

No. API and “signature” are both too narrow; they cover only the surface at the type level. Here, an interface includes everything callers must know in order to use a module correctly: invariants, ordering constraints, error modes, required configuration, and performance characteristics. The term “boundary” has been claimed by DDD’s bounded contexts, making its meaning easy to confuse, so this skill consistently uses “seam,” a term from Michael Feathers. A seam is a place where behavior can be changed without modifying that place—in other words, the location of a module’s interface. Similarly, the skill avoids using “component” or “service” to refer to a module.

Will this skill directly help me write code or complete a refactoring?

No. It provides a design language and criteria for judgment, not a code generator or automated refactoring tool. Its output is a consistent set of concepts, evaluation standards, and a framework for discussion. It also does not prescribe the scale of a module; functions, classes, packages, and cross-layer slices are all applicable. You or your programming assistant must still make the actual code changes and write the tests. The value of the skill lies in providing a shared, precise vocabulary for these discussions and decisions.