From dotlight-skillset
Use before committing to the public surface of a module, library, Minimal API endpoint group, or aggregate root — especially when the first design "feels obvious" or when the type is hard to change later. Generates 3+ radically different designs in parallel, then compares them on simplicity, depth, and ease of correct use.
How this skill is triggered — by the user, by Claude, or both
Slash command
/dotlight-skillset:design-an-interfaceThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Based on **"Design It Twice"** from John Ousterhout's *A Philosophy of Software Design*: your first idea is unlikely to be the best. Generate several radically different designs, then compare. The cost of designing a second time is small. The cost of shipping the wrong shape is large — especially for public surfaces (NuGet packages, persisted contracts, Minimal API routes) where breaking change...
Based on "Design It Twice" from John Ousterhout's A Philosophy of Software Design: your first idea is unlikely to be the best. Generate several radically different designs, then compare. The cost of designing a second time is small. The cost of shipping the wrong shape is large — especially for public surfaces (NuGet packages, persisted contracts, Minimal API routes) where breaking changes are expensive.
Announce at start: "I'm using the design-an-interface skill. I'll gather requirements, then dispatch parallel agents to generate 3–4 radically different designs."
Use when designing a surface that is hard to change later or load-bearing for many callers:
api-design extend-only rules apply downstream).IServiceCollection extension method's options surface.Don't use this for internal helpers, private methods, or single-caller utilities — the cost of three parallel designs outweighs the benefit. Use it when getting the shape right matters more than getting it fast.
Before designing, pin down:
Use AskUserQuestion for choice-shaped requirement decisions (e.g., "Is this exposed over HTTP, in-process, or both?"). For genuinely open requirements, free text.
Dispatch 3–4 agents simultaneously using dispatching-parallel-agents. Each must produce a radically different shape. If two come back similar, dispatch a replacement with a sharper differentiator.
Assign each agent a distinct shaping constraint. Pick from this menu (or invent equivalents) — the goal is radical divergence:
record. No mutation. No internal state."IAsyncEnumerable<T> or ChannelReader<T>."Each agent's prompt should ask for exactly this output:
Design an interface for: <module description>
Requirements: <copy from step 1>
Constraint for THIS design: <one of the options above>
Return:
1. Type signatures — interface, class, record, method shapes (C# syntax).
2. Usage example — 5–15 lines of caller code showing the common case.
3. What this design hides internally — the depth.
4. Trade-offs — what does this shape make easy? What does it make hard?
5. .NET-specific notes — sealed/record/struct choice, allocation, async shape, AOT-compat.
Do NOT implement. Do NOT discuss alternatives. Commit to this one shape.
Keep agent context isolated — they should not see each other's designs. Divergence comes from the constraint, not from negotiation.
Show each design to the user sequentially, not as a side-by-side table. Reading order: simplest first, most flexible last. For each:
Wait for the user to read each before moving to the next. After the last design, move to comparison.
Discuss in prose, not a table. Highlight where designs diverge most — that's where the real decision lives. Evaluate each on:
csharp-api-design for extend-only rules.Cross-reference relevant pattern skills when the comparison touches them:
type-design-performance.dependency-injection-patterns.microsoft-extensions-configuration.api-design.csharp-concurrency-patterns.The best design is often a hybrid. After comparison, ask:
grill-me.)Land on a single chosen shape. Write its signatures and one usage example into the brainstorming spec or directly into the plan's ## Domain Model / ## Public Surface section. Don't leave the choice in chat.
From A Philosophy of Software Design:
"Modules should be deep. The best modules provide powerful functionality through a simple interface. A small interface that hides significant complexity is the ideal."
Concretely, in C#/.NET terms:
IMediator.Send(request) hiding pipeline, retry, validation, dispatch.Prefer deep. Reject shallow.
executing-plans / test-driven-development.Adapted from mattpocock/skills/design-an-interface (MIT, © 2026 Matt Pocock). Modifications: C#/.NET shaping constraints, integration with dispatching-parallel-agents, cross-references to api-design / type-design-performance / dependency-injection-patterns / csharp-concurrency-patterns, handoff to grill-me.
npx claudepluginhub mudramartin/dotlight-skillset --plugin dotlight-skillsetGuides creation, editing, and verification of skills for AI coding agents using test-driven development with subagent scenarios. Use when authoring or debugging skills.