Skip to content

fix: suppress Claude Code lifecycle noise#213

Merged
rapids-bot[bot] merged 2 commits into
NVIDIA:mainfrom
AjayThorve:ajay/relay-176-claude-observability-contract
Jun 4, 2026
Merged

fix: suppress Claude Code lifecycle noise#213
rapids-bot[bot] merged 2 commits into
NVIDIA:mainfrom
AjayThorve:ajay/relay-176-claude-observability-contract

Conversation

@AjayThorve
Copy link
Copy Markdown
Contributor

@AjayThorve AjayThorve commented Jun 4, 2026

Overview

Fix Claude Code lifecycle noise that produced synthetic null, user: test, idle_timeout, or orphan lifecycle-only traces while preserving real per-turn Claude Code spans.

  • 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

  • Detect the exact Claude Code startup probe using the native Claude Code session header plus Anthropic Messages payload shape, then forward it without exported managed LLM observability.
  • Suppress late uncorrelatable Claude SubagentStop hooks only when no turn is active; active-turn orphan diagnostics are preserved.
  • Add focused regressions for the probe classifier, gateway forwarding, null-turn prevention, and ATIF output.
  • Update Claude Code docs/README with expected trace shape, exporter smoke expectations, diagnostics, and hook limitations.

Validation run locally:

  • cargo fmt --all
  • cargo test -p nemo-relay-cli claude -- --nocapture
  • cargo test -p nemo-relay-cli -- --test-threads=1
  • just test-rust
  • cargo clippy --workspace --all-targets -- -D warnings
  • PATH=/Users/athorve/.nvm/versions/node/v23.9.0/bin:$PATH just docs
  • targeted pre-commit on changed files

Where should the reviewer start?

Start with crates/cli/src/alignment/claude_code.rs, then crates/cli/src/session.rs and crates/cli/src/gateway.rs.

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

  • Fixes RELAY-171
  • Resolves RELAY-176
  • Resolves RELAY-202
  • Resolves RELAY-203
  • Resolves RELAY-204

Summary by CodeRabbit

  • New Features

    • Detects Claude Code startup probes and bypasses the managed observability pipeline; bypassed requests are forwarded directly to upstream.
    • Probe-only sessions are marked for pruning after completion.
  • Bug Fixes

    • Prevents creation of null-input/synthetic turns from startup probes.
    • Suppresses orphan subagent-stop events from producing extra turns when no active user turn exists.
  • Tests

    • Added coverage validating probe detection, forwarding, pruning, and observability suppression.
  • Documentation

    • Expanded Claude Code observability docs and README with turn-oriented traces and correlation diagnostics.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Jun 4, 2026

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Enterprise

Run ID: 6c4ec8f6-9efa-452a-84c8-dc5588848376

📥 Commits

Reviewing files that changed from the base of the PR and between 243e7e1 and eee481b.

📒 Files selected for processing (3)
  • crates/cli/src/gateway.rs
  • crates/cli/src/session.rs
  • crates/cli/tests/coverage/session_tests.rs
📜 Recent review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: Rust / Test (linux-amd64)
  • GitHub Check: Rust / Test (windows-amd64)
  • GitHub Check: Rust / Test (windows-arm64)
  • GitHub Check: Rust / Test (macos-arm64)
🧰 Additional context used
📓 Path-based instructions (9)
**/*.rs

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

Use snake_case naming convention for Rust identifiers (e.g., nemo_relay_tool_call)

**/*.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

**/*.rs: Run cargo fmt --all to format all Rust code
Run cargo clippy --workspace --all-targets -- -D warnings to enforce all clippy lints as errors

**/*.rs: Run cargo fmt --all when Rust files changed as part of WebAssembly work
Run cargo clippy --workspace --all-targets -- -D warnings when Rust files changed as part of WebAssembly work

**/*.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
Run Rust formatting with cargo fmt --all
Run Rust linting with cargo clippy --workspace --all-targets -- -D warnings

**/*.rs: Use cargo fmt for Rust code formatting
Run cargo clippy -- -D warnings to lint Rust code and treat all warnings as errors
Use Rust snake_case naming convention for Rust identifiers
Include SPDX license header in all Rust source files using double-slash comment syntax
Validate Rust code with uv run pre-commit run --all-files to enforce cargo fmt formatting check, cargo clippy lints, and cargo deny aud...

Files:

  • crates/cli/src/gateway.rs
  • crates/cli/tests/coverage/session_tests.rs
  • crates/cli/src/session.rs
**/{Cargo.toml,**/*.rs}

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

Maintain consistency between Rust package names in Cargo.toml and their actual usage across the codebase

Files:

  • crates/cli/src/gateway.rs
  • crates/cli/tests/coverage/session_tests.rs
  • crates/cli/src/session.rs
**/*.{h,hpp,c,cpp,rs}

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

Ensure FFI header and library naming follows consistent conventions across platform-specific builds

Files:

  • crates/cli/src/gateway.rs
  • crates/cli/tests/coverage/session_tests.rs
  • crates/cli/src/session.rs
**/*.{rs,toml}

📄 CodeRabbit inference engine (.agents/skills/rename-surfaces/SKILL.md)

Update Rust crate names and module prefixes during coordinated rename operations

Files:

  • crates/cli/src/gateway.rs
  • crates/cli/tests/coverage/session_tests.rs
  • crates/cli/src/session.rs
**/*.{rs,py,js,ts,tsx,jsx,go,sh,toml,yaml,yml,md}

📄 CodeRabbit inference engine (AGENTS.md)

Keep SPDX headers on source, docs, scripts, and configuration files. The project is Apache-2.0.

Files:

  • crates/cli/src/gateway.rs
  • crates/cli/tests/coverage/session_tests.rs
  • crates/cli/src/session.rs
**/*.{rs,py,go,js,ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Follow binding naming conventions: Rust and Python use snake_case, C FFI exports prefixed nemo_relay_, Go uses PascalCase for public APIs, Node.js uses camelCase.

Files:

  • crates/cli/src/gateway.rs
  • crates/cli/tests/coverage/session_tests.rs
  • crates/cli/src/session.rs
crates/**/*.rs

📄 CodeRabbit inference engine (AGENTS.md)

crates/**/*.rs: Keep async behavior on the existing tokio-based model. Bindings should preserve callback and future lifetimes rather than blocking or hiding async work unexpectedly.
Use Json = serde_json::Value in Rust-facing runtime APIs for JSON payload handling.

Files:

  • crates/cli/src/gateway.rs
  • crates/cli/tests/coverage/session_tests.rs
  • crates/cli/src/session.rs
{crates/adaptive/**/*.rs,**/*test*.{rs,py,go,ts,js},**/*adaptive*test*.{rs,py,go,ts,js},docs/plugins/adaptive/**}

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

Maintain documented and tested validation and report behavior for adaptive surfaces

Files:

  • crates/cli/tests/coverage/session_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/session_tests.rs
🔇 Additional comments (14)
crates/cli/src/gateway.rs (5)

184-196: LGTM!


206-227: LGTM!


276-288: LGTM!

Also applies to: 309-309, 323-323


416-421: LGTM!

Also applies to: 435-447, 469-469


661-661: LGTM!

Also applies to: 685-685

crates/cli/src/session.rs (5)

95-97: LGTM!


398-423: LGTM!


430-442: LGTM!


1036-1036: LGTM!


1380-1398: Orphan subagent suppression logic is correct.

For ClaudeCode with no active turn, orphan SubagentStop hooks are silently dropped to avoid creating turn scopes solely for diagnostic marks. The eprintln diagnostic still fires for visibility before the early return.

crates/cli/tests/coverage/session_tests.rs (4)

2226-2228: LGTM!


2267-2298: LGTM!


3968-3968: LGTM!


4704-4724: LGTM!


Walkthrough

Adds Claude Code startup-probe detection and a gateway bypass: probes are identified in alignment, classified to bypass managed observability, forwarded directly by the gateway, handled specially in session lifecycle to avoid synthetic turns, and validated by tests and docs.

Changes

Claude Code Startup Probe Detection and Bypass

Layer / File(s) Summary
Startup probe detection
crates/cli/src/alignment/claude_code.rs
Imports LlmRequest and adds is_startup_probe to detect Anthropic anthropic.messages preflight probes with Claude session header, claude-* model, max_tokens==1, and messages[0] == { role: "user", content: "test" }.
Gateway management policy
crates/cli/src/alignment/mod.rs
Adds GatewayManagementPolicy enum and gateway_management_policy(...) helper to classify requests as Managed or UnmanagedProbe (static status/source) using the Claude predicate.
Gateway bypass execution and forwarding
crates/cli/src/gateway.rs
run_managed_gateway checks prep.bypass_managed_pipeline and delegates bypassed requests to run_unmanaged_gateway which forwards directly upstream (streaming via passthrough, buffered via upstream forward + reconstruct). Managed paths unchanged aside from ignoring the new flag.
Session lifecycle management for startup probes
crates/cli/src/session.rs
Adds bypass_managed_pipeline to GatewayCallPrep. prepare_gateway_call computes the policy, skips turn creation for unmanaged probes, uses unmanaged_probe_owner for correlation, and updates end_subagent to ignore Claude orphan ends when no active turn exists.
Server integration and upstream handler
crates/cli/tests/coverage/server_tests.rs
Adds a test that registers a subscriber to assert Claude startup probes produce no LLM-start events; extends the local Anthropic upstream test server with a /v1/messages handler and router entry.
Session regression tests
crates/cli/tests/coverage/session_tests.rs
Adds tests verifying startup probes do not open null-input turns and orphan subagent stops after closed turns do not create orphan diagnostics or extra turns; includes ATIF trajectory assertions.
Alignment unit tests
crates/cli/tests/coverage/alignment_claude_code_tests.rs
Unit test covering is_startup_probe true/false cases across provider, model, headers, and message content permutations.
Observability and behavior documentation
docs/nemo-relay-cli/claude-code.mdx, integrations/coding-agents/claude-code/README.md
Documents turn-oriented exported traces, suppressed startup probes and late lifecycle hooks in exported observability, troubleshooting correlation metadata, and hook availability/limitations.

🎯 3 (Moderate) | ⏱️ ~25 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 63.41% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed Title follows Conventional Commits format with 'fix' type, concise imperative summary, and is 41 characters—well under the 72-character limit.
Description check ✅ Passed Description includes all required sections: Overview with contributor confirmation, Details explaining the changes, Where should the reviewer start, and Related Issues with action keywords.
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.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Warning

Review ran into problems

🔥 Problems

Stopped waiting for pipeline failures after 30000ms. One of your pipelines takes longer than our 30000ms fetch window to run, so review may not consider pipeline-failure results for inline comments if any failures occurred after the fetch window. Increase the timeout if you want to wait longer or run a @coderabbit review after the pipeline has finished.


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

@github-actions github-actions Bot added size:L PR is large Bug issue describes bug; PR fixes bug lang:rust PR changes/introduces Rust code labels Jun 4, 2026
@AjayThorve AjayThorve force-pushed the ajay/relay-176-claude-observability-contract branch from bbe544f to 4ce112e Compare June 4, 2026 07:29
@github-actions
Copy link
Copy Markdown

github-actions Bot commented Jun 4, 2026

@AjayThorve AjayThorve force-pushed the ajay/relay-176-claude-observability-contract branch from 4ce112e to b03f363 Compare June 4, 2026 07:34
@AjayThorve AjayThorve marked this pull request as ready for review June 4, 2026 07:38
@AjayThorve AjayThorve requested a review from a team as a code owner June 4, 2026 07:38
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
crates/cli/src/session.rs (1)

969-1007: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Prune bypass-only sessions after the probe finishes.

Line 971 skips ensure_turn_started, so a brand-new session inserted by SessionManager::prepare_gateway_call can stay completely empty after the unmanaged probe returns. Nothing in SessionManager::finish_gateway_call removes that empty entry, so probe-only sessions accumulate in SessionManager::inner and can later be picked by single_active_session_id(), miscorrelating headerless gateway traffic.

Suggested cleanup
pub(crate) async fn finish_gateway_call(&self, session_id: &str) {
    let mut sessions = self.inner.lock().await;
-    if let Some(session) = sessions.get_mut(session_id) {
-        session.finish_gateway_call();
-    }
+    let should_remove = if let Some(session) = sessions.get_mut(session_id) {
+        session.finish_gateway_call();
+        session.is_empty()
+    } else {
+        false
+    };
+    if should_remove {
+        sessions.remove(session_id);
+    }
}
🤖 Prompt for 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.

In `@crates/cli/src/session.rs` around lines 969 - 1007, The new logic in
SessionManager::prepare_gateway_call can create a brand-new, bypass-only session
(when gateway_management_policy(&start).bypasses_managed_pipeline() is true) but
never removes it, causing empty probe-only sessions to accumulate in
SessionManager::inner and later be returned by single_active_session_id(); to
fix, record that the session was created as a bypass-only/probe-only session in
prepare_gateway_call (e.g., set a flag or marker on the session or in the
returned GatewayCallPrep) and then update SessionManager::finish_gateway_call to
prune the session if it remains empty after the probe (no turns, no requests, no
attributes) — alternatively, detect and remove bypass-only sessions in
single_active_session_id() — reference SessionManager::prepare_gateway_call,
SessionManager::finish_gateway_call, SessionManager::inner,
single_active_session_id(), and GatewayCallPrep when adding the flag/cleanup so
the empty probe-only entries are removed immediately after the probe completes.
🤖 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/server_tests.rs`:
- Around line 846-864: The subscriber filter is checking for a session_id
metadata field that the LLM span never sets; update the predicate used in
register_subscriber so it matches actual fields emitted by the LLM span (e.g.,
the seeded "gateway_path" value and the correlation fields added by
Session::prepare_gateway_call), not "session_id". Locate the subscriber callback
(the Arc::new move |event| closure in the test) and change the checks to assert
event.name() == "anthropic.messages" and match
event.metadata().and_then(...).and_then(Value::as_str) against the
gateway_path/correlation key(s) produced by build_llm_gateway_start and
Session::prepare_gateway_call so the test only captures real LLM start spans.

In `@crates/cli/tests/coverage/session_tests.rs`:
- Around line 2153-2261: The test registers a global subscriber via
register_subscriber using subscriber_name but never removes it, leaking state;
add a teardown that calls deregister_subscriber(subscriber_name) at the end of
the test (after flush_subscribers() and assertions) to unregister the subscriber
and avoid interference with other tests; reference the existing subscriber_name
variable used with register_subscriber so the teardown targets the same
subscriber (or wrap registration in a scope/Drop helper to ensure deregistration
on test exit).

---

Outside diff comments:
In `@crates/cli/src/session.rs`:
- Around line 969-1007: The new logic in SessionManager::prepare_gateway_call
can create a brand-new, bypass-only session (when
gateway_management_policy(&start).bypasses_managed_pipeline() is true) but never
removes it, causing empty probe-only sessions to accumulate in
SessionManager::inner and later be returned by single_active_session_id(); to
fix, record that the session was created as a bypass-only/probe-only session in
prepare_gateway_call (e.g., set a flag or marker on the session or in the
returned GatewayCallPrep) and then update SessionManager::finish_gateway_call to
prune the session if it remains empty after the probe (no turns, no requests, no
attributes) — alternatively, detect and remove bypass-only sessions in
single_active_session_id() — reference SessionManager::prepare_gateway_call,
SessionManager::finish_gateway_call, SessionManager::inner,
single_active_session_id(), and GatewayCallPrep when adding the flag/cleanup so
the empty probe-only entries are removed immediately after the probe completes.
🪄 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: a5d8c9b5-e51e-49dd-8f68-dee31a9772ee

📥 Commits

Reviewing files that changed from the base of the PR and between f7c9415 and b03f363.

📒 Files selected for processing (9)
  • crates/cli/src/alignment/claude_code.rs
  • crates/cli/src/alignment/mod.rs
  • crates/cli/src/gateway.rs
  • crates/cli/src/session.rs
  • crates/cli/tests/coverage/alignment_claude_code_tests.rs
  • crates/cli/tests/coverage/server_tests.rs
  • crates/cli/tests/coverage/session_tests.rs
  • docs/nemo-relay-cli/claude-code.mdx
  • integrations/coding-agents/claude-code/README.md
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: Rust / Test (macos-arm64)
  • GitHub Check: Rust / Test (windows-arm64)
  • GitHub Check: Rust / Test (windows-amd64)
🧰 Additional context used
📓 Path-based instructions (27)
**/*.rs

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

Use snake_case naming convention for Rust identifiers (e.g., nemo_relay_tool_call)

**/*.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

**/*.rs: Run cargo fmt --all to format all Rust code
Run cargo clippy --workspace --all-targets -- -D warnings to enforce all clippy lints as errors

**/*.rs: Run cargo fmt --all when Rust files changed as part of WebAssembly work
Run cargo clippy --workspace --all-targets -- -D warnings when Rust files changed as part of WebAssembly work

**/*.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
Run Rust formatting with cargo fmt --all
Run Rust linting with cargo clippy --workspace --all-targets -- -D warnings

**/*.rs: Use cargo fmt for Rust code formatting
Run cargo clippy -- -D warnings to lint Rust code and treat all warnings as errors
Use Rust snake_case naming convention for Rust identifiers
Include SPDX license header in all Rust source files using double-slash comment syntax
Validate Rust code with uv run pre-commit run --all-files to enforce cargo fmt formatting check, cargo clippy lints, and cargo deny aud...

Files:

  • crates/cli/tests/coverage/alignment_claude_code_tests.rs
  • crates/cli/src/alignment/mod.rs
  • crates/cli/src/alignment/claude_code.rs
  • crates/cli/src/gateway.rs
  • crates/cli/tests/coverage/server_tests.rs
  • crates/cli/src/session.rs
  • crates/cli/tests/coverage/session_tests.rs
{crates/adaptive/**/*.rs,**/*test*.{rs,py,go,ts,js},**/*adaptive*test*.{rs,py,go,ts,js},docs/plugins/adaptive/**}

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

Maintain documented and tested validation and report behavior for adaptive surfaces

Files:

  • crates/cli/tests/coverage/alignment_claude_code_tests.rs
  • crates/cli/tests/coverage/server_tests.rs
  • crates/cli/tests/coverage/session_tests.rs
**/{Cargo.toml,**/*.rs}

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

Maintain consistency between Rust package names in Cargo.toml and their actual usage across the codebase

Files:

  • crates/cli/tests/coverage/alignment_claude_code_tests.rs
  • crates/cli/src/alignment/mod.rs
  • crates/cli/src/alignment/claude_code.rs
  • crates/cli/src/gateway.rs
  • crates/cli/tests/coverage/server_tests.rs
  • crates/cli/src/session.rs
  • crates/cli/tests/coverage/session_tests.rs
**/*.{h,hpp,c,cpp,rs}

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

Ensure FFI header and library naming follows consistent conventions across platform-specific builds

Files:

  • crates/cli/tests/coverage/alignment_claude_code_tests.rs
  • crates/cli/src/alignment/mod.rs
  • crates/cli/src/alignment/claude_code.rs
  • crates/cli/src/gateway.rs
  • crates/cli/tests/coverage/server_tests.rs
  • crates/cli/src/session.rs
  • crates/cli/tests/coverage/session_tests.rs
**/*.{rs,toml}

📄 CodeRabbit inference engine (.agents/skills/rename-surfaces/SKILL.md)

Update Rust crate names and module prefixes during coordinated rename operations

Files:

  • crates/cli/tests/coverage/alignment_claude_code_tests.rs
  • crates/cli/src/alignment/mod.rs
  • crates/cli/src/alignment/claude_code.rs
  • crates/cli/src/gateway.rs
  • crates/cli/tests/coverage/server_tests.rs
  • crates/cli/src/session.rs
  • crates/cli/tests/coverage/session_tests.rs
**/*.{rs,py,js,ts,tsx,jsx,go,sh,toml,yaml,yml,md}

📄 CodeRabbit inference engine (AGENTS.md)

Keep SPDX headers on source, docs, scripts, and configuration files. The project is Apache-2.0.

Files:

  • crates/cli/tests/coverage/alignment_claude_code_tests.rs
  • integrations/coding-agents/claude-code/README.md
  • crates/cli/src/alignment/mod.rs
  • crates/cli/src/alignment/claude_code.rs
  • crates/cli/src/gateway.rs
  • crates/cli/tests/coverage/server_tests.rs
  • crates/cli/src/session.rs
  • crates/cli/tests/coverage/session_tests.rs
**/*.{rs,py,go,js,ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Follow binding naming conventions: Rust and Python use snake_case, C FFI exports prefixed nemo_relay_, Go uses PascalCase for public APIs, Node.js uses camelCase.

Files:

  • crates/cli/tests/coverage/alignment_claude_code_tests.rs
  • crates/cli/src/alignment/mod.rs
  • crates/cli/src/alignment/claude_code.rs
  • crates/cli/src/gateway.rs
  • crates/cli/tests/coverage/server_tests.rs
  • crates/cli/src/session.rs
  • crates/cli/tests/coverage/session_tests.rs
crates/**/*.rs

📄 CodeRabbit inference engine (AGENTS.md)

crates/**/*.rs: Keep async behavior on the existing tokio-based model. Bindings should preserve callback and future lifetimes rather than blocking or hiding async work unexpectedly.
Use Json = serde_json::Value in Rust-facing runtime APIs for JSON payload handling.

Files:

  • crates/cli/tests/coverage/alignment_claude_code_tests.rs
  • crates/cli/src/alignment/mod.rs
  • crates/cli/src/alignment/claude_code.rs
  • crates/cli/src/gateway.rs
  • crates/cli/tests/coverage/server_tests.rs
  • crates/cli/src/session.rs
  • crates/cli/tests/coverage/session_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/alignment_claude_code_tests.rs
  • crates/cli/tests/coverage/server_tests.rs
  • crates/cli/tests/coverage/session_tests.rs
**/*.{md,rst,html,txt}

📄 CodeRabbit inference engine (.agents/skills/review-doc-style/assets/nvidia-style-brand-terminology.md)

**/*.{md,rst,html,txt}: Always spell NVIDIA in all caps. Do not use Nvidia, nvidia, nVidia, nVIDIA, or NV.
Use an NVIDIA before a noun because the name starts with an 'en' sound.
Do not add a registered trademark symbol after NVIDIA when referring to the company.
Use trademark symbols with product names only when the document type or legal guidance requires them.
Verify official capitalization, spacing, and hyphenation for product names.
Precede NVIDIA product names with NVIDIA on first mention when it is natural and accurate.
Do not rewrite product names for grammar or title-case rules.
Preserve third-party product names according to the owner's spelling.
Include the company name and full model qualifier on first use when it helps identify the model.
Preserve the official capitalization and punctuation of model names.
Use shorter family names only after the full name is established.
Spell out a term on first use and put the acronym in parentheses unless the acronym is widely understood by the intended audience.
Use the acronym on later mentions after it has been defined.
For long documents, reintroduce the full term if readers might lose context.
Form plurals of acronyms with s, not an apostrophe, such as GPUs.
In headings, common acronyms can remain abbreviated. Spell out the term in the first or second sentence of the body.
Common terms such as CPU, GPU, PC, API, and UI usually do not need to be spelled out for developer audiences.

Files:

  • integrations/coding-agents/claude-code/README.md
**/*.{md,rst,html}

📄 CodeRabbit inference engine (.agents/skills/review-doc-style/assets/nvidia-style-brand-terminology.md)

Link the first mention of a product name when the destination helps the reader.

Files:

  • integrations/coding-agents/claude-code/README.md
**/*.md

📄 CodeRabbit inference engine (.agents/skills/contribute-integration/SKILL.md)

Documentation must be updated if activation or usage changed

**/*.md: Use title case consistently in technical documentation headings
Avoid quotation marks, ampersands, and exclamation marks in headings
Keep product, event, research, and whitepaper names in their official title case
Use title case for table headers
Do not force social-media sentence case into technical docs
Format code elements, commands, parameters, package names, and expressions in monospace
Format directories, file names, and paths in monospace using backticks
Use angle brackets inside monospace for variables inside paths, such as /home/<username>/.login
Format error messages and strings in quotation marks, keeping literal code strings in code formatting when clearer
Format UI buttons, menus, fields, and labels in bold
Use angle brackets between UI labels for menu paths, such as File > Save As
Use italics for new terms on first use, sparingly and only when introducing the term
Use italics for publication titles
Format keyboard shortcuts in plain text, such as Press Ctrl+Alt+Delete
Use owner/repo link text for GitHub repositories, preferring [NVIDIA/NeMo](link) over prose references like 'the GitHub repo'
Introduce every code block with a complete sentence
Do not make a code block complete the grammar of the previous sentence
Do not continue a sentence after a code block
Use syntax highlighting when the format supports it for code blocks
Avoid the word 'snippet' unless the surrounding docs already use it as a term of art
Keep inline method, function, and class references consistent with nearby docs, omitting empty parentheses for prose readability when no call is shown
Use descriptive anchor text that matches the destination title when possible for links
Avoid raw URLs in running text
Avoid generic anchor text such as 'here,' 'this page,' and 'read more'
Include acronyms in link text when a linked term includes an acronym
Do not link long sentences or multiple sentences
Avoid links ...

Files:

  • integrations/coding-agents/claude-code/README.md
**/{docs,examples,**/*.md,*.patch,*.diff,.github,*.sh,*.yaml,*.yml}

📄 CodeRabbit inference engine (.agents/skills/rename-surfaces/SKILL.md)

Update documentation, examples, CI configuration, and patch artifacts when performing rename operations

Files:

  • integrations/coding-agents/claude-code/README.md
**/*.{md,rst,txt}

📄 CodeRabbit inference engine (.agents/skills/review-doc-style/assets/nvidia-style-guide.md)

Spell NVIDIA in all caps. Do not use Nvidia, nvidia, or NV.

Files:

  • integrations/coding-agents/claude-code/README.md
**/*.{md,rst}

📄 CodeRabbit inference engine (.agents/skills/review-doc-style/assets/nvidia-style-guide.md)

**/*.{md,rst}: Format commands, code elements, expressions, package names, file names, and paths as inline code.
Use descriptive link text. Avoid raw URLs and weak anchors such as "here" or "read more."
Use title case consistently for technical documentation headings.
Introduce code blocks, lists, tables, and images with complete sentences.
Write procedures as imperative steps. Keep steps parallel and split long procedures into smaller tasks.
Prefer active voice, present tense, short sentences, contractions, and plain English.
Use can for possibility and reserve may for permission.
Use after for temporal relationships instead of once.
Prefer refer to over see when the wording points readers to another resource.
Avoid culture-specific idioms, unnecessary Latinisms, jokes, and marketing exaggeration in technical docs.
Spell out months in body text, avoid ordinal dates, and use clear time zones.
Spell out whole numbers from zero through nine unless they are technical values, parameters, versions, or UI values.
Use numerals for 10 or greater and include commas in thousands.
Do not add trademark symbols to learning-oriented docs unless the source, platform, or legal guidance explicitly requires them.

Files:

  • integrations/coding-agents/claude-code/README.md
{docs/**,README.md,CONTRIBUTING.md,**/*.md}

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

Run docs link validation with just docs-linkcheck when links change

Files:

  • integrations/coding-agents/claude-code/README.md
  • docs/nemo-relay-cli/claude-code.mdx
{docs/**,README.md,**/Cargo.toml,**/package.json,**/*.md}

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

Ensure renamed public surfaces are reflected consistently in manifests and docs for large or public-facing changes

Files:

  • integrations/coding-agents/claude-code/README.md
  • docs/nemo-relay-cli/claude-code.mdx
**/*.{md,mdx,py,sh,yaml,yml,toml,json}

📄 CodeRabbit inference engine (.agents/skills/contribute-docs/SKILL.md)

Keep package names, repo references, and build commands current

Files:

  • integrations/coding-agents/claude-code/README.md
  • docs/nemo-relay-cli/claude-code.mdx
**/*.{html,md,mdx}

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Include SPDX license header in HTML and Markdown files using HTML comment syntax

Files:

  • integrations/coding-agents/claude-code/README.md
  • docs/nemo-relay-cli/claude-code.mdx
**/README.md

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Update relevant crate or package README when that surface changed

Files:

  • integrations/coding-agents/claude-code/README.md
{docs/**,README.md,CONTRIBUTING.md}

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

{docs/**,README.md,CONTRIBUTING.md}: For docs-only changes, run targeted checks only if commands, package names, or examples changed. Use just docs for docs-site builds and just docs-linkcheck when links changed
Run docs site build with just docs

Files:

  • docs/nemo-relay-cli/claude-code.mdx
{docs/**,README.md}

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

Verify README and docs entry points still match current package names and paths for large or public-facing changes

Files:

  • docs/nemo-relay-cli/claude-code.mdx
{docs/**,examples/**,README.md}

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

Verify examples still run with documented commands for large or public-facing changes

Files:

  • docs/nemo-relay-cli/claude-code.mdx
**/*.mdx

📄 CodeRabbit inference engine (.agents/skills/contribute-docs/SKILL.md)

In MDX files, top-of-file comments must use JSX comment delimiters: {/* to open and */} to close. Do not use HTML comments for MDX SPDX headers.

MDX top-of-file SPDX comments must use {/* ... */} delimiters instead of HTML comment delimiters (Must-Fix)

Files:

  • docs/nemo-relay-cli/claude-code.mdx
docs/**/*.{md,mdx}

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Update embedded documentation snippets, patch docs, and binding-support notes if examples or supported bindings changed

Files:

  • docs/nemo-relay-cli/claude-code.mdx
docs/**

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Run just docs or ./scripts/build-docs.sh html to regenerate ignored Fern API reference pages before validation for documentation site changes

Files:

  • docs/nemo-relay-cli/claude-code.mdx
{docs/**,README.md,CONTRIBUTING.md,RELEASING.md,SECURITY.md}

⚙️ CodeRabbit configuration file

{docs/**,README.md,CONTRIBUTING.md,RELEASING.md,SECURITY.md}: Review documentation for technical accuracy against the current API, command correctness, and consistency across language bindings.
Flag stale examples, missing SPDX headers where required, and instructions that no longer match CI or pre-commit behavior.

Files:

  • docs/nemo-relay-cli/claude-code.mdx
🔇 Additional comments (6)
crates/cli/src/alignment/claude_code.rs (1)

11-12: LGTM!

Also applies to: 31-63

crates/cli/src/alignment/mod.rs (1)

53-73: LGTM!

Also applies to: 431-447

crates/cli/tests/coverage/alignment_claude_code_tests.rs (1)

5-7: LGTM!

Also applies to: 48-110

docs/nemo-relay-cli/claude-code.mdx (1)

110-117: LGTM!

Also applies to: 131-133, 162-177, 179-189

integrations/coding-agents/claude-code/README.md (1)

29-35: LGTM!

Also applies to: 137-150, 152-154

crates/cli/tests/coverage/session_tests.rs (1)

2263-2437: LGTM!

Comment thread crates/cli/tests/coverage/server_tests.rs
Comment thread crates/cli/tests/coverage/session_tests.rs
Signed-off-by: Ajay Thorve <athorve@nvidia.com>
@AjayThorve AjayThorve force-pushed the ajay/relay-176-claude-observability-contract branch from b03f363 to 243e7e1 Compare June 4, 2026 07:52
@AjayThorve AjayThorve self-assigned this Jun 4, 2026
Signed-off-by: Ajay Thorve <athorve@nvidia.com>
@willkill07
Copy link
Copy Markdown
Member

/merge

@rapids-bot rapids-bot Bot merged commit 8a852b2 into NVIDIA:main Jun 4, 2026
34 checks passed
@willkill07 willkill07 added this to the 0.4 milestone Jun 4, 2026
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:L PR is large

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants