renzrollon/interlock/spec
Claude Code and agent skill by renzrollon/interlock
- community
Checking that the SKILL.md file is still in the repository.
Take a rough intent to a reviewed, implementation-ready OpenSpec change — explore first, generate proposal, design, tasks and delta specs via the OpenSpec CLI, then gate them through an artifact review. Stops at the human checkpoint, having written nothing but specs. Use when starting a new feature, refactor, or bug fix.
Install
npx vskill@latest install renzrollon/interlock/specSKILL.md
Turn an intent into a reviewed change that is ready to implement — and then stop.
This skill writes specifications. It does not write code. By default it does not run /interlock:ship either: the gap between this skill and that one is the deliberate human checkpoint, because a spec is the cheapest place to catch a wrong idea, so that is where a person looks. --continue is an opt-in that trades that read for speed on changes a machine can prove are narrow — if passed, Read ${CLAUDE_SKILL_DIR}/continuity.md. Without the flag, nothing here bridges the gap.
This skill composes stock OpenSpec rather than replacing it. Artifact scaffolding, ordering, templates and validation all come from the openspec CLI, which is the stable contract. What this adds is the discipline around it: evidence gates, explore handoff, invariant sweeps, a decision ledger, and a review before anyone writes code.
| Flag | Effect | |
|---|---|---|
--no-explore | Skip the explore phase (intent is already sharp, or a brief exists) | |
--brief <path> | Use this explore brief; skip brief matching | |
--tdd | Force test-first task shape: tasks.md leads with a failing-test section, later sections make it green | |
--no-tdd | Force standard implementation-first shape; no leading red section. Never relaxes a bug fix's repro-first task | |
--continue | Advanced. After a clean artifact review, Read ${CLAUDE_SKILL_DIR}/continuity.md — ask interlock ready whether the checkpoint may be skipped, and ship if it says yes | |
--continue --force-checkpoint | Opt back out mid-flight. Always stops at the checkpoint, whatever readiness would have said | |
--strict | Pass to the artifact gate: one independent reviewer, routed by role, reads the artifacts in place of the session |
0. Pre-flight: the openspec CLI
If it does not print a version, stop here: before asking for intent, before explore, before openspec new change, before any Write — every later step calls the CLI.
command not found(or the shell's equivalent): the CLI is missing. Say so in one line, then runinterlock openspec provision, which installs the pinned OpenSpec into the plugin's own data directory, and probeopenspec --versionagain. If provisioning exits non-zero, quote its first line and stop; a sandbox-refused write means one run of the same command outside the sandbox. The user's own route staysnpm install --location=global @fission-ai/openspec@1.15.0, or the project's own package manager if it pins openspec.- A bare
interlockorinterlock-graphthat answerscommand not foundmeans this session predates the plugin. Until a new session, runnode "${CLAUDE_PLUGIN_ROOT}/cli/interlock"(or…/cli/interlock-graph) instead; those calls match no allow rule, so each asks for approval. - Any other error: the CLI is installed but does not run. Do not call it missing and do not offer the install line. Quote its error; the usual cause is a Node.js older than OpenSpec's floor, 20.19.0.
Either way, point at interlock doctor for the full preflight. Do not install or upgrade anything yourself, except by running interlock openspec provision, and do not scaffold openspec/changes/<name>/ by hand — the CLI owns those formats. --no-explore and --brief do not skip this step.
1. Establish intent
If the request is not clear enough to name a change, ask — open-ended, no preset options:
"What change do you want to work on? Describe what you want to build or fix."
Derive a kebab-case name from the answer ("add user authentication" → add-user-auth). Do not proceed without understanding what the user wants.
1a. Classify: feature or bug fix
bug-fix when the request matches fix, regression, broken, crash, 500, error, hang, leak, a stack trace, or an issue reference. feature otherwise.
If bug-fix, gate the proposal on evidence. Before creating any artifact, require both:
- Real log output or error message — pasted, or a path to it.
- A reproduction — a failing test path, or a command that triggers the bug.
Do not run openspec new change until both exist. If the user pushes back: "A repro is required so the fix has a pass/fail signal — without it we're fixing a symptom."
A bug-fix tasks.md must:
- Land the failing repro test as its first task.
- Constrain later tasks to the root cause only. No opportunistic renames, refactors or tidy-ups — those are a separate change.
- "Root cause only" excludes unrelated cleanup. It does not exclude other readers of the same invariant. If the root cause is a shared or transformed value — a normalized identity, a cache or dedup key, a canonicalized field — then every consumer still reading the raw form is part of this fix. Enumerate them per
${CLAUDE_PLUGIN_ROOT}/shared/INVARIANT-SWEEP.mdand give each a task. Fixing one call site and leaving its siblings on the raw form is exactly how the original bug survives its own fix.
Decide the task shape
Two shapes exist, and this picks the one §3 writes:
- standard — tests live inside the section that implements the behaviour they cover.
- TDD — a leading section of failing tests, then implementation that makes them pass.
Resolve in this order:
- `--tdd` or `--no-tdd` wins. Both passed → ask which one. Do not guess between two explicit instructions that contradict each other.
- Neither passed → behaviour-critical work gets TDD, everything else gets standard. Behaviour-critical means the change has a pass/fail core a test can pin before the code exists: a pure function, an algorithm, a parser, a transform, a state machine, or a shared or derived invariant of the kind
${CLAUDE_PLUGIN_ROOT}/shared/INVARIANT-SWEEP.mdsweeps. Plumbing, wiring, config, prose and scaffolding are not — those get standard. When a change is part core and part plumbing, judge the part the change is about, not the part with the most files. - A bug fix is already test-first and stays that way. §1a's repro-first task is not the TDD shape and is not negotiable.
--no-tddsuppresses the leading red section for the rest of the fix and never relaxes the repro;--tddon a bug fix adds nothing the repro rule did not already require.
Announce the call in one line before creating any artifact — the shape, and the reason:
task shape: TDD (pure transform with a pass/fail core) — section 1 is failing tests.
The shape is transient. It is not written into openspec/changes/<name>/ as a field and no later skill reads it back. What survives the run is the shape of tasks.md itself, which is the only thing ship consumes.
1b. Load the explore brief
Prefer a durable handoff over re-deriving discovery from chat. See ${CLAUDE_PLUGIN_ROOT}/shared/EXPLORE-BRIEF.md.
--brief <path>given → read that file, skip matching.- Otherwise:
ls -t .claude/handoff/explore-*.md 2>/dev/null | head -5 - Pick the newest brief whose
## Metatopic, slug, orsuggested_change_nameoverlaps the request (or the newest one if only a single recent brief exists and the topic is vague). - Read the matched brief first. Prefer its recommendations over re-exploring; reopen code only for gaps or contradictions.
- From
## Pending Clarifications, ask only what genuinely blocks a correct proposal. Skip anything already covered by## Assumptions Madethat the user does not contest. - If
suggested_change_nameis set and the user gave no name, use it.
No matching brief is fine — but if none exists and --no-explore was not passed, run `/interlock:explore --autonomous` now and require a decision-oriented brief: conclusions, a recommended direction, options with a winner, assumptions, pending clarifications, and only cited file:line spans. Do not ask for an inventory of every file touched. Use the brief it writes. A spec built on unexplored ground is the most expensive kind to get wrong.
Spec spawns nothing itself. The only workers on this path are explore's investigators, and explore routes them by role: it reads interlock routing explore-investigator and passes what it prints. The cost policy is read from the CLI, never from this skill, so do not name a model or an effort level when you hand off to explore.
One change or an epic. Decide the width before writing. A request that spans many subsystems, or one whose brief reads "cover everything", does not converge at the artifact gate, because a reader of a change that size always finds more. Split it into an epic of briefs, each brief one change with its own gate, and say the split at the checkpoint. Section 4 then measures it: interlock validate reports the width once the delta specs exist, and a wide change stops there.
1c. Check the ground is current
Never blocks, never branches. It exits 0 whatever it finds; read it and move on.
Two findings matter before exploring, because both mean openspec/specs/ describes something other than the code you are about to spec against:
- `unarchived` — changes that finished but were never archived, so the living specs never received their deltas. Name them and the command (
openspec archive <name>). - `stale.broken` — a living spec cites a file that no longer exists. Evidence, not inference, and worth one line even when it looks unrelated: a spec pointing at a deleted file is the clearest sign the area you are about to spec has already moved.
Then continue. Do not stop, do not ask, and do not archive on the user's behalf: archiving rewrites the living specs, which is a decision that belongs to whoever merged the change.
stale.aging is inferred from dates and rarely worth interrupting a spec run for — mention it only if it names a spec directly relevant to this change. Orphan detection needs a diff, which this skill does not have; ignore that field here.
2. Create the change
If a change with that name already exists, ask whether to continue it or start a new one.
3. Generate artifacts, CLI-driven
Parse applyRequires (artifacts needed before implementation), artifacts (each with status and dependencies), and the path context — planningHome, changeRoot, artifactPaths, actionContext. Use those paths; never assume repo-relative locations.
Then loop, in dependency order, over every artifact that is ready:
Filter each ready artifact independently; do not dump the full instructions response or prefetch every artifact. The compact response carries instruction (schema guidance), template (the structure to fill), resolvedOutputPath, and non-empty context / rules.
- Read completed dependency artifacts before writing a new one.
- Write to
resolvedOutputPath, usingtemplateas the structure. - `context` and `rules` constrain you; they are not content. Never copy
<context>,<rules>or<project_context>blocks into the artifact. - Re-run
openspec status --change "<name>" --jsonafter each write; stop when everyapplyRequiresartifact isdone.
Gates while generating
This is the start of the file. Read the full SKILL.md on GitHub.
Security
- Security scanPassed, 90 of 100Pattern checks on the skill's files.
- Model reviewPassed
Quality evaluation
- Task evaluationNot runNo evaluation yet. Run one in Skill Studio.
Source
- SKILL.md in the repositoryCheckingskills/spec/SKILL.md
Popularity
- Repository stars
- 16
- Repository forks
- 2
- 7-day trend score
- 14
Stars and forks are for the whole GitHub repository, not this skill alone. Not refreshed yet.
Works with
Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.
- Claude Code
- Cursor
- GitHub Copilot
- Windsurf
- Codex
- Gemini CLI
- Cline
- Amp
- Roo Code
- Goose
- Continue
- Kilo Code
- Junie
- Trae
- OpenHands
- Qwen Code
- AI Agent
- Tabnine Chat
- Sourcegraph Cody
- Amazon Q
- Firebase Genkit
- Sweep
- Devin
- Phind
- Mentat
- Claude Desktop
- Aider
- GPT Pilot
- Plandex
- bolt.new
- v0
- Replit Agent
- Anse
- TypingMind
- BetterChatGPT
- LibreChat
- Warp AI
- Pieces
- Fig AI
Embed badge
[](https://verified-skill.com/skills/renzrollon/interlock/spec)