Skip to content

Add 'kani verify-artifacts' subcommand#4600

Open
lovesegfault wants to merge 3 commits into
model-checking:mainfrom
lovesegfault:verify-only
Open

Add 'kani verify-artifacts' subcommand#4600
lovesegfault wants to merge 3 commits into
model-checking:mainfrom
lovesegfault:verify-only

Conversation

@lovesegfault
Copy link
Copy Markdown

cargo kani and kani both insist on owning the compile phase. There is no way to verify artifacts from an earlier --only-codegen run, a build system that drives kani-compiler directly, or a CI job that splits compilation and verification across machines: every invocation re-runs cargo or rustc, and a build system with its own per-crate cache ends up re-implementing kani-driver's verify half — the goto-cc/goto-instrument/cbmc pipeline, harness scheduling, verdict rendering — to avoid throwing the cache away. #4079 and #4212 are the same friction from the build side.

Adds kani verify-artifacts <DIR>..., a standalone subcommand that scans the given directories for *.kani-metadata.json, resolves each harness's goto_file by basename against the directory the metadata was found in (the recorded path is the producing machine's OUT_DIR, wrong after relocation), and runs verify_project() over the result. Mirrors verify-std: same Project construction shape, gated behind -Z unstable-options. The script-based-pre test round-trips cargo kani --only-codegenkani verify-artifacts against a fixture with one passing and one deliberately-failing harness, so a non-zero exit proves the verdict actually reached cbmc rather than silently no-op'd.

Two known limitations, documented in the args help: artifacts must come from the same kani version that verifies them (kani-driver does not version-check the metadata schema; happy to add a stamp as a follow-up if there's appetite), and the artifact directory must be writable since Project::try_new() writes the linked .out next to each .symtab.out.

Adds a fourth Project constructor that reads pre-built
*.kani-metadata.json + *.symtab.out artifacts from directories on disk
instead of running cargo or rustc.

The recorded goto_file path is the build machine's OUT_DIR and is wrong
after relocation (CI cache, archive, build-system store), so the
constructor resolves each goto_file by basename against the directory
the metadata file was found in. This relies on kani-compiler's existing
emit layout (artifacts co-located with their metadata).
Adds a standalone subcommand that runs the verification pipeline against
pre-built compiler artifacts without rebuilding. This is the inverse of
'--only-codegen': build systems that own the compile phase (for caching,
sharding, or per-crate incremental builds) can produce artifacts with
kani-compiler and verify them separately.

Mirrors 'kani verify-std' exactly: a standalone subcommand, gated behind
-Z unstable-options, that constructs a Project differently and falls
through to verify_project().
Round-trip test: build artifacts with 'cargo kani --only-codegen', then
verify them with 'kani verify-artifacts'. Uses two harnesses (one passes,
one fails) so the test proves the verdict is honest -- that the pipeline
actually reached CBMC and propagated the result -- not merely that the
command exited.

The fixture crate is excluded from the kani workspace (workspace
Cargo.toml exclude list, same as no_codegen and no_codegen_error).
@lovesegfault lovesegfault marked this pull request as ready for review May 20, 2026 15:31
@lovesegfault lovesegfault requested a review from a team as a code owner May 20, 2026 15:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant