CtrlK
BlogDocsLog inGet started
Tessl Logo

spec-driven-devlopment/spec-as-source

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

Quality

89%

Does it follow best practices?

Impact

No eval scenarios have been run

SecuritybySnyk

Advisory

Suggest reviewing before use

Overview
Quality
Evals
Security
Files

SKILL.mdskills/spec-rebuild/

name:
spec-rebuild
description:
Deletes all files declared as targets in openspec/specs/**/spec.md and rebuilds them from the specs to verify spec-as-source integrity. Trigger — clean rebuild, verify source of truth, spec drift check, regenerate from specifications, rebuild from spec.

Spec Rebuild

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.

Step 1 — Safety checks

Run both before touching anything:

git diff --stat && git diff --cached --stat
find openspec/specs -mindepth 2 -maxdepth 2 -name spec.md
  • Uncommitted changes present → stop: "Commit or stash your changes before rebuilding."
  • No spec.md files found → stop: "No specs found. Nothing to rebuild from."

Step 2 — List targets and reject unsafe paths

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.

Step 3 — Confirm before deleting

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.

Step 4 — Delete the targets

Delete only the validated targets paths from Step 2. Never delete openspec/, scripts/, .github/, .git/, .tessl/, .tessl-plugin/, or config files.

Step 5 — Rebuild from specs

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.

Step 6 — Verify

Run spec-verify (check-spec-links → check-target-ownership → build-spec-manifest → test suite).

  • All checks pass → report: "Rebuild successful. Specs are the source of truth."
  • Any check fails → report which check failed and what is missing, then ask: "Retry the failed spec or stop?"

skills

spec-rebuild

README.md

tile.json