spec-setup
One-time discovery that teaches the spec-driven-dev pipeline how THIS project works, and saves the answers to .spec-driven.yml — project layout (single repo, monorepo, or multiple repos), issue tracke
SKILL.mdplugin/skills/spec-setup/SKILL.md
GitHubspec-setup
Learn this project's rules and context once, save them, and let every other spec-* skill reuse
them. Team rules live in a config file the team can review and change — never in the skills
themselves. What the project knows (areas, conventions, decisions) lives in
{specs_dir}/CONTEXT.md, kept small so loading it is cheap.
Where the config lives
.spec-driven.yml, found by walking up from the current directory (stop at the home folder). The
first one found wins.
| Layout | Put the file in | Share it? |
|---|---|---|
single |
the repo root | Commit it — the whole team gets the same rules |
monorepo |
the repo root | Commit it |
multi-repo |
the shared parent folder of the repos (usually not itself a git repo) | Personal by default; offer to also commit a copy into the repo the team treats as "home" |
A multi-repo config only applies inside the repos it lists. If the current repo sits under that folder but isn't listed, treat it as having no config (ask whether to add it).
Step 1 — Detect before asking
Read, don't guess. Collect a draft of every field in references/config-template.yml:
Layout.
- Inside a git repo with workspace markers (
pnpm-workspace.yaml,workspacesinpackage.json,turbo.json,nx.json,lerna.json,go.work,[workspace]inCargo.toml, severalapps/*/packages/*/services/*with their own manifests) →monorepo; list the packages. - Not inside a git repo, but sibling folders are git repos → candidate
multi-repo. Group them by remote owner (git remote get-url origin) and show the groups — the user picks which repos belong together. Never assume every folder in the parent belongs. Always also ask whether repos in other folders belong (e.g.~/clients/billing). Check each path is a git repo, and store paths inside the workspace as relative and paths outside it as absolute. - The repos of one workspace can live in unrelated places (
/Projects/frontend,~/Work/backend,/srv/database). Put the config in their shared parent folder, or in~/.spec-driven/<name>/when that parent would be the home folder or/. Then record it in~/.spec-driven/workspaces.json({"<config path>": ["<repo path>", …]}) so every repo can find it. - The user can override the detected layout. If they choose
multi-repofrom inside one repo, the workspace folder defaults to that repo's parent, with the current repo pre-selected. If they choosemonorepo, ask for the package folders. Never write amulti-repoconfig with no repos. - Otherwise →
single.
- Inside a git repo with workspace markers (
Existing written rules.
CLAUDE.md,AGENTS.md,CONTRIBUTING.md, PR templates,.github/workflows. Anything stated there is a strong default — quote it back to the user.Tracker. Ticket keys in recent branch names and commit subjects (
STP-123,#45,ENG-91), Jira/Linear links in PR templates or docs, whether GitHub Issues are enabled (gh repo view --json hasIssuesEnabled).Git, per repo. Default branch (
git symbolic-ref refs/remotes/origin/HEADorgh repo view --json defaultBranchRef); integration branches (staging,develop,pre-prod); which branch recent PRs targeted (gh pr list --state merged --limit 20 --json baseRefName); the pattern of the last ~20 remote branch names; the commit style fromgit log -30 --format=%s.Commands, per repo/package.
package.jsonscripts plus the lockfile's package manager,Makefile,pyproject.toml/tox.ini,Cargo.toml,go.mod,composer.json, CI workflow steps (CI is often the most truthful source). Dev URL from the dev script,.env.example, or framework defaults.Models per tier. Write the
models:block from the template. Ask which models the user has for each tool they installed, only if they want to tune it: the Claude defaults (haiku / sonnet / opus) work as-is, anddefaultis safe for the rest.After approval. Ask whether an approved spec should stop after each stage (
stop), or run implement → verify → review → checkpoint in one go (run-through), stopping at any failure and never pushing. Store it aspipeline.after_approval.New or existing project. Detect it (commit and file counts) and confirm in one line. Store it as
context.project. This decides what Step 4 does.
Step 2 — Confirm in one round
Show the draft as a short table grouped by layout, tracker, git, commands, and specs location. Mark each value detected (with where it came from) or guess. Then ask only about guesses and conflicts — in one message, not a drip of questions. Typical ones:
- "Your repos default to
master, but recent PRs targetedstaging. Cut work fromstaging?" - "Recent branches are bare ticket IDs (
STP-282). Keep that, or usefix/STP-282-short-slug?" - "These 6 repos share the
acmeGitHub org. Do they form one workspace for the pipeline?" - "Where should specs live — this folder's
specs/, or inside one repo so they go through PRs?"
If the user says "just use the defaults", accept the detected values and the template defaults for the rest.
Step 3 — Write and report
- Write
.spec-driven.ymlusingreferences/config-template.ymlas the shape. Keep its comments; drop fields that don't apply (e.g.repos:forsingle). Per-repo values only go underrepos:where they differ from the top level. - If it's inside a repo, tell the user it's meant to be committed (so teammates get the same rules) — don't commit it yourself.
- If
npxis available, runnpx -y @benjaminthomas/spec-driven-dev doctorfrom the config's folder. It checks that every branch, folder, andnpm runscript in the file really exists. Fix anything it reports before finishing. - Report: the file path, a one-line summary per section, and "re-run spec-setup any time these change".
Step 4 — Project context
Skip if {specs_dir}/CONTEXT.md already exists (offer a refresh instead, see references/audit.md).
- Read
references/audit.mdand follow it: a shallow audit for an existing project, or the intended stack and conventions for a new one. One round of questions, no more. - Write
{specs_dir}/CONTEXT.md(and any area files) usingreferences/context-template.md. Keep the index to 60 lines and area files to 150. - Risk scores. For an existing project, run
spec-driven-dev risk(ornpx -y @benjaminthomas/spec-driven-dev risk) to write{specs_dir}/context/risk.md. It uses git only, no model, and addsrisk.mdto.gitignorebecause it's regenerated on every run. Skip it for a new project with no history. Mention the hotspot count in the report. Setrisk.enabled: offonly if the user doesn't want it. - Offer, don't do: ask whether to add this one line to
CLAUDE.md/AGENTS.md(whichever the project uses), so hosts reload the pointer after compaction and in every new session:For spec work, read specs/CONTEXT.md first, then the "Resume here" block of any unfinished spec.Add it only on a yes. - Re-run
npx -y @benjaminthomas/spec-driven-dev doctorif available. It checks the size limits and flags context lines that point to files which no longer exist.
Quick switches (plain words, no YAML)
When the user asks to switch a feature on or off, change only that one line of .spec-driven.yml,
keep every other line and comment, and confirm in one sentence. Don't re-run discovery.
| They say | Set |
|---|---|
| "turn GitRisk off", "stop using risk scores", "ignore risky files" | risk.enabled: off |
| "turn GitRisk on", "use the risk scores" | risk.enabled: on, then run spec-driven-dev risk if {specs_dir}/context/risk.md doesn't exist yet |
| "run straight through after I approve", "fewer stops" | pipeline.after_approval: run-through |
| "stop after each stage" | pipeline.after_approval: stop |
Reply with what changed and what it means, for example: "GitRisk is now off. Investigations, plans
and reviews will ignore risk scores until you turn it back on." People who prefer a menu can run
spec-driven-dev settings in a terminal.
Updating
Re-running spec-setup with an existing config: load it, re-detect, and show only what changed or
looks stale (a branch that no longer exists, a script that was renamed). Never silently overwrite
a value the user set by hand.
Boundaries
- Writes
.spec-driven.yml,{specs_dir}/CONTEXT.mdand{specs_dir}/context/*.md, plus the one-line pointer inCLAUDE.md/AGENTS.mdonly if the user says yes. No branches, commits, pushes, installs, or code. Never installs graphify or anything else. - Never put secrets, tokens, or credentials in the config or context files. Ask before saving sensitive business details.
- A value in the config beats a detected value. If the config looks wrong mid-run (a base branch that doesn't exist), the other skills stop and point back here rather than overriding it.