AgentStack
Browse Sign in
Browse Why AgentStack Sell Docs
Sign in
SKILL verified MIT Self-run

Spec Development

skill-evgeny-birch-spec-driven-development-skill-spec-development · by evgeny-birch

Use this skill when the user wants to create, update, or decompose a product specification. A spec is a triplet of documents — `epic.md` (what and why), `tasks.md` (work breakdown), `plan.md` (execution order). Project-agnostic; drop this skill folder into any repo. Invoke when the user says things like "let's write a spec", "create a new spec", "break this epic into tasks", "update SPEC-NNN", or…

No reviews yet
0 installs
30 views
0.0% view→install

Install

$ agentstack add skill-evgeny-birch-spec-driven-development-skill-spec-development

✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access No
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets Used
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

View the full security report →

Verified badge

Passed review? Show it. Paste this badge into your README, it links to the public security report.

AgentStack Verified badge Links to your public security report.
[![AgentStack Verified](https://agentstack.voostack.com/badges/verified.svg)](https://agentstack.voostack.com/security/report/skill-evgeny-birch-spec-driven-development-skill-spec-development)

Reliability & compatibility

Security review passed
0 installs to date
no reviews yet
3mo ago

Declared compatibility

Claude CodeClaude Desktop

Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.

Preview Execution monitoring

We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.

How agent discovery & health will work →
Are you the author of Spec Development? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

spec-development

Writes and maintains specifications in three shapes, depending on the size and urgency of the work. All three live under docs/specs/ and share a single numbering sequence for regular work (SPEC-NNN), with hotfixes on a parallel HF-NNN sequence.

Which track?

Pick the track BEFORE writing anything. Mis-pick and you either over-document a tiny change or under-document a real feature.

| Situation | Track | Artifact | |---|---|---| | New feature, multi-surface, partner coordination, new data model / API, cross-cutting risk | Full triplet | epic.md + tasks.md + plan.md | | Single well-understood change, 1–3 files of impact, low risk, one-sitting execution | Small spec | spec.md (one file) | | Production is broken, user describes the problem, fix is needed now | Hotfix | hotfix.md (one file, written alongside the fix) |

When the user invokes the skill and the intent is ambiguous, ask which track before creating any file. Phrasing clues:

  • "write a spec for …", "new feature …", "break this down" → full triplet candidate
  • "small spec for …", "just a tiny change", "one-file fix" → small-spec candidate
  • "hotfix: …", "prod is broken", "срочно фикс" → hotfix

If a small-spec starts to outgrow itself during execution (new API surface, cross-cutting concern emerges), stop and convert to a full triplet rather than cramming. Conversely, a full-triplet epic that shrank in scope during review can be demoted to a small-spec — one spec.md replaces the triplet.

Templates for all three shapes live under templates/.


Track 1 — Full triplet (epic + tasks + plan)

Three linked documents in docs/specs/SPEC-{NNN}-{slug}/:

  1. epic.md — full description of the work: goals, context, requirements, UX, data model, architecture, acceptance criteria. Read by both an AI agent (as a prompt to decompose work) and a human (to validate intent).
  2. tasks.md — breakdown of the epic into concrete, actionable tasks. Agent-optimised — enough technical detail that any single task can be executed without reading its siblings.
  3. plan.md — execution plan: order, dependencies, parallelisable work.

Workflow

epic.md (draft → in-review → approved)  →  tasks.md  →  plan.md  →  execute

If the user asks to skip ahead ("just make the task list for this half-drafted epic"), push back: misaligned epic produces wasted tasks.

When the user asks for a new spec

  1. Find the next available number with ls docs/specs/ (pattern: SPEC-{NNN}-{slug}/, zero-padded to three digits).
  2. Ask the user for a short slug (kebab-case, e.g. student-intake).
  3. Create docs/specs/SPEC-{NNN}-{slug}/.
  4. Copy templates/epic.md into the new directory as epic.md.
  5. Copy templates/verification-checklist.md into the new directory as verification-checklist.md — universal floor goes in immediately, project-/spec-specific surfaces (§10+) get filled as the epic takes shape.
  6. Fill the Meta section (ID, title, status=draft, dates, owner).
  7. Work with the user section by section. Do not auto-fill everything — the epic is a design conversation, not a dump.

When the user asks for tasks

  1. Confirm the epic is at least in-review. Refuse to decompose a draft epic.
  2. Copy templates/tasks.md into the spec directory (or create tasks/ dir — see "Splitting tasks into files").
  3. Draft the task index first, then expand each task block. Discuss the index with the user before expanding — alignment on slicing saves hours later.
  4. Every task must follow the rules in "Task-writing rules" below.

When the user asks for a plan

  1. Confirm tasks.md exists.
  2. Copy templates/plan.md. Use task metadata (blockedBy, blocks, size) to compute order and parallel tracks.

Track 2 — Small spec (single file)

One document under docs/specs/SPEC-{NNN}-{slug}/spec.md. No triplet, no decomposition, no plan.

Use when: single well-understood change, one to three files of impact, low risk, executable in a single sitting.

Workflow

spec.md (draft → approved)  →  execute directly from this file

No in-review step — small scope doesn't warrant a partner gate. User eyeballs draft, flips to approved, execution starts from the same file.

When the user asks for a small spec

  1. Find the next SPEC-NNN number (same sequence as full specs — ls docs/specs/). Small and full specs share the namespace; the shape is what differs, not the ID.
  2. Ask for a kebab-case slug.
  3. Create docs/specs/SPEC-{NNN}-{slug}/.
  4. Copy templates/small-spec.md into the directory as spec.md.
  5. Fill with the user, section by section. Do NOT auto-fill — brief discussion still saves rework.
  6. When status is approved, execute directly from spec.md. No task agents, no waves — it's one sitting.
  7. Same DoD applies as the full track (types, lint, tests, UX walkthrough for UI, i18n parity, etc.).
  8. At hand-off, present the manual-verification checklist from §7 of the spec.

When a small spec grows

If during execution the change turns out to be bigger than anticipated (new API, new data model, multi-surface work) — pause, tell the user, and convert to full triplet. The existing spec.md becomes the kernel of the new epic.md; rename the file and expand it. Keep the SPEC-NNN ID.


Track 3 — Hotfix (act first, document alongside)

One document under docs/specs/HF-{NNN}-{slug}/hotfix.md. Sits next to SPEC folders in docs/specs/ — hotfixes are spec artefacts, just a different shape and a parallel numbering sequence (HF-001, HF-002, …).

Use when: production (or a critical dev surface) is broken, the user describes the problem, and the fix is needed now.

Workflow

problem triaged  →  HF doc sections 1–2 created  →  regression test (red)
  →  fix  →  test green  →  HF doc sections 3–8 filled  →  single commit

Sections 1–2 (Meta + Problem) go in BEFORE coding — that's the triage paper trail. Sections 3–8 (Timeline, Root cause, Fix, Regression guard, Verification, Follow-up) go in AFTER the fix is green and BEFORE the commit. The single commit bundles fix + regression test + HF doc.

When the user asks for a hotfix

  1. Find the next HF-NNN number via ls docs/specs/ | grep '^HF-'. HF numbering is independent of SPEC.
  2. Ask for a kebab-case slug (or derive from the user's problem description).
  3. Create docs/specs/HF-{NNN}-{slug}/.
  4. Copy templates/hotfix.md into the directory as hotfix.md.
  5. Fill §1 Meta + §2 Problem from what the user said. Quote their words verbatim in §2; don't paraphrase.
  6. Reproduce the bug. Write the regression test FIRST — it should be red before the fix is applied. An urgent fix without a regression guard is how the same bug recurs.
  7. Apply the fix. Test turns green.
  8. Fill §3 Timeline, §4 Root cause, §5 Fix, §6 Regression guard, §7 Verification, §8 Follow-up.
  9. Single commit bundles fix + test + HF doc. Commit message references HF-{NNN}.
  10. If the fix is a band-aid (symptom patched, underlying design flaw remains), §8 points to either a new small-spec or an entry in docs/future-work.md with Source: HF-{NNN}.

What never gets skipped, even in a hotfix

  • Regression test (§6). No exceptions without a documented reason and a follow-up ticket.
  • DoD basics: types pass, linter clean, existing automated suites still green.
  • Safety rails: no --no-verify, no force-push, no mock of the broken dependency to "make it pass".
  • The HF doc itself. "I'll write it later" is how we lose the paper trail — which is exactly when the next similar incident hits.

If you cannot meet these on the hotfix timeline, tell the user; don't silently bypass.


Content rules

No implementation code — but contracts yes

Epics and tasks describe what the system is, not how it is built. Allowed:

  • Type / interface declarations (TypeScript, Go structs, Python TypedDict, SQL DDL) — these are specifications.
  • Schema formats (OpenAPI, JSON Schema, Protobuf, GraphQL SDL) for cross-language or cross-service contracts.
  • Mermaid diagrams (flowchart, sequenceDiagram, stateDiagram-v2, erDiagram, C4-style flowchart).

Disallowed:

  • Function / method bodies, algorithms as code, loops, control flow as code, test assertions as code. Describe these in prose or mermaid.

Choosing a contract format (cross-language interfaces)

Pick the format that best fits the interface style:

| Interface style | Use | |---|---| | REST HTTP API | OpenAPI (generate TS / Go / Python types from it) | | Async events, data payloads, config schemas | JSON Schema | | RPC, strict typed inter-service calls | Protobuf / gRPC | | GraphQL edges | GraphQL SDL | | Single-language internal types | Native (TS interface, Go struct, etc.) |

For any contract used by more than one service or language, make the schema the source of truth and note "generate types from this schema" in the task.

Skip sections that do not apply

For small-scope specs (a UI tweak, a single bug fix), omit irrelevant sections entirely. Do not leave N/A — reason placeholders — they add noise. Keep only sections that carry signal.

For medium or large specs, include all sections. When in doubt, include.

Sections almost always present in a non-trivial epic: Meta, Summary, Business goal, Users & roles affected, User stories & scenarios, Functional requirements, Acceptance criteria, Out of scope.

Sections often omitted for truly small specs: Glossary, Data model, Algorithms, API, Permissions matrix, Analytics, Rollout plan, Risks & assumptions, Success metrics.

Section numbers in the template are for reference, not sequence — do not renumber on omission.

Concrete over abstract

Name real personas in scenarios, quote real copy, link to real source materials. Avoid "a user", "some data", "various options".

Project-specific context

Project-specific conventions (tech stack, brand rules, source materials, compliance requirements, monorepo layout) live in the project's CLAUDE.md or AGENTS.md, not in this skill. Read those first before filling an epic — they inform sections like Architecture, UX, and Non-functional.

Task-writing rules

Self-sufficiency

Each task must be executable without reading sibling tasks. When a cross-task dependency is unavoidable (shared type, produced artefact), quote the interface in the task's References and link to where it is defined (e.g., T-003 §Data structures → Example type). A little controlled duplication beats forcing the agent to chase links.

Task metadata

Every task carries:

| Field | Purpose | |---|---| | type | feature / refactor / test / research / bugfix / infra / docs — steers expectations | | size | S / M / L (see below) — signals complexity, not hours | | languages | TS, Go, Python, SQL, … — agent selects toolchain | | scope paths | explicit blast radius in the monorepo | | blocked by / blocks | dependencies for planning | | epic sections | back-links for context |

Size tiers:

  • S — 1 file or 1 component, trivial logic
  • M — a few files, crosses modules, involves small design decisions
  • L — multiple layers, needs further decomposition — candidate for split

Splitting tasks into files

Rule of thumb based on task count in the epic:

  • ≤ 10 tasks — one tasks.md with full task blocks inline.
  • > 10 tasks — extract each task to tasks/T-NNN-{slug}.md, leave only the task index table in tasks.md.

Judgement call by the author — not a hard cutoff. For a 9-task spec where each task is large and dense, splitting earlier is fine.

Test flow (per task)

Tests inside each task carry four sub-sections:

  1. Strategy — what level (unit / integration / e2e / a11y / visual), what tools. Default: automate as much as the toolchain allows (Playwright, Vitest, axe-core, etc.). Manual verification is the exception, not the rule. For E2E: pin locale, timezoneId, and extraHTTPHeaders (especially Accept-Language) in the runner config to a representative real user — headless defaults differ from real browsers and hide header-sensitive bugs.
  2. Core scenarios (filled up-front) — 3–5 must-pass scenarios derived from user stories and acceptance criteria. Written by the task author before implementation. Each maps to an AC.
  3. Additional scenarios (filled during implementation) — the executing agent appends edge cases it discovered. This grows as implementation progresses and becomes part of the task artefact.
  4. Manual verification (run at task end) — only items automation cannot reliably cover (visual polish, screen-reader flow, device-specific feel). Empty is a good outcome.

Verification rigour — anti-hand-wave rules

Past specs in many projects have shipped with "green tests" that proved mechanics, not behaviour — agents claim a task done because their tests went green, but the tests didn't actually verify the user-facing or persisted-state outcome the spec promised. The rules below are a universal floor against this failure mode. Each rule has been the source of a real bug-after-merge in some past project; they are not academic.

Apply to every task, regardless of language / framework / spec scope. Specs MUST author a verification-checklist.md in their directory (see template + workflow below) that quotes these rules verbatim and extends them with project-/spec-specific surfaces.

  1. Persistence asserted by storage query, not by helper-call inspection. When a task says "X is recorded / written / inserted", the test queries the underlying store (SELECT … FROM WHERE …, equivalent NoSQL get, file-existence check) and asserts presence + key fields. Calling the helper that would write does not count. The most common false positive: helper returned nil, the row was never created.
  2. State-machine transitions asserted by post-condition row read. When status changes, the test reads the row back and asserts the new status. "The handler returned 200" is necessary but not sufficient — the handler can return 200 from a code path that skipped the write.
  3. Audit-row existence asserted by storage grep, not by code path. When a task claims to write an audit-log row, the test queries the audit storage and asserts the actor / entity / action / reason fields match the input verbatim. The audit-helper returning nil is not sufficient.
  4. Concurrency races asserted by post-condition row count. When you claim "second concurrent write returns 409", the test runs N parallel writers (real goroutines / async tasks, not sequential calls) and asserts the resulting row count = 1 (only winner left a row). Sequential calls do not test concurrency.
  5. Negative tests as first-class. Every guard, validator, or rule has both a positive case (fires/passes correctly) AND a negative case (does NOT fire/pass on a clean input). Half-tested guards rubber-stamp.
  6. Content assertions, not shape assertions. A test that asserts "an item came back with N fields and an integer id" is necessary but NOT sufficient. Add at least one content-shaped property: text length > N chars, no placeholder strings (Lorem ipsum, TODO, Step N), no raw markdown fences in JSON output, mandatory non-empty strings. Catch the case where the shape is right but the content is junk. Build-time-inlined env vars are a special case: when the framework substitutes env values into the bundle at build time (Next.js NEXT_PUBLIC_*, Vite VITE_*, similar Webpack / esbuild substitutions), the test must assert against a built artefact, not against a dev-mode runtime — the runtime container's env is irrelevant for these once the bundle is produced. A "framework injects this at build" mismatch never shows up in dev, only in built containers.
  7. Browser walkthrough for every UI surface. Hand-off bar = green tests + live dev env up + pages personally clicked. If the executing agent cannot run a browser, surface

Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet, be the first.

Versions

  • v0.1.0 Imported from the upstream source.