agentleFS
renzrollonrenzrollon/interlock/skills/spec/SKILL.md

spec

Skill61 starsChanged 7 days agoMITView on GitHub

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.

  • Installs packages

168 other projects use a version of this.

Adopted by

Most recently taken up by

Used with

Projects with it also use backprop, ios-clean and 10 more.

Other files people use alongside this one.

Files found in the same public projects as a version of this one, more often than they turn up anywhere else. Each project counts once, large collections count for less, and this file's own repository is left out.
  • JuliusBrusseeSkill

    backprop

    Bug → spec protocol. When a bug is found or a test fails, trace the cause, decide whether a new §V invariant would catch recurrence, append to §B. This is the one non-obvious thing SDD does that plan-then-execute doesn't. Triggers on test failure, bug report, post-mortem, or explicit user ask.

    Also in 4 projects that use this

  • Saqlain-811Skill

    ios-clean

    Remove the DebugBridge SPM package and all #if DEBUG wiring from an iOS app. (gstack)

    Also in 5 projects that use this

  • Saqlain-811Skill

    ios-fix

    Autonomous iOS bug fixer. (gstack)

    Also in 5 projects that use this

  • bastosSkill

    ios-design-review

    Review iOS app UI/UX design quality using Apple's design principles and the Liquid Glass-era design language from WWDC25/26. Use when asked for a design review, UX critique, visual design assessment, or evaluation of an app's interface quality, design intent, alignment with the new Apple design system, or usability. Triggers: "design review", "UX review", "visual design critique", "review the UI", "does this design work", "evaluate this interface", "design feedback", "Liquid Glass review".

    Also in 5 projects that use this

  • ShreyRaviSkill

    plan-tune

    Self-tuning question sensitivity + developer psychographic for gstack (v1: observational). Review which AskUserQuestion prompts fire across gstack skills, set per-question preferences (never-ask / always-ask / ask-only-for-one-way), inspect the dual-track profile (what you declared vs what your behavior suggests), and enable/disable question tuning. Conversational interface — no CLI syntax required.

    Also in 7 projects that use this

  • timurgaleevSkill

    document-generate

    Generate missing docs for a feature, module or project as tutorials, how-tos, reference and explanation.

    Also in 6 projects that use this

  • +2 more from Saqlain-811

The file

Show its rules and text

We split this skill into the rules it gives an agent

21 rules. 0 are common, 9 are distinctive, and 12 are very specific to this project.

  • 0

    Common

    Most of the 145 edited versions we read keep these.

  • 9

    Distinctive

    This author's own choices. Worth a look.

  • 12

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Very specific:

    If it does not print a version, stop here: before asking for intent, before explore, before openspec new change, before any Write — every …

    line 42
  2. Distinctive:

    If the request is not clear enough to name a change, ask — open-ended, no preset options:

    line 54
  3. Very specific:

    bug-fix: when the request matches fix, regression, broken, crash, 500, error, hang, leak, a stack trace, or an issue reference.

    line 62
  4. Distinctive:

    If bug-fix, gate the proposal on evidence: Before creating any artifact, require both:

    line 64
  5. Very specific:

    Do not run openspec new change until both exist.

    line 69
  6. Very specific:

    Prefer a durable handoff over re-deriving discovery from chat.

    line 97
  7. Distinctive:

    Read the matched brief first: Prefer its recommendations over re-exploring.

    line 102
  8. Very specific:

    If suggested_change_name is set and the user gave no name, use it.

    line 104
  9. Distinctive:

    If a change with that name already exists, ask whether to continue it or start a new one.

    line 137
  10. Distinctive:

    Read completed dependency artifacts before writing a new one.

    line 157
  11. Very specific:

    Write to resolvedOutputPath, using template as the structure.

    line 158
  12. Very specific:

    context and rules constrain you; they are not content: Never copy <context>, <rules> or <project_context> blocks into the artifact.

    line 159
  13. Very specific:

    Invariant sweep: If the change touches a shared or derived value, tasks.md must include a task per consumer.

    line 164
  14. Distinctive:

    Pinned versions: If the design names a dependency without a version, ask for it.

    line 165
  15. Distinctive:

    Genuine ambiguity: Ask when it blocks a correct proposal.

    line 166
  16. Very specific:

    Default grouping is the numbered section (1.x share a wave, 2.x share the next).

    line 174
  17. Distinctive:

    Start a new numbered section only when a later set of tasks needs the previous section's output to already exist.

    line 177
  18. Very specific:

    Write openspec/changes/<name>/decisions.md.

    line 215
  19. Distinctive:

    Check the file rather than trusting that you wrote it well:

    line 224
  20. Very specific:

    Width: Read width.wide from the validate JSON.

    line 245
  21. Very specific:

    If the user passed --continue, Read ${CLAUDE_SKILL_DIR}/continuity.md and follow it.

    line 288

“Common” is measured: kept by at least 6 in 10 of the 145 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.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.

FlagEffect
--no-exploreSkip the explore phase (intent is already sharp, or a brief exists)
--brief <path>Use this explore brief; skip brief matching
--tddForce test-first task shape: tasks.md leads with a failing-test section, later sections make it green
--no-tddForce standard implementation-first shape; no leading red section. Never relaxes a bug fix's repro-first task
--continueAdvanced. 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-checkpointOpt back out mid-flight. Always stops at the checkpoint, whatever readiness would have said
--strictPass to the artifact gate: one independent reviewer, routed by role, reads the artifacts in place of the session

0. Pre-flight: the openspec CLI

openspec --version

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 run interlock openspec provision, which installs the pinned OpenSpec into the plugin's own data directory, and probe openspec --version again. 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 stays npm install -g @fission-ai/openspec@latest, or the project's own package manager if it pins openspec.
  • A bare interlock or interlock-graph that answers command not found means this session predates the plugin. Until a new session, run node "${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:

  1. Real log output or error message — pasted, or a path to it.
  2. 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.md and 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:

  1. --tdd or --no-tdd wins. Both passed → ask which one. Do not guess between two explicit instructions that contradict each other.
  2. 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.md sweeps. 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.
  3. 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-tdd suppresses the leading red section for the rest of the fix and never relaxes the repro; --tdd on 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.

  1. --brief <path> given → read that file, skip matching.
  2. Otherwise: ls -t .claude/handoff/explore-*.md 2>/dev/null | head -5
  3. Pick the newest brief whose ## Meta topic, slug, or suggested_change_name overlaps the request (or the newest one if only a single recent brief exists and the topic is vague).
  4. Read the matched brief first. Prefer its recommendations over re-exploring; reopen code only for gaps or contradictions.
  5. From ## Pending Clarifications, ask only what genuinely blocks a correct proposal. Skip anything already covered by ## Assumptions Made that the user does not contest.
  6. If suggested_change_name is 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

interlock drift --json

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

openspec new change "<name>"

If a change with that name already exists, ask whether to continue it or start a new one.


3. Generate artifacts, CLI-driven

openspec status --change "<name>" --json

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:

openspec instructions <artifact-id> --change "<name>" --json | node "${CLAUDE_PLUGIN_ROOT}/skills/spec/scripts/compact-instructions.mjs"

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, using template as 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>" --json after each write; stop when every applyRequires artifact is done.

Gates while generating

  • Invariant sweep. If the change touches a shared or derived value, tasks.md must include a task per consumer. Use interlock-graph consumers <symbol> for the structural pass, then grep for string-keyed readers. See ${CLAUDE_PLUGIN_ROOT}/shared/INVARIANT-SWEEP.md.
  • Pinned versions. If the design names a dependency without a version, ask for it. Do not gap-fill a version number — a plausible-looking wrong pin is worse than an open question.
  • Genuine ambiguity. Ask when it blocks a correct proposal. Otherwise take a reasonable default to keep momentum. Either way, write the row — see below.
  • Advisor tool. This session may have Claude Code's advisor tool because the user turned it on; this skill asks for no call to it. Never run /advisor or edit advisorModel: whether it is on, and what it spends, is the user's choice. If the session does consult it, its advice is guidance, not evidence: where it conflicts with what the code or the artifacts show, write a ledger row instead of settling it in prose. A call that fails is said at the hand-off and never retried, and the spec continues. The tool being absent is not an error either; §6 says so.
  • MODIFIED keeps every scenario. A ## MODIFIED requirement copies every #### Scenario: title its living spec holds, each scenario title verbatim. To drop or rename one, use ## REMOVED and add the requirement back under ## ADDED, because archive refuses a MODIFIED block that omits a living scenario.

Task shape for ship

tasks.md is the wave plan. A numbered ## N. section is one wave. Follow these four rules when writing it:

  1. Default grouping is the numbered section (1.x share a wave, 2.x share the next).
  2. Sequential same-file work is one checkbox — not one checkbox per TDD beat, comment move, or trap on the same production path.
  3. A task that needs another task's output when the two edit different files is a dependsOn edge, not a new section. The classifier reads the task text and emits that edge; write the dependency into the task so it can. Incrementing the section to order one cross-file dependency serializes every task in the new section that is independent of it — the edge orders only the dependent task, so its independent siblings keep sharing a batch.
  4. Start a new numbered section only when a later set of tasks needs the previous section's output to already exist. Independent files that do not need each other belong in the same section so they can share a batch.

These rules apply even when openspec instructions tasks injects no rules.tasks. Path collisions inside a section are the planner's problem (paths), and a cross-file dependency is an edge (dependsOn) — neither is a reason to increment the section number.

Never split a section to buy parallelism. The planner packs low-tier siblings in one section into a single lane run by one agent, and a small change may ship solo — the whole change implemented in order by one agent — so a section written wide does not become a spawn per checkbox. Write the sections the work actually has; how many agents run them is the planner's decision, made under caps interlock limits publishes.

Where the tests go

The four rules above are about grouping and hold under either shape. The shape decided in §1a decides only where the tests sit inside that grouping.

  • standard — unchanged from the four rules: a test checkbox lives in the section that implements the behaviour it covers.
  • TDD — ## 1. is the failing-test wave. Title it Failing tests first, and have each later section that satisfies it say so: (make §1 green). Cover the transform boundary the invariant sweep found, not just the happy path.

Rule 2 still binds inside the red wave: the failing suite is one checkbox, not one checkbox per TDD beat. A leading test section is a wave, not a licence to split. One checkbox per assertion serializes the change and buys nothing — the anti-split rule was never about disliking TDD, it was about the planner packing what you wrote.

The heading is the contract with ship, so write it exactly. /interlock:ship reads Failing tests first off the ## 1. heading and plans that section as a leading red wave: its tests run first instead of deferring to the trailing test wave, in solo mode too. A reworded heading is not a smaller signal, it is no signal — the change plans as an ordinary one, and nothing fails to tell you so except the plan preview, which will not say RED.

Two things follow from how ship treats that wave:

  • The red wave's own inter-wave check is skipped, by design. The suite is supposed to be failing there, so checking it would spend the run's fix attempts trying to repair tests that were just written on purpose. The next section's check is the gate: by then the implementation exists, and a still-red suite is a real failure. So the section that makes §1 green must be a section, not a later batch of §1 — which the numbered-section rule already gives you.
  • A dependency from an implementation task onto the red wave is now legal, where it used to fail the plan outright. Prefer to leave it out anyway: ## 1. already runs before ## 2., so (make §1 green) as prose is enough, and an edge buys ordering the sections had already.

One consequence worth stating at the checkpoint: because the red wave's check is skipped, a run cannot tell a genuinely failing suite from one that already passed. Tests that pass before the implementation exists are not pinning new behaviour — that is a review question, and §6 flags it as one.

Do not enumerate every existing test pin the change breaks. No one can list them all before the code exists, and a reviewer who asks for the complete list asks for something that cannot be written yet. Name the pins you know, by file and line, and state the bounded rule: an assertion that pins a meaning the delta specs change is updated in the task that changes that meaning, never during a remediation stage (the test guard denies test edits there), and the update names the assertion and the requirement it now pins. With that rule in tasks.md, an incomplete pin list is a warning at the artifact gate, not a blocker.

Compound notes

Once the loop has written tasks.md, and before the ledger audit in §3a, read the compound notes for the files the tasks name:

interlock note match "<name>" --json

Each entry in rows is a rule an earlier change learned about a file this change touches. For each, check that design.md and tasks.md honour its rule. Where they do not, revise the artifact, or write a ledger row (§3a) before acting on it. omitted counts matches past the cap, and unreadable counts table rows the CLI could not parse; say both at the hand-off when they are not 0. When the line exits non-zero, report its first output line and continue: notes are guidance and never a gate.

3a. The decision ledger

Write openspec/changes/<name>/decisions.md. The format, the two classes, and what makes a row invalid are the contract in ${CLAUDE_PLUGIN_ROOT}/shared/DECISION-LEDGER.md — read it and follow it; do not restate it here or invent a third class.

What this skill owes the ledger:

  1. Every ambiguity that surfaces mid-flight becomes a row, before it is acted on. Never resolve an ambiguity silently in the design prose. A decision that exists only in chat does not exist.
  2. Carry forward what explore wrote. Transcribe the rows from the brief's Pending Clarifications and Assumptions Made — ids, questions and classes as explore assigned them — as the first write to this file. Do not start a fresh ledger and do not renumber.
  3. agent_resolved is a claim, and interlock ledger audits all three parts of it. It requires a written resolution, evidence a reader can follow, and the row's id appearing in design.md. Each is checked: an empty resolution, an empty evidence cell, a hedge that asserts nothing (obvious, standard practice, see above — the whole cell, not a word inside a real citation), or an id design.md never mentions all make the row invalid, and an invalid row blocks exactly like needs_human. A missing design.md makes every reference unresolvable rather than resolving all of them.
  4. When in doubt, needs_human. A wrong agent_resolved ships an unreviewed product decision; a needless needs_human costs one question.

Check the file rather than trusting that you wrote it well:

interlock ledger "<name>" --json

It exits non-zero when the ledger blocks — a needs_human row remains, a row is invalid, or the ledger is missing entirely. An absent decisions.md is a failure of the audit, not an empty result: "no rows" reads as "nothing needs a human", which is the one conclusion a file that was never written cannot support. The output distinguishes missing from present and empty from unparseable. In the JSON, blocking is the verdict; report the needs_human entries of rows by id and question and the entries of invalidRows by reason, and read missing or unparseable as why a ledger with no rows still blocks.

A blocking ledger with rows in it is not a failure of this skill: an honest blocking ledger is the correct output for a change that hit a real product question. It is only a failure if the questions never got written down.


4. Validate

openspec validate "<name>"
interlock validate "<name>" --json

openspec validate "<name>" checks this change's delta structure and every MODIFIED block against its living spec; a bare openspec validate names no target and checks nothing. interlock validate checks the flow's own preconditions — all three artifacts present and non-empty, tasks.md actually containing checkbox tasks — and exits non-zero when the change is not implementable. Fix anything it reports before continuing. In the JSON, ready is the verdict and problems is the list to fix; an output carrying error and candidates instead of ready means the name did not resolve.

Width. Read width.wide from the validate JSON.

  • width.wide true: print the CHANGE WIDE: line(s) from the validate output verbatim, run no /interlock:review-artifacts, write no interlock autonomy line, and stop at the checkpoint (section 6) with an epic of briefs: group the delta spec capabilities from the printed list into briefs, each brief one change with its own gate, naming only capabilities from that list.
  • width absent (an older CLI): print CHANGE WIDTH: not reported by this CLI and continue to the gate.
  • width.wide false: continue to the gate.

5. Gate: artifact review

Run /interlock:review-artifacts <name> against the change, or /interlock:review-artifacts <name> --strict when --strict was passed to this skill. The gate runs once per spec run, at the end: it is not a loop, and no second reviewer is spawned to re-read a change the first one blocked. A fresh exhaustive reader of a wide change always finds more, so re-gating the whole change does not converge; it costs a full review a round and the warnings keep arriving.

  • Blockers → HALT. Record them, report them and stop at the checkpoint with the findings. Fix nothing and re-gate nothing: do not proceed to ship, and do not "fix and continue" silently, because a blocker at this gate means the spec was wrong and the user should see that before anything else happens. A re-gate is the person's call, run as /interlock:review-artifacts <change> --since <findings file>, which judges the fix rather than the whole change again.
  • Clean → record it and stop at the checkpoint.
# blockers found
interlock autonomy record review-artifacts --blockers <n>
# clean
interlock autonomy clean review-artifacts explore spec

A clean gate credits explore and spec too; a blocker resets them. That is what stops this skill earning autonomy by emitting shallow specs — the downstream gate blames whoever produced the bad artifact.

<n> is autonomyOutcome.blockers from the gate's JSON, carried over from the review — never a count made in prose, including the review's own SUMMARY: line. Continuity takes the findings file itself, so keep its path.


6. Hand off to the human

This is where the default run ends. Close with:

  • Change name and artifact paths
  • What the change does, in two or three lines
  • Assumptions made and any pending clarifications
  • Task count, and the wave shape if it is obvious
  • The task shape, and — when it is TDD — that ship will run section 1's failing tests first and skip that wave's check, so nobody is told whether the suite was genuinely red. Ask the reviewer to confirm the leading tests actually fail against the current code; a test that passes before the implementation exists pins nothing.
  • Anything the artifact review flagged below blocker severity. When the change was wide, the CHANGE WIDE: line and the epic of briefs split replace the review: no gate ran.
  • The advisor tool: whether it was available to this session, or not available in this session, and the consults the session made, by its own account. The spec meter's advisor line is the record of that count.
  • Compound notes: how many rows matched, with omitted and unreadable when not 0, or the note match line's first output line when it failed

Then say plainly: review the spec, and run /interlock:ship when it looks right.

If the user passed --continue, Read ${CLAUDE_SKILL_DIR}/continuity.md and follow it. Do not print a spec GOAL MET line on that path — if readiness launches ship, finish() prints GOAL MET: interlock ship.

Without --continue, the run ended here. First print the checkpoint card:

interlock checkpoint "<change-name>"

It prints the card; a non-zero exit is reported in one line and does not stop the hand-off. An Unknown command answer means an older interlock is first on PATH: say so in that line and name interlock doctor, whose cli-version row shows which one.

The checkpoint waits for a human, so mark it for the spec meter:

interlock notify checkpoint "<change-name>"

It sends nothing: it prints one checkpoint: line and exits 0, so run it unconditionally and never branch on the result.

Then print this greppable line so a session /goal can stop instead of wandering into implementation:

GOAL MET: interlock spec stopped at the checkpoint.

Do not run ship. Do not offer to "just start on the first task". The checkpoint is the point. Do not call /goal from this skill — a /goal does not skip the checkpoint and does not start ship. Continuity's only opt-in skip is --continue plus interlock ready.

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.