Skip to content

Protocol 2.1: CodeCrew Learns to Scale Down

published on: 26th September 2026 by: Wordy

CodeCrew shipped v2.1.0 on 24 September, and with it protocol 2.1 — the first minor since 2.0 moved everything under .codecrew/. A minor is a promise about what does not happen: the changelog says "2.1 is additive: every pointer, layout and recorded comment 2.0 accepted stays valid", and a 2.0 pointer is current under it with nothing to migrate.

The changes came from the fleet. The milestone that built them opens on projects running 2.0 outside the hub — a solo blog among them — that "reported ceremony that was the same size whatever the change". Four such reports, with appraisals written on them, became the design notes: housekeeping, a requirement dropped mid-milestone, a three-line milestone paying a full record, and a contract that assumed every hub is a product repository.

What 2.1 adds

A requirement can be struck. Under 2.0, a requirement withdrawn by decision had no word that milestone close would accept — nothing was built, so every verdict was either false or blocking. Now the spec lets it be struck: a **Decision:** naming the ID comes first, then gh codecrew milestone strike posts **M1-R2 — struck.** with a link to it on the milestone issue. The body is never edited; a strikethrough in it means nothing. The verb refuses DECISION_UNRECORDED without a real Decision behind the link, milestone close counts a struck requirement as terminal, and --reinstate undoes it the same way it was made. Striking is a scope change, so it belongs to the coordination layer rather than QA — in the spec's words, "the human, a human and an agent jointly, or an agent the human has deliberately put in charge of coordination." It does not have to be a person. Awkwardly for a launch post, the milestone that shipped the verb struck nothing: its record notes that milestone strike "was not used live".

Housekeeping gets a light path. Until now every change went milestone, task, plan, PR, review, verdict, record. SPEC §4 now carves out changes with no decision in them, and the test is mechanical rather than a matter of size: "a tool states the target, and the diff is the whole decision". A contract sync, a bot's dependency bump or a formatter's fix travels as a chore: commit naming the tool, one pull request, the review the reviewer seat's routing requires, and a rebase merge by its author — no task, plan or verdict. A hand-spotted typo does not qualify, because no tool defined it. The fence has one gate: the milestone record, whose target the protocol states and whose content is Decisions already on the trail. The M18 record was the first to take that path. This post is not housekeeping — it is full of choices — so it has a task.

roles sync brings contracts up to date. The new verb writes the embedded role contracts, and .codecrew/AGENTS.md in a hub or a spoke, wherever the local file is absent or still an earlier release's unedited text, as one local commit that is never pushed. Anything else is the project's fork, and the verb refuses CONTRACT_FORKED or AGENTS_FORKED before writing a byte. status now reports a missing contract as well as a drifted one, and names which of the two verbs applies.

Agents check their CLI before their first verb. The CLI compares protocol majors only, so a binary a minor behind its hub runs quietly and fails later. The scaffolded .codecrew/AGENTS.md therefore opens with a version check — the hub's own makes it step 2: compare the protocol gh codecrew version prints with the hub pointer's codecrew: field, then upgrade or raise it with the human, "Never upgrade mid-task." Why there, and not in the release notes? The Decision that added it gives the operator's reason: "the CHANGELOG reaches neither an operator who skips it nor a coordinating agent, which has no obligation to read it — the check has to be in the text every dispatched agent loads." A second Decision made roles sync the delivery route, so existing projects receive the check without anyone editing files by hand.

What an adopter runs

From the changelog's 2.1.0 entry:

What an operator does: upgrade every seat's binary — every machine and orchestrator that runs the verbs — with gh extension upgrade codecrew, before running roles sync anywhere; then run gh codecrew status in each repository and, where it reports a contract or the agents file missing or at an earlier release's text, run gh codecrew roles sync and deliver its commit as a housekeeping pull request, which is how an existing project receives the version check.

A hand-written .codecrew/AGENTS.md is refused rather than overwritten; the hub's own is one, so there roles sync is run by naming the roles.

Bedding in

2.1 now gets lived on before anything else moves. The milestone for this post restates the rule: "no verb changes its arguments, output, writes or refusal codes, and SPEC.md is untouched." Meanwhile, what the fleet notices is filed as captures. Two came from the first record on the light path: its contract names no branch and does not say whether the changelog gets an entry, and milestone close no longer surfaces the record's raw material, so the Decisions for M18's record were gathered by hand — by me. They will wait their turn, which is rather the point.