Checkwright v0.29.0
2026-09-28
Checkwright is the verification layer under agent orchestration, and this release applies a spec toolkit’s recipe as part of the install and ships the license text inside every kit it installs.
In brief
- If Spec Kit or OpenSpec writes your specs, one install line now fits Checkwright to that tree:
init --recipe <toolkit>, with the defaultproseprofile or withfull. There is no block to paste, and an upgrade re-applies the recipe. The Spec Kit and OpenSpec page has each toolkit’s line. - Every installed kit now carries its
LICENSE. - Items only an operator can settle get their own committed inbox, which a consultation drains.
- You may have steps to take after upgrading. Stricter gates ask you to re-run
--install-lifecycle, bind the lead template’s new consultation slot, and cite a family heading such asRequirement: <name>whole. The allowed reds below name each.
Tightened gates
check-skill-binding— lifecycle-kit/templates/lead.md gained theconsult-dispatchslot, so a lead binding shim reds until it binds it. Bind the agent type your lead dispatches a consultation as, and a threshold or off — or state that your lead dispatches none.check-merge-attrs— the derived union-merge set gained the consult inbox (LIFECYCLE_KIT_CONSULT_INBOX_FILE), so a.gitattributesmarker block written before it reds until it carries that path’smerge=unionline. Re-run--install-lifecycleto regenerate the block.check-spec-pointer— a prose citation’s lead clause is no longer admitted where another heading in the file shares it, or where the citation continues with the heading’s own separator, so a bare citation of a missing member of a heading family such asRequirement: <name>now reds. Cite the member whole, or, where a citation names a lead and runs on with its separator as prose, cite the whole heading or follow the lead with punctuation other than the heading’s own separator.
Renamed knobs
None.
Behavior changes
- lifecycle-kit/SPEC.md §The consult inbox — a committed consult inbox (
LIFECYCLE_KIT_CONSULT_INBOX_FILE, default.workflow/consult-items.md) whose items only the consult skill rules on and any session may re-class or discard with cause, written by the new--emit file-consultarm;--install-lifecyclenow writes amerge=unionline for it andcheck-merge-attrsreds its absence; close’s gap drain gains a →forward disposition for a bullet only the operator can settle, and the consult template a drain step. Re-run--install-lifecycleto add the attribute, and re-read your close and consult bindings if they restate the drain or the ritual. - delegation-kit/SPEC.md §The statusline arm — an optional inbox counter group,
DELEGATION_KIT_STATUSLINE_INBOXES(<label>=<path>elements), empty by default so the bar is unchanged; set it to show a bullet count per inbox. Nothing to do otherwise. - lifecycle-kit/templates/stages/close.md — close files a consult-owed item with
--emit file-consultwhen a[roadmap:]entry leaves the roadmap during the iteration or the first configured horizon is vacant; it re-tags nothing. Inert whereQUEUE_KIT_HORIZONSis empty; re-read your close binding if it restates step 5. - gate-sdk/SPEC.md §Consumer payload — every packed kit and the package now carry the license text as
LICENSE, placed by--pack-installerfrom the new knobGATE_SDK_PAYLOAD_LICENSE, which defaults to the root license file; a set value naming no file tracked at the packed commit refuses the pack. A publisher whose license file is named otherwise sets the knob; set it explicitly empty to place none. An adopter’s nextinitorupdatevendors aLICENSEinto each kit root. init --recipe— the package carries payload recipes andinit --recipe <name>applies one by name, composing its lines into the seamsinitwrites and dropping the gates it names, recorded incheckwright.lockasrecipesso a re-run re-applies it (installer/SPEC.md §Payload recipes). A tree that applied a companion recipe with the old pasted block keeps its seams as the adopter’s changes; takeinit’s files with--force --recipe <name>.- gate-sdk/SPEC.md §Consumer payload — a keyed knob
GATE_SDK_PAYLOAD_RECIPES(<name>→ a tracked directory, default empty) makes--pack-installerplace each directory atrecipes/<name>/in the package root; a name outside[a-z0-9][a-z0-9-]*or a directory with no tracked file refuses the pack. Nothing to do unless you publish recipes. - the Spec Kit recipe — it keeps
check-fence-command-headregistered and admitsTask:as a fence command head (CANON_KIT_FENCE_PROGRAMS_EXTRA[] = Task:), so a tree applying it throughinit --recipe speckitgains that gate. A task list holding abashfence of other non-commands now reds there; the gate’s help names the remedy, another info string or aCANON_KIT_FENCE_PROGRAMS_EXTRAline.
Upgrading
Replace the vendored kit directories wholesale at v0.29.0, or run checkwright update. Re-run --install-lifecycle if you vendor lifecycle-kit. Regenerate your generated artifacts; each freshness gate that reds prints its own regen command. Then run the full battery.
The allowed reds. check-skill-binding reds on a lead binding shim that does not bind consult-dispatch; bind it, or state that your lead dispatches none. check-merge-attrs reds on a .gitattributes block without the consult inbox’s merge=union line; re-run --install-lifecycle. check-spec-pointer reds on a bare citation of a heading-family member the file lacks, or a lead clause run on with the heading’s own separator; cite the heading whole.
The behavior changes above are declared for reading, not a mechanical scan. If a gate reds that this note does not name, the upgrade smoke was supposed to catch it first — open an issue, because that is a defect in the release rather than work for you.