verirun
v0.2.1-dev
Published
Verirun — execution-grounded verification runtime for AI coding agents on Windows. The agent may propose; only evidence may prove.
Maintainers
Readme
Verirun
Execution-grounded verification runtime for AI coding agents on Windows. The agent may propose; only evidence may prove.
Verirun gives a coding agent an agent-independent way to prove that the software it just built actually behaves correctly — by launching the app, driving it, and collecting its own evidence (UI tree, filesystem, SQLite, process state, logs), then producing a verdict-of-record the agent cannot fabricate through the MCP/API surface.
The agent connects to Verirun as an MCP (stdio) client. It is treated as an
untrusted planner: it may request actions and relay requirements, but every
receipt, observation, and verdict is stamped by Verirun itself. A requirement
the agent relays carries no authority — a CONFIRMED verdict comes only from
Verirun's own invariants (e.g. "the target must not crash or hang") or from a
requirement the user authored directly.
What it is (and is not)
- Is: independent evidence collection + an auditable verdict-of-record. When
the UI says "Saved" but the file was never written, Verirun catches it from
the filesystem — not from the app's own claim (
receipt ≠ effect). - Trust boundary (V0, stated honestly): the run record is protected against fabrication via the MCP/API surface. It does not detect out-of-band tampering by another same-user process with file-write access. This is a TCB limitation, published as-is — not a marketing claim.
Requirements
- Windows 10/11.
- Node.js ≥ 22. On an LTS Node, the native dependency (better-sqlite3) installs from a prebuilt binary — no C++ build tools needed. On a brand-new non-LTS Node a prebuild may not exist yet; use an LTS Node or install the Windows build tools if the install falls back to compiling.
Quick start
# Run the MCP server (stdio). Point your coding agent's MCP config at this.
npx verirun mcp
# Environment self-check.
npx verirun doctorBefore publishing a release, run a manual pre-publish smoke: npm ci → npm test → npm pack → install the tarball on a clean prefix → verirun doctor. Publish by hand with npm publish --provenance and 2FA.
Register it with your agent (see examples/):
- Claude Code —
.mcp.json - Codex — MCP server config
- Cursor —
mcp.json
How a run works
verify_begin— declare the workspace + the scope paths this run may touch, and for a web app thedeclared_endpointsit may read. Over-broad scope (drive root, user profile, workspace root, wildcard hosts) is refused.target_launch— Verirun launches the app and starts a supervised watcher.- Drive the app:
ui_inspect,ui_search,ui_act(tiered input),wait_until.ui_inspectwalks the full depth by default and bounds the reply by node count instead —truncatedNodessays how many it left out, andmax_nodesraises the budget when you want the whole tree. Chromium-backed UIs (Electron apps, web pages) build their tree lazily, so the walk repeats until two passes agree across a real pause —settle_gap_mstunes that pause andtreeSettledreports whether they ever agreed, with the whole settle capped at six seconds. Starting a Chromium target with--force-renderer-accessibilitymakes its tree complete from the first query, and Verirun says so when the flag is missing rather than adding it for you: changing how the app under test runs is not a runtime's call. For a targeted lookup at any depth, useui_search. - Assert on evidence:
observe_filesystem,observe_sqlite,observe_logs,observe_http,assert_evaluate— the evaluator collects its own evidence; cherry-picked agent references cannot steer the result. A web app keeps its effect on a server, soobserve_httpreads the endpoint itself: GET/HEAD only, no ambient credentials, and redirects are reported rather than followed, so a 3xx cannot carry the read outside what you declared. It needs thenet_readcapability, which is never granted by default. Declare a host by IP and no name resolution is involved at all; declare it by name and it is pinned to the addresses it resolved to when scope was granted, so a later DNS change refuses the read instead of following it elsewhere. A deployment that legitimately rotates addresses (a proxy or CDN) can be allowed to move withVERIRUN_ALLOW_ENDPOINT_REPIN=1— a user-side setting, never agent-declarable — and every move is recorded in the run. verify_finalize— Verirun writes the verdict-of-record (report.md+verdict.json) and tears the run down. A run whose scripted action came back other thanEXECUTEDcannot tell a wrong app from a scenario that never happened, so a missing effect is reportedINCONCLUSIVEwith the unexecuted steps named — never as a suspected app defect.
Inspect any run's evidence chain, trust-tagged by origin:
npx verirun show <run-id>Endpoints behind a login
An agent cannot know which account you test with and must never hold your
secret, so auth lives on your side. Write http-auth.json in the run store
(verirun doctor prints the path and the exact shape):
{
"staging-api": {
"header": "Authorization",
"secret": "Bearer <token>",
"endpoint": "https://staging.example.com/api"
}
}A short-lived token (OAuth, a signed session cookie) goes in as a command
instead of a value — its stdout is the secret, cached for ttl_seconds:
{
"oauth-api": {
"header": "Authorization",
"secret_command": "gcloud auth print-identity-token",
"ttl_seconds": 300,
"endpoint": "https://api.example.com/v1"
}
}The agent then passes auth: "staging-api" to observe_http or an
http_response assertion — a name, never a value. Each profile is bound to the
endpoint prefix it may be sent to, so an agent cannot point your token at a
server of its choosing; cleartext http is accepted for loopback only; if the
endpoint echoes the secret back, it is scrubbed out of the body before the agent
or the run record sees it; and when an auth command fails, the agent is told the
exit status and nothing more — run the command yourself to see why.
Input tiers (Windows)
- Tier A — UIA patterns (invoke / set-value): targeted, no synthetic input.
- Tier B — post-message keyed input: HWND-targeted, no focus steal (cannot type into most text boxes — measured).
- Tier C — send-input / click: OS-wide, steals focus, can interleave with
your typing. Off unless
VERIRUN_ALLOW_INPUT_INJECTION=1(a user-side setting, never agent-declarable), with a focus pre-check and abort-on-focus-loss.
Telemetry
Opt-in only. Nothing is collected or transmitted by default. verirun telemetry
on starts local metric capture you can inspect with verirun telemetry
show; V0 has no network sink.
Status
V0, under active development. See the implementation plan and evidence trail in
plans/.
License
Apache-2.0.
