Checkwright v0.35.0

2026-10-25

Checkwright catches reproducible classes of unsupported claims in coding-agent delivery before merge, and this release names your own git hook when it refuses the install commit, refuses a hooks setting its restore command could not set back, and refuses a damaged marker block rather than deleting past it.

In brief

Section Entries Who acts
New and tightened gates 0 everyone: these may red on upgrade
Knob changes 0 if you set knobs
Gate-authoring changes 0 if you write or shadow gates
Platforms 0 if you install on a listed platform
Behavior changes 5 if you depend on a listed behavior
  • If one of your own git hooks refuses the install commit, the installer now names that hook and its directory, and still prints the steps that finish the setup.
  • Placing the checks now refuses a hooks setting whose printed restore command would not set it back, rather than recording one it cannot restore.
  • A file whose begin and end markers do not pair is now left untouched and named, where removing a block could delete everything after it.
  • Nothing to reconcile on upgrade: no gate is new or stricter, and no knob moved.

New and tightened gates

None.

Knob changes

None.

Gate-authoring changes

None.

Platforms

None.

Behavior changes

  • gate-sdk --install-hooks and installer uninstall, the restore line — --install-hooks now refuses at exit 2, placing nothing, a core.hooksPath set to the empty string, and on native Windows a local value Windows PowerShell 5.1 would hand git altered from the restore line, one carrying a double quote or one holding whitespace and ending in a backslash, where it recorded a value its restore line could not set back. uninstall over a chain record it cannot read now prints the record’s sentence and that the prior value is unknown, where it printed git config --unset core.hooksPath. Nothing to do unless the arm refuses; then unset or respell core.hooksPath as its help says, and re-run.
  • marker blocks: installer init --personal and uninstall, --install-doctrine and its --remove, --install-lifecycle, --emit env-probe — a target whose markers do not pair, a stray end marker ahead of the begin, a second begin left open after a complete block or a begin inside an open block, is now refused at exit 2 with the file untouched, where removing the block deleted from that begin to the end of the file; a gone worktree’s exclude block so malformed is named and left. Bytes outside the block that are not UTF-8 are now written back as they were read, where they came back as U+FFFD. Nothing to do unless a run refuses; then repair the named file’s markers and re-run.
  • installer init and uninstall, a failed commit — where git’s trace records a pre-commit, prepare-commit-msg or commit-msg hook refusing the install or removal commit, from a directory other than the gate hooks directory, the refusal now names that hook and its directory, with a help line naming the kit directories it must let pass, where it said only that the commit failed. A failed init vendoring commit now prints the follow-up block after the refusal, still exiting 1, where the run ended before it. Nothing to do; if your own hook refuses the install, let it pass the named kit directories and commit the staged files, or re-run with --no-commit.
  • canon-kit/templates/amendment.md — the amendment skeleton, renamed from canon-kit/templates/SPEC-amendment.md so no default amendment glob matches it and an adopter’s amendment-pairing check no longer reads it as an unpaired amendment. An upgraded tree keeps canon-kit/templates/SPEC-amendment.md until you delete it, since init never deletes a file a release stopped shipping; deleting it is safe whenever it is unedited.
  • lifecycle-kit stage templates and lead template, the journal markers — each stage template’s last step now names --emit journal DONE as the DONE append’s writer, and the lead template’s disposal step --emit journal --lead DISPOSED, where both named no writer and sessions hand-spelled the append. Nothing to do; a raw append stays legal.

Upgrading

Replace the vendored kit directories wholesale at v0.35.0, or run checkwright update. Regenerate your generated artifacts; each freshness gate that reds prints its own regen command. Then run the full battery.

No allowed reds.

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.