Skip to main content
ClaudeWave
Skill255 repo starsupdated 4d ago

design-an-api

>

Install in Claude Code
Copy
git clone --depth 1 https://github.com/testdouble/han /tmp/design-an-api && cp -r /tmp/design-an-api/han-coding/skills/design-an-api ~/.claude/skills/design-an-api
Then start a new Claude Code session; the skill loads automatically.

SKILL.md

## Project Context

- git installed: !`which git 2>/dev/null || echo "not installed"`
- current branch: !`git branch --show-current 2>/dev/null || echo "no git branch"`
- default branch: !`git symbolic-ref --short refs/remotes/origin/HEAD 2>/dev/null || echo unknown`
- CLAUDE.md: !`find . -maxdepth 1 -name "CLAUDE.md" -type f`
- project-discovery.md: !`find . -maxdepth 3 -name "project-discovery.md" -type f`
- personal config directory: !`bash "${CLAUDE_PLUGIN_ROOT}/scripts/han-config-dir.sh" 2>/dev/null || echo "$HOME/.claude"`
- project .han/config.md: !`cat .han/config.md 2>/dev/null || echo ""`

As your first action, use the Read tool on `.han/config.md` inside the `personal config directory` path above. A read
that returns no file is no personal configuration: continue silently. When that file or the `project .han/config.md`
probe supplies content, apply it per [config-rule.md](../../references/config-rule.md), which governs precedence
between the two files, relative-path resolution, and what to do with a file that reads but cannot be used.

## Operating Principles

Read these before dispatching anything. They constrain every step below.

- **A stated goal is required, and it is the scope governor.** This skill designs a contract in service of one named
  goal: a ticket, an issue, a written requirement, or a described capability. If no goal resolves, stop and ask for one
  BECAUSE without a goal there is nothing to justify the design against, and the run degrades into designing a
  general-purpose framework for a single consumer.
- **Every element of the contract carries a justification.** Each named parameter, field, type, default, precedence
  rule, and failure behavior states exactly one of two things: the part of the stated goal it descends from, quoted or
  named; or the asked-for behavior it is a necessity of. An element that can fill neither does not enter the design. It
  moves to the cut list with what it would have done and why it was cut.
- **Silence never cuts a necessity.** The goal is short and does not enumerate what it depends on. A goal that never
  mentions a caching layer justifies cutting one. The same goal's silence about invalid input, error behavior, and
  types does not cut those, because they are necessities of the surface it did ask for.
- **The agents own the judgment; the skill orchestrates.** The skill resolves the goal and the interface, classifies
  size, selects the roster, fans agents out and in, runs the two human gates, and renders the design document. It
  produces no design content of its own.
- **The four-agent spine always runs; specialists are signal-selected.** `han-core:codebase-explorer`,
  `han-core:software-architect`, `han-core:junior-developer`, and `han-core:adversarial-validator` run at every size
  BECAUSE evidence, design, questioning, and attack are the irreducible core of a contract that survives contact. Every
  other specialist is added only when the interface's signals warrant it and the band allows it, BECAUSE dispatching an
  agent whose domain the contract never touches burns tokens and pulls the design toward concerns the goal did not ask
  for.
- **Default to small.** Start classification at small and escalate only when a higher-band signal is clearly present.
  Borderline signals stay at the smaller band. Under-dispatching is recoverable by re-running at a larger size;
  over-dispatching is not.
- **This skill changes no code.** It produces a design document. Implementation is a separate, later step, normally a
  `tdd` run against this document.
- **Options before commitment.** The architect produces two or three real options with one recommendation, not a single
  design with alternatives invented afterward to justify it. The user picks before three further agent rounds are spent
  refining one.
- **The design document template lives at
  [references/api-design-template.md](./references/api-design-template.md).** The skill renders that template by filling
  its sections. It does not invent a structure inline.
- **The document is written for a named reader.** As the skill writes the design document's synthesized prose, it
  sources the shared standard by invoking `han-communication:readability-guidance` and applies it, holding one audience
  above the writing: the engineer who will implement this contract and the reviewer who will approve it. Scope that
  frame per section so the specifics that reader needs — exact signatures, types, precedence rules, file paths — are
  preserved, never simplified away.

# Design an API

## Step 1: Resolve the Goal, the Interface, and the Starting Point

**Bind `$size`.** If the user passed `small`, `medium`, `large`, or `dynamic` as the first positional argument, bind
`$size` to it. Anything else is part of the goal-and-interface context, not a size; bind `$size` to the literal
`none provided`.

**Resolve the goal.** Take the remaining argument and conversation context as the goal this design serves. A ticket
reference, issue URL, file path, or a described capability all qualify. Read the referenced material if it names a file
or is fetchable from the conversation. Record the goal verbatim where it is quotable — the justification field in every
later step cites it. If no goal resolves, stop and ask the user for the ticket, issue, or one-paragraph statement of
what this change is for. Do not proceed without it.

**Resolve the interface.** Identify what is being designed: which component, function, module, route, or payload, and
where it lives. Confirm it resolves to real files using `Glob` and `Read`. If the interface is genuinely new and has no
file yet, resolve instead the module or directory it will live in and the consumers that will call it. If neither
resolves, ask the user to name the surface before going further.

**Resolve the starting point.** Read the `current branch` and `default branch` values from Project Context. When
`default branch` reads `unknown`, `origin/HEAD` is unse