v2.0.0: the kit stops being a folder of good intentions

Released 2026-08-31. The only major so far: four skills renamed with no shims, workers redefined as in-process sub-agents, and every doctrine the lifecycle skills read moved out of a third-party plugin and into this repository.

What we were trying to fix

By the end of the 1.x line the kit worked, and almost nothing about it could go red.

The skill names had drifted into whatever each one had been called on the day it was written: get-repo-profile, followups, systematic-debugging, legacy-upgrade. Nothing was wrong with any one of them, and together they meant a reader could not guess a skill’s name from what it did, which is the whole job a name has in a plugin whose invocation surface is its folder names.

Worse, the two skills that do the actual work, create-issue and implement-issue, read their doctrine out of the third-party superpowers plugin. Brainstorm shape, plan shape, the TDD loop: all of it lived somewhere the kit did not ship, so the kit behaved differently depending on what else the user happened to have installed. The kit is what is being dogfooded here, and it was outsourcing its own method.

And the fleet’s cost was unbounded. auto-dev dispatched workers as one-shot claude -p processes whose context nobody could see, size, or stop, and a session that ran long was discovered afterwards from a bill.

What we decided

Break things once, on purpose, and write down why.

The four skills were renamed to obey exactly two rules, verb-object or family-role, with no aliases, no shims and no deprecation window (#389). The reasoning is ADR 0012: a skill folder name is the identifier six times over, so renaming one is a breaking change and belongs in a major, and a deprecation window would have meant carrying two spellings of every name through the release that exists to remove them.

Workers became in-process sub-agents, never claude -p (#314, ADR 0007), which is what made the counted turn and context budgets of #270 possible at all: you cannot bound what you cannot observe.

The doctrine came home to skills/_shared/ (#324), so the lifecycle skills now run identically with or without any third-party plugin installed, and CI refuses a superpowers: invocation outright.

Around those three, the release filled in the record-keeping the kit had been doing in prose. ADRs became a real, askable index served by AdrMcp (#316). Trigger contracts moved out of markdown lists and into evals/*.json, one home per skill, structurally guarded (#331). CONTEXT.md gave the kit a shared vocabulary (#313). Every skill gained the same closing recap and a hand-off table CI checks (#175). A git write-gate hook started denying destructive and unguarded git writes at the tool boundary rather than in a paragraph (#326). And create-issue learned to decompose work too large for one worker into tracer-bullet children wired by real GitHub blocking edges (#315), which is the machinery this very journal entry was filed by.

What got cut

The renames stopped at the skill folders. Every commands/ entry point kept its name, and so did the scripts inside the renamed folders and the test suites named after them, because those are not the invocation surface and renaming them would have widened a breaking change for tidiness.

AdrMcp shipped as recommended, not required. Making it required would have been symmetric with RoselineMCP, and it would also have failed phase 0 for every consumer on a .NET 8 or 9 host over a feature that degrades cleanly to reading markdown files.

The two decision registries stayed two. There was a real proposal to fold the seven architectural decisions into docs/decisions.md, and it was rejected: that document registers programs with verdict vocabularies, guarded by ten rules it earned from #208, and an architectural decision has neither. Merging them would have taught every future reader that the two kinds are one.

What bit us

Roughly a quarter of this release is fixes to things the 1.x guards had been reporting confidently and wrongly, which is the tax for a release this wide.

tick-plan.sh still had raw-text comparisons left over from its round-trip hardening (#215). The release-title gate was forcing a release for nested eval fixtures (#58). strip_comments in the decision checker could not read the escaped-apostrophe shell idiom (#306). repo-setup.sh had refusals that did not name the cause they had observed (#222). The worktrees-ignored suite was sharing one scratch repository across calls (#363). And the usage measurement missed workflow-nested sub-agent transcripts entirely (#309), which meant the very numbers used to argue for the sub-agent change were undercounting.

The lesson we took from the cluster is the one the release is built around: prose that cannot go red will be wrong eventually, and you will find out from a worker improvising around it.