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
One registered skill instead of seventeen. The others stay in
$SKILL_SOURCE_ROOT/skills/ and are activated by reading their SKILL.md,
not by being installed.
The hard part is not matching. These skills are the ordered phases of a process, not a menu of peer tools. Asked to "implement the login" with no spec on disk, textual similarity points straight at the implementation skill — and that is the wrong answer: the right move is upstream. A router that matches by similarity alone skips phases, and skipping phases is precisely what this method exists to prevent.
So: exclude first, determine the phase second, match last.
Read ROUTER.md — the decision procedure — and follow its five stages in
order. It is the policy; this file is only the entry point.
python3 skills/skill-router/build_router.py # Stage 0: refresh the tableThen work through ROUTER.md Stage 1 → Stage 5 and act on the outcome.
| File | What it is |
|---|---|
ROUTER.md | the decision procedure — the five stages, the probes, the trace format |
routing-table.md | generated from the skills on disk: index, divergences, dangling references, verbatim descriptions |
the chosen SKILL.md | read only after the decision, and only for the skill selected |
Never decide from memory of what a skill does. The description in the table
is the routing contract; the rest of a skill is read after it has been chosen.
SKILL.md and following it — inline, or handed to a subagent.rules/ file. Rules are always-active constraints on the
router itself, not destinations.bash skills/skill-router/install.sh # absolute symlink into ~/.claude/skills/
bash skills/skill-router/install.sh --check # read-onlyA symlink, never a copy: a copy becomes a second source of truth that diverges
in silence. This repo already carries the evidence — install.sh --check
reports it.
It cannot stop the harness from auto-triggering a skill that is already
registered globally. It governs what happens when it is invoked. If an
obsolete same-named skill is installed in ~/.claude/skills/, that one may run
without the router ever being consulted — install.sh reports those, and
removing them is a separate, deliberate act.
.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-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