with one click
spec-propose
Write or fully rewrite proposal.md (## Why /
Install with Codex or Claude Copy this prompt, paste it into Codex, Claude, or another assistant, and let it review the skill page and install it for you.
Menu
Write or fully rewrite proposal.md (## Why /
Install with Codex or Claude Copy this prompt, paste it into Codex, Claude, or another assistant, and let it review the skill page and install it for you.
Based on SOC occupation classification
Interrogates preference-driven decision points. Works through each [TBD] in research.md one by one as numbered plain-text questions; answered items are moved to
Spec-driven development workflow overview. Load this skill when the user says "spec this first / draft a proposal / design first / write a proposal", or when a task is >150 lines / spans 3+ files / introduces a new dependency / involves an architecture choice — to learn the sdd plugin's 11 commands, artifact map, and Shared Principles (HARD GATE / interrogation / Stuck Protection / Anti-Cheating).
Implement the code, advancing by proposal/tasks. A pre-command hook checks that proposal.md carries the required prerequisites. Incremental verification: call $spec-verify close to each node as it lands, don't save it all for the end.
Dispatches a researcher agent to survey industry practices and key constraints, writing findings into research.md (single file; Open[TBD]/Decided maintained as before). Changing direction = snapshot the current research.md into the research/ discarded-draft pile first, then overwrite with the new direction; old drafts can be resurrected at any time.
Verifies the current change by dispatching the independent spec-verifier agent (fresh context — the implementing conversation never audits itself) across three dimensions + charter audit. Every run updates the verification ledger spec/changes/<name>/verify.md (stable finding IDs + round diffing + unfixed-escalation). Can be re-run independently.
Archives the current change to spec/archive/YYYY-MM-DD-<name>/. Only invoked when the user explicitly says "archive". Writes an archive-stage retrospect, checks for uncommitted code, and is guarded by the check-archive hook.
| name | spec-propose |
| description | Write or fully rewrite proposal.md (## Why / |
The hook already scanned research.md before the command. If the hook blocks (outputs {"decision":"block"} to stdout, codex/hooks/) → switch to $spec-ask to resolve the [TBD] items.
Stay disciplined at the prompt level too:
spec/changes/<name>/research.md must exist## Open [TBD] must be empty## Decided + ## Practices / ## Constraints (the research conclusions for the current direction; research/ drafts don't participate unless already revived into research.md)spec/changes/<name>/proposal.md — every ## What item carries a | verify: <observable behavior / executable check> clause, and the section closes with a Not in this change list (adjacent scope explicitly excluded). Two later stages consume these: $spec-verify checks Completeness against the verify: clauses; the HARD GATE shows Not-in-this-change as the approval boundaryFull format + HARD GATE approval-marker rules + revision flow → ../spec-core/references/proposal-spec.md
The generation decision is declared at the gate, never silently attached: the user must see which trigger fired and how the work was split (the gate template's tasks line carries trigger + split), so they can veto the need or the granularity before $spec-apply.
When any one condition holds, the propose stage generates spec/changes/<name>/tasks.md as well:
Simple single-threaded implementation gets none — apply advances straight down the proposal ## What list.
Source the information (by priority):
## What — each What item → one level-1 task node## Interfaces lands the contract task (must precede all implementation tasks)## Decided is reflected in the concrete actions of the subtasksSplitting granularity:
owner assignment:
owner: frontend / owner: backenddeps derivation:
deps: <node>Execution: the main conversation (not a dispatched dev agent) writes spec/changes/<name>/tasks.md, produced in the same propose stage as proposal.md
Full format + field rules + completion marking + lifecycle → ../spec-core/references/tasks-spec.md
Heterogeneous peer review (
--codex) is not available in this port — Codex cannot be its own heterogeneous reviewer.
After writing proposal.md (+ possibly tasks.md), you MUST emit:
<HARD-GATE>
=== Proposal ready ===
Path: spec/changes/<name>/proposal.md
(if tasks.md was generated too → declare the decision, not just the fact:
+ tasks.md — trigger: <cross-stack / >5 subtasks / multi-executor>; split: <N> groups — <one-line group list>
disagree with the need or the split → say so now, before $spec-apply)
Changes — the explanation layer for the decision-maker. proposal.md stays compressed for
the executor; this block is where it gets explained. NEVER paste proposal lines verbatim.
One block per key decision (3–6):
1. <the decision, one plain sentence>
Scenario: <the concrete situation where the problem bites — who does what, what goes wrong>
Avoided by: <how this decision prevents that, in plain words>
Cost: <the price paid — dependency / latency / limitation / rework>
Register test: a smart reader who has never seen this codebase can approve or veto every
point without a follow-up question. Define each domain term at first use; a line only an
insider can parse must be rewritten around its scenario.
Decided without asking: <factual [TBD]s resolved autonomously, one line each + the evidence
used; "none" if none — mandatory line, it lets the user catch a misclassified preference>
Not in this change: <mirror What's "Not in this change" list — what approval does NOT cover>
Next:
✅ Looks good → run $spec-apply to start implementing
apply will automatically append the <!-- APPROVED: ... --> marker to the end of proposal.md
🔧 Tweak one section → $spec-revise [why | what | how | risk]
💭 Want to talk the direction over → $spec-chat
🔄 Research needs redoing → $spec-research "<new direction>"
</HARD-GATE>
After emitting the HARD GATE, NEVER write code — wait for the user to run $spec-apply or another command.
The <!-- APPROVED: ... --> marker is appended automatically by $spec-apply before it runs (treating the user's deliberate invocation as the act of approval) — the propose command does not append it directly. This design removes a redundant "reply go" step from the UX.
User rejects → go through $spec-revise [section] (local) or $spec-chat (rethink the direction).
| User reaction | Handling |
|---|---|
| Same goal, minor tweak ("change X to Y") | $spec-revise [section], re-run the HARD GATE |
| Goal / direction changed | $spec-chat to talk it through, then decide between $spec-research <new direction> and a $spec-revise tweak |
| Vague / unclear | Ask "a local tweak or a change of direction", don't guess |
## How copying research.md ## Decided verbatim (distill, don't transport)## What item without a verify: clause (leaves $spec-verify's Completeness check nothing falsifiable)## 为什么(Why)) — headers are always ## Why / ## What / ## How / ## Risk; $spec-revise targets sections by English name$spec-revise)The full anti-pattern lists for proposal.md / tasks.md are in their respective spec files.