Spec-driven development on OpenSpec, with mechanical spec-as-source enforcement: a custom 'spec-as-source' OpenSpec schema adds file-ownership (targets) and test-verification ([@test]) metadata to every capability spec, three scripts (link check, ownership check, manifest build) keep code and specs from drifting apart, plus requirement-gathering, spec-writer, work-review, and a session-handoff skill with a proactive context-warning hook.
68
85%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
View guide
Low
Low-risk findings worth noting
Turn "is this prompt ready?" into a mechanical check. The loop scores the
incoming prompt against a fixed rubric (templates/SCORING_RUBRIC.md),
interviews the user on the weakest dimensions, locks confirmed answers,
rewrites the prompt, and re-scores — repeating until the score crosses the
threshold — with every block of the coverage gate answered — or the round
cap is hit. The output is a refined prompt of verified quality, confirmed by
the user and handed as a file to prompt-engineer, which turns it into the
input of openspec-propose or openspec-explore.
The loop is human-in-the-loop by nature: the user is present in every round. It never runs headless and it never produces downstream artifacts (proposal, spec, code) while refinement is still in progress.
Each round moves through these phases in order. A phase is entered only when its entry condition holds and left only when its exit condition holds — no skipping except where a condition explicitly says so.
templates/SCORING_RUBRIC.md, quoting evidence for every
score above 0, and total the result.n/a or left as an open question — never invented.The loop stops on the first of these, never on a feeling of "good enough":
If the very first scoring of the incoming prompt totals 9 or more and the incoming prompt already answers every block of the coverage gate (each answer locked as the user's own words), skip the interview and rewrite phases entirely and go straight to the output contract. A prompt that is already good does not get five rounds of ceremony.
The rubric measures how good the prompt's text is. The coverage gate measures
something else: whether every block that prompt-engineer needs has been
answered. prompt-engineer runs in a fresh-context subagent with no channel
to the user, so whatever this loop does not ask is lost for good — it could
only come back downstream as n/a, which is exactly the gap the engineering
step exists to close. The questions have to happen here.
The gate covers eight blocks:
A block is covered only when a lock entry holds either the user's answer for it or the user's explicit statement that the block does not apply. Track the gate in the session document as a table, block → lock id; a block without a lock id is uncovered. Never mark a block "does not apply" on the user's behalf: if it seems not to apply, ask — the user's "no tools here" is a lock, your guess is not.
The gate is independent of the rubric score. A round totalling 9 or 10 does not cover an uncovered block, and the rubric itself keeps its five dimensions: the gate is not a sixth one, so a high score can never mask a block nobody asked about.
The interview phase absorbs the discipline of the requirement-gathering
skill. Its hard rules are restated here in full so this skill is
self-sufficient even when installed alone; consult requirement-gathering
for question craft, but the rules below are binding on their own:
n/a; it is never filled in.openspec-propose, never write a spec, and
never write code. The loop must reach its stop criterion — and the user
must confirm the output contract — before any downstream step starts.Questions come from the rubric, not from generic checklists. After each scoring round:
The loop's state lives in a session document, not in conversation memory.
At the start of a session, instantiate templates/PROMPT_SESSION.md and
keep it current from then on — it is what makes locks enforceable and
rounds auditable. The document is an artifact of the conversation (kept in
the change-planning area or scratch space), not a repo deliverable.
Record every round in it as it happens:
The ## Locked register in the session document is the loop's memory of
what the user has decided. Its rules:
## Locked — not a paraphrase.~~old text~~ — superseded) for audit. Never delete a
lock, and never treat your own reinterpretation as an override.Always active, in every phase of the loop — analyze, score, interview, lock, rewrite, re-score, and the final output contract alike:
Any information the loop needs but does not have is marked
n/aor turned into an interview question — never invented, never assumed, never filled with a plausible default.
Concretely: a rewrite that would need a fact the user never provided marks
the slot n/a or queues the fact as the next question; a score is never
propped up by imagined context; an output-contract section with nothing
confirmed to put in it says n/a rather than something plausible. When in
doubt whether something was actually stated or confirmed, it was not — ask.
Entered only when the loop has stopped — the threshold was reached (or the first-round pass fired), or the round cap was hit and the user chose to proceed anyway. This phase turns the session into the artifact the SDD workflow consumes:
templates/REFINED_PROMPT.md and fill every section from
the session document: the final prompt revision verbatim, objective,
context and source priority, scope in/out/do not change, core behavior,
edge cases, constraints, tools policy, action boundaries, output, stop
condition, capabilities touched, verification expectations, the coverage
table (each of the eight blocks with the lock id that covers it), the
final rubric score per dimension with its evidence quotes, and the
complete lock register copied verbatim (superseded entries kept
struck-through). A section with nothing confirmed to put in it says
n/a — the anti-invention invariant applies here as everywhere.prompt-engineer, which runs in a subagent and writes
ENGINEERED_PROMPT.md next to it; that engineered prompt becomes the input
of openspec-propose (or openspec-explore when the user wants to think
first). Hand the refined prompt directly to openspec-propose only when
the user explicitly chooses to skip engineering, and say that the step was
skipped. The lock register travels with the document precisely so that
downstream steps never re-ask a locked decision — everything the user
already decided is settled; downstream questions may only cover genuinely
new ground..tessl-plugin
rules
skills
handoff
handoff-skill
openspec-apply-change
openspec-archive-change
openspec-explore
openspec-propose
openspec-sync-specs
plan-judge
plan-mode
prompt-engineer
prompt-loop
requirement-gathering
spec-as-source-setup
templates
openspec-schema
spec-as-source
templates
spec-ci-sync
spec-loop
spec-rebuild
spec-verify
spec-writer
work-review