Checkwright v0.16.0
2026-07-26
Checkwright is the verification layer under agent orchestration, and this
release gives it an activation path: npx checkwright init vendors pinned kit
source into your repository, registers the gates each kit can run with no
configuration, writes a checkwright.lock manifest, and commits the result.
checkwright doctor reports whether your toolchain clears the floor the battery
needs. Nothing about the verification model changes — this is how you get it
into a tree.
Tightened gates
None. Gates did land and tighten in this repository’s own scripts/ gate
directory this release — check-installer-no-deps is new, and
check-install-toolchain moved from name-set to whole-element parity — but
neither ships inside a kit, so neither can appear in a vendored tree. A reader
watching this repository’s battery grow would otherwise expect a red that cannot
reach them. The clean upgrade’s allowed-red set is empty.
Renamed knobs
None. This release adds knobs (GATE_SDK_LINT_EXTRA_DIRS, and the
installer’s INSTALLER_PACK_TMP_DIR) but renames and removes none.
Behavior changes
installer/— new. A published npm package whose payload is this repository’s kit source, assembled at pack time and stamped from the release tag.checkwright initresolves a profile (starter,delegation,full), copies the kits that profile names, registers each kit’s zero-config gates, writescheckwright.lock, and commits.checkwright doctorrenders the toolchain verdict in its exit status. The package is a delivery vehicle only: the payload is bash, and nothing resolves, compiles, or downloads at your build time — Node is used to fetch and unpack, never to run what governs your tree. What a consumer reconciles: nothing. An existing vendored tree is untouched by this release, and the wholesale-sync upgrade path in §The upgrade contract remains exactly as it was;initis an alternative to doing that sync by hand, not a replacement for it.context-kit/lib/toolfloor.sh— new library, and thePROBE_SETroster moved into it out ofcontext-kit/bin/env-probe.sh. The roster also gained a grammar —name:min-version:impl-token, sobash:4.0carries a version floor andawk::GNU/sort::coreutilscarry an implementation requirement — and gainedsortas a member. What a consumer reconciles: runningenv-probe.shis unchanged. A tree that parsedenv-probe.shfor thePROBE_SETarray reads the library instead, and must expect roster elements to carry colon-separated fields rather than being bare tool names.context-kit/bin/env-probe.sh— both version probes now read stdin from/dev/null.-Vprints a version banner for most tools but is an ordinary flag for some (GNUsort’s version-sort), so a tool that rejected--versioncould fall through to a-Vthat consumed inherited stdin and hung the probe. What a consumer reconciles: nothing — a hang becomes a result.gate-sdk/checks/check-shellcheck.sh— a newGATE_SDK_LINT_EXTRA_DIRSknob appends consumer-named directories to the derived default lint set. It is append-only, never substituted for the default, so a consumer naming a shipped script that sits under no kit root can only widen coverage. What a consumer reconciles: nothing — the knob defaults to empty and the default lint set is unchanged, so this gate cannot newly red on upgrade. Set it if you ship shell outside your kit roots.delegation-kit/SPEC.md§Layout and configuration — theDELEGATION_KIT_GATE_FILESdescription is corrected. It had said a consumer’s config widens the default; the loader guards the array withdeclare -p … ||, so a consumer declaration replaces the default outright. The mechanism did not change — the documentation was the inverse of it. What a consumer reconciles: read your own declaration. If you declareDELEGATION_KIT_GATE_FILESand expected the default’s<gates-dir>/check-*.shglob to still apply, it does not, and those gates are outsidecheck-gate-tamper’s coverage. Restate every glob you want covered. This repository had exactly that hole and fixed it in this release.
Upgrading
Replace the vendored kit directories wholesale at v0.16.0, then regenerate the
generated artifacts — the pre-commit hook and the graph projection. Then run the
full battery.
No allowed reds. No kit-shipped gate landed or tightened this release.
If you are installing for the first time
Erratum, added 2026-07-26. The pinned command below does not resolve, and
will not. This release’s tag fired the publish workflow, but the job passed npm
a package spec npm read as a GitHub owner/repo shorthand rather than as a
path, so it exited before contacting the registry and 0.16.0 was never
published. Use the unpinned npx checkwright init, which resolves whatever
version is current. Everything below this paragraph is the note as shipped.
npx checkwright@0.16.0 init does the vendoring, gate registration, and commit
for you. Two limits are worth knowing before you rely on it, because this
release ships init and doctor only — update, diff, and uninstall are
deferred:
-
Upgrading is supported, but it is spelled
init. Re-runnpx checkwright@<newer> initfrom the newer package: the version check refuses only the downgrade direction, so an upgrade passes through, the profile is re-read from yourcheckwright.lock, and files you have modified are preserved and reported rather than overwritten. You would not guess that verb, which is the honest cost ofupdatebeing deferred.--forceis a deliberate-rollback override, not the upgrade path.Erratum, added 2026-08-05. The preservation half of that promise is wrong, and it was wrong on the day this note was published. The profile re-read is accurate; files you have modified are preserved and reported rather than overwritten was not. Three classes of file were overwritten instead, and none of them needs an upgrade or a
--forceto lose your edits — a bareinitat the same version is enough. Each kit’stemplates/*-config.shwas copied into your gates directory before the hash comparison ran, so the comparison was made against the copy that had just replaced your edit and reported nothing; the affected set is every kit that ships such a template, which is most of them.gate-sdk’smsg-patterns.listwas copied the same way, and it reaches thestarterprofile, so the smallest install is affected too. And a<!-- doctrine-digest-trim: … -->line — the sanctioned way to drop a doctrine rule you do not keep resident — was discarded and its rule restored, silently, because the resulting file hashed the same as what the installer had recorded. All three predate this note: the first two landed in this release itself, the trim marker just over two weeks earlier. A fourth route reaches the same false sentence but is narrower — a release that stops shipping a fileinitcreated, followed by a later one that re-adds it — so it needs that window rather than firing on any re-run.A fix is in progress. It is in no published release, so until one ships, treat that sentence as false for those files: commit your tree before you re-run
init, and read the diff afterwards.Update, later the same day. The fix has landed:
initnow claims every file it rewrites before writing it, so a config template ormsg-patterns.listyou have edited is reported rather than silently replaced, and a declareddoctrine-digest-trimis re-emitted in its rule’s position instead of being discarded. It is still in no published release. The advice above therefore stands unchanged until one ships — this records that the work is done, not that you can stop reading the diff. - Previewing is supported.
init --dry-runprints the file plan and the manifest that would be written, which covers most of what adiffverb would add. uninstallis genuinely absent. Backing out means deleting files by hand.checkwright.lockrecords every installed path with its hash, so the work is mechanical — but there is no verb for it, and that is a real gap rather than a discoverability one.- The cross-version upgrade path is implemented but not yet smoke-covered.
The consumer smoke packs a single version and asserts a same-version re-run
leaves the tree unchanged; it does not yet exercise a version bump. If you
upgrade from
v0.16.0to the next release, you are the first execution of that path. It was read against the source, not run.
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.