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.
71
89%
Does it follow best practices?
Impact
—
No eval scenarios have been run
Advisory
Suggest reviewing before use
Proves that spec.md capability files are the real source of truth: deletes the generated code and tests declared as targets in specs, rebuilds them from the specs, then runs spec-verify to confirm everything passes.
Only files listed under targets: in a spec's frontmatter are touched — that list is the ownership contract.
Run both before touching anything:
git diff --stat && git diff --cached --stat
find openspec/specs -mindepth 2 -maxdepth 2 -name spec.mdspec.md files found → stop: "No specs found. Nothing to rebuild from."List every targets: path and refuse any that escapes the project or points at a protected directory. Targets are written relative to the project root (e.g. src/app.py):
python3 -c "
import os, re, sys, glob
unsafe, ok = [], []
for f in sorted(glob.glob('openspec/specs/*/spec.md')):
fm = re.search(r'^---\n(.*?)\n---', open(f).read(), re.DOTALL)
if not fm: continue
for t in re.findall(r'^\s*-\s+(\S+)', fm.group(1).split('targets:')[-1], re.M):
rel = os.path.normpath(os.path.join(os.path.dirname(f), t)) if t.startswith('../') else os.path.normpath(t)
bad = os.path.isabs(t) or t.startswith('~') or rel.startswith('..') or rel.split(os.sep)[0] in ('openspec','scripts','.git','.github','.tessl','.tessl-plugin')
(unsafe if bad else ok).append((rel, f))
if unsafe:
print('UNSAFE TARGET PATHS — aborting:')
for r, f in unsafe: print(f' {r} <- {f}')
sys.exit(1)
for r, f in ok: print(f' {r} <- {f}')
"If it exits non-zero, stop — a spec is declaring a target outside the project or in a protected directory. Do not delete anything.
Write the validated deletion plan from Step 2 to .spec-rebuild-plan.md (each file to be deleted and the spec that owns it) so there is a durable record of exactly what is about to happen, then show that same list to the user and ask, in these words:
Delete these files and rebuild them from the specs? (yes/no)
Wait for an explicit yes. Anything else → stop (the plan file is harmless on its own — nothing has been deleted). Never delete without confirmation.
Delete only the validated targets paths from Step 2. Never delete openspec/, scripts/, .github/, .git/, .tessl/, .tessl-plugin/, or config files.
For each spec in openspec/specs/ (alphabetical order by capability directory name, if several share targets), issue this prompt, substituting the capability name:
The spec at openspec/specs/<capability>/spec.md is approved and is the only source of truth.
Implement all its targets from scratch:
- Create every file listed in `targets:` frontmatter.
- Implement only requirements present in the spec (### Requirement: sections). Do not add behaviour not described.
- Add `# GENERATED FROM SPEC: openspec/specs/<capability>/spec.md` as the first line of every target source file.
- In every test file that is a target, add `# @spec: openspec/specs/<capability>/spec.md` and a `# @requirement: <requirement name>` comment above each test function that covers that requirement.
Do not ask clarifying questions — the spec is the specification.Run spec-verify (check-spec-links → check-target-ownership → build-spec-manifest → test suite).
.tessl-plugin
skills
handoff
openspec-apply-change
openspec-archive-change
openspec-explore
openspec-propose
openspec-sync-specs
requirement-gathering
spec-as-source-setup
templates
openspec-schema
spec-as-source
templates
spec-ci-sync
spec-rebuild
spec-verify
spec-writer
work-review