agentleFS
marcin-urbanskimarcin-urbanski/claude-skills/skills/spec-first/SKILL.md

spec-first

Skill0 starsChanged 7 days agoMITView on GitHub

Plan code changes before writing them, scaled to the size of the task. Use when starting a feature, a behaviour change, a new module or a larger project in a codebase. A small fix goes straight to tdd; a feature gets a short spec in chat with acceptance criteria and a task list; an epic gets a spec and plan in docs/ and task-by-task execution with independent review. Also use when continuing a plan from docs/plans/. Not for questions, explanations or one-off scripts.

  • Commits and pushes

12 other projects use a version of this.

Adopted by

Most recently taken up by

The file

Show its rules and text

We split this skill into the rules it gives an agent

13 rules. 0 are common, 6 are distinctive, and 7 are very specific to this project.

  • 0

    Common

    Most of the 9 edited versions we read keep these.

  • 6

    Distinctive

    This author's own choices. Worth a look.

  • 7

    Very specific

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

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    If a fix turns out bigger than it looked, stop and say so, then move up a size.

    line 20
  2. Distinctive:

    Search the codebase for what already does this or something close: services, helpers, components, traits, hooks, validators, API clients, …

    line 26
  3. Very specific:

    Check installed dependencies (composer.json, package.json, framework built-ins) before adding a library or writing a utility.

    line 27
  4. Distinctive:

    If existing code nearly fits, extend it rather than write a parallel version.

    line 30
  5. Distinctive:

    Keep it to what the user needs to approve (about 20–40 lines):

    line 34
  6. Very specific:

    Write the plan to docs/plans/YYYY-MM-DD-<topic>.md:

    line 51
  7. Distinctive:

    Follow the project's CLAUDE.md for locations if it names others.

    line 66
  8. Very specific:

    Write _overview.md with handoff, one thread per part with its branch.

    line 77
  9. Very specific:

    Default (fix, feature): do the task in this session with tdd, then a self-review against reviewer-checklist.md in this folder and the …

    line 86
  10. Distinctive:

    Do not trust any report: check git diff and the test output yourself before moving on.

    line 95
  11. Very specific:

    When a session resumes inside a part, say which part you are in and mark its tasks as ✓ 5.1 – … (finished) and → 5.2 – … (next).

    line 105
  12. Very specific:

    Use handoff between sessions on epics.

    line 109
  13. Very specific:

    If the diff changes UI and the project has a design in docs/design (a Claude Design export, a Design artifact's files, mockup images or a …

    line 113

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

Spec-first

Agile in miniature: agree what "done" means, find what already exists, split the work into small testable tasks, build each task with tdd, review, open a PR.

1. Size the task

Say the size in one line so the user can correct it, then follow that path.

SizeLooks likePath
Fixbug, typo, config value, a change inside one functionNo spec. Reuse check, then tdd (or systematic-debugging for a bug).
Featurea user story: new endpoint, form, screen, integration stepShort spec in chat → user approves → task list in chat → branch → build with tdd
Epicnew module, several stories, schema redesign, anything spanning sessionsSpec file → user approves → plan file → plan review → build task by task with review per task

If a fix turns out bigger than it looked, stop and say so, then move up a size. Do not ask for approval of a fix; just do it well.

2. Reuse check (every size, before designing anything)

The worst outcome is rebuilding something the project already has. Before proposing new code:

  1. Search the codebase for what already does this or something close: services, helpers, components, traits, hooks, validators, API clients, migrations, config. Search by domain words and by likely names (grep/rg, the framework's usual folders, existing tests).
  2. Check installed dependencies (composer.json, package.json, framework built-ins) before adding a library or writing a utility.
  3. In the spec or in chat, list what you will reuse, what you will extend, and what is genuinely new, with file paths. Anything new must say why the existing code does not fit.

If existing code nearly fits, extend it rather than write a parallel version. If it is broken, fix it rather than work around it. Never leave two implementations of the same thing.

3. Feature: spec in chat

Keep it to what the user needs to approve (about 20–40 lines):

  • Story: who wants what, and why (one or two sentences).
  • Acceptance criteria: 3–7 checkable statements ("Given…, when…, then…" or plain bullets). These become the tests.
  • Evidence of success: how the user will know after release that the story's outcome happened, something passing tests can't show: one signal from outside the code (error reports, a metric, a query on real data, a user doing the task), the value that counts as success, and when to check it. Prefer a signal that already exists; add code only when none does, and only the smallest that shows the value (a log line, a stored count). This is part of the work, not a proposal, so it never goes under Deeper, Out of scope or Decisions needed, and any such code is in the task list (in an epic, a plan task). If nothing outside the code can show it, say so in one line.
  • Reuse: from step 2.
  • Approach: files to touch, data changes, anything the user must decide.
  • Security: what input is untrusted, who may do this (authorisation), what data is sensitive. Write "none" only if that is true.
  • Deeper: what a top professional in the field would do beyond this request: the raw data they would start from and the methods or tools they would use. Two or three proposals the user can take or leave, each with "not now" as the default; none goes into the task list or plan unless the user picks it, and a picked one becomes acceptance criteria.
  • Out of scope: what you will not do.
  • Decisions needed: the questions whose answers change the design, each with the default you take if the user only says "ok". Leave the section out when there are none.

Then wait for approval. After approval, give a numbered task list (each task small enough for one red-green-refactor cycle or a few) and start.

4. Epic: spec and plan files

  1. Write the spec to docs/specs/YYYY-MM-DD-<topic>.md with the same sections as above, plus data model, integrations, error handling and migration/rollout where relevant. The acceptance criteria range above applies per story; the file has no line limit, but the summary you show in chat keeps to about 40 lines. Ask the user to review it; wait for approval, leaving the spec uncommitted where it is (it is not a code change). Then create the feature branch from the base branch (per the project's or global git rules). In a worktree on a placeholder branch, such as the desktop app's cc/<name>, switch that worktree to it with git switch -c feature/<name> <base> instead of committing on the placeholder.
  2. Write the plan to docs/plans/YYYY-MM-DD-<topic>.md:
    • Header: goal, link to the spec, branch name, global constraints (exact values, formats, security rules every task must respect).
    • Tasks, each with: an In short line, files (including every caller of a function or type whose signature or behaviour the task changes, found with rg, and what changes for it or why nothing does), what to reuse, acceptance criteria covered, the tests to write first, and a done check (command + expected result).
    • In short is one short sentence for the user (about 15 words), in plain words: the gist of what the task changes and what they will see or get when it is done, not a list of everything it does. No codes the user would have to look up (mockup IDs, AC numbers, internal type names). The task title alone is not enough; the rest of the task is for the implementer.
    • Tasks ordered so each leaves the app working and tests green.
    • A plan spanning several PRs groups its tasks into named parts, one per PR, and numbers tasks N.M (task 2 of part 5 is 5.2). A plan without parts is one part; number its tasks 1, 2, 3.
  3. Review the plan adversarially before anyone builds from it. Dispatch one fresh reviewer subagent with plan-review-prompt.md in this folder: it gets the spec, the plan and the repository, never your reasons for the choices, since a reviewer handed conclusions tends to confirm them. Re-read the plan and the code each finding points at, then sort it (first match wins):

    • Spec gap: the spec is silent, unclear or wrong → a question for the user, with your default. Gaps you found yourself while writing the plan go in the same message.
    • Noise: wrong given context the reviewer lacked, or right but asking for no change → change no task for it, but add that context to the plan's global constraints if its absence caused the finding.
    • Trade-off: real, but fixing costs more than accepting → note it in the plan header and tell the user.
    • Plan fix: any other real finding → fix the plan.

    Tell the user in a few lines what the review changed, with the spec questions, and each finding you dropped as noise with the reason in one line. If there are questions, wait for the answers, record them in the spec and adjust the plan. Then re-review with a fresh reviewer, but only when the fixes or answers changed tasks substantially, for at most 3 reviews in total; substantive findings still left after the third go to the user. If the session ends while you wait, the handoff says the plan review is open and the spec and plan not yet committed.

  4. Commit spec and plan together on the feature branch as its first commit (e.g. docs: add spec and plan for <topic>), with the new CODING_STANDARDS.md and its CLAUDE.md line if the epic starts them (below), before any task starts. A plan left untracked in a worktree disappears with it, and handoffs point at it; committed, any worktree gets it after git switch <branch>. If the project's .gitignore excludes the docs folder, tell the user and ask before forcing anything; never git add -f silently.

Follow the project's CLAUDE.md for locations if it names others.

Coding standards. An epic in a repository without CODING_STANDARDS.md, a new project included, starts one. Propose it in the spec under Decisions needed (default: yes), with its Core rules in a line each so the user sees what they approve, chosen and checked against the code as coding-standards-template.md in this folder says. After approval, write the file from the template's skeleton and add its pointer line to the project's CLAUDE.md.

5. Build

Session layout. Decide it by size, and state it in one line when you show the reviewed plan (for a fix or feature, with the task list):

  • Fix, feature, or an epic with one part: this session builds it and opens one PR.
  • An epic with several parts, when you can start other sessions (the Claude desktop app's start_session): this session becomes the main session, the orchestrator in handoff. It writes no code and runs no build loop; one worker session per part does, each in its own worktree. Unless the user wants everything here:

    1. Step 4's feature branch, with spec and plan committed, is part 1's branch: rename it with git branch -m feature/<topic>-1 if it has another name (later parts get feature/<topic>-<n>). Push it and switch this checkout back to the branch it was on before (the base branch in the main checkout, the cc/<name> placeholder in an app worktree). Part 1 carries spec and plan to the base branch, so the other parts start once it is merged.
    2. Write _overview.md with handoff, one thread per part with its branch.
    3. Start a worker for each part whose dependencies are merged, at the same time when they do not depend on each other: fresh context, own worktree, brief You are the worker for part N (<name>) of <plan path>, which is reviewed and approved: invoke spec-first and go straight to step 5. Build this part in this session through Finish to its PR, on branch feature/<topic>-<n> (switch to it if it exists, otherwise fetch and create it from origin/<base>). Handoff thread: <topic>-<n>. Each start is a card the user clicks unless they told you to start them. Tell the user to come back to this session after each merge.
    4. On every turn, first check each open part's PR (gh pr view), since a merge does not wake this session. When a worker's PR is open, check its diff yourself. After a merge, run pr-done if it is installed (otherwise update the base branch), update _overview.md and start the parts that are now unblocked.

    Without session tools (the terminal CLI), or when the user prefers one session, build the parts here one after another, with handoff between sessions.

  • A worker (its brief names one part) builds that part like an epic with one part and never starts workers of its own.

For a fix or feature, create the branch first (per global git rules); an epic already has it from step 4. Then, per task:

Default (fix, feature): do the task in this session with tdd, then a self-review against reviewer-checklist.md in this folder and the project's CODING_STANDARDS.md and CONTRIBUTING.md, whichever exist: reuse, security, best practices, spec compliance. Fix what you find. Commit with a conventional message. Next task.

Epic: for each task, dispatch one implementer subagent and then one fresh reviewer subagent. Both come from the claude-skills repo, linked into ~/.claude/agents/ or installed with its marcin-skills plugin (then named marcin-skills:implementer and marcin-skills:reviewer): the implementer starts with tdd and verification-before-completion loaded and cannot spawn subagents, the reviewer is read-only.

  • Implementer prompt: the task text from the plan, global constraints and the reuse list. The agent's own instructions cover TDD, verification, the commit and the report.
  • Reviewer prompt: reviewer-prompt.md in this folder, filled in with the task, constraints and the commit range.
  • Critical or Important findings, including those the judge says stand in the whole-branch review, go back to the implementer; re-review only the fix. Minor findings are listed for the user.
  • You plan, dispatch and check; every code change goes through an implementer and a reviewer, and you write no production code.
  • A product or spec question an agent raises (behaviour, copy, an existing test's assertion) goes to the user, not to another agent. Record the answer in the spec.
  • Do not trust any report: check git diff and the test output yourself before moving on.

Tell the user where you are, so they never meet a bare task number. Write it in the language of the conversation, labels included (the examples below are English only for illustration):

  • Starting a part of the plan, and at the start of every session that continues the plan: what just finished, which part comes now and how many there are, then all its tasks, one line each:
    Part 4 (week and month) is finished. Now part 5 of 6: menu bar. It contains:
    5.1 – a setting for what the menu bar shows
    5.2 – menu bar icon with a running clock, and the classic menu on right-click
    When a session resumes inside a part, say which part you are in and mark its tasks as ✓ 5.1 – … (finished) and → 5.2 – … (next).
  • Each further task in the same part: one line before you dispatch the implementer, such as Task 5.2: menu bar icon with a running clock, and the classic menu on right-click.
  • The short description is the task's In short line, translated if the plan is in another language. If the plan has none, write one in the same way from the task's text: one short sentence (about 15 words), the gist, not a list of features. Never only the title.

Use handoff between sessions on epics.

6. Finish (every size)

  1. If the diff changes UI and the project has a design in docs/design (a Claude Design export, a Design artifact's files, mockup images or a figma.md), run design-check.
  2. verification-before-completion: full test suite, linters/static analysis the project uses, build if there is one. Read the output.
  3. Independent review of the whole branch, for every size, against main...HEAD:

    • Fix or feature: dispatch one reviewer subagent with reviewer-prompt.md.
    • Epic: an adversarial review. Dispatch three fresh reviewer subagents in parallel with adversarial-review-prompt.md in this folder, one per angle it lists, then one fresh reviewer with judge-prompt.md and their reports. The judge decides which findings stand, because a session tends to dismiss criticism of its own work.

    Critical and Important findings (in an epic, those the judge says stand) are fixed, in an epic by an implementer, and a fresh reviewer checks only the fix. In an epic, ask the user each of the judge's Open questions, record the answer in the spec, and treat the finding as standing or rejected accordingly; wait for the answers before the PR. Tell the user every finding you do not act on, with the reason in one line (for a rejected one, the judge's reason); never drop one silently.

  4. Walk through the acceptance criteria (for a fix, the behaviour the request asks for) one by one and say how each is met (test name or manual check). For a feature or epic whose spec names a signal for evidence of success, then say how and when the user checks it.
  5. Push and open the PR with gh pr create, writing the body with the pr skill, with the evidence-of-success check from step 4 under Notes for the reviewer. Do not merge.

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.