Claude Skill

codebase-design

Imported from paulrberg/agent-skills/skills/codebase-design.

LLM Mart · 0 points · 0 views 0 listing impressions 0 install-command copies
Virus-scanned Reviewed automatically before listing.

Full trust report

Download paulrberg-agent-skills-skills_codebase-design-913232a.zip · 5 KB
Part of paulrberg/agent-skills — 42 skills

Install

skills CLI npx skills add https://github.com/PaulRBerg/agent-skills/tree/main/skills/codebase-design
Claude Code claude plugin marketplace add https://llmmart.ai/marketplace.json && claude plugin install paulrberg-agent-skills@llmmart
Git git clone https://github.com/PaulRBerg/agent-skills.git

The skills CLI installs just this skill, for any of its supported agents. Claude Code installs the whole paulrberg/agent-skills collection as a plugin from our marketplace. Git is the plain clone.

Skill manifest

Codebase Design

Design deep modules: substantial behaviour behind a small interface at a clean seam, testable through that interface. Use this vocabulary when it clarifies a design decision. The aim is leverage for callers, locality for maintainers, and testability.

Glossary

Use these terms consistently where their distinctions matter.

Module — anything with an interface and an implementation. Deliberately scale-agnostic: a function, class, package, or tier-spanning slice. Avoid: unit, component, service.

Interface — everything a caller must know to use the module correctly: the type signature, but also invariants, ordering constraints, error modes, required configuration, and performance characteristics. Avoid: API, signature (too narrow — they refer only to the type-level surface).

Implementation — what's inside a module, its body of code. Distinct from Adapter: a thing can be a small adapter with a large implementation (a Postgres repo) or a large adapter with a small implementation (an in-memory fake). Reach for "adapter" when the seam is the topic; "implementation" otherwise.

Depth — leverage at the interface: the amount of behaviour a caller (or test) can exercise per unit of interface they have to learn. A module is deep when a large amount of behaviour sits behind a small interface, shallow when the interface is nearly as complex as the implementation.

Seam (Michael Feathers) — a place where you can alter behaviour without editing in that place; the location at which a module's interface lives. Where to put the seam is its own design decision, distinct from what goes behind it. Avoid: boundary (overloaded with DDD's bounded context).

Adapter — a concrete thing that satisfies an interface at a seam. Describes role (what slot it fills), not substance (what's inside).

Leverage — what callers get from depth: more capability per unit of interface they learn. One implementation pays back across N call sites and M tests.

Locality — what maintainers get from depth: change, bugs, knowledge, and verification concentrate in one place rather than spreading across callers. Fix once, fixed everywhere.

Deep vs shallow

Deep module — small interface (few methods, simple params) hiding a lot of implementation.

Shallow module (avoid) — interface nearly as large as its thin, pass-through implementation.

When designing an interface, ask:

  • Can I reduce the number of methods?
  • Can I simplify the parameters?
  • Can I hide more complexity inside?

Principles

  • Depth is a property of the interface, not the implementation. A deep module can be internally composed of small, mockable, swappable parts — they just aren't part of the interface. A module can have internal seams (private to its implementation, used by its own tests) as well as the external seam at its interface.
  • The deletion test. Imagine deleting the module. If complexity vanishes, it was a pass-through. If complexity reappears across N callers, it was earning its keep.
  • The interface is the test surface. Callers and tests cross the same seam. If you want to test past the interface, the module is probably the wrong shape.
  • One adapter means a hypothetical seam. Two adapters means a real one. Don't introduce a seam unless something actually varies across it.

Designing for testability

Good interfaces make testing natural:

  • At a real seam, accept the dependency as a parameter instead of constructing it inside the module.
  • Prefer returning results to side effects when that keeps the interface simpler.
  • Keep the surface small: fewer methods and parameters mean fewer, simpler tests.

Relationships

  • A Module has exactly one Interface (the surface it presents to callers and tests).
  • Depth is a property of a Module, measured against its Interface.
  • A Seam is where a Module's Interface lives.
  • An Adapter sits at a Seam and satisfies the Interface.
  • Depth produces Leverage for callers and Locality for maintainers.

Rejected framings

  • Depth as ratio of implementation-lines to interface-lines (Ousterhout): rewards padding the implementation. We use depth-as-leverage instead.
  • "Interface" as the TypeScript interface keyword or a class's public methods: too narrow — interface here includes every fact a caller must know.
  • "Boundary": overloaded with DDD's bounded context. Say seam or interface.

Output Contract

When applying this vocabulary to a design or review, report the recommended module, interface, and seam; explain how the result improves depth, leverage, locality, or testability; and identify material tradeoffs or unresolved evidence. When this skill is only supporting another requested artifact, incorporate that analysis into the artifact instead of adding a separate report.

Going deeper

  • Deepening a cluster given its dependencies — see references/DEEPENING.md: dependency categories, seam discipline, and replace-don't-layer testing.
  • Exploring alternative interfaces — see references/DESIGN-IT-TWICE.md: spin up parallel sub-agents to design the interface several radically different ways, then compare on depth, locality, and seam placement.

Forked from mattpocock/skills.

Files (agent-skills)
  • agents
    • openai.yaml 144 B
      interface:
        display_name: "Codebase Design"
        short_description: "Vocabulary for deep-module design"
      policy:
        allow_implicit_invocation: true
      
  • references
    • DEEPENING.md 2.9 KB
      # Deepening
      
      How to deepen a cluster of shallow modules safely, given its dependencies. Assumes the vocabulary in
      [SKILL.md](../SKILL.md) — **module**, **interface**, **seam**, **adapter**.
      
      ## Dependency categories
      
      When assessing a candidate for deepening, classify its dependencies. The category determines how the deepened module is
      tested across its seam.
      
      ### 1. In-process
      
      Pure computation, in-memory state, no I/O. A strong deepening candidate when merging reduces total complexity; test
      through the new interface directly. No adapter is needed.
      
      ### 2. Local-substitutable
      
      Dependencies that have local test stand-ins (PGLite for Postgres, in-memory filesystem). Deepenable if the stand-in
      exists. The deepened module is tested with the stand-in running in the test suite. The seam is internal; no port at the
      module's external interface.
      
      ### 3. Remote but owned (Ports & Adapters)
      
      Your own services across a network boundary (microservices, internal APIs). Define a **port** (interface) at the seam.
      The deep module owns the logic; the transport is injected as an **adapter**. Tests use an in-memory adapter. Production
      uses an HTTP/gRPC/queue adapter.
      
      Recommendation shape: _"Define a port at the seam, implement an HTTP adapter for production and an in-memory adapter for
      testing, so the logic sits in one deep module even though it's deployed across a network."_
      
      ### 4. True external (Mock)
      
      Third-party services (Stripe, Twilio, etc.) you don't control. The deepened module takes the external dependency as an
      injected port; tests provide a mock adapter.
      
      ## Seam discipline
      
      - Don't introduce a port unless at least two adapters are justified (typically production + test). A single-adapter seam
        is just indirection.
      - Don't expose internal seams through the interface just because tests use them.
      
      ## Testing strategy: replace, don't layer
      
      - Old unit tests on shallow modules become waste once tests at the deepened module's interface exist — delete them.
      - Write new tests at the deepened module's interface. The **interface is the test surface**.
      - Tests assert on observable outcomes through the interface, not internal state.
      - Tests should survive internal refactors — they describe behaviour, not implementation. If a test has to change when
        the implementation changes, it's testing past the interface.
      
      ## Finding deepening candidates
      
      - Weight recently changed hot spots first: walk `git log --oneline` for recurring files and areas. Deepening pays off
        where change concentrates.
      - Look for friction signals:
        - Understanding one concept requires bouncing between many small modules.
        - Interfaces are nearly as complex as their implementations.
        - Pure functions were extracted for testability while the real bugs hide in how they are called; locality is missing.
        - Code is untestable through its current interface.
      - Apply the deletion test to each suspect: "Would deleting it concentrate complexity, or just move it?" Treat
        "concentrates" as the signal to deepen.
      
    • DESIGN-IT-TWICE.md 2.7 KB
      # Design It Twice
      
      When the user wants to explore alternative interfaces for a chosen deepening candidate, use this parallel sub-agent
      pattern. Based on "Design It Twice" (Ousterhout) — your first idea is unlikely to be the best.
      
      Uses the vocabulary in [SKILL.md](../SKILL.md) — **module**, **interface**, **seam**, **adapter**, **leverage**.
      
      ## Process
      
      ### 1. Frame the problem space
      
      Before spawning sub-agents, write a user-facing explanation of the problem space for the chosen candidate:
      
      - The constraints any new interface would need to satisfy
      - The dependencies it would rely on, and which category they fall into (see [DEEPENING.md](DEEPENING.md))
      - A rough illustrative code sketch to ground the constraints — not a proposal, just a way to make the constraints
        concrete
      
      Show this to the user, then immediately proceed to Step 2. The user reads and thinks while the sub-agents work in
      parallel.
      
      ### 2. Spawn sub-agents
      
      Spawn 3+ sub-agents in parallel. Each must produce a **radically different** interface for the deepened module.
      
      Prompt each sub-agent with a separate technical brief (file paths, coupling details, dependency category from
      [DEEPENING.md](DEEPENING.md), what sits behind the seam). The brief is independent of the user-facing problem-space
      explanation in Step 1. Give each agent a different design constraint:
      
      - Agent 1: "Minimize the interface — aim for 1–3 entry points max. Maximise leverage per entry point."
      - Agent 2: "Maximise flexibility — support many use cases and extension."
      - Agent 3: "Optimise for the most common caller — make the default case trivial."
      - Agent 4 (if applicable): "Design around ports & adapters for cross-seam dependencies."
      
      Include both [SKILL.md](../SKILL.md) vocabulary and the target project's own domain vocabulary — from its `AGENTS.md`,
      glossary, or docs — so each sub-agent names things consistently with the architecture language and the project's domain
      language.
      
      Each sub-agent outputs:
      
      1. Interface (types, methods, params — plus invariants, ordering, error modes)
      2. Usage example showing how callers use it
      3. What the implementation hides behind the seam
      4. Dependency strategy and adapters (see [DEEPENING.md](DEEPENING.md))
      5. Trade-offs — where leverage is high, where it's thin
      
      ### 3. Present and compare
      
      Present designs sequentially so the user can absorb each one, then compare them in prose. Contrast by **depth**
      (leverage at the interface), **locality** (where change concentrates), and **seam placement**.
      
      After comparing, give your own recommendation: which design you think is strongest and why. If elements from different
      designs would combine well, propose a hybrid. Be opinionated — the user wants a strong read, not a menu.
      
  • SKILL.md 5.7 KB
    ---
    name: codebase-design
    description:
      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
    
    Design **deep modules**: substantial behaviour behind a small interface at a clean seam, testable through that
    interface. Use this vocabulary when it clarifies a design decision. The aim is leverage for callers, locality for
    maintainers, and testability.
    
    ## Glossary
    
    Use these terms consistently where their distinctions matter.
    
    **Module** — anything with an interface and an implementation. Deliberately scale-agnostic: a function, class, package,
    or tier-spanning slice. _Avoid_: unit, component, service.
    
    **Interface** — everything a caller must know to use the module correctly: the type signature, but also invariants,
    ordering constraints, error modes, required configuration, and performance characteristics. _Avoid_: API, signature (too
    narrow — they refer only to the type-level surface).
    
    **Implementation** — what's inside a module, its body of code. Distinct from **Adapter**: a thing can be a small adapter
    with a large implementation (a Postgres repo) or a large adapter with a small implementation (an in-memory fake). Reach
    for "adapter" when the seam is the topic; "implementation" otherwise.
    
    **Depth** — leverage at the interface: the amount of behaviour a caller (or test) can exercise per unit of interface
    they have to learn. A module is **deep** when a large amount of behaviour sits behind a small interface, **shallow**
    when the interface is nearly as complex as the implementation.
    
    **Seam** _(Michael Feathers)_ — a place where you can alter behaviour without editing in that place; the _location_ at
    which a module's interface lives. Where to put the seam is its own design decision, distinct from what goes behind it.
    _Avoid_: boundary (overloaded with DDD's bounded context).
    
    **Adapter** — a concrete thing that satisfies an interface at a seam. Describes _role_ (what slot it fills), not
    substance (what's inside).
    
    **Leverage** — what callers get from depth: more capability per unit of interface they learn. One implementation pays
    back across N call sites and M tests.
    
    **Locality** — what maintainers get from depth: change, bugs, knowledge, and verification concentrate in one place
    rather than spreading across callers. Fix once, fixed everywhere.
    
    ## Deep vs shallow
    
    **Deep module** — small interface (few methods, simple params) hiding a lot of implementation.
    
    **Shallow module** (avoid) — interface nearly as large as its thin, pass-through implementation.
    
    When designing an interface, ask:
    
    - Can I reduce the number of methods?
    - Can I simplify the parameters?
    - Can I hide more complexity inside?
    
    ## Principles
    
    - **Depth is a property of the interface, not the implementation.** A deep module can be internally composed of small,
      mockable, swappable parts — they just aren't part of the interface. A module can have **internal seams** (private to
      its implementation, used by its own tests) as well as the **external seam** at its interface.
    - **The deletion test.** Imagine deleting the module. If complexity vanishes, it was a pass-through. If complexity
      reappears across N callers, it was earning its keep.
    - **The interface is the test surface.** Callers and tests cross the same seam. If you want to test _past_ the
      interface, the module is probably the wrong shape.
    - **One adapter means a hypothetical seam. Two adapters means a real one.** Don't introduce a seam unless something
      actually varies across it.
    
    ## Designing for testability
    
    Good interfaces make testing natural:
    
    - At a real seam, accept the dependency as a parameter instead of constructing it inside the module.
    - Prefer returning results to side effects when that keeps the interface simpler.
    - Keep the surface small: fewer methods and parameters mean fewer, simpler tests.
    
    ## Relationships
    
    - A **Module** has exactly one **Interface** (the surface it presents to callers and tests).
    - **Depth** is a property of a **Module**, measured against its **Interface**.
    - A **Seam** is where a **Module**'s **Interface** lives.
    - An **Adapter** sits at a **Seam** and satisfies the **Interface**.
    - **Depth** produces **Leverage** for callers and **Locality** for maintainers.
    
    ## Rejected framings
    
    - **Depth as ratio of implementation-lines to interface-lines** (Ousterhout): rewards padding the implementation. We use
      depth-as-leverage instead.
    - **"Interface" as the TypeScript `interface` keyword or a class's public methods**: too narrow — interface here
      includes every fact a caller must know.
    - **"Boundary"**: overloaded with DDD's bounded context. Say **seam** or **interface**.
    
    ## Output Contract
    
    When applying this vocabulary to a design or review, report the recommended module, interface, and seam; explain how the
    result improves depth, leverage, locality, or testability; and identify material tradeoffs or unresolved evidence. When
    this skill is only supporting another requested artifact, incorporate that analysis into the artifact instead of adding
    a separate report.
    
    ## Going deeper
    
    - **Deepening a cluster given its dependencies** — see [references/DEEPENING.md](references/DEEPENING.md): dependency
      categories, seam discipline, and replace-don't-layer testing.
    - **Exploring alternative interfaces** — see [references/DESIGN-IT-TWICE.md](references/DESIGN-IT-TWICE.md): spin up
      parallel sub-agents to design the interface several radically different ways, then compare on depth, locality, and
      seam placement.
    
    Forked from [mattpocock/skills](https://github.com/mattpocock/skills/tree/main/skills/engineering/codebase-design).
    

Comments (0)

Sign in to join the conversation.

No comments yet.

Reviews (0)

No reviews yet.

Related