agentleFS
bartstcbartstc/vite-ts-react-template/.agents/skills/writing-spec/SKILL.md

writing-spec

Skill122 starsChanged 38 days agoMITView on GitHub

Collaboratively write a feature spec with the developer. Trigger when a task involves 5+ unconstrained decisions, spans 10+ files, or the developer explicitly asks for a spec. Do NOT trigger for config edits, CSS fixes, helper functions, exploratory prototyping, presentation-only changes, or when the developer explicitly opts out.

2 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

23 rules. About 0 are common, 16 are distinctive, and 7 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈16

    Distinctive · estimate

    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. Very specific:

    Read ./templates/requirements-template.md, ./templates/design-template.md, ./templates/tasks-template.md, and …

    line 12
  2. Very specific:

    Read @docs/architecture.md to understand current building block types and project structure

    line 13
  3. Distinctive:

    Ask the developer to describe the feature in 2-5 sentences (or accept what they've already provided)

    line 24
  4. Distinctive:

    Before drafting, ask 3-5 clarifying questions about scope boundaries, error scenarios, and unstated assumptions — only where the answer …

    line 25
  5. Distinctive:

    Add Open Questions for anything unresolved that blocks a specific task

    line 68
  6. Distinctive:

    Run a structured self-audit and present findings to the developer (don't silently verify — show the results):

    line 73
  7. Very specific:

    Contract coverage: every contract file links back from a design.md block entry.

    line 79
  8. Distinctive:

    Contract count: no hard cap — report the count.

    line 81
  9. Very specific:

    ALWAYS read the three template files in ./templates/ before drafting

    line 90
  10. Very specific:

    ALWAYS use EARS notation for requirements and GIVEN/WHEN/THEN for edge cases

    line 91
  11. Distinctive:

    ALWAYS assign stable IDs to requirements (R1, R2, …) — tasks reference these for traceability

    line 92
  12. Distinctive:

    ALWAYS include the three-tier boundary system (✅ / ⚠️ / 🚫) with specific paths

    line 93
  13. Distinctive:

    NEVER invent requirements the developer hasn't stated or confirmed — ask instead

    line 97
  14. Very specific:

    NEVER define building block internals (interfaces, schemas, implementation) in design.md — reference name + type only.

    line 98
  15. Very specific:

    NEVER duplicate a decision across design.md and a contract — cross-block decisions go in design.md Design Decisions.

    line 99
  16. Distinctive:

    NEVER skip a review gate — each phase needs explicit developer approval

    line 100
  17. Distinctive:

    NEVER conflate spec layers: requirements constrain intent, design constrains approach, tasks constrain sequencing.

    line 101
  18. Distinctive:

    NEVER add boilerplate boundaries — every item in ✅/⚠️/🚫 must be reachable during implementation of this specific feature

    line 102
  19. Distinctive:

    Prefer concise specs (combined ~200 lines: requirements ≤50, design ≤80, tasks ≤70) over exhaustive ones — the curse of instructions means …

    line 106
  20. Distinctive:

    Prefer mechanical enforcement (lint, tests, schemas) over prose rules — if a constraint can be a linter rule, it doesn't belong in the spec

    line 107
  21. Distinctive:

    Prefer two design options with tradeoffs over a single "obvious" choice — this surfaces assumptions

    line 108
  22. Distinctive:

    Prefer specific file paths in boundaries over vague module names

    line 109
  23. Distinctive:

    R3: WHEN the login form is submitted with an empty email field, THE SYSTEM SHALL display an inline validation error without making an API …

    line 151

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “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

Purpose

Guide the developer through writing a feature spec before any code is written. The spec constrains intent and approach so implementation decisions are explicit, reviewed, and traceable. This skill produces three files in specs/NNN-feature-name/ — requirements.md, design.md, tasks.md — using the templates in ./templates/.

Prerequisites

  • Read ./templates/requirements-template.md, ./templates/design-template.md, ./templates/tasks-template.md, and ./templates/contract-template.md before starting — they define the section structure
  • Read @docs/architecture.md to understand current building block types and project structure
  • Determine the next available sequence number by checking both specs/ directory listings AND git log for prior spec-related commits — use the higher of the two

Workflow: Four Phases with Gates

Each phase ends with a human review gate. Do NOT advance to the next phase without explicit developer approval ("continue", "ok", "next", "looks good", or similar). If something goes wrong, STOP and re-plan — do not push forward.

Phase 1 — Goal & Scope (Intent)

Collaborate with the developer to fill requirements.md.

  1. Ask the developer to describe the feature in 2-5 sentences (or accept what they've already provided)
  2. Before drafting, ask 3-5 clarifying questions about scope boundaries, error scenarios, and unstated assumptions — only where the answer would change the spec. Skip obvious ones.
    • If the feature introduces new API calls (queries or mutations): explicitly ask which server-side error responses each call must handle, and how the UI should react to each.
  3. Draft the Goal & Context section — focus on the problem, not the solution
  4. Draft Requirements using EARS notation: WHEN [condition] THE SYSTEM SHALL [behavior]. Assign stable IDs (R1, R2, …)
  5. Draft Non-Goals — ask: "What should this feature explicitly NOT do?"
  6. Present requirements.md for review

What to ask if unclear: "What's the observable user behavior when this works correctly?" Never invent requirements — if the developer hasn't specified a behavior, ask about it.

Phase 2 — Design (Approach)

Collaborate on design.md.

  1. Propose a Building Blocks Diff — list every block that is ADDED, MODIFIED, or DELETED. Use the project's building block taxonomy from .agents/skills/building-blocks/SKILL.md. Reference by name and type only — do not define internals. Implementation details belong in coding standards and per-type skills, not specs. For changes that don't map to a typed building block, use the target file path + a short description instead.
  2. Cross-slice concerns — ask whether any new block needs to interact with another feature or sub-feature slice. If yes, decide the wiring point (parent feature or page) and injection mechanism (callback, render prop, slot) in the design — don't defer to implementation.
  3. Identify contract candidates. For each block in the diff, check the signal checklist below. For every block hitting ≥1 signal, present an inline proposal — one line each: `blockName` (type) — <signal(s) hit>; design problem: <one phrase>. The developer approves/rejects each. For approved blocks, create specs/NNN-feature-name/contracts/{block-slug}.md (slug = block name kebab-cased per code-style.md; on a slug collision, suffix the type, e.g. review-form-store.md) from ./templates/contract-template.md, and add a contract link to that block's design.md Building Blocks Diff entry. Contracts are signal-driven, not type-driven — most blocks hit zero signals and get nothing. If no block hits a signal, skip this step entirely: no contracts/ directory, no proposals. When a block hits a signal but the developer rejects the proposal (or you judge it trivial), record the skip reason inline in that block's design.md entry — e.g. `fooStore` (store) — contract skipped: shape is flat.

    Signals — a block warrants a contract proposal if ≥1 holds. Signals describe properties of the design problem, not block types:

    1. Multiple states & transitions — the block moves through several discrete states with conditional or guarded transitions.
    2. Structured internal state — more than a couple of flat fields: derived values, interdependent fields, or normalized collections.
    3. Branching domain logic — conditional rules, invariants, or multi-step computation where the rules themselves are the design.
    4. Cross-slice coordination — behavior depends on wiring into another feature or sub-feature slice; the seam (callback, slot, render-prop) needs design.
    5. No canonical pattern — the block matches no established pattern the agent can look up, so its shape must be designed from scratch.
  4. For non-trivial features, propose two plausible designs with tradeoffs. Let the developer choose. Capture the winner and rationale in Design Decisions
  5. Draft the Boundaries section using the three-tier system:
    • ✅ Always — proceed without asking (e.g., create files in the feature directory)
    • ⚠️ Ask first — needs approval (e.g., modify API contracts, change schema, create shared utilities)
    • 🚫 Never — hard stops (e.g., modify core auth, remove tests, commit secrets)
  6. Present design.md for review

Critical rule for building blocks: Reference names and types. Do NOT define contracts, interfaces, or implementation — those live in separate coding-standards skills and existing code. The spec describes a CHANGE to the status quo. The agent reads relevant code to see the current status quo.

Phase 3 — Spec (Sequencing)

Fill tasks.md.

  1. Break work into a Task Breakdown — ordered, independently testable tasks. Each task:
    • References building blocks from design.md if any are involved
    • Traces to requirement IDs (R1, R2, …)
    • Includes target file paths
    • Is marked [P] (parallelizable) or [S] (sequential)
  2. Draft Error & Edge Cases using GIVEN/WHEN/THEN — cover failure modes (including fetch errors for data-fetching components), boundary conditions, concurrency
  3. Add Open Questions for anything unresolved that blocks a specific task
  4. Present tasks.md for review

Phase 4 — Review & Finalize

  1. Run a structured self-audit and present findings to the developer (don't silently verify — show the results):
    • Coverage matrix: for each requirement ID, list which task(s) implement it. Flag any requirement with zero tasks
    • Orphan tasks: flag any task that doesn't trace back to a requirement ID
    • EARS compliance: flag any requirement missing WHEN/THE SYSTEM SHALL or using vague language ("handle properly", "work correctly")
    • Boundary specificity: flag any boundary item (✅/⚠️/🚫) that references a vague category instead of a file path or module name
    • Building block references: flag any block in design.md that doesn't exist in the building-blocks catalog — acceptable without a catalog match if the block has a contract (signal 5, no canonical pattern); flag it only if it lacks both
    • Contract coverage: every contract file links back from a design.md block entry; every design.md block that hits a signal either has a contract or an inline skip reason in its entry
    • Line count: report each file's count and the combined total. Caps: requirements.md ≤50, design.md ≤80, tasks.md ≤70, combined ≤200. Contracts are excluded from the combined cap — report each contract's count separately, ≤80 each. If any cap is exceeded, identify which section to compress or extract
    • Contract count: no hard cap — report the count. A high count (e.g. >3) signals the feature should be split into separate specs; surface it, don't enforce it
  2. Fix any issues found in step 1 before proceeding
  3. Set status to review in each Meta table
  4. Present the audit results and the final spec for developer sign-off

Rules & Constraints

What the agent MUST do

  • ALWAYS read the three template files in ./templates/ before drafting
  • ALWAYS use EARS notation for requirements and GIVEN/WHEN/THEN for edge cases
  • ALWAYS assign stable IDs to requirements (R1, R2, …) — tasks reference these for traceability
  • ALWAYS include the three-tier boundary system (✅ / ⚠️ / 🚫) with specific paths

What the agent MUST NOT do

  • NEVER invent requirements the developer hasn't stated or confirmed — ask instead
  • NEVER define building block internals (interfaces, schemas, implementation) in design.md — reference name + type only. Internals/pseudocode for complex blocks belong in contracts/; contracts are the one sanctioned place for block-shape detail in a spec
  • NEVER duplicate a decision across design.md and a contract — cross-block decisions go in design.md Design Decisions; intra-block shape rationale goes in the contract
  • NEVER skip a review gate — each phase needs explicit developer approval
  • NEVER conflate spec layers: requirements constrain intent, design constrains approach, tasks constrain sequencing. Keep them separate
  • NEVER add boilerplate boundaries — every item in ✅/⚠️/🚫 must be reachable during implementation of this specific feature

Prefer

  • Prefer concise specs (combined ~200 lines: requirements ≤50, design ≤80, tasks ≤70) over exhaustive ones — the curse of instructions means longer specs get followed less reliably. Contracts are excluded from the ~200 combined cap and capped individually at ≤80 lines
  • Prefer mechanical enforcement (lint, tests, schemas) over prose rules — if a constraint can be a linter rule, it doesn't belong in the spec
  • Prefer two design options with tradeoffs over a single "obvious" choice — this surfaces assumptions
  • Prefer specific file paths in boundaries over vague module names

Anti-Patterns

  • Spec that's actually a task list — "first create the model, then add the service" constrains sequencing but not intent. The agent follows every step and still builds the wrong thing. Fix: write requirements first, derive tasks from them
  • Over-specification that becomes code — if the spec includes TypeScript interfaces, database DDL, or code snippets, it has crossed from "what" into "how." Move those to design docs or coding standards
  • Under-specification that forces guessing — if a requirement says "handle errors gracefully" without specifying which errors and what "gracefully" means, the agent will guess. Fix: use GIVEN/WHEN/THEN for every error scenario
  • Auto-generated specs — LLM-generated context files have been shown to reduce task success rates. The developer drives content; the agent structures and challenges it
  • Markdown review trap — if any file exceeds its cap (requirements 50 / design 80 / tasks 70) or the combined spec exceeds ~200 lines, the review cost may exceed the value. Split the feature or compress the spec

Examples

✅ Correct: Building block reference

### Added

- `loginMutation` (mutation) — handles POST /auth/login
- `LoginForm` (component) — email/password form with validation

❌ Wrong: Building block with implementation details

### Added

- `loginMutation` (mutation):
  ```typescript
  export const loginMutation = {
    mutationFn: (data: LoginData) => api.post("/auth/login", data),
    onSuccess: (response) => {
      authStore.setToken(response.token);
    },
  };
  ```
Why wrong: the spec now contains code. The mutation's internals are governed by coding standards, not the feature spec.

### ✅ Correct: EARS requirement
```markdown
- **R3**: WHEN the login form is submitted with an empty email field, THE SYSTEM SHALL display an inline validation error without making an API call.

❌ Wrong: Vague requirement

- **R3**: The form should validate inputs properly.

Why wrong: "properly" is undefined — the agent will guess what validations to apply and what "proper" error display looks like.

Exit Criteria

The spec is ready for implementation when:

  • Every section marked REQUIRED in each template is filled
  • Every requirement has a stable ID and uses EARS notation
  • Every task traces to ≥1 requirement ID
  • Building blocks reference name + type only, no implementation details
  • Boundaries use specific file paths, not vague categories
  • Open questions are either resolved or explicitly block named tasks
  • Developer has approved the final spec (status set to approved)
  • Every proposed-and-approved contract is filled and linked from design.md
  • File sizes within caps: requirements.md ≤50, design.md ≤80, tasks.md ≤70, combined ≤200 lines; each contract ≤80 lines (excluded from the combined cap)

References

  • .agents/skills/building-blocks/SKILL.md — building block type dictionary (names, descriptions, when to use each)
  • ./templates/requirements-template.md, ./templates/design-template.md, ./templates/tasks-template.md, ./templates/contract-template.md — section structure and inline guidance
  • @docs/architecture.md — project structure, architectural decisions, conventions

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.