Skip to content

Conversation

@joshlf
Copy link
Member

@joshlf joshlf commented Feb 2, 2026


Latest Update: v5 — Compare vs v4

📚 Full Patch History

Links show the diff between the row version and the column version.

Version v4 v3 v2 v1 Base
v5 vs v4 vs v3 vs v2 vs v1 vs Base
v4 vs v3 vs v2 vs v1 vs Base
v3 vs v2 vs v1 vs Base
v2 vs v1 vs Base
v1 vs Base
⬇️ Download this PR

Branch

git fetch origin refs/heads/Gb0d4d182a8f82f845a81ba9cd36038cef442a30e && git checkout -b pr-Gb0d4d182a8f82f845a81ba9cd36038cef442a30e FETCH_HEAD

Checkout

git fetch origin refs/heads/Gb0d4d182a8f82f845a81ba9cd36038cef442a30e && git checkout FETCH_HEAD

Cherry Pick

git fetch origin refs/heads/Gb0d4d182a8f82f845a81ba9cd36038cef442a30e && git cherry-pick FETCH_HEAD

Pull

git pull origin refs/heads/Gb0d4d182a8f82f845a81ba9cd36038cef442a30e

Stacked PRs enabled by GHerrit.

gherrit-pr-id: Gb0d4d182a8f82f845a81ba9cd36038cef442a30e
@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @joshlf, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request establishes the foundational framework for formal verification of Rust programs by introducing cargo-hermes. This tool enables a workflow where Rust code can be annotated with formal specifications and proofs, which are then processed through a series of steps involving LLBC extraction, Lean translation, and automated verification. The primary goal is to provide a robust mechanism for ensuring the correctness and reliability of Rust software components.

Highlights

  • New cargo-hermes Tool Introduced: This pull request adds the initial version of cargo-hermes, a new tool designed to orchestrate formal verification for Rust code.
  • Formal Verification Pipeline: The cargo-hermes tool integrates with external tools like Charon (for LLBC extraction) and Aeneas (for Lean translation) to create a pipeline for verifying Rust code.
  • Embedded Specifications and Proofs: Developers can now embed Lean specifications (/*@ lean spec ... @*/) and proofs (/*@ proof ... @*/) directly within Rust code comments, which are then extracted and used in the verification process.
  • Automated Lean Verification: The tool automatically generates lakefile.lean and runs lake build to compile and verify the generated Lean code, ensuring the correctness of the Rust implementation against its formal specification.
  • New Dependencies and Vendorization: Several new Rust crates, including anyhow, clap, cargo_metadata, regex, walkdir, and the anstyle family of crates, have been added and/or vendorized to support the functionality of cargo-hermes.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces the initial commit for the hermes tool, a verification orchestrator for Rust. The changes include the core logic for parsing verification annotations, orchestrating Charon and Aeneas, and stitching generated Lean code, along with integration tests.

My review has identified several critical issues that need to be addressed:

  • The test case files contain unresolved merge conflict markers, which will cause the build to fail.
  • The integration tests have a hardcoded absolute path, making them non-portable.
  • There are several instances of .unwrap() on Path to &str conversions that can lead to panics on non-Windows systems.
  • The integration tests use env::set_var in an unsafe manner, which can cause data races when tests are run in parallel.

Additionally, there are some medium-severity issues regarding the use of the unstable 2024 Rust edition and a dependency on a main branch which affects reproducibility.

Please address these points to improve the robustness, portability, and correctness of the new tool.

Comment on lines +12 to +23
<<<<<<< Updated upstream
spec id (T : Type) (x : T)
: id T x = ok x
@*/
/*@ proof
=======
spec id {T : Type} (x : T)
ensures |ret| ret = x
@*/
/*@ proof
:= by
>>>>>>> Stashed changes
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

This file, along with several other test case files in this PR (incorrect_proof.rs, syntax_error_in_spec.rs, undefined_variable.rs, add.rs, checked_add.rs, struct_method.rs, unchecked_wrapper.rs), contains git merge conflict markers (<<<<<<<, =======, >>>>>>>). These markers make the files syntactically incorrect and will cause build failures. Please resolve the merge conflicts and remove these markers.

let cases_dir = manifest_dir.join("tests/cases");

let aeneas_path =
PathBuf::from("/usr/local/google/home/joshlf/workspace/zerocopy/hermes2/aeneas");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

This hardcoded absolute path makes the tests unrunnable on any machine other than the author's. This path should be made configurable, for example, through an environment variable. The test could then read this environment variable and be skipped if it's not set.

Suggested change
PathBuf::from("/usr/local/google/home/joshlf/workspace/zerocopy/hermes2/aeneas");
std::env::var("AENEAS_PATH").expect("AENEAS_PATH must be set for integration tests").into()

Comment on lines +20 to +21
let crate_root = crate_root.to_str().unwrap();
let dest_file = dest_file.to_str().unwrap();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

Using .unwrap() on Path::to_str() can cause a panic if a path contains non-UTF-8 characters, which is possible on non-Windows systems. It's safer to handle this possibility. crate_root is used with println! and current_dir, both of which can work directly with &Path, so its conversion to &str is unnecessary. For dest_file, you should handle the potential conversion failure gracefully by returning an error.

Suggested change
let crate_root = crate_root.to_str().unwrap();
let dest_file = dest_file.to_str().unwrap();
let dest_file = dest_file.to_str().ok_or_else(|| anyhow!("destination path is not valid UTF-8"))?;

Comment on lines +53 to +54
let llbc_path = llbc_path.to_str().unwrap();
let dest = dest.to_str().unwrap();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

Using .unwrap() on Path::to_str() can cause a panic if a path contains non-UTF-8 characters. It's safer to handle this possibility by returning an error.

Suggested change
let llbc_path = llbc_path.to_str().unwrap();
let dest = dest.to_str().unwrap();
let llbc_path = llbc_path.to_str().ok_or_else(|| anyhow!("llbc path is not valid UTF-8"))?;
let dest = dest.to_str().ok_or_else(|| anyhow!("destination path is not valid UTF-8"))?;

Comment on lines +71 to +73
unsafe {
env::set_var("PATH", new_path);
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

Using env::set_var is not thread-safe and can lead to race conditions if tests are run in parallel, which Cargo might do. The unsafe block here hides this danger. Instead of modifying the PATH for the whole process, it's safer to set the environment for the Commands that need it. Since charon and aeneas are executed via std::process::Command in orchestration.rs, you could pass the required PATH to those commands using Command::env. If that's not feasible, consider using a std::sync::Mutex to ensure exclusive access when modifying the environment variable.

[package]
name = "cargo-hermes"
version = "0.1.0"
edition = "2024"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The 2024 Rust edition is not yet stable. Using it might cause build failures on stable or beta toolchains. It's recommended to use the latest stable edition, '2021', unless this project is explicitly intended to be built only with a nightly Rust toolchain.

Suggested change
edition = "2024"
edition = "2021"

if let Some(path) = manifest_path {
// If it's a script, we just use the filename.
if path.extension().map_or(false, |e| e == "rs") {
return Ok(path.file_stem().unwrap().to_string_lossy().to_string());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

.unwrap() can panic if the path has no file stem (e.g., it's a directory like . or .., or a file like .bashrc). It's safer to handle this case gracefully by returning an error.

Suggested change
return Ok(path.file_stem().unwrap().to_string_lossy().to_string());
return Ok(path.file_stem().ok_or_else(|| anyhow!("script path has no file stem: {:?}", path))?.to_string_lossy().to_string());

let require_line = if let Some(path) = aeneas_path {
format!("require aeneas from \"{}\"", path.display())
} else {
r#"require aeneas from git "https://github.com/AeneasVerif/aeneas" @ "main""#.to_string()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Depending on the main branch of a git repository can lead to non-reproducible builds, as main can change at any time. It's recommended to pin this dependency to a specific commit hash or tag to ensure builds are reproducible, for example: ... @ "a1b2c3d4...".

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