Cargo
Rust crates, diffed with cargo-semver-checks from docs.rs or a sandbox build, then upgraded with cargo update --precise and verified with your tests.
| Cargo | |
|---|---|
| Manifests | Cargo.toml, read as TOML (Cargo isn't run on the worker): workspace members, dependencies, dev- and build-dependencies, target tables, workspace = true, renames |
| Lockfile | Cargo.lock v1 to v4 |
| API diff | cargo-semver-checks 0.51.0 |
| Finds your lines with | a syntax-level search |
| Sandbox | Rust 1.99.1 |
| Docs for the agent | the target's rustdoc JSON from docs.rs |
How breaks are found
cargo-semver-checks compares the two published versions. It takes their rustdoc JSON from docs.rs when both are there in a supported format, so nothing is compiled. Otherwise it builds both versions in the Rust sandbox. Features a new version removes come from the crates.io index.
Your code is then searched for the changed items. The search covers full and module paths, use groups, prelude globs, trait methods in files that import the trait, and removed features in Cargo.toml. Comments and strings are blanked first.
For a new major, or an advisory that names functions, Teire then indexes your project with rust-analyzer in the Rust sandbox. Build scripts and proc-macros run there, never on Teire's own server. The dependencies are fetched first; the index runs with the network off, after cargo metadata --offline --locked proves every dependency is present (rust-analyzer would otherwise drop them quietly). Each reference to the installed version is a type-resolved site, so an unused removed item reads not affected. A textual match the index doesn't confirm, or a file the index didn't cover that names the crate, stays unresolved and reads inconclusive. When the index can't be built, the search stays textual and says so.
A RustSec advisory that names its vulnerable functions is matched the same way: the finding says where they're called, or that they aren't.
How it upgrades
The requirement in Cargo.toml is edited as text in its own style. Removed features are dropped, and workspace = true dependencies are bumped in the root [workspace.dependencies]. Then cargo update -p name@old --precise new regenerates the lockfile. A version crates.io's index marks yanked is never a target, even before deps.dev reports the yank.
How it verifies
cargo fetch --locked, then with CARGO_NET_OFFLINE:
| Check | Command |
|---|---|
| build | cargo build --workspace --locked --offline |
| test | cargo test --workspace --locked --offline --no-fail-fast |
--features or --all-features are copied from your CI's cargo test.
In the evaluation
| Repository | Upgrade | Result |
|---|---|---|
| demo-rust-major | rand 0.8.8 → 0.10.3, 4 sites | verified by Nemotron 3 Ultra · 1 attempt · 16 steps · $0.129 |
| demo-rust-clean | thiserror 1.0.69 → 2.0.21 | inconclusive (syntax-level), upgrade verified as a plain bump |
Limits
The search is syntax-level and can miss use crate::* globs and renamed imports. There is no clippy step. The sandbox runs stable Rust 1.99.1, and a rust-toolchain.toml can't install another; crates needing nightly or a newer MSRV aren't excluded. Advisories that name a function read inconclusive, because their call sites aren't searched.
Go
Go modules, diffed with apidiff, located with go/types, and security advisories judged by govulncheck on the code you actually call.
RubyGems
Bundler projects and Rails apps, diffed with Prism from both published gems, upgraded with bundle lock --conservative, and verified with your tests and databases.