interlock
CLAUDE.md61 starsChanged 7 days agoMITView on GitHub
Autonomous spec-driven development orchestration for Claude Code, layered on OpenSpec. This file is the canonical instruction file. It lives at .claude/CLAUDE.md, not the repository root, because the root is also the plugin root and claude plugin validate --strict rejects a CLAUDE.md there. AGENTS.md, if present, is a pointer to it — do not maintain a second copy of this content there.
In this repository16 other files it gives its agents.
- bootstrapSkill
- commitSkill
- dispatchSkill
- docs-digestSkill
- evalsSkill
- explain-codeSkill
- exploreSkill
- fix-testsSkill
- graphSkill
- manual-test-planSkill
- reportSkill
- review-artifactsSkill
- review-codeSkill
- settleSkill
- shipSkill
- specSkill
The file
We split this CLAUDE.md into the rules it gives an agent
4 rules. About 0 are common, 3 are distinctive, and 1 is very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈3
Distinctive · estimate
This author's own choices. Worth a look.
1
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- could be automatic: a setting could enforce it
- Distinctive: line 11
There is no lint or build step: Do not invent one, and do not add one to a verification block.
- Distinctive: line 33
Guards fail open, never closed: Every hook allows on anything it cannot establish — unknown stage, unresolvable path, missing profile, its …
- Distinctive: line 36
Degradation is spoken, never silent: If a path degrades — a missing graph, an absent credential, an unreadable file — say so in the output.
- Very specific: line 40
Run npm test before reporting any task complete, and paste the output.
≈ “Common” is an estimate: at least 1 in 5 of the 26,980 CLAUDE.md files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Interlock
Autonomous spec-driven development orchestration for Claude Code, layered on OpenSpec.
This file is the canonical instruction file. It lives at .claude/CLAUDE.md, not the repository root, because the root is also the plugin root and claude plugin validate --strict rejects a CLAUDE.md there. AGENTS.md, if present, is a pointer to it — do not maintain a second copy of this content there.
Commands
- Test:
npm test—node --testover afind-piped file list. Run it this way; a barenode --test 'test/**/*.test.mjs'relies on runner-side glob expansion, which collects zero tests on Node 18 and 20 and reports success. - Validate the plugin:
npm run validate—claude plugin validate . --strict. Manifest and marketplace shape. - There is no lint or build step. Do not invent one, and do not add one to a verification block.
Conventions
- Zero runtime dependencies.
package.jsonhas nodependencieskey and CI installs nothing — the whole toolchain is stdlib Node. Adding a dependency is a design decision, not an implementation detail; it belongs in a change'sdesign.mdwith a pinned exact version. - Node >= 18,
"type": "module",.mjsthroughout. The one exception is the hooks module's tests,test/mod/*.test.ts:claude plugin testruns only*.test.ts/*.test.tsxfiles against the engine itself, andnpm testcollects*.test.mjsonly, so they never reach the Node runner. hooks/mod.mjs(named byhooks/hooks.json) runs inside the engine with no Node: it and everything it imports must stay free ofnode:modules and bare specifiers other thanclaude-code.test/spine/mod-pins.test.mjspins that, and its observe-only allow-list.openspec/belongs to the OpenSpec CLI. Write into it throughopenspec new change/openspec instructions, not by hand-scaffolding directories.
Architecture
cli/— the executables that land on a user's PATH (interlock,interlock-graph,interlock-run, plus theinterlock-ship-acpdeprecation shim). It is notbin/: the plugin directory asks a plugin to ship readable scripts outsidebin/, so the SessionStart preflight putscli/on the session PATH andpackage.json'sbinmap points here for npm.interlock openspec provisioninstalls the pinned OpenSpec (lib/openspec-cli.mjs,lib/openspec-pin.mjs); nothing compiled or downloaded at install time ships. Exit codes are the contract; a gate blocks by exiting non-zero.lib/— pure decision modules, one concern each. No I/O beyond what a module's name implies.lib/run.mjsis the ship loop itself: it emits the whole program as versioned steps (agents to spawn, briefings, the exact CLI argv to call next);lib/prompts/assembles every briefing those steps carry.skills/— model-facing prose. This is a shipped surface: a reworded instruction is a behaviour change.hooks/—PreToolUseandSessionStartguards, registered in.claude-plugin/plugin.json; andmod.mjs, the ship meter, a hooks modulehooks/hooks.jsonnames, which observes a ship run and decides nothing.workflows/ship.js— the drivers are interpreters, not orchestrators: this script (andcli/interlock-run) spawn what a step frominterlock runnames, create the lane worktree it names, and call what it names next. Neither holds loop logic;lib/run.mjsdoes.lib/host/— one adapter per vendor coding CLI (claude-cli,acp,codex,qwen), plus the registry that declares what each host cannot do and the one model map they all read. A capability is declared so the run program can branch on it and the runner can banner it; a host that could not be bannered is a run that degraded silently.docs/— numbered, human-facing..claude/graph/holds the agent-facing digests instead.
Things to get right
- Thresholds live in the CLI, not in prose. Caps, bands and gate verdicts are code specifically so a model cannot re-argue them. Never restate a numeric threshold in a skill or a review prompt — read it from
interlock limits, or let the gate decide. Seedocs/12-repository-review-policy.md. - Guards fail open, never closed. Every hook allows on anything it cannot establish — unknown stage, unresolvable path, missing profile, its own crash. A guard that blocked whenever its marker was absent would break ordinary work the moment the plugin is installed.
- Corpus-loss semantics differ by corpus, and the difference is deliberate. The outcome corpus and review metrics report their own write failures and never touch the exit code. The run trajectory (
.claude/ship/runs) and spill arefatal: true— a failed append exits 1, because a run nobody can reconstruct defeats the reason the file exists. Do not "make it consistent." - A prose instruction nobody asserts silently stops running.
interlock review --metricsexisted for a year and no skill ever passed it; the corpus stayed empty and read exactly like a loop that never ran. When you add an instruction to a skill, pin it intest/skills.test.mjs— and assert tokens, not sentences, or the first reword deletes the pin. - Degradation is spoken, never silent. If a path degrades — a missing graph, an absent credential, an unreadable file — say so in the output. Never fall back quietly.
Verifying your work
Run npm test before reporting any task complete, and paste the output.
If a test fails, fix the code. Do not edit, weaken, skip, or delete the test — hooks/guard-tests.mjs denies test edits during a run's remediation and fix-tests stages for exactly this reason, and doing it by hand outside a run is the same mistake without the guard.
Testing
<!-- BEGIN interlock:testing -->Unit: npm test (cwd: .)
Filter: node --test --test-name-pattern <pattern> <file>
Single file: node --test path/to/file.test.mjs
E2E: opt-in via /fix-tests --e2e (not configured)
Prerequisites: none
Profile: .claude/testing/profile.json (managed by /interlock:fix-tests)
<!-- END interlock:testing -->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
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.

