CtrlK
BlogDocsLog inGet started
Tessl Logo

spec-driven-development/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.

68

Quality

85%

Does it follow best practices?

Run evals on this skill

Adds up to 20 points to the overall score

View guide

SecuritybySnyk

Low

Low-risk findings worth noting

Overview
Quality
Evals
Security
Files

SKILL.mdskills/spec-as-source-setup/

name:
spec-as-source-setup
description:
Installs the spec-as-source OpenSpec schema, enforcement scripts, CI workflow, and pre-commit hooks into a project. Trigger — setup spec enforcement, add spec checks, configure spec-as-source, install spec scripts, add spec CI, install openspec schema.

Spec-as-Source Setup

Set up mechanical spec-as-source enforcement on top of OpenSpec's spec-driven workflow, using a custom spec-as-source OpenSpec schema that extends spec.md with file-ownership (targets:) and test-verification ([@test]) metadata. Execute every step in order. Create each file by copying the corresponding template from this skill's templates/ directory verbatim, unless a step says to adapt something.

Prerequisites: the openspec CLI installed and on PATH. Git repo initialized.


Step 0 — Verify or bootstrap OpenSpec

Run openspec --version. If the command is not found, install it:

npm install -g @fission-ai/openspec

(or add it as a local devDependency with npm install -D @fission-ai/openspec and prefix subsequent openspec calls with npx.)

If openspec/config.yaml does not already exist, run openspec init and follow its prompts (or pass --tools claude non-interactively if running headless). Accept the default spec-driven schema for now — Step 1 replaces it with spec-as-source.


Step 1 — Install the spec-as-source OpenSpec schema

Copy this skill's templates/openspec-schema/spec-as-source/ directory verbatim to the project's openspec/schemas/spec-as-source/ directory:

mkdir -p openspec/schemas
cp -r <skill-dir>/templates/openspec-schema/spec-as-source openspec/schemas/spec-as-source

Validate the copied schema:

openspec schema validate spec-as-source

Set it as the project's active schema by editing openspec/config.yaml: add or update the top-level schema: field to schema: spec-as-source. If openspec/config.yaml does not exist yet, create it with exactly that one line.

Confirm resolution:

openspec schema which spec-as-source

It should report Source: project.


Step 2 — Create scripts/check-spec-links.sh

Create the scripts/ directory if it does not exist. Copy templates/check-spec-links.sh to scripts/check-spec-links.sh, then make it executable:

chmod +x scripts/check-spec-links.sh

What it does: verifies that every [@test] annotation in every openspec/specs/**/spec.md points to a file that actually exists on disk. A missing test file is worse than a failing test: the requirement has no verifier.


Step 3 — Create scripts/check-target-ownership.sh

Copy templates/check-target-ownership.sh to scripts/check-target-ownership.sh, then make it executable:

chmod +x scripts/check-target-ownership.sh

What it does: detects whether any file declared as a targets entry in a capability spec has been modified without a corresponding update to its owning spec. This is the core spec-as-source guard.


Step 4 — Create scripts/build-spec-manifest.py

Copy templates/build-spec-manifest.py to scripts/build-spec-manifest.py. No chmod needed — it is a Python script called directly.

What it does: reads all openspec/specs/**/spec.md files and writes .spec-source-manifest.json — a machine-readable map of specs → requirements → targets → tests.


Step 5 — Create scripts/verify.sh

Copy templates/verify.sh to scripts/verify.sh.

What it does: orchestrates steps 2–4 in sequence, then auto-detects and runs the project test suite (pytest / npm test / cargo test).

Now make every shell script executable in one step and verify the bits actually stuck — the executable bit is a separate operation that file-write tools do not set, so a freshly written .sh is 644 until you chmod it:

chmod +x scripts/check-spec-links.sh scripts/check-target-ownership.sh scripts/verify.sh
ls -l scripts/

Every .sh in the listing must show x in its permissions (e.g. -rwxr-xr-x). If any does not, re-run the chmod. Without the executable bit the scripts are useless to pre-commit and CI. (build-spec-manifest.py needs no +x — it is called as python3 scripts/build-spec-manifest.py.)

Step 5b — Install the plan gate

Copy templates/check-plan-gate.sh to scripts/check-plan-gate.sh in the target project and make it executable:

mkdir -p scripts
cp <skill-dir>/templates/check-plan-gate.sh scripts/check-plan-gate.sh
chmod +x scripts/check-plan-gate.sh
test -x scripts/check-plan-gate.sh
if grep -Eq '^# Source: openspec/specs/.*/spec\\.md' scripts/check-plan-gate.sh; then
  echo "ERROR: installed gate references a capability spec absent from the target" >&2
  exit 1
fi

The template is target-safe: its provenance must not point at a capability spec that setup did not install. Do not create openspec/PLAN.md, add an approval block, or modify an existing plan in this step; those actions belong to plan-mode.

If scripts/check-plan-gate.sh already exists, stop before copying and report the named conflict to the human. Ask whether to keep the existing file or replace it. keep leaves its bytes and permissions unchanged. Only an explicit replace decision permits copying the template, after which setup must run chmod +x and test -x again. Never merge or silently overwrite a customized gate.


Step 6 — Create .pre-commit-config.yaml

Copy templates/pre-commit-config.yaml to .pre-commit-config.yaml in the project root. No adaptation needed.


Step 7 — Create .github/workflows/spec-verification.yml

Create .github/workflows/ if it does not exist. Copy templates/spec-verification.yml to .github/workflows/spec-verification.yml.

Auto-detect the test runner — do not block the rest of setup waiting for an answer. The CI file must exist on disk before you move on. First match wins:

  • pytest.ini / setup.cfg / pyproject.toml [tool.pytest]pytest
  • package.json with a test script → npm (jest/vitest if in devDependencies)
  • Cargo.tomlcargo
  • go.modgo
  • no match → default to pytest and flag it in the confirmation below

Then replace the # ADAPT: install and run tests here placeholder with the install + test steps for the detected runner (never leave the placeholder in the final file):

Runnersteps to insert
pytest- uses: actions/setup-python@v5
with: { python-version: "3.11" }
- run: pip install -r requirements.txt
- run: pytest -v
npm- uses: actions/setup-node@v4
with: { node-version: "20" }
- run: npm ci
- run: npm test
cargo- run: cargo test
go- run: go test ./...

After writing the file, surface the runner as a non-blocking confirmation (state it, then keep going — do not wait):

"I detected and configured the CI workflow accordingly. If this project uses a different runner, tell me and I'll re-sync it with spec-ci-sync."

Continue to Step 8 immediately.


Step 8 — Post-setup checklist

After creating all files, write this checklist to SPEC_SETUP.md in the project root and print it verbatim, so the user has both a durable record and the in-session reminder:

Setup complete. Remaining steps:

1. Enable pre-commit locally:
   pip install pre-commit && pre-commit install

2. On GitHub → Settings → Branches → Add rule for "main":
   ✓ Require status checks to pass before merging
   ✓ Require branches to be up to date before merging
   ✓ Status check: "Run spec verification"

3. Start your first change with openspec-propose (or openspec-explore), then
   openspec-apply-change to implement it, then spec-verify to check it.

Step 9 — Verify the install

Run verification automatically by invoking spec-verify (it runs the three spec checks plus the test suite and writes .spec-verify-report.md). This both proves the freshly installed scripts work and leaves a baseline report. Do not end the setup before this runs.


spec-as-source — built by Giuseppe Di Canosa.

skills

README.md

tile.json