agentleFS
mik2winmik2win/foureyes/skills/codebase-design/SKILL.md

codebase-design

Skill2 starsChanged 3 months agoMITView on GitHub

Shared vocabulary and discipline for designing deep modules — a lot of behaviour behind a small interface, placed at a clean seam, testable through that interface. The design lens the kit's planning and quality skills reach for. TRIGGER when: the user wants to design or improve a module's interface, decide where a seam goes, make code more testable or AI-navigable, weigh two designs, OR another skill (/prepare, /tdd, /refactor, /arch-health) needs the deep-module vocabulary. DO NOT TRIGGER when: the user wants to run tests, hunt for correctness bugs (use /code-review), or do a mechanical rename with no design question.

194 other projects use a version of this, 163 of them edited.

Adopted by

Most recently taken up by

Used with

Projects with it also use setup-ts-deep-modules, decision-mapping and 10 more.

Other files people use alongside this one.

Files found in the same public projects as a version of this one, more often than they turn up anywhere else. Each project counts once, large collections count for less, and this file's own repository is left out.
  • liufeng1976Skill

    setup-ts-deep-modules

    Wire dependency-cruiser into a TypeScript repo so each package is a deep module — implementation hidden in subfolders, reachable only through its entry-point files. User-invoked.

    Also in 43 projects that use this

  • FabienDehopreSkill

    decision-mapping

    Turn a loose idea into a sequenced map of investigation tickets, then drive them to resolution one at a time.

    Also in 8 projects that use this

  • RoentekSkill

    loop-me

    Grill me about specs for the workflows I want to build, within this workspace.

    Also in 55 projects that use this

  • LesaniSkill

    writing-beats

    Shape an article as a journey of beats, choose-your-own-adventure style. The user picks a starting beat from the raw material, you write only that beat, then offer options for where to pivot next, beat by beat, until the article reaches a natural end. Use when the user has raw material and wants to assemble it as a narrative rather than an argument.

    Also in 58 projects that use this

  • AWSSkill

    to-questionnaire

    Turn a decision you can't fully answer into a questionnaire for someone else to fill in.

    Also in 90 projects that use this

  • LesaniSkill

    writing-shape

    Take a markdown file of raw material and shape it into an article through a conversational session — drafting candidate openings, growing the piece paragraph by paragraph, arguing about format (lists, tables, callouts, quotes) at each step. Use when the user has a pile of notes, fragments, or a rough draft and wants help turning it into something publishable.

    Also in 58 projects that use this

  • +1 more from Lesani

The file

We split this skill into the rules it gives an agent

3 rules. 1 is common, 1 is distinctive, and 1 is very specific to this project.

  • 1

    Common

    Most of the 181 edited versions we read keep these.

  • 1

    Distinctive

    This author's own choices. Worth a look.

  • 1

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Very specific:

    Use these terms exactly — don't substitute "component," "service," "API," or "boundary." Consistent language is the whole point (and feeds …

    line 29
  2. Common:

    When designing an interface, ask:

    line 68
  3. Distinctive:

    Put the seam where behaviour must vary: Place the interface exactly at the point you'll need to swap implementations (real vs fake, prod vs …

    line 81

“Common” is measured: kept by at least 6 in 10 of the 181 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Codebase Design

Design deep modules: a lot of behaviour behind a small interface, placed at a clean seam, testable through that interface. Use this language and these principles wherever code is being designed or restructured. The aim is leverage for callers, locality for maintainers, and testability for everyone — including the agent navigating the codebase next session.

This skill is reference vocabulary, not a workflow. It carries no project facts — read .claude/PROJECT.md → Architecture for where this project's seams and layers actually live, and rules/_generic/code-quality.md for the size/naming/composition floor this builds on.

Glossary

Use these terms exactly — don't substitute "component," "service," "API," or "boundary." Consistent language is the whole point (and feeds the project's own CONTEXT.md).

  • 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 — type-level surface only).
  • Implementation — what's inside a module, its body of code.
  • Depth — leverage at the interface: how much behaviour a caller (or test) exercises per unit of interface they must learn. Deep = large behaviour behind a small interface; shallow = interface nearly as complex as the implementation.
  • Seam — a place where you can alter behaviour without editing in that place; the location where 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).
  • Adapter — a concrete thing that satisfies an interface at a seam. Names a role (what slot it fills), not substance. A small adapter can wrap a large implementation (a Postgres repo); a large adapter can wrap a small one (an in-memory fake).
  • Leverage — what callers get from depth: more capability per unit of interface learned. 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 instead of spreading across callers. Fix once, fixed everywhere.

Deep vs shallow

Deep = small interface + lots of implementation (aim for this):

┌─────────────────────┐
│   Small interface   │  ← few methods, simple params
├─────────────────────┤
│  Deep implementation│  ← complex logic hidden
└─────────────────────┘

Shallow = large interface + thin implementation (avoid): the interface is nearly as costly to learn as the code it hides, so it buys the caller almost nothing — a pass-through wrapper, a "manager" that just forwards, getters/setters with no invariant.

When designing an interface, ask:

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

Principles

  • Pull complexity downward. It's better for the implementer to suffer than every caller. A messy detail handled once inside the module beats the same detail handled at every call site.
  • Make modules somewhat general-purpose. A slightly more general interface is often simpler than a special-purpose one and serves more callers. Don't gold-plate — aim for "general enough."
  • Define errors out of existence. The best error handling is an interface where the error can't arise (an operation that's a no-op on the empty case beats one that throws on it).
  • Put the seam where behaviour must vary. Place the interface exactly at the point you'll need to swap implementations (real vs fake, prod vs test, vendor A vs B) — not one layer off. The fake/test swap alone earns it: "we will never change the provider" does not retire the seam.
  • Design it twice. The first design that works is rarely the best. See DESIGN-IT-TWICE.md.
  • Testable through the interface. A deep module is tested by exercising its interface with a fake at the seam — not by reaching into its implementation. If a test must mock internals, the seam is in the wrong place. This is why /tdd and /test lean on this vocabulary.

Finding deepening opportunities

Shallow modules, leaky interfaces, and misplaced seams are where a codebase rots into a ball of mud. DEEPENING.md lists the smells and the moves that deepen a module. /arch-health runs that hunt across a whole codebase; /refactor and /prepare apply it to the change at hand. WHEN-TO-CUT.md comes first when the move is a new seam: is it due, on which axis. SHAPE.md when the question is the form behind it: function or class, a subtype, a pattern's price.

How the kit uses this

  • /prepare — borrow this vocabulary when weighing design alternatives and checking SOLID; a "new-abstraction" approach should be justified as a deeper module, not just more files.
  • /tdd — use the depth/seam language when confirming the public interface before the first test; tests go through the seam.
  • /test — a unit that needs internals mocked has its seam in the wrong place; this vocabulary names why and where to move it so tests exercise the interface.
  • /refactor — D2 (architecture hygiene) is deepening work; name the smell from DEEPENING.md.
  • /arch-health — the whole scan is "where are the shallow modules and bad seams?".

See also

  • DESIGN-IT-TWICE.md — generate two genuinely different designs, compare, synthesize.
  • DEEPENING.md — shallow-module smells and the moves that fix them.
  • WHEN-TO-CUT.md — is a new seam due yet, along which axis, and what proves it.
  • SHAPE.md — function, class or transform; when a subtype is legal; what a pattern costs.
  • rules/_generic/code-quality.md — the size/naming/composition floor this design lens sits on.

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.