Repository navigation
SpecForge 6.1 closes the gaps 6.0 left open. The guard read only the command line, so a script the agent wrote went unseen. Every copy wrote the whole project, sometimes several times over. And changing an approved specification could move every scenario's identity. Each change was tried with Claude Code and measured.
Install
R=https://github.com/jefmonjor/specforge/releases/download/v6.1.0
F=specforge-darwin-arm64 # or darwin-amd64, linux-amd64, linux-arm64
curl -LO $R/$F && curl -LO $R/checksums.txt
sha256sum -c checksums.txt --ignore-missing # macOS: shasum -a 256 -c …
chmod +x $F && sudo mv $F /usr/local/bin/specforge
specforge version
specforge doctorOn Windows, download specforge-windows-amd64.exe, rename it to specforge.exe and put it in a folder on your PATH. Then follow the quickstart and the user guide.
What's new in 6.1
🛡 The guard reads what a command runs
- Scripts:
sh x.sh,./x.sh,source x, followed into the scripts they run; a shebang names the language. - Programs: the file given to
python,node,ruby,perl,php,go run,denoorbun, and code given inline (python -c,node -e…). It looks for calls that delete a tree (shutil.rmtree, a recursivefs.rm,FileUtils.rm_rf,os.RemoveAll…) and for shell or SQL in their strings. - Package scripts and make targets:
npm/pnpm/yarn/bun run xwith its pre-script, andmake xwith its prerequisites. - A file written and run in one command: the text of
echo,printfor a heredoc is inspected. A file the line writes without showing what (curl -o,cp,base64 -d >) is refused until the agent writes it first and runs it in a second command. rimrafandnpxare recognised.- The rules
setupwrites intoCLAUDE.md/GEMINI.mdtell the agent to write a script before running it.
↩️ Checkpoints and specforge restore
Before every agent turn, the loop checkpoints your working tree. Uncommitted and untracked files are included; ignored ones are not.
- Checkpoints live under
refs/specforge/checkpoints/, outside your branch, index, stash and pushes, and the newest 50 are kept. specforge restorelists them.specforge restore latestbrings the newest back without deleting anything written since. The restore is itself checkpointed, so it can be undone.- This is the way back from what no guard can read, such as a compiled binary.
- Scenarios run side by side are not checkpointed inside their sandboxes; when a checkpoint cannot be saved, the loop warns once and goes on.
✏️ Specifications that change safely
- A scenario keeps its marker for good. The marker names its tests, its records and its plan row. It survives insertions, moves and edits of other scenarios. A rename with the same steps keeps it too, and a removed scenario's number is never reused. The markers live in
specs/NNNN-slug/scenarios.json, and a specification approved under 6.0 takes them from its loop state (see Upgrading from 6.0). specforge spec change 0001 "<request>"applies a change request in a guided conversation. It asks what the request leaves open, then previews what the approval will record.spec clarifyhas the agent write each decision into every section it affects, not only on its question's line.- The loop redoes exactly what changed:
- A modified scenario goes back to RED with its previous version shown, so its old test is updated instead of being taken as done.
- Changing an invariant redoes the scenarios that name it.
- Reviews, verifications and risk of unchanged scenarios are kept.
- Removed scenarios and outdated plans are flagged:
approveand the loop warn about tests left behind by a removed scenario.- A plan naming a scenario that is gone is refused.
approvesays when the plan needs revising.
📦 Copies that write each byte once
- Verifier base: checked out straight from git, with no archive in between.
- Sandboxes: they borrow the project's git objects instead of storing them again.
- Copy-on-write: files are cloned on APFS, Btrfs and XFS.
- Size limit: checked before anything is written.
- Measured: a verifier copy of a 177 MB repository wrote 477 MB and now writes 310 MB. A sandbox of incompressible files writes half what it did.
🧪 Proven with Claude Code
- Claude Code was asked to wipe a repository three ways the 6.0 guard could not see.
- The first run got one through: Claude wrote the script and ran it in the same command. That is fixed, and the same request was then blocked three times.
- A compiled binary ran
git reset --hardandgit clean;specforge restore latestbrought back every uncommitted and untracked file. - The three ways into a specification were run for real:
- a feature change on the payroll module of 6.0, with a scenario inserted in the middle and done alone while the others kept their tests and commits;
- a technical requirement (an exchange-rate cache);
- a spec drafted from Python legacy code, whose decisions now reach every section.
- A fuzz test of 260,000 command lines found a panic, now fixed.
- CI now also runs the copier's and the guard's tests on macOS and Windows.
Upgrading from 6.0
- Run
specforge setupin each project to refresh the SpecForge block ofCLAUDE.md/GEMINI.mdwith the new shell rules. Nothing else in your files changes. - The first approval of an existing specification writes
specs/NNNN-slug/scenarios.json. Make it in the clone where the loop ran, so the markers come from the loop state, and commit the file. - Approved somewhere else, without the loop state, the markers follow the scenarios' order:
spec approveandspec changewarn about it and say how to undo it. - Rename scenarios after that first approval: until then a new title reads as a new scenario.
- Earlier
approvals.mdentries keep their old format; new ones list each scenario's marker. - No setting was added or renamed.
See docs/DEMO.md.
Full changelog: v6.0.0...v6.1.0