CtrlK
BlogDocsLog inGet started
Tessl Logo

design-an-interface

Produce 3+ radically different designs for a module, API, or interface, compare them in prose, and synthesize a recommendation. Use when asked to "design an interface", "shape this API", "design it twice", "explore module boundaries", or when planning a new deep module and the first idea is unlikely to be the best. Based on "Design It Twice" from A Philosophy of Software Design — the value is the contrast, not the first draft.

80

Quality

100%

Does it follow best practices?

Run evals on this skill

Adds up to 20 points to the overall score

View guide

SecuritybySnyk

Passed

No findings from the security scan

SKILL.md
Quality
Evals
Security
Generate at least three radically different interface designs for a single module or API, present them sequentially, compare them honestly, and recommend one (or a hybrid). The goal is to surface the design space — not to pick fast. A small interface hiding significant complexity is a deep module; a large interface with thin implementation is a shallow one. Optimize for the former. This skill runs during planning — before `S##-PLAN.md` task decomposition, or mid-slice when a seam turns out to be more load-bearing than the roadmap assumed. It is not for picking between two libraries. It is for shaping the interface your own code will expose.

Typical invocation points:

  • A slice plan says "add module X" and the shape of X is not obvious.
  • Two callers are about to grow coupled to an interface that has not been designed on purpose.
  • A refactor surfaces a seam that needs to be re-cut deliberately.

<core_principle> RADICALLY DIFFERENT, NOT VARIANTS. Three designs with different method names are one design. Three designs that hide different things, expose different axes of control, or invert the caller/callee relationship are three designs. Enforce real divergence by assigning each sub-agent a constraint that would force a different shape.

INTERFACE, NOT IMPLEMENTATION. Do not estimate effort. Do not argue about how hard it is to build. Argue about how the interface behaves from the caller's side and what it hides internally. </core_principle>

Step 1: Gather requirements

Before spawning anything, answer in the conversation:

  • What problem does the module solve?
  • Who calls it? (other modules, external users, tests)
  • What are the key operations?
  • What constraints exist? (performance, compatibility, existing patterns)
  • What should stay hidden inside vs be exposed?

If the user did not supply all of these, ask — one round, 1–3 questions max, per the ask-vs-infer rule.

Step 2: Spawn parallel design agents

Use Agent(subagent_type=general-purpose) for 3–4 agents in one message so they run concurrently. Each agent gets the same requirements brief plus one divergent constraint:

  • Agent 1: "Minimize method count — 1 to 3 entry points max."
  • Agent 2: "Maximize flexibility — support many extension points and composition."
  • Agent 3: "Optimize for the single most common caller — make the default case trivial and the advanced case possible."
  • Agent 4 (optional): "Design around a ports-and-adapters boundary — interface is the port, concrete implementations are adapters."

Each agent returns:

  1. Interface signature (types, methods, params)
  2. One worked usage example showing a real caller
  3. What complexity this design keeps internal
  4. Trade-offs — what it's bad at

Step 3: Present sequentially

Show the three designs one after another. Let the user read each before the next. Do not lead with the comparison — the value is in feeling the shape of each option first.

Step 4: Compare in prose

After all three are on the page, compare them on:

  • Simplicity — fewer methods and simpler params are easier to learn and harder to misuse
  • Depth — small interface hiding significant complexity (good) vs large interface with thin implementation (bad)
  • Generality vs specialization — does it cover the real use case without overfitting?
  • Efficiency of the shape — does the interface let the implementation be efficient, or force awkward internals?
  • Misuse surface — what can a caller do wrong?

Prose, not a table. Highlight where the designs diverge most sharply — that is where the interesting trade-off lives.

Step 5: Recommend

Be opinionated. Pick one, or propose a hybrid that takes specific elements from multiple designs. State the reason in one paragraph. The user wants a strong read, not a menu.

Step 6: Capture the decision

Once the user picks:

  • Append to .gsd/DECISIONS.md with the chosen shape and the reason.
  • If a slice is active, update S##-CONTEXT.md with the interface sketch.
  • Do not write the implementation — that happens during execute.

<anti_patterns>

  • Three-variants-of-the-same-idea: all three use a builder, all three return the same object, etc. Kill and re-spawn.
  • Implementation creep: proposing file paths, call graphs, or internal data structures. Keep it at interface shape.
  • Skipping comparison: presenting three designs and asking "which do you like?" The comparison is the whole skill.
  • Effort-based ranking: "#2 is easiest to build" is not an interface argument. Rank by what the caller experiences.

</anti_patterns>

<success_criteria>

  • 3+ genuinely different interface shapes were produced.
  • Each design shows a real usage example, not a type signature in isolation.
  • Trade-offs are named per design.
  • A specific recommendation (or hybrid) is on the page with a reason.
  • The decision is captured in .gsd/DECISIONS.md or the active S##-CONTEXT.md.

</success_criteria>

Repository
gsd-build/gsd-2
Last updated
First committed

Is this your skill?

If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.