agentleFS
NitinJNitinJ/specforge/skills/create-spec/SKILL.md

create-spec

Skill4 starsChanged 2 months agoMITView on GitHub

Author a new house-style spec into the SpecForge store. Use when the user asks to "write a spec", "create a design doc", "draft a spec for <x>", "research <x>", "write a PRD / UX spec / test plan / launch plan / security review", or "plan to implement <x>". Reads the installed spec types and picks the one whose "when to use" line fits, then scaffolds that type's shell and authors its sections against the guidance it carries — light/dark HTML, stable section ids, a floating TOC; impl types also get a Stages/Tasks plan, a live task tracker, and impl-time stubs; general is the fallback when nothing fits and the sections come from the use case. Lints the universal basics before done.

17 other projects use a version of this.

Adopted by

Most recently taken up by

Used with

Projects with it also use create-plan, pr-review and 4 more.

Other files people use alongside this one.

Files found in the same public projects as a version of this one, more often than they turn up anywhere else. Each project counts once, large collections count for less, and this file's own repository is left out.
  • JetBrainsSkill

    create-plan

    Research the codebase and create an implementation plan with architecture notes, design document, and track decomposition. Use when starting a new feature or large change.

    Also in 3 projects that use this

  • MicrosoftSkill

    pr-review

    Verify the technical accuracy of a vscode-docs pull request against the VS Code source code in microsoft/vscode. Use when reviewing a docs PR for factual correctness: setting names, command IDs, default values, API shapes, keybindings, versioned availability, and described behavior.

    Also in 3 projects that use this

  • VercelSkill

    vercel-react-best-practices

    React and Next.js performance optimization guidelines from Vercel Engineering. This skill should be used when writing, reviewing, or refactoring React/Next.js code to ensure optimal performance patterns. Triggers on tasks involving React components, Next.js pages, data fetching, bundle optimization, or performance improvements.

    Also in 3 projects that use this

  • BlockSkill

    frontend-design

    Create distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.

    Also in 4 projects that use this

  • MicrosoftSkill

    handoff

    Compact the current conversation into a handoff document for another agent to pick up.

    Also in 3 projects that use this

  • SentrySkill

    skill-creator

    Create new agent skills following the Agent Skills specification. Use when asked to "create a skill", "add a new skill", "write a skill", "make a skill", "build a skill", or scaffold a new skill with SKILL.md. Guides through requirements, writing, registration, and verification.

    Also in 3 projects that use this

The file

We split this skill into the rules it gives an agent

9 rules. 0 are common, 3 are distinctive, and 6 are very specific to this project.

  • 0

    Common

    Most of the 14 edited versions we read keep these.

  • 3

    Distinctive

    This author's own choices. Worth a look.

  • 6

    Very specific

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

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    Every type prints with a when to use line saying what it is for and what it is not for.

    line 37
  2. Distinctive:

    Do not reach for one unasked.

    line 82
  3. Very specific:

    Read the house rules: ${CLAUDE_PLUGIN_ROOT}/templates/house-rules.md.

    line 90
  4. Very specific:

    Read the component rules: ${CLAUDE_PLUGIN_ROOT}/references/spec-components.md — keep its Choosing table (top of the file) in context.

    line 91
  5. Very specific:

    If you are asked to review a spec rather than write one, this is the wrong skill: write-review files the review as a child spec of the one …

    line 126
  6. Very specific:

    When that is what you find, the section set is decided and your job is to fill it, not to redesign it.

    line 143
  7. Very specific:

    Do not go looking for references/spec-language.md to supplement it: a rule the owner deleted is deleted, and reading the shipped file …

    line 150
  8. Very specific:

    Leave impl-decisions / deviations / tradeoffs as the empty stubs — or the runtime section holding them, depending on the template.

    line 230
  9. Distinctive:

    Read it there, in full, before you write a sentence of the spec.

    line 244

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

create-spec

Generate a new SpecForge spec in the global store (~/.specforge/specs/<id>/), honoring house rules, and lint it before declaring done. The daemon serves it and injects the review layer at serve time.

${CLAUDE_PLUGIN_ROOT} below denotes the installed plugin directory. Claude and Pi export it; Codex provides the exact value in SpecForge SessionStart context. Substitute that value in every path and shell command.

1. Understand the request + pick the type

  • Identify the topic. If scope is unclear or has multiple interpretations, ask before writing — don't guess.
  • Read the type list before picking. It is the list, and it is not short:

    node "${CLAUDE_PLUGIN_ROOT}/lib/spec-types-cli.mjs"

    Every type prints with a when to use line saying what it is for and what it is not for. That line is the rule. This skill deliberately does not repeat the types here: a copy in this file goes stale the moment a type is added or its description is sharpened, and a stale copy is worse than no copy because it reads as authoritative.

  • Pick by reading all of them, not by stopping at the first plausible match. That is the failure this list exists to prevent, and it has a shape: a request to plan a release matches general on a quick read and launch-plan on a full one, and the first produces a document with none of the sections that make a launch survivable. Four rules settle nearly every case:

    • The request names a type, take it. "Write a PRD", "do a security review", "test plan for this" name a type. Do not reinterpret them.
    • Two fit, take the more specific one. A specific type carries sections and guidance the general one cannot. design-impl beats general for a design that will be built; code-exploration-spec beats research when the subject is code in this repo.
    • The type is decided by what the document has to do, not by the verb. "Explore" appears in research, exploration-spec, code-exploration-spec and design-exploration-spec, and the four differ by whether there is a question with a right answer, a space to map, a codebase to read, or options to compare.
    • general is the fallback, never the way to avoid choosing. Reach for it only when you have read the list and nothing fits, and say in one line what it did not fit, since that is how a missing type gets noticed.
  • Confirm in one line before writing ("Creating a launch-plan spec — sound right?"). One line, not a menu: the user corrects a wrong pick faster than they answer a question about it.

Is it a child spec? A child spec is a full spec of its own that records which spec it belongs to: its own id, its own URL, its own status, its own review cycle. What it is for is one area of a larger spec that has grown enough to be read on its own — the code grounding behind a design, the research it rests on, the testing strategy that follows from it.

Pass --parent <id> when the user asks for one, in either of the two ways they arrive:

  • In the request. "Write a design spec for X, with a child spec for the code grounding" is two creates, the second carrying --parent with the first's id.
  • In a review comment. A comment on a parent asking for a child is answered by making one and replying with its id and URL. See the review-spec skill.

Do not reach for one unasked. Splitting a spec is the user's call about how they want to read it, and a design that is 900 words does not need a child spec for its testing section. The type is still chosen from the list above and on the same rules: a child is not a kind of spec, it is a spec with a parent.

A child takes its parent's project and collection unless you pass your own, so it is filed beside the spec it belongs to rather than wherever the home page was pointing.

  • Read the house rules: ${CLAUDE_PLUGIN_ROOT}/templates/house-rules.md.
  • Read the component rules: ${CLAUDE_PLUGIN_ROOT}/references/spec-components.md — keep its Choosing table (top of the file) in context; read an individual component's entry when that component is used (grep the file for its heading), not before. Pick by what a block asserts, never by how it should look. Its Drawing section is the choice between the three ways to draw; read it before writing any diagram, because the cheapest option and the most powerful one are different choices:

    • a graph (flowchart, sequence, state, ER, class) is <pre data-lang="mermaid">, and states the relationships rather than any coordinates;
    • a picture where exact placement carries meaning is inline SVG;
    • a comparison, peer items, or anything that must reflow is a table or a grid, not a diagram at all.

    Its Interactive components section covers the three blocks that respond to a reader (<details class="disclosure">, .tabs, table.sortable). Read it before reaching for one. All three are complete with no JavaScript, so write the content as though nothing will run; what they cost is a reader's attention, not their access. The disclosure is the safe one and the only one three document products ship natively. Never put a section heading inside a disclosure — a part of the argument behind a summary line is a part a reader misses, and the lint reports it.

2. Scaffold into the store

node "${CLAUDE_PLUGIN_ROOT}/lib/specforge-cli.mjs" create --title "<title>" --type <type> --model <your model id> [--project <name>] [--parent <id>]

--model is your own model id, exactly as your harness names it (for example claude-fable-5-1, gpt-6-astra, glm-5.3-flash). The harness is detected. Together they credit you as the spec's author, shown on the home page row and in the spec's header as "✎ Claude · claude-fable-5-1". Leave it out and the credit names only the harness.

If you are asked to review a spec rather than write one, this is the wrong skill: write-review files the review as a child spec of the one you reviewed and credits you as its reviewer.

Prints { id, htmlPath, url, status, type, project, parent, parentTitle, language, skeleton, prompts }. It has started/reused the daemon, copied the type's shell to htmlPath, and attached the spec to this session. Author into htmlPath — that file IS the spec — but do not read the whole file to find the blanks: the payload's skeleton array lists every section with its id, line range, heading and placeholder text. Fill sections one at a time: read the section's slice with spec-nav section <id> --spec "<htmlPath>", edit in place between the section's existing tags, then move to the next. The style block, the TOC and the section ids never need re-reading; the verify gate checks TOC sync and section ids either way.

Most types arrive with their sections already in place. The shell you get is that type's own: its headings, its table of contents, its {{ … }} placeholders. When that is what you find, the section set is decided and your job is to fill it, not to redesign it. Only general arrives with nothing but a TL;DR, because choosing the sections is what that type is for.

language is the writing contract in force, and it is the whole of it. Not a note added to a contract you read somewhere else: it already contains SpecForge's own rules, unless this store's owner edited or removed them. Follow what it says and nothing it does not. Do not go looking for references/spec-language.md to supplement it: a rule the owner deleted is deleted, and reading the shipped file behind their back reinstates it. They edit this in the Configuration pane, under Language.

Read prompts before you write. Each entry is { section, text }: authoring guidance the spec type attaches to one section, written by the user into the template and stripped out of your copy so a reader never sees it. It is instruction, not content — follow it when you write that section. Open questions and Decisions carry one on most types, because those are the two sections review corrects most.

Projects. With no --project, the spec is filed into whichever project the home page is showing, which is usually what the user means: they are working inside that body of work. Pass it explicitly only when the request names a different one, or when the spec plainly belongs elsewhere — and say where it went in the one-line confirmation, since the default is invisible otherwise. Use --project "" to file it nowhere. A project that does not exist yet is created by using its name.

The shell comes from the store's per-type template spec (template-<type>, listed under Templates on the index) when one exists, else the bundled file. To change what future specs start from, edit the template spec like any other spec (open template-<type> and edit its html). Never delete a template spec.

3. Author from the shell — sections by type

Replace every {{ … }} placeholder ({{TITLE}}, {{DATE}} = today YYYY-MM-DD, {{STATUS}} = draft, {{OWNER}}).

If the shell already carries this type's sections, they are the skeleton. The prompts from create say what belongs in each one, and the skeletons below are for the types that do not ship with their own: read them as an example of the shape, not as a list to impose on a scaffold that already has one. Adding, cutting or reordering a shipped type's sections is a decision worth making, not a default: they are what makes that type worth having, and the type's rules are written against them.

Whatever sections you end up with:

  • Keep every <section> with a stable, unique id (anchors + comments depend on them). Keep the theme CSS (light/dark vars, [data-theme], prefers-color-scheme, --maxw) — the review layer drives theme + width.
  • Leave the stamped component block alone. The shell's <style> opens with /* specforge:components v1 start */ … /* specforge:components end */. It is generated; editing it is refused by components sync and overwritten by the next build. Your own rules go after it and win. Use the library's classes rather than restyling them: a notice is <div class="callout decision">, never <div class="callout warn">.
  • Color only via the canonical palette tokens (--bg --panel --panel2 --ink --muted --line --accent --green --amber --red --code --shadow --mono) — the lint requires them and the review-layer theme variants re-tint by overriding exactly these. Don't invent per-spec color names (--card, --ecru, …); derive any tint with color-mix(... var(--token) …). See templates/house-rules.md → Palette tokens.
  • Keep <nav class="toc"> as the floating left sidebar and keep its <a href="#…"> entries in sync with the sections you end up with.

general — the shell ships tldr and nothing else, because the sections are the use case's to decide. Work out what this document needs before you write it (a proposal wants context / proposal / impact / decision; a postmortem wants timeline / impact / root cause / actions; a runbook wants preconditions / steps / rollback), then author those sections with stable kebab-case ids, add one TOC link per section in document order, and stop. Do not import another type's skeleton wholesale. If the document turns out to need stages and tasks, it is a design-impl or impl spec: say so and rescaffold rather than growing a plan here.

design — tldr · overview (problem / motivation) · goals (goals & non-goals) · design (the core: architecture, components, alternatives, tradeoffs — use panels / tables / diagrams) · decisions · open-questions. No build plan.

research — repurpose the doc shell's sections: tldr (headline finding) · question (objective) · background · method (scope + sources consulted) · findings (the bulk, organized by sub-question; cite evidence) · analysis (synthesis) · recommendations · open-questions (gaps) · sources. Rename the section headings + ids accordingly and update the TOC to match.

design-impl (impl shell) — author tldr · overview · goals · design · decisions · open-questions, then build impl-plan as Stages → Tasks using the data-sf-stage / data-sf-task / data-sf-status markup (one stage = one PR, each task a verify: note) and mirror it into the task-tracker snapshot table. Leave impl-decisions / deviations / tradeoffs as the empty stubs — or the runtime section holding them, depending on the template. They are filled during implementation, and each entry has one fixed card shape and a fixed set of bold labels: the section's own prompt carries it, and so does specforge doc house-rules.

impl (impl shell) — keep the design prose light: tldr · overview (scope + link to the design if it lives elsewhere) · a brief design (prerequisites / context). Focus on impl-plan (Stages → Tasks) + the task-tracker snapshot, and keep the Runtime stubs. Trim goals / decisions if they add nothing.

3.5 Language (read before writing prose)

Specs follow a language contract, and language from step 2 is that contract. Read it there, in full, before you write a sentence of the spec. It is short.

There is no summary of it here on purpose. This store's owner edits these rules, and a summary would go on stating a rule after they had deleted it: a rule that is gone from the contract has nothing left to contradict a copy of itself.

4. The gate — loop until it passes

node "${CLAUDE_PLUGIN_ROOT}/lib/specforge-cli.mjs" verify <id> --json

The spec is not finished until this exits 0. It is a gate, not a report: run it, fix what it names, run it again, repeat.

On FAIL it returns failing, and every entry says what is wrong and what to do:

  • kind: "check" — a function found a defect. Fix the spec.
  • kind: "judge" — no function can answer this one. Read the spec against it. If the spec satisfies it, name it in --judged on the next run. If it does not, fix the spec.
node "${CLAUDE_PLUGIN_ROOT}/lib/specforge-cli.mjs" verify <id> --judged tldr-matches-body,decisions-have-reasons

--judged is your word, and it lasts one run — nothing is stored, so the next run asks again. A rule it does not recognise fails the gate rather than being ignored, so a typo cannot quietly settle nothing. A judged id never papers over a check defect: claiming to have judged a broken spec still fails.

Judge in a subagent if your harness can run one, handing it only the spec path and the rules to judge. A fresh reader judges a document more honestly than its author, and the author is you: an agent that has just written a spec is the party least able to notice its TL;DR overclaims. If your harness has no subagent, judge them yourself, reading the spec from the top as though you had not written it.

At most three rounds. An agent that cannot satisfy a rule in three attempts is usually failing to understand the rule rather than the spec. If you run out, hand over and say in one line which rules still fail — do not judge a rule you do not believe just to reach 0.

advisories are reported and never block. spec-language is one of them: the mechanically detectable slice of the contract, as code. Being code, it reports the rules SpecForge ships whatever this store's contract now says, so read a hit against language before acting on it, and clear the ones that contract still asks for. It cannot see register at all, so a clean report is a floor, not a pass.

The lint still exists and the gate is a superset of it; run node "${CLAUDE_PLUGIN_ROOT}/lib/lint-spec.mjs" <htmlPath> only when you want the mechanical checks alone.

5. Hand off + arm review delivery

  • Print the spec url (open it to review). Edits to htmlPath live-reload.
  • The spec is attached to this session. In Codex, finish the turn: lifecycle hooks own the background watcher and deliver browser comments automatically. Do not start a watcher or wait for comments in a tool call.
  • For an explicit Codex pickup, run node "${CLAUDE_PLUGIN_ROOT}/lib/specforge-cli.mjs" review-wait once. It checks queued work and returns immediately. Follow reason when ready is true; when reason is next-turn, finish without re-arming.
  • In Claude Code, run that command as one background task per session and re-arm it after handling delivered work. Pi owns delivery through its extension.

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.