Checkwright v0.21.0

2026-08-01

Checkwright is the verification layer under agent orchestration, and this release makes the battery cost what it does rather than what its process spawns do — full run 40977ms down to 23706ms while adding a gate — and puts the delegation layer’s own dispatch decisions under an oracle instead of a habit.

Tightened gates

  • check-agent-tier-explicit — a new gate. Every agent definition under DELEGATION_KIT_AGENT_DIR must declare a model: field in its frontmatter. It polices silence, not the choice: an explicit inherit passes, and only omission reds. The intent is that an unselected dispatch does not fall back to a cheap default — it inherits the dispatcher’s tier, so declining to choose silently buys the most expensive tier in reach, and buys it precisely for the read-only fan-outs that are the cheapest work you dispatch. Stating inherit is a decision; omitting the field is the same outcome reached by not deciding, and the gate makes them distinguishable.
  • check-docs-render-fidelity — tightened, not widened. It lands no new finding class, but the new batch renderer default (below) now arms on a vendored consumer’s default stack, so a renderer probe failure or a document-count mismatch can refuse (exit 2) where the gate previously ran the per-document path clean. A refusal is the gate declining to certify, never a finding about your docs.

Renamed knobs

None. Two knobs are added, neither renamed nor removed: SITE_KIT_RENDERER_BATCH (below) and DELEGATION_KIT_AGENT_DIR, the directory check-agent-tier-explicit walks. The per-document SITE_KIT_RENDERER contract is untouched and remains the fallback, so nothing you have set needs to move.

Behavior changes

  • context-kit/lib/toolfloor.sh — the declared bash floor rises from 4.0 to 4.3. This corrects a fail-open, not a requirement: the battery has been running a nameref (local -n, bash 4.3) in gate-sdk/lib/gate.sh’s couples expander, which every gate sources, so a consumer on bash 4.2 already could not run the battery — it just got a green env-probe first and an obscure syntax error second. docs/install.md’s Requirements list moves with it, held in parity by check-install-toolchain. Reconcile: if you vendor context-kit and your build hosts run bash 4.0–4.2, env-probe will now report below-contract. That reading is correct and was always true; upgrade bash or drop the namerefs from your shadowed copy of lib/gate.sh.
  • SITE_KIT_RENDERER_BATCH — an optional second renderer knob, filled by default only where the first is untouched. It renders N documents over one stream, NUL-terminated both directions and count-preserving, which is where most of this release’s wall-time saving comes from (that gate alone went 14373ms to ~700ms; almost none of the old cost was rendering — it was one interpreter start per tracked page). The seam call worth knowing: the batch default is filled only where SITE_KIT_RENDERER is itself still at its kit default. A consumer who pinned the per-document renderer at a version-locked bundle would otherwise have that deliberate pin silently replaced by the kit’s unpinned one, and the gate would report clean against a parser build they explicitly rejected. Reconcile: nothing, unless you pinned SITE_KIT_RENDERER and also want the speed — then set SITE_KIT_RENDERER_BATCH to your own batch-framing command. A half-applied pin costs speed, never fidelity. Where you set both, the kit cannot verify your two renderers agree document for document; it holds only its own pair, asserted byte-identical over a corpus by fixture.
  • delegation-kit/templates/agent-execution.md — the protocol is now scoped to the dispatched role, and its backgrounding rule states a different mechanism. A dispatched agent’s turn end kills the observer, not always the work: an Agent child is reaped with its parent, but a shell run_in_background child survives, orphaned and still writing, with nothing left able to read it — the worse case, because it mutates shared files while the next actor moves against them. The instruction is unchanged (never end a turn on work still running); the rule now also names the channel a dispatched role actually has, an in-turn wait on the work’s own artifact, because a session reasoned correctly into the failure for want of one. Reconcile if you have vendored the template: re-vendor it. If you have copied its bullets into your own always-loaded surface, the backgrounding bullet’s stated reason is the part that changed.
  • gate-sdk/lib/gate.sh and the checks named below — process-spawn hoists. No contract change and no new finding class in any of them; the work moved out of per-item subshells (check-tree-terms, check-md-refs, check-spec-pointer, and gate_kit_roots_rel itself). Reconcile: nothing. Named here because the battery’s timing profile is now materially different: check-shellcheck (~5.9s) is the largest single line where check-docs-render-fidelity used to be.

Upgrading

Replace the vendored kit directories wholesale at v0.21.0, then regenerate the generated artifacts — the pre-commit hook (check-agent-tier-explicit is a tier=precommit gate and joins the generated hook) and the graph projection. Then run the full battery.

The allowed reds. check-agent-tier-explicit reds on every agent definition in your scanned directory that omits a model: field; clear it by adding the field, stating inherit where inheriting the dispatcher’s tier is the decision you want. check-docs-render-fidelity can newly exit 2 rather than run, if the batch renderer default cannot be probed on your box; clear it by installing the default renderer or by setting SITE_KIT_RENDERER_BATCH to a command that satisfies the framing contract. Neither is a finding about your tree.

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.