Skip to content
Skills Library
Programming · Analysis

codebase-design

/codebase-design

Module design discipline from John Ousterhout's A Philosophy of Software Design, depth as the metric (a lot of functionality behind a simple interface), information hiding vs. leakage, the concrete red flags that mark a shallow module, and comparing at least two designs before committing. Use when designing a new module or class, deciding where an interface boundary (seam) should go, reviewing a design for unnecessary complexity, or asking whether something should be split or merged.

Repository
doctrine ↗
Licence
MIT
Last repository change
11.09.2026

Assessment and security

90/ 100Class: good
Format25 / 25
Frontmatter with name and description, valid name, description up to 1,024 characters, name matching the folder.
Discoverability25 / 25
Description explains when to use the skill, has a reasonable length and uses third person.
Content25 / 35
At least 150 words and at most 500 lines, headings, step lists, examples or code.
Hygiene15 / 15
No placeholders such as TODO, no Windows paths, with a licence.
Riskno signals detected in the scan
Files in this package
2
Scripts
0
HTML comments
0
URLs in SKILL.md
0
Deprecation

No signals detected. Repository changed on 11.09.2026, without references to retired models or APIs.

Licence

MIT, open: use and modify while retaining author attribution.

What it does and when to use it

Module design discipline from John Ousterhout's A Philosophy of Software Design, depth as the metric (a lot of functionality behind a simple interface), information hiding vs. leakage, the concrete red flags that mark a shallow module, and comparing at least two designs before committing. Use when designing a new module or class, deciding where an interface boundary (seam) should go, reviewing a design for unnecessary complexity, or asking whether something should be split or merged.

Original author description

Module design discipline from John Ousterhout's A Philosophy of Software Design, depth as the metric (a lot of functionality behind a simple interface), information hiding vs. leakage, the concrete red flags that mark a shallow module, and comparing at least two designs before committing. Use when designing a new module or class, deciding where an interface boundary (seam) should go, reviewing a design for unnecessary complexity, or asking whether something should be split or merged.

How it works

  1. Phase 1: Depth is the metric
  2. Phase 2: Information hiding, and its failure mode
  3. Phase 3: Concrete red flags
  4. Phase 4: Design it twice
  5. Phase 5: Where the seam goes
  6. Done when
Original SKILL.md headings · 42 lines, 842 words
SKILL.md preview
---
name: codebase-design
description: Module design discipline from John Ousterhout's A Philosophy of Software Design, depth as the metric (a lot of functionality behind a simple interface), information hiding vs. leakage, the concrete red flags that mark a shallow module, and comparing at least two designs before committing. Use when designing a new module or class, deciding where an interface boundary (seam) should go, reviewing a design for unnecessary complexity, or asking whether something should be split or merged.
---

# Codebase Design

Complexity is the enemy, and the single lever that fights it at the module level is **depth**: a module's value is the ratio of functionality it provides to the size of the interface a caller has to learn. A deep module hides a lot behind a little; a shallow one exposes almost as much as it does. Given a choice, make the interface simpler even if that means the implementation underneath grows; the interface is what every caller pays for, forever; the implementation is paid for once, by whoever maintains it.

## Phase 1: Depth is the metric

- A **deep module**: powerful functionality, a small number of simple things a caller needs to know to use it. A well-designed file system API, or a well-designed HTTP client with a handful of methods that hide connection pooling, retries, and serialization.
- A **shallow module**: an interface about as complicated as what it does. A class with one method that thinly wraps a single library call adds a name to learn without hiding any real complexity; the caller might as well have called the library directly.
- When deciding whether to add a class, function, or layer, ask what it hides. If the honest answer is "not much," it's shallow, and shallow modules accumulate into a system where understanding any one part requires understanding many parts at once; the opposite of what modules are for.

## Phase 2: Information hiding, and its failure mode

- **Information hiding**: a design decision (a data format, an algorithm, an internal data structure) lives inside one module and is invisible to its callers: they depend on the module's behavior, not its internals.
- **Information leakage**: the same piece of knowledge is needed in two or more places to make a change. If changing one internal detail forces edits in a second, ostensibly unrelated module, that detail leaked across the boundary: the two modules are more coupled than their interfaces admit.
- A common leak source is **temporal decomposition**: splitting a module by the *order operations happen in* rather than by the *knowledge each part owns* (a `Parse` class, a `Validate` class, a `Save` class, each half-empty and only sensible read together in sequence); this scatters one coherent piece of domain knowledge across several classes that all have to change together.

## Phase 3: Concrete red flags

Name the smell rather than a vague "this feels off" (same discipline as `code-review`'s Fowler-smell naming):

- **Pass-through method**: a method that does nothing but call another method with the same arguments. It adds interface surface without adding depth; usually a sign the layering itself is unnecessary or misplaced.
- **Conjoined methods/classes**: two pieces that can't be understood independently, because a change to one routinely requires a matching change to the other. Either merge them (they're really one module pretending to be two) or find the actual missing abstraction that would let them vary independently.
- **Generic-sounding names hiding a special-purpose module**: a class called `Manager`, `Helper`, or `Processor` with no further specificity is a sign the module's actual responsibility was never named, which usually means it was never really decided either.
- **Repeated pattern with no shared home**: the same few lines copy-pasted at every call site is knowledge that should be hidden inside one deep module instead of known by every caller.

## Phase 4: Design it twice

For a genuinely new interface or module boundary, sketch **at least two substantially different designs** before committing to one, not two trivial variations of the same idea. Comparing two real alternatives surfaces trade-offs neither would reveal alone, and the second design is often clearly better once the first exists as a point of contrast. Skipping straight to the first idea that comes to mind is how a project ends up living with the first idea's weaknesses indefinitely.

## Phase 5: Where the seam goes

The module boundary chosen here **is** the seam `tdd` tests against; a seam placed at a genuinely deep interface stays stable as implementation changes, which is exactly what makes tests at that seam survive refactors. A seam placed at a shallow, leaky boundary forces tests (and every caller) to know internal details, and both the tests and the callers break together whenever the internals shift. If a `tdd` cycle keeps needing to update tests for reasons that aren't behavior changes, that's this phase's red flag showing up from the testing side; revisit where the seam actually sits.

## Done when

- [ ] Every new module's interface is simpler, in absolute terms, than what it hides, not proportionally simpler, actually simple enough to hold in your head.
- [ ] No single piece of domain knowledge requires touching two or more modules to change.
- [ ] None of Phase 3's red flags describe the design as shipped.
- [ ] A genuinely new module boundary was compared against at least one real alternative before being committed to.
- [ ] Generated prose uses commas, colons, periods, or reworded sentences instead of em dashes.
Files in this package (2)
  • SKILL.md 6 KB
  • agents/openai.yaml 1 KB

Versions

RepositoryScoreLicence
This page · aethrox/doctrine90MIT
mikeleg/skills100MIT
VincenzoImp/pitcrew100MIT
kriscard/kriscard-claude-plugins100MIT
akillness/jeo-skills100MIT
JamalLyons/Agent-Skills100MIT
zenobi-us/dotfiles100MIT
FrancoStino/opencode-skills-collection100MIT
yassimba/loom100Apache-2.0

Database snapshot: 13.11.2026 · package version 9627004184fb (SHA-256 digest of the entire package)

Downloads in the last 30 days: 0 · ranking

Report a problem with this skill: harmful content, incorrect descriptions or an author’s removal request.

Similar skills

  • 95software-design-philosophy
    Software design philosophy guide based on John Ousterhout's "A Philosophy of Software Design." Use this skill during: code reviews, architecture discussions, API design, module decomposition decisions, refactoring guidance, complexity analysis, naming and commenting…
  • 100software-design-philosophy
    Manage software complexity through deep modules, information hiding, and strategic programming. Use when the user mentions "module design", "API too complex", "shallow class", "complexity budget", "strategic vs tactical", "deep module", "information leakage", "pass-through…
  • 100improve-codebase-architecture
    Explore a codebase to find opportunities for architectural improvement by deepening shallow modules (John Ousterhout, "A Philosophy of Software Design"). Use when the user says "improve architecture", "find refactoring opportunities", "make this more testable", "this codebase is…
  • 100software-design-complexity
    Manage software complexity through deep modules, information hiding, and strategic programming. Use when the user mentions "module design", "API too complex", "shallow class", "complexity budget", or "strategic vs tactical". Covers deep vs shallow modules, red flags for…
  • 100design-it-twice
    Generate multiple radically different interface designs for a module using parallel sub-agents, then compare and synthesize. Based on Ousterhout's "Design It Twice" principle. Use when the user wants to explore interface options, design an API, compare module shapes, or says…
  • 90software-design
    Design judgment for modules, interfaces, and where information lives. Use when designing or restructuring a module or interface, deciding where an abstraction goes, evaluating a decomposition, placing rationale in comments or scoped docs, or comparing alternative designs for a larger change.

Feedback and reports

Your message goes to Bartosz Sokoliński. An email address is needed only for a reply. See the privacy policy.