agentleFS
etretr/groundwork/skills/design-it-twice/SKILL.md

design-it-twice

Skill45 starsChanged 4 days agoMITView on GitHub

Use before committing to a non-trivial module, service boundary, or public API - generate 2-3 divergent interface designs, compare them on depth/locality/seam, and recommend one

3 other projects use a version of this.

Adopted by

Most recently taken up by

The file

We split this skill into the rules it gives an agent

2 rules. 0 are common, 2 are distinctive, and 0 are very specific to this project.

  • 0

    Common

    Most of the 3 edited versions we read keep these.

  • 2

    Distinctive

    This author's own choices. Worth a look.

  • 0

    Very specific

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

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    Before generating alternatives, write down the constraints, dependencies, the dominant use case, and a rough code sketch of the interface.

    line 29
  2. Distinctive:

    If proceeding with a new interface:

    line 80

“Common” is measured: kept by at least 6 in 10 of the 3 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

Design It Twice

Overview

Your first interface is rarely your best (Design it twice, Ousterhout). Before you commit a module boundary, generate genuinely different designs and compare them — the cost of exploring on paper is trivial next to the cost of a shallow interface that Hyrum's Law then freezes into a contract.

Core principle: Aim for deep modules — a simple interface hiding substantial functionality. A design that merely forwards calls is shallow and usually a liability.

This is a build-time and architecture-time discipline. [[design-architecture]] and [[swarm-design-architecture]] invoke it for module boundaries; invoke it directly any time you're about to design a single non-trivial interface.

When to Use

  • A new module, service boundary, or public API
  • A refactor that reshapes an existing interface many callers depend on
  • Any seam where a future change is likely to land and you want it to land in one place

Skip for trivial or single-call-site code, or interfaces fully dictated by an existing contract.

Process

1. Frame the problem space

Before generating alternatives, write down the constraints, dependencies, the dominant use case, and a rough code sketch of the interface. Use the project's domain language (see [[domain-modeling]]). Vague framing yields vague designs.

Check the premise: What assumption makes this interface necessary? Could doing nothing, reusing an existing interface, or changing the boundary solve the underlying problem? Challenge inferred assumptions while keeping explicit user requirements fixed unless the user changes them. If no new interface is needed, recommend that and stop.

2. Generate 2–3 divergent designs

Each design optimizes one distinct goal — they must genuinely differ, not be three shades of the same idea:

LensOptimizes for
Minimize entry pointsFewest interfaces, maximum leverage per surface — a deep module
Maximize flexibilityReuse across the widest set of use cases
Optimize the common caseSimplest path for the dominant workflow
Isolate seamsCross-boundary dependencies behind ports & adapters

Orchestration: if the Agent/Task tool is available, fan out one agent per design in parallel, each with the same framing and a different lens. No agent teams or debate are needed — the designs are independent. If agents are unavailable, produce the designs sequentially yourself. Each brief returns the interface sketch plus its trade-offs.

3. Compare on three axes

  • Depth — functionality hidden behind the interface vs. surface exposed. Favor depth; mind Hyrum's Law on every exposed behavior.
  • Locality — where a likely future change concentrates (one module vs. scattered across callers).
  • Seam placement — whether boundaries fall where the system actually flexes.

4. Recommend, don't enumerate

Give an opinionated recommendation — which design solves the problem best and why — possibly a hybrid that grafts the best of two. A neutral menu pushes the judgment onto the reader and defeats the exercise.

Preserve the strongest unresolved objection, if any, and state what evidence would change the recommendation. Base confidence on evidence, not agreement among agents; if no substantive objection remains, say so without inventing one.

Named principles referenced here are defined in ${CLAUDE_PLUGIN_ROOT}/references/engineering-principles.md.

Rationalizations

ExcuseReality
"My first design is obviously right"That feeling is exactly when a second design most often beats it. Cost of checking is one sketch.
"Three designs is slower"Slower than reworking a shallow interface every caller already depends on? No.
"They'd all come out the same"Then your lenses aren't divergent. Force distinct optimization goals.
"I'll just present the options and let them pick"A menu without a recommendation is unfinished work. Take a position.

Red Flags

  • The alternatives differ only cosmetically (same interface, renamed)
  • A "design" that forwards calls with no functionality hidden (shallow module)
  • Comparing on taste rather than depth / locality / seam
  • Ending with "any of these could work" instead of a recommendation

Verification

  • Premise checked against simpler alternatives within explicit user requirements; stopped if no new interface is needed

If proceeding with a new interface:

  • Problem space framed: constraints, dominant use case, interface sketch
  • 2–3 designs, each optimizing a genuinely distinct goal
  • Compared explicitly on depth, locality, and seam placement
  • A single opinionated recommendation (or justified hybrid), with reasoning
  • Strongest unresolved objection preserved (or none identified), with evidence that would change the recommendation

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.