api-and-interface-design
Design a stable API or module contract before implementation. Use for interface decisions; not diff review or a system-wide architecture audit.
SKILL.mdagent-plugins/skills/api-and-interface-design/SKILL.md
GitHubAPI and Interface Design
Design an interface consumers can use, validate, and evolve. Adapted from Addy Osmani's api-and-interface-design workflow; see the bundled license and repository third-party notice.
Route precisely
- Use for a new or changing public API, protocol, event, module interface, or cross-component contract before implementation.
- Use
write-specfor full feature requirements,review-specto evaluate an existing design document,review-archfor the whole system's boundaries,vet-dependencyfor library adoption, andcode-reviewfor a changed implementation. - Do not impose REST or TypeScript conventions on a different transport or language.
Fix the consumer contract
- Read repository instructions, existing versioned contracts, callers, serializers, tests, and deployment constraints. Name the consumers and what they need to accomplish.
- Define inputs, outputs, types or schema, errors, side effects, ordering, defaults, and lifecycle. Separate transport validation from trusted internal invariants. Treat external responses as untrusted data.
- For a changed interface, inventory observable old behavior and compatibility obligations. Prefer additive evolution when consumers may be deployed independently; document intentional breaks and migration requirements.
- Address pagination, partial updates, idempotency, duplicate in-flight requests, timeouts, retries, and authorization only when the operation needs them. Specify the outcome of each relevant edge case rather than importing a generic pattern.
- Compare at least one simpler contract that meets the same requirements. Identify naming or versioning choices that create ambiguity for consumers.
Compare alternative interfaces when the decision warrants it
For a consequential or explicitly requested interface exploration, compare materially different shapes before implementing. Keep the ordinary one-contract path for routine changes.
- Fix the same consumer scenarios, invariants, compatibility obligations, and dependency constraints for all alternatives.
- Sketch a minimal surface, a shape optimized for the common caller, and a more flexible shape only when flexibility serves a real requirement. Show a normal call and a failure call for each; name what complexity the module hides from callers.
- Compare ease of correct use, misuse, lifecycle ownership, testability through the interface, change locality, implementation cost, and compatibility. More methods or fewer lines alone do not determine quality. A thin adapter can still earn its place at a real integration boundary.
- Recommend one shape or a justified combination and state the deciding scenario. Do not implement an exploration-only request.
Use independent design passes only when requested or authorized by the applicable workflow. Parallel agents are optional; respect the project budget and do not require three or more agents for every contract decision. Keep project terminology rather than imposing a new glossary.
This comparison guidance adapts Matt Pocock's Design It Twice, under the bundled LICENSE.mattpocock-skills.
Go contracts, when applicable
For Go APIs, check the supported toolchain and actual consumers before choosing interfaces or generics. Define interfaces around a consumer's required capabilities when that keeps the contract smaller; avoid an interface or generic abstraction that adds no required variation. Check typed-nil/error semantics and resource ownership at the boundary. Adding a method to an exported interface can break downstream implementations even when your own code still builds; separate that compatibility obligation from a local refactor.
These Go-specific considerations adapt spf13's Go API guidance, under the bundled LICENSE.spf13-go-skills; they do not prescribe a universal package layout.
Make it testable
Give representative valid, invalid, and failure examples. Identify contract tests or probes at the actual boundary, including serialization and compatibility when relevant. Verify claims against the installed framework or protocol version and local implementation pattern. Return the proposed contract, consumer assumptions, alternatives, acceptance evidence, and unresolved decisions. Do not claim runtime compatibility from type checking alone.