feat: verify a run package from a shell - #32
Merged
Merged
Conversation
`pnpm verify <run-package.zip>` verifies a run and writes the same JSON and Markdown evidence pack the product exports, so an evaluation pipeline or a CI job can do what previously needed the import screen. It is the import screen's own code rather than a second implementation: the same `importRun`, the same `readContractArtifact`, and the same deterministic verifier behind `buildRunView`. A package that verifies here verifies identically in the product, because there is only one of each check. The contract comes from whichever of three sources is available, in the order the product prefers: named with `--contract`, shipped inside the package, or the frozen sample contract whose task fingerprint the run reproduces. When none is, the command says so and stops. It never compiles one, so no model is called on any path — verification never calls one either, which is the product's central claim. Exit codes separate a failed run from a broken invocation: 0 for PASS, 1 for FAIL, 2 when the package, the contract or the invocation did not validate. NEEDS_REVIEW is a real outcome rather than an error, so whether it fails the command is the caller's choice via `--fail-on-needs-review`. `parseContractDocument` is extracted from the importer and shared, so a contract passed on the command line reports the same problems, field by field, as one uploaded through the screen. Two readers would drift. Five integration tests run the real command rather than calling the module, since an exit code is only worth asserting if a process produced it: the sample package end to end including both written files and `verificationModelCalls: 0`, an unreadable package, a contract that does not resolve, `--help`, and an unknown option. Full suite: 542 passing. Refs #2.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Refs #2.
It is the import screen's code, not a second copy of it
The same
importRun, the samereadContractArtifact, the same deterministic verifier behindbuildRunView, and the samebuildEvidencePack/renderEvidenceMarkdown. Nothing here re-implements a check, so a package that verifies here verifies identically in the product.One small extraction was needed to keep that literally true.
--contracttakes a file, and the importer's handling of a contract document — bare contract or full artifact, with the resulting Zod problems — lived inline. It is nowparseContractDocument, shared by both, so a contract passed on the command line reports the same problems, field by field, as one uploaded through the screen. Two readers would drift; one cannot.Against each constraint in the issue
No model call unless a contract is missing and a credential is explicitly supplied. Stronger than asked: no model is called on any path. The contract comes from whichever of three sources is available, in the order the product prefers them — named with
--contract, shipped in the package, or the frozen sample contract whose task fingerprint the run reproduces. When none is, the command reports that and stops rather than compiling one. Compilation from the shell is a separate decision, and quietly spending a credential inside a verification command seemed like the wrong default to choose on your behalf. Say the word if you want it behind an explicit flag.The same validation errors as the import screen, field by field. That is what the extraction above buys, and what the second test asserts.
Read-only by construction. It reads the package and the contract and writes only into
--out.Exit codes
A CI job has to tell a failed run from a broken invocation, so they are separated:
--fail-on-needs-reviewNEEDS_REVIEWis a real outcome rather than an error, so whether it fails the command is the caller's choice, as the issue asked.Tests
Five integration tests in
apps/product/test/verify-cli.test.ts. They spawn the real command rather than calling the module, because an exit code is only worth asserting if a process actually produced it:usage.verificationModelCallsis0--help: exit 0pnpm typecheckpasses and the full suite is 542 passing across 31 files, so the importer extraction broke nothing.Not in this PR
The issue writes the command as
stateproof verify. This ispnpm verify, matching the repo's existing command contract. Thestateproofbinary name belongs with #4, where the package gains abin, so I left the issue open rather than closing it.Note
Low Risk
Overview
Introduces a new
pnpm verify <run.zip>shell command that imports a run package from disk and prints a verdict per task based on the same checks the web UI uses (refund outcome, customer message, approval-before-refund ordering, scope, frozen contract, etc.), writing per-task evidence to an--outdirectory. The CLI is implemented asscripts/verify.tsand reuses the server's import pipeline (apps/product/src/server/importer.ts) by exposing it as a reusable function rather than duplicating logic. Test coverage is added inapps/product/test/verify-cli.test.ts, a newverifyscript is wired intopackage.json, and the README is updated with usage instructions.Written by Gitzilla for commit 9299249. This will update automatically on new runs. Configure in the Gitzilla dashboard.