Skip to content

fix: persist Hermes session state across runs#497

Merged
rapids-bot[bot] merged 4 commits into
NVIDIA:release/0.6from
bbednarski9:bbednarski/relay-516-nemo-relay060-rc2-hermes-session-resume-fails-across-relay
Jul 21, 2026
Merged

fix: persist Hermes session state across runs#497
rapids-bot[bot] merged 4 commits into
NVIDIA:release/0.6from
bbednarski9:bbednarski/relay-516-nemo-relay060-rc2-hermes-session-resume-fails-across-relay

Conversation

@bbednarski9

@bbednarski9 bbednarski9 commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

Overview

Fix Hermes session resume across separate nemo-relay run --agent hermes processes when the caller starts with a fresh HERMES_HOME.

Hermes Agent v0.18.2 stores session metadata in $HERMES_HOME/state.db. Relay's temporary Hermes overlay previously linked only entries that already existed in the caller's home. A database first created inside the overlay was therefore deleted with that overlay, causing the next process to fail with Session not found.

  • I confirm this contribution is my own work, or I have the right to submit it under this project's license.
  • I searched existing issues and open pull requests, and this does not duplicate existing work.

Details

  • Create the caller-owned HERMES_HOME and durable sessions/ directory before populating the temporary overlay.
  • Create an empty caller-owned state.db only when it is absent, using create_new(true) so existing state is never truncated and a concurrent creator is tolerated.
  • Populate the existing per-process overlay afterward, allowing its symlink/junction/hard-link behavior to bind state.db and sessions/ back to the durable home.
  • Preserve side-effect-free --dry-run behavior and per-run config.yaml isolation.
  • Add regression coverage that starts with a nonexistent Hermes home, writes simulated state through the first overlay, removes it, and verifies a second overlay sees the same caller-owned state.
  • Strengthen existing coverage to prove a pre-existing state.db is not truncated.

No public CLI or API surface changes. The Switchyard example and documentation are unchanged because seeding the database there would mask the general launcher defect.

Validation

Passed:

  • cargo test -p nemo-relay-cli sequential_hermes_runs_preserve_state_from_a_fresh_home
  • cargo test -p nemo-relay-cli hermes_
  • cargo fmt --all
  • cargo clippy --workspace --all-targets -- -D warnings
  • uv run pre-commit run --all-files with only the unrelated attributions-rust hook skipped; all remaining hooks passed, including Cargo formatting, clippy, check, deny, FFI synchronization, Python, Go, Node, and documentation checks.
  • Live Hermes Agent v0.18.2 validation against local Ollama: a first Relay process created session 20260720_133907_e11614; a second Relay process resumed the same ID, and the caller-owned SQLite row remained with four messages after both temporary overlays were removed.

Known environment limitations:

  • just test-rust completed all Hermes and launcher coverage successfully, including this regression. The two full-suite attempts were not fully green because unrelated tests flaked under suite load: one temporary dynamic-plugin manifest lookup on the first run, then eight loopback HTTP/MCP health timeouts on the second. The first failure passed immediately in isolation.
  • The standalone attributions-rust hook rewrites an unrelated md-5 license entry already present on release/0.6; that generated change was restored and excluded from this PR.
  • The exact Docker-backed Switchyard three-query smoke could not run because the local Docker Desktop VM had remounted its internal ext4 filesystem read-only after I/O/no-space errors. Docker data was not reset or modified. A clean Switchyard checkout at 8f9db9a6a47f848cdff1d262276ba25a8ae9cbc8 and both required Ollama models were otherwise available.

Where should the reviewer start?

Start with ensure_durable_state_paths in crates/cli/src/agents/hermes/launch.rs, then review sequential_hermes_runs_preserve_state_from_a_fresh_home in crates/cli/tests/coverage/agents/launcher_tests.rs for the cross-process lifecycle being protected.

Related Issues: (use one of the action keywords Closes / Fixes / Resolves / Relates to)

  • Fixes RELAY-516

Summary by CodeRabbit

  • Bug Fixes

    • Hermes launches now reliably pre-create durable state artifacts, preserving session data and the state database across sequential runs.
    • Hermes setup now validates the expected durable state contents and handles conflicting state.db paths safely before overlay population.
    • Failed Hermes setup no longer leaves partial hooks or overlay leftovers behind.
  • Tests

    • Added coverage for state persistence across multiple Hermes runs, exact state.db contents, and failure behavior when state.db is an existing directory.

Signed-off-by: Bryan Bednarski <bbednarski@nvidia.com>
@github-actions github-actions Bot added size:S PR is small Bug issue describes bug; PR fixes bug lang:rust PR changes/introduces Rust code labels Jul 20, 2026
@coderabbitai

coderabbitai Bot commented Jul 20, 2026

Copy link
Copy Markdown

Review Change Stack

Walkthrough

Hermes overlay creation now pre-populates durable state paths in the shared source home. Tests verify state content, sequential state preservation, cleanup, and failure when state.db is a directory.

Changes

Hermes durable state

Layer / File(s) Summary
Initialize durable Hermes state
crates/cli/src/agents/hermes/launch.rs
create_overlay creates sessions/ and state.db before populating the overlay, preserving existing files and mapping other I/O failures.
Validate state preservation and failure handling
crates/cli/tests/coverage/agents/launcher_tests.rs
Tests verify exact state contents, sequential state and session reuse, overlay cleanup, and rejection of a directory at state.db.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant PreparedAgentLaunch
  participant HermesOverlay
  participant source_home
  PreparedAgentLaunch->>HermesOverlay: prepare first run
  HermesOverlay->>source_home: persist state.db and session.json
  PreparedAgentLaunch->>HermesOverlay: restore first run
  HermesOverlay->>source_home: retain durable state
  PreparedAgentLaunch->>HermesOverlay: prepare second run
  source_home->>HermesOverlay: provide persisted state
  PreparedAgentLaunch->>HermesOverlay: restore second run
Loading
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title follows Conventional Commits and accurately summarizes the Hermes state persistence fix.
Description check ✅ Passed The description includes the required Overview, Details, reviewer start, and related issue sections, with useful validation notes.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands.

@bbednarski9

Copy link
Copy Markdown
Contributor Author

RELAY-516 design walkthrough

The diagrams below separate the pre-fix failure from the post-fix lifecycle. Click a code-backed node to open the corresponding immutable source lines.

Before: state first created in the temporary overlay is deleted

flowchart TD
    A["Live Hermes launch resolves caller HERMES_HOME"] --> B["Relay creates a private temporary overlay"]
    B --> C["populate_overlay reads entries that already exist in caller HERMES_HOME"]
    C --> D{"Do state.db and sessions/ already exist?"}
    D -- "yes" --> E["link_state binds existing entries into the overlay"]
    D -- "no: fresh home" --> F["No durable state link is created"]
    E --> G["Hermes receives the overlay as HERMES_HOME"]
    F --> G
    G --> H["Hermes v0.18.2 creates state.db only inside the overlay"]
    H --> I["Relay process exits and restore removes every temp_dir"]
    I --> J["The only state.db is deleted"]
    J --> K["Next Relay process uses --resume"]
    K --> L["Session not found"]

    click A "https://github.com/NVIDIA/NeMo-Relay/blob/3a88c4cc64ec34afeec99205742c61819efb05e3/crates/cli/src/agents/hermes/launch.rs#L35-L41" "Resolve the source Hermes home"
    click B "https://github.com/NVIDIA/NeMo-Relay/blob/3a88c4cc64ec34afeec99205742c61819efb05e3/crates/cli/src/agents/hermes/launch.rs#L53-L73" "Create the old overlay"
    click C "https://github.com/NVIDIA/NeMo-Relay/blob/3a88c4cc64ec34afeec99205742c61819efb05e3/crates/cli/src/agents/hermes/launch.rs#L75-L102" "Enumerate only pre-existing source entries"
    click D "https://github.com/NVIDIA/NeMo-Relay/blob/3a88c4cc64ec34afeec99205742c61819efb05e3/crates/cli/src/agents/hermes/launch.rs#L84-L102" "Missing source entries produce no links"
    click E "https://github.com/NVIDIA/NeMo-Relay/blob/3a88c4cc64ec34afeec99205742c61819efb05e3/crates/cli/src/agents/hermes/launch.rs#L92-L98" "Link existing entries"
    click F "https://github.com/NVIDIA/NeMo-Relay/blob/3a88c4cc64ec34afeec99205742c61819efb05e3/crates/cli/src/agents/hermes/launch.rs#L84-L102" "Fresh homes have nothing to enumerate"
    click G "https://github.com/NVIDIA/NeMo-Relay/blob/3a88c4cc64ec34afeec99205742c61819efb05e3/crates/cli/src/agents/hermes/launch.rs#L41-L49" "Inject overlay as HERMES_HOME and register it for cleanup"
    click H "https://github.com/NVIDIA/NeMo-Relay/blob/3a88c4cc64ec34afeec99205742c61819efb05e3/crates/cli/src/agents/hermes/launch.rs#L41-L49" "Hermes writes beneath the injected overlay home"
    click I "https://github.com/NVIDIA/NeMo-Relay/blob/3a88c4cc64ec34afeec99205742c61819efb05e3/crates/cli/src/process/launcher.rs#L491-L501" "Remove temporary launch directories"
    click J "https://github.com/NVIDIA/NeMo-Relay/blob/416b3e75260bbff7f71b7a764cb4febea7fcf5cb/crates/cli/tests/coverage/agents/launcher_tests.rs#L1034-L1056" "Regression boundary: first overlay is removed"
    click K "https://github.com/NVIDIA/NeMo-Relay/blob/416b3e75260bbff7f71b7a764cb4febea7fcf5cb/crates/cli/tests/coverage/agents/launcher_tests.rs#L1058-L1072" "Regression boundary: second launch"
    click L "https://github.com/NVIDIA/NeMo-Relay/blob/416b3e75260bbff7f71b7a764cb4febea7fcf5cb/crates/cli/tests/coverage/agents/launcher_tests.rs#L998-L1073" "Failure reproduced by the new sequential-run test before the fix"

    classDef failure fill:#ffebe9,stroke:#cf222e,color:#24292f;
    class F,H,I,J,K,L failure;
Loading

After: durable state is provisioned before overlay population

flowchart TD
    A["prepare keeps --dry-run side-effect free"] --> B["Live launch calls create_overlay"]
    B --> C["ensure_durable_state_paths runs first"]
    C --> D["create_dir_all caller HERMES_HOME/sessions"]
    D --> E["create_new caller HERMES_HOME/state.db"]
    E --> F{"state.db already exists?"}
    F -- "no" --> G["Create an empty durable database without truncation"]
    F -- "yes / concurrent creator" --> H["Treat AlreadyExists as success"]
    G --> I["Create temporary overlay"]
    H --> I
    I --> J["populate_overlay now discovers state.db and sessions/"]
    J --> K["link_state binds both paths back to caller HERMES_HOME"]
    K --> L["Hermes writes through overlay links into durable state"]
    L --> M["Relay cleanup removes only the temporary overlay"]
    M --> N["Second Relay process links the same durable state"]
    N --> O["Hermes --resume finds the session"]

    click A "https://github.com/NVIDIA/NeMo-Relay/blob/416b3e75260bbff7f71b7a764cb4febea7fcf5cb/crates/cli/src/agents/hermes/launch.rs#L28-L34" "Dry-run exits before filesystem preparation"
    click B "https://github.com/NVIDIA/NeMo-Relay/blob/416b3e75260bbff7f71b7a764cb4febea7fcf5cb/crates/cli/src/agents/hermes/launch.rs#L35-L49" "Live Hermes overlay preparation"
    click C "https://github.com/NVIDIA/NeMo-Relay/blob/416b3e75260bbff7f71b7a764cb4febea7fcf5cb/crates/cli/src/agents/hermes/launch.rs#L53-L69" "Provision durable paths before overlay population"
    click D "https://github.com/NVIDIA/NeMo-Relay/blob/416b3e75260bbff7f71b7a764cb4febea7fcf5cb/crates/cli/src/agents/hermes/launch.rs#L76-L77" "Create caller-owned home and sessions directory"
    click E "https://github.com/NVIDIA/NeMo-Relay/blob/416b3e75260bbff7f71b7a764cb4febea7fcf5cb/crates/cli/src/agents/hermes/launch.rs#L78-L82" "Open state.db with create_new"
    click F "https://github.com/NVIDIA/NeMo-Relay/blob/416b3e75260bbff7f71b7a764cb4febea7fcf5cb/crates/cli/src/agents/hermes/launch.rs#L82-L86" "Handle the create result"
    click G "https://github.com/NVIDIA/NeMo-Relay/blob/416b3e75260bbff7f71b7a764cb4febea7fcf5cb/crates/cli/src/agents/hermes/launch.rs#L78-L83" "Create only when absent"
    click H "https://github.com/NVIDIA/NeMo-Relay/blob/416b3e75260bbff7f71b7a764cb4febea7fcf5cb/crates/cli/src/agents/hermes/launch.rs#L83-L85" "Tolerate a pre-existing file or concurrent creator"
    click I "https://github.com/NVIDIA/NeMo-Relay/blob/416b3e75260bbff7f71b7a764cb4febea7fcf5cb/crates/cli/src/agents/hermes/launch.rs#L59-L68" "Create the process-private overlay"
    click J "https://github.com/NVIDIA/NeMo-Relay/blob/416b3e75260bbff7f71b7a764cb4febea7fcf5cb/crates/cli/src/agents/hermes/launch.rs#L89-L116" "Enumerate durable source entries"
    click K "https://github.com/NVIDIA/NeMo-Relay/blob/416b3e75260bbff7f71b7a764cb4febea7fcf5cb/crates/cli/src/agents/hermes/launch.rs#L106-L112" "Bind entries into the overlay"
    click L "https://github.com/NVIDIA/NeMo-Relay/blob/416b3e75260bbff7f71b7a764cb4febea7fcf5cb/crates/cli/tests/coverage/agents/launcher_tests.rs#L1034-L1053" "Write through the first overlay and observe durable state"
    click M "https://github.com/NVIDIA/NeMo-Relay/blob/416b3e75260bbff7f71b7a764cb4febea7fcf5cb/crates/cli/src/process/launcher.rs#L491-L501" "Remove only registered temporary directories"
    click N "https://github.com/NVIDIA/NeMo-Relay/blob/416b3e75260bbff7f71b7a764cb4febea7fcf5cb/crates/cli/tests/coverage/agents/launcher_tests.rs#L1055-L1067" "Second overlay sees the same state"
    click O "https://github.com/NVIDIA/NeMo-Relay/blob/416b3e75260bbff7f71b7a764cb4febea7fcf5cb/crates/cli/tests/coverage/agents/launcher_tests.rs#L1069-L1072" "Caller-owned state survives both overlay cleanups"

    classDef durable fill:#dafbe1,stroke:#1a7f37,color:#24292f;
    class C,D,E,G,H,J,K,L,M,N,O durable;
Loading

The behavioral change is intentionally before populate_overlay: it makes the existing link machinery see the durable Hermes state surfaces without changing overlay cleanup, configuration isolation, or dry-run semantics.

@willkill07 willkill07 added this to the 0.6 milestone Jul 20, 2026
@bbednarski9
bbednarski9 marked this pull request as ready for review July 20, 2026 20:50
@bbednarski9
bbednarski9 requested a review from a team as a code owner July 20, 2026 20:50

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@crates/cli/src/agents/hermes/launch.rs`:
- Around line 76-85: Update ensure_durable_state_paths so the AlreadyExists
fallback succeeds only when source_home.join("state.db").is_file() is true;
return the existing I/O error for directories or other invalid entries. Add a
regression test covering an existing state.db directory and verify it is
rejected before populate_overlay can link it.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Enterprise

Run ID: 7275d02d-9028-4224-9a3b-e83dfa08a632

📥 Commits

Reviewing files that changed from the base of the PR and between eebacb6 and 416b3e7.

📒 Files selected for processing (2)
  • crates/cli/src/agents/hermes/launch.rs
  • crates/cli/tests/coverage/agents/launcher_tests.rs
📜 Review details
⏰ Context from checks skipped due to timeout. (5)
  • GitHub Check: Rust / Test (windows-amd64)
  • GitHub Check: Rust / Test (macos-arm64)
  • GitHub Check: Rust / Test (linux-amd64)
  • GitHub Check: Rust / Test (windows-arm64)
  • GitHub Check: Rust / Test (linux-arm64)
🧰 Additional context used
📓 Path-based instructions (10)
**/*.rs

📄 CodeRabbit inference engine (.agents/skills/prepare-pr/SKILL.md)

**/*.rs: Any Rust change must run just test-rust
Any Rust change must run cargo fmt --all
Any Rust change must run cargo clippy --workspace --all-targets -- -D warnings

**/*.rs: Run cargo fmt --all for all FFI work since it is Rust work
Run just test-rust to validate FFI changes
Run cargo clippy --workspace --all-targets -- -D warnings to enforce strict linting on FFI work

When Rust files changed as part of Go work, also run cargo fmt --all, just test-rust, and cargo clippy --workspace --all-targets -- -D warnings

**/*.rs: Run cargo fmt --all when Rust files are changed as part of Node work
Run cargo clippy --workspace --all-targets -- -D warnings when Rust files are changed as part of Node work
Run just test-rust when Rust files are changed as part of Node work

When changing the core Rust runtime or Rust-facing API surface, format Rust code with cargo fmt (rustfmt defaults), keep cargo clippy -- -D warnings clean, and satisfy cargo deny check per deny.toml.

**/*.rs: If any Rust code changed, always run just test-rust.
If any Rust code changed, also run cargo fmt --all.
If any Rust code changed, also run cargo clippy --workspace --all-targets -- -D warnings.
For Rust changes headed for review, run cargo fmt --all and cargo clippy --workspace --all-targets -- -D warnings even if relying on pre-commit.

Files:

  • crates/cli/src/agents/hermes/launch.rs
  • crates/cli/tests/coverage/agents/launcher_tests.rs
**/*.{rs,py}

📄 CodeRabbit inference engine (AGENTS.md)

Follow binding naming conventions in Rust and Python: use snake_case.

Files:

  • crates/cli/src/agents/hermes/launch.rs
  • crates/cli/tests/coverage/agents/launcher_tests.rs
**/*.{rs,py,js,mjs,cjs,ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{rs,py,js,mjs,cjs,ts,tsx}: Use Json = serde_json::Value in Rust-facing runtime APIs where the existing code expects JSON payloads.
Use Result<T> with FlowError in core runtime paths, and keep errors explicit and binding-appropriate at the wrapper layer.
Keep async behavior on the existing tokio-based model; bindings should preserve callback and future lifetimes rather than blocking or hiding async work unexpectedly.

Files:

  • crates/cli/src/agents/hermes/launch.rs
  • crates/cli/tests/coverage/agents/launcher_tests.rs
**/*.{rs,py,go,js,ts,c,h}

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Use language-appropriate naming conventions: Rust snake_case, C FFI exports prefixed nemo_relay_, Go PascalCase, Node.js camelCase, and Python snake_case.

Files:

  • crates/cli/src/agents/hermes/launch.rs
  • crates/cli/tests/coverage/agents/launcher_tests.rs
**/*.{rs,go,js,ts}

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Add the SPDX license header to all Rust, Go, JavaScript, and TypeScript source files using the corresponding // comment form.

Files:

  • crates/cli/src/agents/hermes/launch.rs
  • crates/cli/tests/coverage/agents/launcher_tests.rs
{crates/**/src/**/*.rs,python/**/*.py}

📄 CodeRabbit inference engine (.agents/skills/maintain-dynamic-plugins/SKILL.md)

Do not add tests under src; Rust tests belong in crate tests/ trees, and Python SDK tests belong under python/tests.

Files:

  • crates/cli/src/agents/hermes/launch.rs
**/*

📄 CodeRabbit inference engine (.agents/skills/validate-change/SKILL.md)

**/*: Format changed files with the language-native formatter before the final lint/test pass.
If dynamic plugin behavior changed, use maintain-dynamic-plugins and include the native SDK, worker protocol, Python SDK, docs, packaging, and Codecov surfaces in the validation plan.
If code changes alter APIs, bindings, commands, paths, packaging behavior, observability/adaptive semantics, or documented best practices, update any dependent maintainer or consumer skills in the same branch.
During iteration, prefer uv run pre-commit run --files <changed files...>.
Before review or handoff, run uv run pre-commit run --all-files.

Files:

  • crates/cli/src/agents/hermes/launch.rs
  • crates/cli/tests/coverage/agents/launcher_tests.rs
**/*.{rs,py,go,js,ts}

📄 CodeRabbit inference engine (.agents/skills/validate-change/SKILL.md)

If a language surface changed, always run that language's test target even when Rust core did not change.

Files:

  • crates/cli/src/agents/hermes/launch.rs
  • crates/cli/tests/coverage/agents/launcher_tests.rs
**/*.{rs,py,js,ts,tsx,go,java,kt,swift}

📄 CodeRabbit inference engine (.agents/skills/add-middleware/SKILL.md)

Add tests covering registration and duplicate names, deregistration and missing names, priority ordering, callback failure policy, scope-local inheritance and cleanup, event payload semantics, immutable mark and scope fields, and parity across affected bindings.

Files:

  • crates/cli/src/agents/hermes/launch.rs
  • crates/cli/tests/coverage/agents/launcher_tests.rs
{crates/**/tests/**,python/tests/**,go/nemo_relay/**/*_test.go}

⚙️ CodeRabbit configuration file

{crates/**/tests/**,python/tests/**,go/nemo_relay/**/*_test.go}: Tests should cover the behavior promised by the changed API surface, including error paths and cross-request isolation where relevant.
Prefer assertions on lifecycle events, scope stacks, middleware ordering, and binding parity over shallow smoke tests.

Files:

  • crates/cli/tests/coverage/agents/launcher_tests.rs
🔇 Additional comments (4)
crates/cli/src/agents/hermes/launch.rs (2)

58-58: 🎯 Functional Correctness

Verify dry-run bypasses durable-state provisioning.

Line 58 creates caller-home paths. The supplied regression invokes PreparedAgentLaunch::new(..., false), so it does not prove that --dry-run remains side-effect free. Confirm the dry-run path never reaches create_overlay, or add a regression for it.


58-87: 📐 Maintainability & Code Quality

Run the required Rust validation before merge.

Provide successful results for cargo fmt --all, cargo clippy --workspace --all-targets -- -D warnings, just test-rust, and uv run pre-commit run --all-files. As per coding guidelines, “Any Rust change must run just test-rust,” cargo fmt --all, cargo clippy --workspace --all-targets -- -D warnings, and “Before review or handoff, run uv run pre-commit run --all-files.”

Source: Coding guidelines

crates/cli/tests/coverage/agents/launcher_tests.rs (2)

974-977: LGTM!


998-1073: LGTM!

Comment thread crates/cli/src/agents/hermes/launch.rs
Signed-off-by: Bryan Bednarski <bbednarski@nvidia.com>
@bbednarski9
bbednarski9 marked this pull request as draft July 20, 2026 21:17
@github-actions github-actions Bot added size:M PR is medium and removed size:S PR is small labels Jul 20, 2026
@bbednarski9
bbednarski9 marked this pull request as ready for review July 20, 2026 21:18
Signed-off-by: Bryan Bednarski <bbednarski@nvidia.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@crates/cli/tests/coverage/agents/launcher_tests.rs`:
- Line 1108: Update the regression assertion around the launcher test’s
`CliError::Io` result to verify the wrapped I/O error has kind
`ErrorKind::AlreadyExists`, rather than accepting any I/O error. Retain the
existing platform-specific side-effect checks and the test’s coverage of the
existing-directory error path.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Enterprise

Run ID: de50ac86-f39d-4b98-8e47-60bc032af688

📥 Commits

Reviewing files that changed from the base of the PR and between ee4b429 and b1bfd94.

📒 Files selected for processing (1)
  • crates/cli/tests/coverage/agents/launcher_tests.rs
📜 Review details
⏰ Context from checks skipped due to timeout. (1)
  • GitHub Check: Check / Run
🧰 Additional context used
📓 Path-based instructions (9)
**/*.rs

📄 CodeRabbit inference engine (.agents/skills/prepare-pr/SKILL.md)

**/*.rs: Any Rust change must run just test-rust
Any Rust change must run cargo fmt --all
Any Rust change must run cargo clippy --workspace --all-targets -- -D warnings

**/*.rs: Run cargo fmt --all for all FFI work since it is Rust work
Run just test-rust to validate FFI changes
Run cargo clippy --workspace --all-targets -- -D warnings to enforce strict linting on FFI work

When Rust files changed as part of Go work, also run cargo fmt --all, just test-rust, and cargo clippy --workspace --all-targets -- -D warnings

**/*.rs: Run cargo fmt --all when Rust files are changed as part of Node work
Run cargo clippy --workspace --all-targets -- -D warnings when Rust files are changed as part of Node work
Run just test-rust when Rust files are changed as part of Node work

When changing the core Rust runtime or Rust-facing API surface, format Rust code with cargo fmt (rustfmt defaults), keep cargo clippy -- -D warnings clean, and satisfy cargo deny check per deny.toml.

**/*.rs: If any Rust code changed, always run just test-rust.
If any Rust code changed, also run cargo fmt --all.
If any Rust code changed, also run cargo clippy --workspace --all-targets -- -D warnings.
For Rust changes headed for review, run cargo fmt --all and cargo clippy --workspace --all-targets -- -D warnings even if relying on pre-commit.

Files:

  • crates/cli/tests/coverage/agents/launcher_tests.rs
**/*.{rs,py}

📄 CodeRabbit inference engine (AGENTS.md)

Follow binding naming conventions in Rust and Python: use snake_case.

Files:

  • crates/cli/tests/coverage/agents/launcher_tests.rs
**/*.{rs,py,js,mjs,cjs,ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{rs,py,js,mjs,cjs,ts,tsx}: Use Json = serde_json::Value in Rust-facing runtime APIs where the existing code expects JSON payloads.
Use Result<T> with FlowError in core runtime paths, and keep errors explicit and binding-appropriate at the wrapper layer.
Keep async behavior on the existing tokio-based model; bindings should preserve callback and future lifetimes rather than blocking or hiding async work unexpectedly.

Files:

  • crates/cli/tests/coverage/agents/launcher_tests.rs
**/*.{rs,py,go,js,ts,c,h}

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Use language-appropriate naming conventions: Rust snake_case, C FFI exports prefixed nemo_relay_, Go PascalCase, Node.js camelCase, and Python snake_case.

Files:

  • crates/cli/tests/coverage/agents/launcher_tests.rs
**/*.{rs,go,js,ts}

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Add the SPDX license header to all Rust, Go, JavaScript, and TypeScript source files using the corresponding // comment form.

Files:

  • crates/cli/tests/coverage/agents/launcher_tests.rs
**/*

📄 CodeRabbit inference engine (.agents/skills/validate-change/SKILL.md)

**/*: Format changed files with the language-native formatter before the final lint/test pass.
If dynamic plugin behavior changed, use maintain-dynamic-plugins and include the native SDK, worker protocol, Python SDK, docs, packaging, and Codecov surfaces in the validation plan.
If code changes alter APIs, bindings, commands, paths, packaging behavior, observability/adaptive semantics, or documented best practices, update any dependent maintainer or consumer skills in the same branch.
During iteration, prefer uv run pre-commit run --files <changed files...>.
Before review or handoff, run uv run pre-commit run --all-files.

Files:

  • crates/cli/tests/coverage/agents/launcher_tests.rs
**/*.{rs,py,go,js,ts}

📄 CodeRabbit inference engine (.agents/skills/validate-change/SKILL.md)

If a language surface changed, always run that language's test target even when Rust core did not change.

Files:

  • crates/cli/tests/coverage/agents/launcher_tests.rs
**/*.{rs,py,js,ts,tsx,go,java,kt,swift}

📄 CodeRabbit inference engine (.agents/skills/add-middleware/SKILL.md)

Add tests covering registration and duplicate names, deregistration and missing names, priority ordering, callback failure policy, scope-local inheritance and cleanup, event payload semantics, immutable mark and scope fields, and parity across affected bindings.

Files:

  • crates/cli/tests/coverage/agents/launcher_tests.rs
{crates/**/tests/**,python/tests/**,go/nemo_relay/**/*_test.go}

⚙️ CodeRabbit configuration file

{crates/**/tests/**,python/tests/**,go/nemo_relay/**/*_test.go}: Tests should cover the behavior promised by the changed API surface, including error paths and cross-request isolation where relevant.
Prefer assertions on lifecycle events, scope stacks, middleware ordering, and binding parity over shallow smoke tests.

Files:

  • crates/cli/tests/coverage/agents/launcher_tests.rs

Comment thread crates/cli/tests/coverage/agents/launcher_tests.rs
@bbednarski9

Copy link
Copy Markdown
Contributor Author

/merge

@rapids-bot
rapids-bot Bot merged commit cf03327 into NVIDIA:release/0.6 Jul 21, 2026
36 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Bug issue describes bug; PR fixes bug lang:rust PR changes/introduces Rust code size:M PR is medium

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants