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
prompt-loop settles what the user wants: it interviews them until every
block of the task contract has an answer, and hands back a confirmed
REFINED_PROMPT.md. That document is a contract of requirements, written for
the user to confirm — not a prompt written for a model to execute. This skill
closes the gap: it turns the confirmed contract into a prompt that the complex
work downstream (openspec-propose, then implementation) can start from.
It does that by applying a cited rule corpus, references/PROMPTING_RULES.md
(R1–R38, gathered from the 2026 Anthropic guidance and converging third-party
sources), and nothing else. Its guiding principle comes from that corpus: the
prompt defines the contract of the work, not the way to think.
REFINED_PROMPT.md that
prompt-loop produced and the user confirmed. Nothing else is an input —
not a summary, not your memory of a discussion.ENGINEERED_PROMPT.md, written in the same directory as the
input, instantiated from templates/ENGINEERED_PROMPT.md.This skill MUST NOT ask the user anything and never runs an interview. Every
question belongs to prompt-loop, whose coverage gate guarantees that each of
the eight blocks — objective, context and source priority, scope, tools
policy, action boundaries, verification, output, stop condition — has either
the user's answer or the user's own statement that it does not apply. The
interview happens once, upstream, with the user present; a subagent that asked
would be talking to no one.
So the engineered prompt draws every block from the input only:
prompt-loop. Stop, and send the document
back to prompt-loop (see Procedure, step 2);Open questions holds only residual tensions found inside covered
blocks — two locks that pull in different directions, a verification
criterion that the stop condition makes unreachable. Keep both locks
verbatim, name the tension, and leave it to the user. Never use Open questions to paper over a block that was never answered.Every entry of the input's lock register goes into the output's
## Lock register byte-identical — superseded entries included, still
struck-through. The engineered prompt may restate a locked decision in the
words the block needs, but it must never contradict one. A lock rewritten
"for clarity" is a decision overridden without the user, and only a mechanical
comparison makes that visible — which is why the checker compares bytes, not
meaning.
references/ and templates/). If no path was
given, or it is unreadable, stop with a declared error naming the missing
input, and write no output file.python3 scripts/check_engineered.py --input <REFINED_PROMPT.md>.
prompt-loop for the
user to answer it; write nothing.
Only a clean exit lets you continue.references/PROMPTING_RULES.md over the refined prompt. Remove
reasoning-scripting (R9), requests to reproduce internal reasoning (R10),
and capitalised pressure (R12); replace "be careful / double-check" with
observable verification (R11, R25); say a repeated constraint once (R13).OBJECTIVE,
CONTEXT, SCOPE, TOOLS, ACTION BOUNDARIES, VERIFICATION, OUTPUT,
STOP CONDITION (R2), outcome before method (R1), context kept apart from
scope (R4), keeping only the blocks the input gives content for (R3). Write
it so a colleague who never saw the conversation could act on it (R7, R34).## Change log says what
changed and cites at least one R<n> that exists in the corpus. A change
you cannot justify by a numbered rule is taste, and taste is not this
skill's job — undo it.## Lock register.n/a when
there is none.low, medium, high, xhigh,
max, under ## Recommended effort. Depth of reasoning is a runtime
setting, so it is recommended beside the prompt and never written into it
(R37).python3 scripts/check_engineered.py <REFINED_PROMPT.md> <ENGINEERED_PROMPT.md>.
If it exits non-zero, fix what it names and run it again. An output the
checker rejects is never returned.ENGINEERED_PROMPT.md, the
checker's result, the recommended effort and any open questions. That
document — not the refined prompt — is the input of openspec-propose (or
openspec-explore).scripts/check_engineered.py (stdlib only) enforces what would otherwise be
only words: required sections present, locks byte-identical, no listed
reasoning-scripting phrase in the prompt section, every change-log entry
citing an existing R<n>, effort in the allowed set; with --input, a
readable file with a lock register and full coverage. It is a net, not the
judge: a paraphrase of a banned formula slips through it, and staying clear of
those remains your job under R9–R11.
.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