One command runs the whole verification pipeline — types, lint, structure, dead code, tests, docs, links, spelling. exit 0 means the work is complete. Agents stop guessing; humans stop re-reviewing half-finished work.
"Done" in most repos is folklore — fifteen npm scripts, a CI file that runs a different subset, and whatever the person who set it up remembers. checkride replaces that folklore with a contract: one command, one exit code, the same in every repo that adopts it.
pnpm check exits 0 when the work is complete and non-zero when it isn't — with an exit-code taxonomy, timeouts on by default, and a machine-readable summary. A gate can't be talked past.
Deep modules, enforced mechanically: a folder module's index.ts is its only public surface, and siblings never reach the internals. Humans and agents work in parallel with minimal merge conflicts.
The consumer is an LLM, so checkride never reshapes diagnostics into a common format. Each tool's own JSON lands in .check/ untouched — deleting the layer that makes every meta-runner expensive to extend.
checkride runs your pinned tools against your configs and adds no runtime dependency on any of them. Delete the dependency and the config, and the repo is exactly where it was. The worst case of adopting it is ending up where you already are.
Scripts are a list of commands. A gate needs semantics: what does each exit code promise, what may a consumer parse, what happens when a tool hangs — and can "green" ever mean "nothing ran"? checkride answers all four, and locks the answers with a contract test suite.
checkride init writes the contract into the repo: an AGENTS.md stanza stating the "exit 0 = done" rule, and a Claude Code Stop hook that fires when the agent tries to finish — exit 2 blocks the stop and sends the agent back to work until the pipeline is green.
When a check fails, the agent reads .check/summary.json, then the failing slot's raw JSON. On a big red repo, --digest writes a token-bounded excerpt so the agent starts from a capped index, not a wall of text.
Set up the harness →checkride init --baseline grandfathers the diagnostics a repo has today, so day-one runs pass — while any new diagnostic still fails. "Don't make it worse" becomes the definition of done for legacy code.
The baseline is a ratchet: fixing a grandfathered finding prunes it from the committed file permanently — it only ever shrinks. Debt is paid down monotonically instead of being ignored, or blocking adoption.
A slot is a role in the pipeline; an adapter is the concrete tool that fills it. Zero-config: checkride runs the first adapter whose config file exists and skips slots with no detected tool. The core has no runtime dependency on any checked tool — your repo owns the pinned versions.
Opt-in slots stay out of the default run, so adopting checkride — or bumping its version — never turns a repo red on a check it didn't ask for. The last four are the publish-ready bundle: they gate the artifact a consumer actually installs.
| SLOT | role | default tool | default run? |
|---|---|---|---|
| {{ row.name }} | {{ row.role }} | {{ row.tool }} | {{ row.def }} |
Install, run init, and the gate is up — alias, agent stanza, Stop hook, all of it. Existing repos adopt with a baseline; new ones scaffold green out of the box.
An agent harness for code repositories. One command, one exit code — a portable definition of done.