Setlist 2.1.1 (edition v1.9)
Setlist 2.1.1 (edition v1.9, the reckoning edition, unchanged)
Setlist turns Claude Code into a spec-driven engineering partner: you direct as
architect and reviewer, the agent writes the code, and a spec, not the keyboard,
is the control surface.
2.1.1 is a documentation release. No command, no hook and no gate changes, and
the framework document is not edited. Every enforcement file in this release is
byte-for-byte what 2.1.0 shipped. What changed is the honesty and the legibility
of what this project tells you about its own limits.
Known limitations is now three lists instead of one
The section had grown to 29 bullets arriving as a single undifferentiated wall.
That is a bad way to read a list where the items are not the same kind of thing:
sixteen of them were deliberate design decisions, and a decision that reads like
a defect overstates the problem exactly as much as a defect that reads like a
decision understates it. The section now splits into three, each carrying its own
count:
- Design boundaries. Places the layer deliberately stops, each with the date
the decision was taken and the reason it was taken. These are not bugs and are
not scheduled to be fixed. - Open limitations. Real defects and gaps. Each one now carries a status line
naming what will close it: the release cycle it is scheduled to, the gate it
waits on, or an honest "candidate, nothing scheduled" where that is the truth. - Upstream conditions. Things this project does not control, each naming what
would lift it and the check that re-measures it every release, so it stops
being true by measurement rather than by someone remembering to look.
Every pre-existing bullet was MOVED, not rewritten. No claim, no measurement and
no workaround changed, and no bullet was deleted or softened. That is now the
stated policy for this section: the list shrinks by fixing, never by editing.
Four limitations that were true but undocumented are now listed
Three are routes the session gates do not read and the push-time trunk audit
refuses: git rebase onto a spec branch, git reset --hard onto one, and the
pathspec form of git checkout. All three were measured for this release, with
controls in both directions: each puts role-path code on your local trunk, and
each is refused at push with the remote untouched. What they cost you is the
early refusal, not the trunk.
The fourth discloses a false denial that is still present, because you are
entitled to meet it in the documentation rather than in a refused commit: a spec
that QUOTES the closing-report template inside a fenced block is refused an
ordinary commit. The detector reads the raw staged diff and does not strip
fences, so a quotation looks identical to a real close. The bullet names the
workaround that works, and names explicitly the plausible one that does not.
That bullet is scheduled to be deleted by the commit that fixes the defect,
which is the policy above working as intended.
An honest positioning note
The enforcement guarantee itself is harness-agnostic. It lives in git hooks that
git runs from its own state, so it holds under any agent, another vendor's, or
none at all, and it travels with your repository rather than with your tool. What
is Claude Code-specific is the ceremony that installs and tailors it, plus the
advisory session layer above it. Changing harness later costs you the ceremony
and the advisories, not the part that refuses work.
Upgrading from 2.1.x or 2.0.x: run /setlist:upgrade in your instance.
Because no enforcement file changes in this release, the upgrade moves the
framework document and leaves your hooks exactly as they are; the wiring check
still verifies the enforcement is live before it reports success. Full per-version
deltas are in CHANGELOG.md; the framework document ships as setlist.md
(edition v1.9).
Known open issues in this release
Everything below is in the Known limitations section of the README, with its
measurement and its workaround. This is the short list of what a new adopter
most wants to know before starting.
1. A spec that quotes the closing-report template inside a fence is refused an
ordinary commit. This is a false denial: it refuses honest work rather than
permitting dishonest work, which makes it the entry most likely to meet you
first. It is pre-existing rather than new in this release. The workaround is to
keep the quotation out of specs/*.md, where the same fenced text commits
cleanly. Staging specs/STATUS.md alongside does NOT help, because adding an
unmodified file stages nothing. A fix is scheduled for the next release cycle.
2. A compliant fast-forward or --squash close is still permanently
unpushable. Close with --no-ff, which is what /setlist:checkpoint does for
you. The commit-time and push-time layers read a fast-forward differently, and
rather than add a defence that would refuse ordinary work, it stays documented.
3. Three ordinary git commands reach the trunk without a session-level
warning. git rebase, git reset --hard, and the pathspec form of
git checkout, newly documented in this release. All three are refused at push
and the remote is not reached.
4. Secret and style scanning is best-effort early warning, not a control.
Treat any secret that reached a commit as compromised and rotate it, whatever
these hooks reported. Several structural holes in the scan are enumerated in the
README, four of them scheduled for the next release cycle.
5. The gates are verified on the platforms that are actually tested. That is
Linux and macOS on every push, plus a local bash 3.2 run before each release. It
is not a claim about every shell, every awk or every BSD. The set of tested
platforms is a list, not a proof.
6. The session gates' warnings do not reach the agent on current harnesses.
The advisory layer computes its verdict and emits it on three channels, and the
harness delivers none of them to the model when the decision is allow, which is
every advisory verdict. The feedback you actually see is the git hooks' refusal
at commit or merge time. This lifts by itself when the harness renders them.
The standing framing has not changed and is worth repeating: these hooks are a
backstop against ordinary mistakes, not a sandbox. Anything that can run a shell
can reach the trunk, and the gates have never claimed otherwise. A merge
performed in a forge's web UI is not reached by them at all. The trunk audit
(scripts/trunk-audit.sh) reads history rather than commands and is the designed
catch for that whole family. If you need a boundary that holds against deliberate
evasion, it belongs on your forge, in branch protection and required checks.