spec-propose
Skill6 starsChanged 44 days agoMITView on GitHub
Draft the OpenSpec change artifacts - `proposal.md`, the `specs/` delta, `design.md`, `tasks.md` - on a fresh branch, install the wave rules that make `tasks.md` parallel-safe, validate, and commit. Use when the user says "propose this", "write the proposal", "spec this out", "/spec-propose", "turn this into an OpenSpec change", "plan this as a change", "decompose this", "what are the tasks for X", or whenever a design discussion has converged and needs artifacts. Wraps `/opsx:propose` and owns only the git seam it ignores - branch first, issue link so the later commit and PR close the ticket, commit after. Boundaries: still working out what the change even is -> `spec-explore`; artifacts already written and ready to build -> `spec-apply`; one indivisible piece of work needing no spec at all -> `git-branch-create`; a tracked ticket rather than a spec -> `git-issue-create`. This skill plans and stops - it never implements.
We split this skill into the rules it gives an agent
12 rules. About 0 are common, 3 are distinctive, and 9 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈3
Distinctive · estimate
This author's own choices. Worth a look.
9
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 23
No issue, repo has a GitHub remote and uses issues -> offer git-issue-create for this change, then set the key from the number it returns.
- Distinctive: line 24
No GitHub remote, or the user declines -> skip silently and carry on.
- Very specific: line 31
Sanity-read
tasks.md: before committing. See Disjointness Check. - Distinctive: line 98
Prefer domain and feature slices over layer slices.
- Very specific: line 100
Never split "write the tests" from the feature it covers.
- Very specific: line 118
Stop after the commit. Do not open a file under src/, do not start task 1.1, do not "get a head start" in the same response
- Very specific: line 132
Never auto-run openspec init.
- Very specific: line 133
Never mutate the global openspec profile without asking.
- Very specific: line 136
Every task has a non-empty files: and an explicit needs: (none counts, blank does not)
- Very specific: line 137
Never commit a tasks.md with overlapping files: and no needs: edge between them
- Very specific: line 140
Never author artifact content that openspec instructions would have given you
- Distinctive: line 141
Never invent a verify command.
≈ “Common” is an estimate: at least 1 in 5 of the 308,232 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.
Files
Spec Propose
converged idea -> branch -> config rules -> artifacts -> commit.
Planning only. The request that reaches this skill authorizes artifacts, nothing more, even when it is phrased as "build X" or "fix Y". See Planning Boundary.
Order is load-bearing twice: the branch exists before any artifact is written, and the wave rules are installed before tasks.md is written. Both are one-way doors.
Flow
- Preflight.
openspec context --json.no_openspec_root-> stop, offeropenspec init --tools claude, wait for the user. Never auto-init, never fall back to the current directory. Otherwise takeroot.pathas authoritative. User named a store ->openspec store list --jsonfor ids, then--store <id>on every command for the rest of the run - Branch first, via
git-branch-create. Type from the change (feat,fix,refactor), desc matching the change name. Why -> artifacts written on the base branch put an unreviewed spec onmain, and relocating them afterwards means hand-rewriting the paths in.openspec.yamlon top of the git move Link the issue, if there is one. The branch carries no ticket id of its own:
- User named an existing issue ->
git config branch.<branch>.issue <n> - No issue, repo has a GitHub remote and uses issues -> offer
git-issue-createfor this change, then set the key from the number it returns. Offer it, never file one unasked - No GitHub remote, or the user declines -> skip silently and carry on. Not every repo tracks work in issues, and a spec is perfectly valid without one
Why -> this one
git configcall is the only thing that makesgit-commit'sCloses #<n>trailer andgit-pr-create'sResolves:line fire later.git-branch-createnever writes the key, and nothing downstream can recover the number if it is not set here- User named an existing issue ->
- Derive the change name. Kebab-case, from the request, and it should read as the branch name without its
<type>/prefix. Name already taken underopenspec/changes/-> ask whether to continue that change (that isspec-apply's job) or start a new one. Never overwrite an existing change directory - Install the wave rules into
openspec/config.yamlbefore the tasks artifact is written. See Wave Rules. This is the step the whole set depends on - Scaffold.
openspec new change "<kebab-name>"->openspec/changes/<name>/.openspec.yaml. Thespec-drivenschema's artifacts areproposal-> (specs,design) ->tasks, withapplyRequires: ["tasks"] - Author the artifacts. See Delegation. Never write artifact content from your own head when
openspec instructionscan hand you the authoritative guidance - this is a wrapper - Sanity-read
tasks.mdbefore committing. See Disjointness Check. Overlap -> fix it now by merging, reassigning ownership, or ordering withneeds: - Validate.
openspec validate <change> --strict --json-> readitems[].issues, fix, re-run untilsummary.totalsis clean - Commit via
git-commit:docs(spec): add <change-name> proposal. Artifacts only. Why -> a commit mixing the spec with its implementation makes the spec unreviewable, andspec-applycan no longer revert one without the other - Stop. Print the change name, the branch, and the task count, then hand to
spec-apply
Wave Rules
tasks.md carries no dependency or file-ownership information by default, so nothing in it says what is safe to run concurrently. Force the markers at authoring time, as per-artifact rules in <root.path>/openspec/config.yaml:
rules:
tasks:
- "Every task MUST end with a `files:` line listing every path it will write."
- "Every task MUST end with a `needs:` line listing task ids it depends on, or `none`."Probed: these surface verbatim under rules in openspec instructions tasks --change "<name>" --json, and the propose workflow applies rules as constraints on the artifact it writes. That is the whole mechanism.
Rules already present in the file -> leave them alone, do not restate or reformat them.
Why -> the markers can only be forced at authoring time. openspec instructions apply --change "<name>" --json strips every continuation line on the way back out, so a tasks.md written without them can never be made parallel-safe except by rewriting it task by task.
Delegation
.claude/commands/opsx/propose.md present -> it owns artifact authoring. Invoke it and own only the git seam around it: the branch, the rules, the validate, the commit.
Absent -> drive the CLI yourself, in dependency order:
openspec status --change "<name>" --json
openspec instructions <artifact-id> --change "<name>" --jsonstatusreturnsartifacts[] {id, outputPath, status, requires, missingDeps}. Write everyreadyartifact, re-runstatus, repeat untilisPlanningComplete- The required set is
applyRequiresplus everything reachable from it byrequiresedges - the transitive closure, not the literal list. Why ->applyRequiresis["tasks"]alone, and writing onlytasks.mdleaves a change with no proposal behind it statusis FILE-EXISTENCE ONLY. Adoneartifact proves a file exists at that path, never that its dependencies do. Walk the edges yourself rather than trusting the labelinstruction,context, andrulesfrominstructionsare constraints on the writer. They are never content to paste into the artifact
Tasks Shape
What step 5's rules buy you -> references/tasks-shape.md.
files:every path the task will write. Comma separated. Required, never emptyneeds:theN.Mlabels that must be ticked first, ornone. Required- Both are continuation lines under the checkbox, indented, one key per line
spec-apply builds a wave from unticked tasks whose needs: are all ticked AND whose files: sets are pairwise disjoint. Ready is not the same as safe - both halves must hold.
Decomposition
A task is right-sized when all four hold:
- One agent can finish it in one context
- It leaves the repo's verify command green on its own
- Its
files:set is nameable now, not after starting - Its description fits without "and"
A change worth specifying at all is worth at least two tasks. One task -> either the decomposition never happened, or the work needed no spec and belongs to git-branch-create. Why -> a single task is a wave of one, so the files: and needs: markers step 5 just forced go unread and spec-apply fans out to exactly one agent; the whole mechanism this skill exists to install does nothing.
Apply the four to the description you actually wrote, not the one you had in mind. After drafting tasks.md, re-read every task line against them. Why -> "fits without 'and'" is a test on a written sentence, and a run-on that read fine while planning is the exact line that ends up in the file - nothing catches it unless something re-reads the file.
Verification belongs in the task's verify expectation - the second criterion above, which spec-apply proves by running the repo's command itself - never stapled onto the description as "and then run ...". Why -> a description ending in "then run just check" fails the "and" test and duplicates a step spec-apply already runs for every task in the wave.
Split signals -> the description needs "and" / "also"; two unrelated modules; two independent halves of the done-when.
Merge signals -> two tasks share a file; one is a one-line edit inside the other's file; neither is verifiable without the other.
Prefer domain and feature slices over layer slices. Why -> layer-sliced tasks ("all the types", "all the components", "all the tests") all touch the same files and collapse into a single wave, which is a task list that cannot parallelize at all.
Never split "write the tests" from the feature it covers. Why -> tests and their code live in the same slice, so splitting them guarantees a files: overlap and a red tree in between.
Disjointness Check
On paper, before the commit.
- List every task with its
files: - Compare every pair. Any shared path -> not parallel-safe
- Overlap, work genuinely divisible -> one task takes sole ownership of that file and every change to it
- Overlap, work not divisible -> it is one task. Merge them
- Overlap real and unavoidable (a barrel export, a shared registry, a lockfile) -> keep them separate and express it as
needs:, so they land in different waves
A pair that is neither disjoint nor ordered by needs: is a defect in tasks.md, not a decision to defer. Why -> spec-apply reads exactly these markers to build its waves; an unmarked or overlapping pair makes it stop and ask, or silently clobber if the markers lie.
Planning Boundary
The triggering request authorizes PLANNING ONLY. "Build the tag filter" reaching this skill means "write the change that describes building the tag filter".
- Stop after the commit. Do not open a file under
src/, do not start task 1.1, do not "get a head start" in the same response - Hand to
spec-applyand wait for a new request. Why -> the artifacts are a review gate; implementing in the same turn means the user reviews a spec whose code already exists, which is not a review
Planning stays with you - never fan decomposition out to workers. Why -> every task's files: set depends on the ones already assigned, so parallel planners produce overlapping slices that cannot be reconciled afterwards. Only spec-apply fans out.
When Not to Use This
- Still working out what the change even is, or which capability it touches ->
spec-explore - Artifacts already exist and the work is ready to build ->
spec-apply - One indivisible piece of work that needs no spec at all ->
git-branch-create - A tracked ticket rather than a spec ->
git-issue-create
Rules
- Never auto-run
openspec init. Offer it and wait - Never mutate the global
openspecprofile without asking.openspec config setis machine-wide, not per-repo - Branch before the first artifact, always
- Wave rules land in
openspec/config.yamlbeforetasks.mdis authored. After is too late - Every task has a non-empty
files:and an explicitneeds:(nonecounts, blank does not) - Never commit a
tasks.mdwith overlappingfiles:and noneeds:edge between them openspec validate <change> --strict --jsonpasses before the commit- The commit carries artifacts only. No implementation, no
--no-verify - Never author artifact content that
openspec instructionswould have given you - Never invent a verify command. Read the justfile or the package scripts, or ask
Other versions1 project uses a version of this.
Word for word · 0
None found.
Edited · 0
None found.
Wrote their own version · 1
- sourjya/kiro-rails★ 9same name
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository21 other files it gives its agents.
- CLAUDE.mdCLAUDE.md
- blog-writeSkill
- cloudflare-hygieneSkill
- git-branch-cleanupSkill
- git-branch-createSkill
- git-branch-syncSkill
- git-commitSkill
- git-issue-createSkill
- git-issue-startSkill
- git-issue-triageSkill
- git-pr-createSkill
- herdr-dispatchSkill
- humanizeSkill
- macos-cleanupSkill
- macos-maintenanceSkill
- obsidian-markdownSkill
- spec-applySkill
- spec-archiveSkill
- spec-exploreSkill
- spec-verifySkill
- vercel-hygieneSkill
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
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.

