Skip to content

feat(logging): add configurable operational logging#413

Merged
rapids-bot[bot] merged 26 commits into
NVIDIA:mainfrom
ericevans-nv:feat/persistent-relay-logging
Jul 16, 2026
Merged

feat(logging): add configurable operational logging#413
rapids-bot[bot] merged 26 commits into
NVIDIA:mainfrom
ericevans-nv:feat/persistent-relay-logging

Conversation

@ericevans-nv

@ericevans-nv ericevans-nv commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

Overview

Add configurable, process-wide operational logging backed by the log facade and spdlog-rs. Operational commands initialize logging during top-level dispatch, before command execution. nemo-relay config and nemo-relay plugins edit intentionally skip initialization so invalid logging configuration cannot prevent users from repairing it.

This PR establishes the logging configuration and runtime. Broader production operational event call sites will be added separately.

  • 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

  • Add core-owned LoggingConfig and LoggingRuntime APIs shared by CLI and library integrations.
  • Support built-in defaults, normal config.toml discovery, environment configuration, explicit absolute TOML paths, and direct CLI settings. CLI sources take precedence over environment configuration, which takes precedence over discovered file configuration and defaults.
  • Add an always-on stderr sink for initialized operational commands and optional asynchronous JSONL or human-readable file sinks.
  • Bound asynchronous file queues, reject duplicate resolved sink paths, and drain pending file records during shutdown.
  • Attach one root Relay ID to operational records for process-level correlation.
  • Keep logging output on stderr or configured files; operational logging does not write to stdout.
  • Keep logging configuration under [logging] in config.toml. A separate interactive logging editor is outside this PR.
  • Documentation for the configuration surface is tracked in docs(cli): document operational process logging config #419.
  • Add focused core and CLI coverage for parsing, validation, formatting, sink behavior, configuration precedence, initialization policy, and shutdown flushing.
  • Regenerate ATTRIBUTIONS-Rust.md for the new Rust dependencies.

Where should the reviewer start?

  • crates/core/src/logging/ for configuration types, runtime ownership, formatting, sinks, and shutdown behavior
  • crates/cli/src/commands/logging.rs and crates/cli/src/commands/mod.rs for configuration-source selection and early command initialization
  • crates/cli/src/configuration/logging.rs for normal Relay TOML integration
  • crates/core/tests/coverage/logging_tests.rs and crates/cli/tests/coverage/shared/config_tests.rs for runtime and configuration guarantees
  • crates/cli/tests/coverage/commands/main_tests.rs for CLI precedence and command policy

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

  • Closes: RELAY-451

Summary by CodeRabbit

  • New Features
    • Added configurable operational logging with human-readable or JSONL output.
    • Added stderr and asynchronous file sinks with per-sink level/format, queue limits, and periodic flushing.
    • Introduced logging configuration via CLI options, environment variables, and TOML (including scoped application).
    • Logging now initializes automatically for applicable CLI commands, while configuration/editor commands can bypass it.
  • Bug Fixes
    • Strengthened validation for configuration values and file sink destination handling (including duplicates and invalid paths).
  • Tests
    • Added extensive logging coverage for config loading, formatter output, sink runtime behavior, shutdown behavior, and CLI precedence/policy.
  • Chores
    • Regenerated dependency attribution and license metadata.

Signed-off-by: Eric Evans <194135482+ericevans-nv@users.noreply.github.com>
…ent-relay-logging

Signed-off-by: Eric Evans <194135482+ericevans-nv@users.noreply.github.com>
@ericevans-nv
ericevans-nv requested review from a team and lvojtku as code owners July 13, 2026 22:26
@github-actions github-actions Bot added size:XXL PR is very large Feature a new feature lang:rust PR changes/introduces Rust code labels Jul 13, 2026
@coderabbitai

coderabbitai Bot commented Jul 13, 2026

Copy link
Copy Markdown

Review Change Stack

Walkthrough

Adds configurable operational logging with human and JSONL output, asynchronous file sinks, runtime lifecycle management, CLI and TOML/environment configuration, validation tests, and refreshed Rust dependency attribution records.

Changes

Operational logging

Layer / File(s) Summary
Logging configuration and public types
crates/core/src/logging/*, crates/core/src/lib.rs, crates/core/Cargo.toml, crates/cli/src/configuration/*
Adds logging types, parsing, environment/TOML loading, file-sink validation, queue limits, and resolved configuration propagation.
Logger assembly and runtime lifecycle
crates/core/src/logging/format.rs, crates/core/src/logging/sink.rs, crates/core/src/logging/mod.rs
Adds human and JSONL formatting, stderr and asynchronous file sinks, duplicate-path detection, queue-drop reporting, proxy installation, and shutdown flushing.
CLI lifecycle integration
crates/cli/src/commands/*
Adds logging options, source precedence, dispatch initialization, runtime retention, and bypass rules for configuration-editing commands.
Logging behavior coverage
crates/core/tests/coverage/*, crates/cli/tests/coverage/*
Tests configuration, formatting, filtering, fan-out, path and queue validation, flushing, shutdown, proxy lifecycle, CLI policies, and launcher behavior.
Dependency attribution refresh
ATTRIBUTIONS-Rust.md
Regenerates Rust crate metadata, license references, SPDX links, and embedded license text.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant CLI
  participant LoggingArgs
  participant LoggingRuntime
  participant build_logger
  participant AsyncFileSink
  CLI->>LoggingArgs: resolve CLI, environment, or TOML settings
  LoggingArgs->>LoggingRuntime: configure LoggingConfig
  LoggingRuntime->>build_logger: build logger and sinks
  build_logger->>AsyncFileSink: create bounded asynchronous file sink
  LoggingRuntime-->>CLI: retain LoggingRuntime during dispatch
  CLI->>LoggingRuntime: drop or shutdown
  LoggingRuntime->>AsyncFileSink: flush queued records
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 logging feature.
Description check ✅ Passed The description follows the template well and includes all required sections with substantive content.
Docstring Coverage ✅ Passed Docstring coverage is 91.89% which is sufficient. The required threshold is 80.00%.
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.

@github-actions

Copy link
Copy Markdown

@github-actions

github-actions Bot commented Jul 13, 2026

Copy link
Copy Markdown

License Diff

Compared against origin/main.

Lockfile license changes

Lockfile License Changes

Rust

Added

  • atomic 0.6.1 (Apache-2.0)
  • bytemuck 1.25.1 (Apache-2.0)
  • bytemuck_derive 1.11.0 (Apache-2.0)
  • crossbeam 0.8.4 (Apache-2.0)
  • crossbeam-channel 0.5.16 (Apache-2.0)
  • crossbeam-deque 0.8.7 (Apache-2.0)
  • crossbeam-epoch 0.9.20 (Apache-2.0)
  • crossbeam-queue 0.3.13 (Apache-2.0)
  • env_filter 0.1.4 (Apache-2.0)
  • erased-serde 0.4.10 (MIT OR Apache-2.0)
  • nom 8.0.0 (MIT)
  • rustc_version 0.4.1 (Apache-2.0)
  • serde_buf 0.1.2 (Apache-2.0 OR MIT)
  • serde_fmt 1.1.0 (Apache-2.0 OR MIT)
  • spdlog-internal 0.2.1 (Apache-2.0)
  • spdlog-macros 0.3.1 (Apache-2.0)
  • spdlog-rs 0.5.3 (Apache-2.0)
  • sval 2.20.0 (Apache-2.0 OR MIT)
  • sval_buffer 2.20.0 (Apache-2.0 OR MIT)
  • sval_dynamic 2.20.0 (Apache-2.0 OR MIT)
  • sval_fmt 2.20.0 (Apache-2.0 OR MIT)
  • sval_json 2.20.0 (Apache-2.0 OR MIT)
  • sval_nested 2.20.0 (Apache-2.0 OR MIT)
  • sval_ref 2.20.0 (Apache-2.0 OR MIT)
  • sval_serde 2.20.0 (Apache-2.0 OR MIT)
  • typeid 1.0.3 (MIT OR Apache-2.0)
  • value-bag 1.13.0 (Apache-2.0)
  • value-bag-serde1 1.13.0 (Apache-2.0 OR MIT)
  • value-bag-sval2 1.13.0 (Apache-2.0 OR MIT)

Removed

  • None

Updated/Changed

  • None

Node

Added

  • None

Removed

  • None

Updated/Changed

  • None

Python

Added

  • None

Removed

  • None

Updated/Changed

  • None
Status output
[license-diff] selected languages: rust, node, python
[license-diff] generating current inventory
[license-diff] current: generating Rust inventory
[license-diff] current: Rust inventory complete (421 packages)
[license-diff] current: generating Node inventory
[license-diff] current: Node inventory complete (363 packages)
[license-diff] current: generating Python inventory
[license-diff] current: Python inventory complete (105 packages)
[license-diff] current inventory complete
[license-diff] checking out base ref origin/main into a temporary worktree
[license-diff] base: generating Rust inventory
[license-diff] base: Rust inventory complete (392 packages)
[license-diff] base: generating Node inventory
[license-diff] base: Node inventory complete (363 packages)
[license-diff] base: generating Python inventory
[license-diff] base: Python inventory complete (105 packages)
[license-diff] base inventory complete
[license-diff] removing temporary base worktree
[license-diff] comparing inventories
[license-diff] rendering Markdown output
[license-diff] done

@ericevans-nv
ericevans-nv force-pushed the feat/persistent-relay-logging branch from 24e823d to 7b0bc50 Compare July 13, 2026 22:46
Signed-off-by: Eric Evans <194135482+ericevans-nv@users.noreply.github.com>
@ericevans-nv
ericevans-nv force-pushed the feat/persistent-relay-logging branch from 7b0bc50 to 71cd417 Compare July 13, 2026 23:14
…ay-logging

Signed-off-by: Eric Evans <194135482+ericevans-nv@users.noreply.github.com>
@willkill07 willkill07 added this to the 0.6 milestone Jul 14, 2026
…ay-logging

Signed-off-by: Eric Evans <194135482+ericevans-nv@users.noreply.github.com>

@willkill07 willkill07 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Logging should be part of core, not just the CLI.

I also don't understand why/how nemo_relay.h has been changed.

Signed-off-by: Eric Evans <194135482+ericevans-nv@users.noreply.github.com>
Signed-off-by: Eric Evans <194135482+ericevans-nv@users.noreply.github.com>

Copy link
Copy Markdown
Contributor Author

I addressed the open configuration and initialization items from the latest review:

  • Logging now initializes during top-level dispatch for operational commands, including hook forwarding, MCP, and wrapped execution. Only config and plugins edit skip initialization so invalid settings cannot block configuration repair.
  • Environment configuration supports NEMO_RELAY_LOG, NEMO_RELAY_LOG_STDERR_FORMAT, and an absolute TOML path through NEMO_RELAY_LOG_CONFIG_PATH.
  • CLI and library integrations share the core LoggingConfig and LoggingRuntime types, validation, defaults, and initialization behavior.
  • CLI runtime overrides are available through --log-level, --log-stderr-format, and --log-config-path.

Logging remains under [logging] in the normal Relay configuration. I kept a separate interactive logging editor outside this PR because the existing file, CLI, environment, and library configuration surfaces cover the runtime use cases without introducing another configuration workflow.

@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: 6

🤖 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/commands/mod.rs`:
- Around line 59-65: Update the initialize_logging decision in the CLI command
dispatch to disable logging for every dry-run mode, including run, install, and
uninstall, rather than relying only on Command::skips_logging. Ensure these
commands bypass logging setup even with an invalid logging configuration, and
add a CLI test covering that behavior.

In `@crates/cli/src/commands/root.rs`:
- Around line 128-134: The dry-run run command must bypass logging
initialization, and its assertion must be tested through CLI dispatch. Update
Command::skips_logging() to match RunCommand only when dry-run is enabled; in
crates/cli/tests/coverage/agents/launcher_tests.rs:1594-1600, move the assertion
to a CLI dispatch test because the launcher path bypasses this logging gate.

In `@crates/cli/tests/coverage/shared/config_tests.rs`:
- Around line 2919-2928: Extend the test around resolved.logging.sinks and its
LogSinkConfig::File entry to exercise the configured sink through the runtime,
not just parsed values. Initialize the logger using the resolved configuration,
emit a trace record, then read the configured log_a file and assert the trace
record is present, ensuring sink-level Trace overrides the global Debug filter.

In `@crates/core/src/logging/config.rs`:
- Around line 240-247: Make both RawLoggingConfig and RawFileLogSinkConfig
reject unknown fields by applying serde’s deny-unknown-fields behavior to each
struct. Add tests covering misspelled or unsupported fields such as
queue_capcity and sink, asserting deserialization fails instead of silently
using defaults or omitting sinks.

In `@crates/core/src/logging/mod.rs`:
- Around line 110-117: Serialize logger installation and removal across teardown
and configure flows so swap_logger(None) cannot overwrite a newer logger
installed concurrently. Update the relevant teardown logic around swap_logger
and the configure path to use a process-wide synchronization mechanism or
generation validation, preserving the newest installation. Add a concurrent
regression test covering reconfiguration racing with teardown.
- Around line 56-60: Update the initialization flow around
spdlog::init_log_crate_proxy and set_logger so an initialization failure is
propagated when the process has a foreign global logger, rather than silently
ignored. Treat SetLoggerError as benign only for genuine re-entry where the
Relay proxy is already installed, and preserve receiver/filter setup for
successful initialization.
🪄 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: 7ead193d-202f-42f5-ba42-73727a0736fb

📥 Commits

Reviewing files that changed from the base of the PR and between b47edca and 07d31ee.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (19)
  • ATTRIBUTIONS-Rust.md
  • crates/cli/src/commands/logging.rs
  • crates/cli/src/commands/mod.rs
  • crates/cli/src/commands/plugins/subcommands.rs
  • crates/cli/src/commands/root.rs
  • crates/cli/src/configuration/logging.rs
  • crates/cli/src/configuration/mod.rs
  • crates/cli/src/configuration/types.rs
  • crates/cli/tests/coverage/agents/launcher_tests.rs
  • crates/cli/tests/coverage/commands/main_tests.rs
  • crates/cli/tests/coverage/shared/config_tests.rs
  • crates/core/Cargo.toml
  • crates/core/src/lib.rs
  • crates/core/src/logging/config.rs
  • crates/core/src/logging/format.rs
  • crates/core/src/logging/mod.rs
  • crates/core/src/logging/sink.rs
  • crates/core/tests/coverage/logging_sink_tests.rs
  • crates/core/tests/coverage/logging_tests.rs
📜 Review details
🧰 Additional context used
📓 Path-based instructions (22)
**/*.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/core/src/lib.rs
  • crates/core/tests/coverage/logging_sink_tests.rs
  • crates/cli/src/commands/plugins/subcommands.rs
  • crates/cli/src/commands/mod.rs
  • crates/cli/src/configuration/types.rs
  • crates/cli/tests/coverage/agents/launcher_tests.rs
  • crates/cli/src/commands/logging.rs
  • crates/cli/src/commands/root.rs
  • crates/core/src/logging/sink.rs
  • crates/cli/tests/coverage/commands/main_tests.rs
  • crates/cli/tests/coverage/shared/config_tests.rs
  • crates/core/src/logging/config.rs
  • crates/core/src/logging/mod.rs
  • crates/core/src/logging/format.rs
  • crates/cli/src/configuration/logging.rs
  • crates/core/tests/coverage/logging_tests.rs
  • crates/cli/src/configuration/mod.rs
{crates/core,crates/adaptive}/**/*

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

Changes to crates/core or crates/adaptive must run the full language matrix

Files:

  • crates/core/src/lib.rs
  • crates/core/Cargo.toml
  • crates/core/tests/coverage/logging_sink_tests.rs
  • crates/core/src/logging/sink.rs
  • crates/core/src/logging/config.rs
  • crates/core/src/logging/mod.rs
  • crates/core/src/logging/format.rs
  • crates/core/tests/coverage/logging_tests.rs
crates/core/**/*.rs

📄 CodeRabbit inference engine (.agents/skills/test-go-binding/SKILL.md)

If the change touched crates/core or shared runtime semantics, also use validate-change for broader validation

Files:

  • crates/core/src/lib.rs
  • crates/core/tests/coverage/logging_sink_tests.rs
  • crates/core/src/logging/sink.rs
  • crates/core/src/logging/config.rs
  • crates/core/src/logging/mod.rs
  • crates/core/src/logging/format.rs
  • crates/core/tests/coverage/logging_tests.rs
**/*.{rs,py}

📄 CodeRabbit inference engine (AGENTS.md)

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

Files:

  • crates/core/src/lib.rs
  • crates/core/tests/coverage/logging_sink_tests.rs
  • crates/cli/src/commands/plugins/subcommands.rs
  • crates/cli/src/commands/mod.rs
  • crates/cli/src/configuration/types.rs
  • crates/cli/tests/coverage/agents/launcher_tests.rs
  • crates/cli/src/commands/logging.rs
  • crates/cli/src/commands/root.rs
  • crates/core/src/logging/sink.rs
  • crates/cli/tests/coverage/commands/main_tests.rs
  • crates/cli/tests/coverage/shared/config_tests.rs
  • crates/core/src/logging/config.rs
  • crates/core/src/logging/mod.rs
  • crates/core/src/logging/format.rs
  • crates/cli/src/configuration/logging.rs
  • crates/core/tests/coverage/logging_tests.rs
  • crates/cli/src/configuration/mod.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/core/src/lib.rs
  • crates/core/tests/coverage/logging_sink_tests.rs
  • crates/cli/src/commands/plugins/subcommands.rs
  • crates/cli/src/commands/mod.rs
  • crates/cli/src/configuration/types.rs
  • crates/cli/tests/coverage/agents/launcher_tests.rs
  • crates/cli/src/commands/logging.rs
  • crates/cli/src/commands/root.rs
  • crates/core/src/logging/sink.rs
  • crates/cli/tests/coverage/commands/main_tests.rs
  • crates/cli/tests/coverage/shared/config_tests.rs
  • crates/core/src/logging/config.rs
  • crates/core/src/logging/mod.rs
  • crates/core/src/logging/format.rs
  • crates/cli/src/configuration/logging.rs
  • crates/core/tests/coverage/logging_tests.rs
  • crates/cli/src/configuration/mod.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/core/src/lib.rs
  • crates/core/tests/coverage/logging_sink_tests.rs
  • crates/cli/src/commands/plugins/subcommands.rs
  • crates/cli/src/commands/mod.rs
  • crates/cli/src/configuration/types.rs
  • crates/cli/tests/coverage/agents/launcher_tests.rs
  • crates/cli/src/commands/logging.rs
  • crates/cli/src/commands/root.rs
  • crates/core/src/logging/sink.rs
  • crates/cli/tests/coverage/commands/main_tests.rs
  • crates/cli/tests/coverage/shared/config_tests.rs
  • crates/core/src/logging/config.rs
  • crates/core/src/logging/mod.rs
  • crates/core/src/logging/format.rs
  • crates/cli/src/configuration/logging.rs
  • crates/core/tests/coverage/logging_tests.rs
  • crates/cli/src/configuration/mod.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/core/src/lib.rs
  • crates/core/tests/coverage/logging_sink_tests.rs
  • crates/cli/src/commands/plugins/subcommands.rs
  • crates/cli/src/commands/mod.rs
  • crates/cli/src/configuration/types.rs
  • crates/cli/tests/coverage/agents/launcher_tests.rs
  • crates/cli/src/commands/logging.rs
  • crates/cli/src/commands/root.rs
  • crates/core/src/logging/sink.rs
  • crates/cli/tests/coverage/commands/main_tests.rs
  • crates/cli/tests/coverage/shared/config_tests.rs
  • crates/core/src/logging/config.rs
  • crates/core/src/logging/mod.rs
  • crates/core/src/logging/format.rs
  • crates/cli/src/configuration/logging.rs
  • crates/core/tests/coverage/logging_tests.rs
  • crates/cli/src/configuration/mod.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/core/src/lib.rs
  • crates/cli/src/commands/plugins/subcommands.rs
  • crates/cli/src/commands/mod.rs
  • crates/cli/src/configuration/types.rs
  • crates/cli/src/commands/logging.rs
  • crates/cli/src/commands/root.rs
  • crates/core/src/logging/sink.rs
  • crates/core/src/logging/config.rs
  • crates/core/src/logging/mod.rs
  • crates/core/src/logging/format.rs
  • crates/cli/src/configuration/logging.rs
  • crates/cli/src/configuration/mod.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/core/src/lib.rs
  • crates/core/Cargo.toml
  • crates/core/tests/coverage/logging_sink_tests.rs
  • crates/cli/src/commands/plugins/subcommands.rs
  • crates/cli/src/commands/mod.rs
  • crates/cli/src/configuration/types.rs
  • crates/cli/tests/coverage/agents/launcher_tests.rs
  • crates/cli/src/commands/logging.rs
  • crates/cli/src/commands/root.rs
  • crates/core/src/logging/sink.rs
  • crates/cli/tests/coverage/commands/main_tests.rs
  • crates/cli/tests/coverage/shared/config_tests.rs
  • crates/core/src/logging/config.rs
  • crates/core/src/logging/mod.rs
  • crates/core/src/logging/format.rs
  • crates/cli/src/configuration/logging.rs
  • ATTRIBUTIONS-Rust.md
  • crates/core/tests/coverage/logging_tests.rs
  • crates/cli/src/configuration/mod.rs
crates/{core,adaptive}/**/*

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

If crates/core or crates/adaptive changed, run the full validation matrix across Rust, Python, Go, and Node.js.

Files:

  • crates/core/src/lib.rs
  • crates/core/Cargo.toml
  • crates/core/tests/coverage/logging_sink_tests.rs
  • crates/core/src/logging/sink.rs
  • crates/core/src/logging/config.rs
  • crates/core/src/logging/mod.rs
  • crates/core/src/logging/format.rs
  • crates/core/tests/coverage/logging_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/core/src/lib.rs
  • crates/core/tests/coverage/logging_sink_tests.rs
  • crates/cli/src/commands/plugins/subcommands.rs
  • crates/cli/src/commands/mod.rs
  • crates/cli/src/configuration/types.rs
  • crates/cli/tests/coverage/agents/launcher_tests.rs
  • crates/cli/src/commands/logging.rs
  • crates/cli/src/commands/root.rs
  • crates/core/src/logging/sink.rs
  • crates/cli/tests/coverage/commands/main_tests.rs
  • crates/cli/tests/coverage/shared/config_tests.rs
  • crates/core/src/logging/config.rs
  • crates/core/src/logging/mod.rs
  • crates/core/src/logging/format.rs
  • crates/cli/src/configuration/logging.rs
  • crates/core/tests/coverage/logging_tests.rs
  • crates/cli/src/configuration/mod.rs
crates/{core,adaptive}/**/*.rs

⚙️ CodeRabbit configuration file

crates/{core,adaptive}/**/*.rs: Review the Rust runtime for async correctness, scope isolation, middleware ordering, and event lifecycle regressions.
Pay close attention to task-local/thread-local scope propagation, callback lifetimes, stream finalization, and root_uuid isolation.
Public API changes should preserve existing behavior unless tests and docs show the intended migration path.

Files:

  • crates/core/src/lib.rs
  • crates/core/tests/coverage/logging_sink_tests.rs
  • crates/core/src/logging/sink.rs
  • crates/core/src/logging/config.rs
  • crates/core/src/logging/mod.rs
  • crates/core/src/logging/format.rs
  • crates/core/tests/coverage/logging_tests.rs
**/Cargo.toml

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

Confirm or infer the target release version from upstream/main:Cargo.toml. Derive the release branch as release/<major>.<minor>.

Keep Rust package names and workspace metadata in Cargo.toml internally consistent across the project.

Files:

  • crates/core/Cargo.toml
**/*.toml

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Add the SPDX license header to all TOML files using the # comment form.

Files:

  • crates/core/Cargo.toml
{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/core/tests/coverage/logging_sink_tests.rs
  • crates/cli/tests/coverage/agents/launcher_tests.rs
  • crates/cli/tests/coverage/commands/main_tests.rs
  • crates/cli/tests/coverage/shared/config_tests.rs
  • crates/core/tests/coverage/logging_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:

  • ATTRIBUTIONS-Rust.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:

  • ATTRIBUTIONS-Rust.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:

  • ATTRIBUTIONS-Rust.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:

  • ATTRIBUTIONS-Rust.md
**/*.md

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

**/*.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 that pull readers away from a procedure unless the link is a p...

Files:

  • ATTRIBUTIONS-Rust.md
**/*.{md,mdx}

📄 CodeRabbit inference engine (AGENTS.md)

Update README.md, fern/, package READMEs, and binding-support notes when public behavior, package names, examples, or supported bindings change.

**/*.{md,mdx}: Prefer the documented public API, not internal shortcuts
Keep package names, repo references, and build commands current
Keep release-process and release-notes guidance in repo-maintainer docs such as RELEASING.md, not as user-facing docs pages or CHANGELOG.md
Keep stable user-facing wrappers at scripts/ root in docs and examples; only point at namespaced helper paths when documenting internal maintenance work
When detailed dynamic plugin guides exist, keep Rust native plugin examples, Python worker plugin examples, and grpc-v1 protocol details on separate pages

If links in documentation change, run just docs-linkcheck.

Files:

  • ATTRIBUTIONS-Rust.md
**/*.{md,markdown,mdx}

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Add the SPDX license header to all Markdown/MDX documentation files using the HTML comment block form.

Files:

  • ATTRIBUTIONS-Rust.md
🪛 markdownlint-cli2 (0.23.0)
ATTRIBUTIONS-Rust.md

[warning] 2303-2303: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 2306-2306: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Above

(MD022, blanks-around-headings)


[warning] 2306-2306: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 2307-2307: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


[warning] 2307-2307: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


[warning] 4902-4902: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 4905-4905: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Above

(MD022, blanks-around-headings)


[warning] 4905-4905: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 4906-4906: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


[warning] 4906-4906: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


[warning] 4971-4971: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 4974-4974: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Above

(MD022, blanks-around-headings)


[warning] 4974-4974: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 4975-4975: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


[warning] 4975-4975: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


[warning] 8979-8979: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 8982-8982: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Above

(MD022, blanks-around-headings)


[warning] 8982-8982: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 8983-8983: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


[warning] 8983-8983: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


[warning] 9188-9188: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 9191-9191: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Above

(MD022, blanks-around-headings)


[warning] 9191-9191: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 9192-9192: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


[warning] 9192-9192: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


[warning] 9397-9397: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 9400-9400: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Above

(MD022, blanks-around-headings)


[warning] 9400-9400: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 9401-9401: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


[warning] 9401-9401: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


[warning] 9606-9606: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 9609-9609: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Above

(MD022, blanks-around-headings)


[warning] 9609-9609: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 9610-9610: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


[warning] 9610-9610: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


[warning] 9815-9815: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 9818-9818: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Above

(MD022, blanks-around-headings)


[warning] 9818-9818: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 9819-9819: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


[warning] 9819-9819: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


[warning] 12530-12530: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 12533-12533: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Above

(MD022, blanks-around-headings)


[warning] 12533-12533: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 12534-12534: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


[warning] 12534-12534: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


[warning] 12949-12949: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 12952-12952: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Above

(MD022, blanks-around-headings)


[warning] 12952-12952: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 12953-12953: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Above

(MD022, blanks-around-headings)


[warning] 12953-12953: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 12954-12954: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


[warning] 12954-12954: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


[warning] 13133-13133: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 13134-13134: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


[warning] 13134-13134: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


[warning] 25583-25583: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 25586-25586: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Above

(MD022, blanks-around-headings)


[warning] 25586-25586: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 25587-25587: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


[warning] 25587-25587: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


[warning] 35780-35780: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 35783-35783: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Above

(MD022, blanks-around-headings)


[warning] 35783-35783: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 35784-35784: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


[warning] 35784-35784: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


[warning] 37957-37957: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 37960-37960: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Above

(MD022, blanks-around-headings)


[warning] 37960-37960: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 37961-37961: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Above

(MD022, blanks-around-headings)


[warning] 37961-37961: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 37962-37962: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


[warning] 37962-37962: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


[warning] 38166-38166: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 38167-38167: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


[warning] 38167-38167: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


[warning] 38434-38434: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 38437-38437: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Above

(MD022, blanks-around-headings)


[warning] 38437-38437: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 38438-38438: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Above

(MD022, blanks-around-headings)


[warning] 38438-38438: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 38439-38439: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


[warning] 38439-38439: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


[warning] 38643-38643: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 38644-38644: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


[warning] 38644-38644: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


[warning] 40618-40618: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 40621-40621: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Above

(MD022, blanks-around-headings)


[warning] 40621-40621: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 40622-40622: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


[warning] 40622-40622: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


[warning] 40699-40699: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 40702-40702: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Above

(MD022, blanks-around-headings)


[warning] 40702-40702: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 40703-40703: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


[warning] 40703-40703: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


[warning] 40780-40780: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 40783-40783: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Above

(MD022, blanks-around-headings)


[warning] 40783-40783: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 40784-40784: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


[warning] 40784-40784: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


[warning] 41324-41324: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 41327-41327: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Above

(MD022, blanks-around-headings)


[warning] 41327-41327: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 41328-41328: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Above

(MD022, blanks-around-headings)


[warning] 41328-41328: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 41329-41329: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


[warning] 41329-41329: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


[warning] 41533-41533: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 41534-41534: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


[warning] 41534-41534: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


[warning] 41558-41558: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 41561-41561: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Above

(MD022, blanks-around-headings)


[warning] 41561-41561: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 41562-41562: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Above

(MD022, blanks-around-headings)


[warning] 41562-41562: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 41563-41563: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


[warning] 41563-41563: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


[warning] 41767-41767: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 41768-41768: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


[warning] 41768-41768: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


[warning] 41792-41792: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 41795-41795: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Above

(MD022, blanks-around-headings)


[warning] 41795-41795: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 41796-41796: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Above

(MD022, blanks-around-headings)


[warning] 41796-41796: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 41797-41797: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


[warning] 41797-41797: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


[warning] 42001-42001: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 42002-42002: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


[warning] 42002-42002: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


[warning] 42026-42026: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 42029-42029: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Above

(MD022, blanks-around-headings)


[warning] 42029-42029: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 42030-42030: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Above

(MD022, blanks-around-headings)


[warning] 42030-42030: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 42031-42031: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


[warning] 42031-42031: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


[warning] 42235-42235: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 42236-42236: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


[warning] 42236-42236: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


[warning] 42260-42260: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 42263-42263: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Above

(MD022, blanks-around-headings)


[warning] 42263-42263: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 42264-42264: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Above

(MD022, blanks-around-headings)


[warning] 42264-42264: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 42265-42265: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


[warning] 42265-42265: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


[warning] 42469-42469: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 42470-42470: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


[warning] 42470-42470: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


[warning] 42494-42494: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 42497-42497: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Above

(MD022, blanks-around-headings)


[warning] 42497-42497: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 42498-42498: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Above

(MD022, blanks-around-headings)


[warning] 42498-42498: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 42499-42499: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


[warning] 42499-42499: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


[warning] 42503-42503: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 42504-42504: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


[warning] 42504-42504: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


[warning] 42508-42508: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 42511-42511: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Above

(MD022, blanks-around-headings)


[warning] 42511-42511: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 42512-42512: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Above

(MD022, blanks-around-headings)


[warning] 42512-42512: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 42513-42513: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


[warning] 42513-42513: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


[warning] 42717-42717: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 42718-42718: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


[warning] 42718-42718: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


[warning] 42742-42742: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 42745-42745: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Above

(MD022, blanks-around-headings)


[warning] 42745-42745: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 42746-42746: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Above

(MD022, blanks-around-headings)


[warning] 42746-42746: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 42747-42747: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


[warning] 42747-42747: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


[warning] 42951-42951: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 42952-42952: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


[warning] 42952-42952: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


[warning] 47525-47525: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 47528-47528: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Above

(MD022, blanks-around-headings)


[warning] 47528-47528: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 47529-47529: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Above

(MD022, blanks-around-headings)


[warning] 47529-47529: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 47530-47530: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


[warning] 47530-47530: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


[warning] 47709-47709: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 47710-47710: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


[warning] 47710-47710: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


[warning] 50014-50014: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 50017-50017: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Above

(MD022, blanks-around-headings)


[warning] 50017-50017: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 50018-50018: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


[warning] 50018-50018: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


[warning] 50223-50223: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 50226-50226: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Above

(MD022, blanks-around-headings)


[warning] 50226-50226: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 50227-50227: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Above

(MD022, blanks-around-headings)


[warning] 50227-50227: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 50228-50228: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


[warning] 50228-50228: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


[warning] 50432-50432: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 50433-50433: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


[warning] 50433-50433: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


[warning] 50457-50457: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 50460-50460: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Above

(MD022, blanks-around-headings)


[warning] 50460-50460: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 50461-50461: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Above

(MD022, blanks-around-headings)


[warning] 50461-50461: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 50462-50462: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


[warning] 50462-50462: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


[warning] 50666-50666: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 50667-50667: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


[warning] 50667-50667: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

🔇 Additional comments (22)
ATTRIBUTIONS-Rust.md (1)

2303-2511: 📐 Maintainability & Code Quality

ATTRIBUTIONS-Rust.md is already excluded from markdownlint. The repo’s pre-commit config exempts ATTRIBUTIONS-*.md, and the Rust attribution hook only regenerates the file from Cargo.lock; the MD022/MD031/MD040 note is not actionable.

			> Likely an incorrect or invalid review comment.
crates/core/Cargo.toml (1)

103-104: LGTM!

crates/cli/src/configuration/logging.rs (2)

70-76: 🗄️ Data Integrity & Integration

Preserve normalized duplicate-path validation on this adapter path.

This code only rejects an empty path and stores the PathBuf unchanged. Confirm that every LogSinkConfig::File created here passes through the core validator before use; otherwise equivalent paths such as logs/app.jsonl and logs/../logs/app.jsonl can bypass the promised duplicate-path rejection.

Also applies to: 101-106


1-64: LGTM!

Also applies to: 66-69, 78-100, 107-114

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

4-4: LGTM!

Also applies to: 18-18, 56-56, 98-132, 1160-1160

crates/cli/src/configuration/types.rs (1)

10-10: LGTM!

Also applies to: 61-61

crates/cli/tests/coverage/commands/main_tests.rs (1)

115-140: LGTM!

Also applies to: 142-176, 178-193, 195-208

crates/core/tests/coverage/logging_sink_tests.rs (1)

1-15: LGTM!

crates/core/src/lib.rs (2)

37-37: LGTM!


63-63: 📐 Maintainability & Code Quality

Run the required core-runtime validation before handoff.

Run cargo fmt --all, cargo clippy --workspace --all-targets -- -D warnings, just test-rust, cargo deny check, validate-change, the full Rust/Python/Go/Node.js matrix, and uv run pre-commit run --all-files.

As per coding guidelines, core runtime and public Rust API changes require these validation passes.

Source: Coding guidelines

crates/core/src/logging/mod.rs (2)

1-55: LGTM!

Also applies to: 62-109, 118-134


61-61: 🎯 Functional Correctness

Per-sink levels are intentionally constrained by the process maximum. LoggingConfig::level sets the global minimum for both the log facade and the spdlog::Logger; file sinks only apply an additional, stricter filter, so a Trace sink under Debug is not a supported case.

			> Likely an incorrect or invalid review comment.
crates/core/src/logging/format.rs (1)

1-180: LGTM!

crates/core/src/logging/sink.rs (1)

1-118: LGTM!

Also applies to: 123-306

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

11-11: LGTM!

Also applies to: 66-83

crates/cli/tests/coverage/shared/config_tests.rs (1)

12-15: LGTM!

Also applies to: 174-178, 2864-2918, 2929-3133

crates/core/src/logging/config.rs (2)

31-45: 📐 Maintainability & Code Quality

Confirm the required core-runtime validation completed.

Verify formatting, strict Clippy, Rust tests, cargo deny check, validate-change, the full language matrix, and the final pre-commit pass.

As per coding guidelines, changes to crates/core must run the full language matrix and validate-change, while Rust-facing API changes must pass formatting, Clippy, tests, and cargo deny check.

Source: Coding guidelines


1-30: LGTM!

Also applies to: 46-239, 249-270, 280-339

crates/cli/src/commands/logging.rs (1)

1-75: LGTM!

crates/cli/src/commands/plugins/subcommands.rs (1)

14-18: LGTM!

crates/cli/src/commands/root.rs (1)

11-11: LGTM!

Also applies to: 44-45

crates/core/tests/coverage/logging_tests.rs (1)

1-891: LGTM!

Comment thread crates/cli/src/commands/mod.rs
Comment thread crates/cli/src/commands/root.rs
Comment thread crates/cli/tests/coverage/shared/config_tests.rs
Comment thread crates/core/src/logging/config.rs
Comment thread crates/core/src/logging/mod.rs
Comment thread crates/core/src/logging/mod.rs
Signed-off-by: Eric Evans <194135482+ericevans-nv@users.noreply.github.com>
Signed-off-by: Eric Evans <194135482+ericevans-nv@users.noreply.github.com>
Signed-off-by: Eric Evans <194135482+ericevans-nv@users.noreply.github.com>
Signed-off-by: Eric Evans <194135482+ericevans-nv@users.noreply.github.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: 3

🤖 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/shared/config_tests.rs`:
- Around line 719-750: Update logging_resolution_respects_environment_user_scope
to isolate inherited NEMO_RELAY_LOG* environment variables: capture every
matching variable, clear them before entering PluginConfigDiscoveryScope, and
restore their original values when the test guard is dropped. Keep the
fixture-based logging resolution assertions focused on config files and add
coverage for the changed scope-guard behavior if required by the API contract.
- Around line 760-762: Strengthen the test after enable_user_scope and
resolve_logging_config by asserting that user_only contains the configured user
logging level, not just the absence of a project sink. Use the existing expected
user-level value or configuration symbol so the test verifies user-scope
selection rather than a default or empty result.

In `@crates/core/tests/coverage/logging_tests.rs`:
- Around line 934-972: Update concurrent_stale_teardown_preserves_newest_logger
so stale teardown cannot proceed until the configure thread has installed the
newer runtime. Add synchronization or an existing lifecycle test hook around
init_logging, and assert the installation event before allowing drop(stale);
retain the final logger identity assertion to verify the newest logger remains
installed.
🪄 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: 55f809fa-e72e-4633-b8ef-0ea9a576b1a4

📥 Commits

Reviewing files that changed from the base of the PR and between 07d31ee and 697a2cb.

📒 Files selected for processing (6)
  • crates/cli/src/configuration/logging.rs
  • crates/cli/src/configuration/mod.rs
  • crates/cli/tests/coverage/shared/config_tests.rs
  • crates/core/src/logging/config.rs
  • crates/core/src/logging/mod.rs
  • crates/core/tests/coverage/logging_tests.rs
📜 Review details
🧰 Additional context used
📓 Path-based instructions (13)
**/*.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/configuration/mod.rs
  • crates/cli/src/configuration/logging.rs
  • crates/cli/tests/coverage/shared/config_tests.rs
  • crates/core/src/logging/mod.rs
  • crates/core/src/logging/config.rs
  • crates/core/tests/coverage/logging_tests.rs
**/*.{rs,py}

📄 CodeRabbit inference engine (AGENTS.md)

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

Files:

  • crates/cli/src/configuration/mod.rs
  • crates/cli/src/configuration/logging.rs
  • crates/cli/tests/coverage/shared/config_tests.rs
  • crates/core/src/logging/mod.rs
  • crates/core/src/logging/config.rs
  • crates/core/tests/coverage/logging_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/configuration/mod.rs
  • crates/cli/src/configuration/logging.rs
  • crates/cli/tests/coverage/shared/config_tests.rs
  • crates/core/src/logging/mod.rs
  • crates/core/src/logging/config.rs
  • crates/core/tests/coverage/logging_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/configuration/mod.rs
  • crates/cli/src/configuration/logging.rs
  • crates/cli/tests/coverage/shared/config_tests.rs
  • crates/core/src/logging/mod.rs
  • crates/core/src/logging/config.rs
  • crates/core/tests/coverage/logging_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/configuration/mod.rs
  • crates/cli/src/configuration/logging.rs
  • crates/cli/tests/coverage/shared/config_tests.rs
  • crates/core/src/logging/mod.rs
  • crates/core/src/logging/config.rs
  • crates/core/tests/coverage/logging_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/configuration/mod.rs
  • crates/cli/src/configuration/logging.rs
  • crates/core/src/logging/mod.rs
  • crates/core/src/logging/config.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/configuration/mod.rs
  • crates/cli/src/configuration/logging.rs
  • crates/cli/tests/coverage/shared/config_tests.rs
  • crates/core/src/logging/mod.rs
  • crates/core/src/logging/config.rs
  • crates/core/tests/coverage/logging_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/configuration/mod.rs
  • crates/cli/src/configuration/logging.rs
  • crates/cli/tests/coverage/shared/config_tests.rs
  • crates/core/src/logging/mod.rs
  • crates/core/src/logging/config.rs
  • crates/core/tests/coverage/logging_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/shared/config_tests.rs
  • crates/core/tests/coverage/logging_tests.rs
{crates/core,crates/adaptive}/**/*

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

Changes to crates/core or crates/adaptive must run the full language matrix

Files:

  • crates/core/src/logging/mod.rs
  • crates/core/src/logging/config.rs
  • crates/core/tests/coverage/logging_tests.rs
crates/core/**/*.rs

📄 CodeRabbit inference engine (.agents/skills/test-go-binding/SKILL.md)

If the change touched crates/core or shared runtime semantics, also use validate-change for broader validation

Files:

  • crates/core/src/logging/mod.rs
  • crates/core/src/logging/config.rs
  • crates/core/tests/coverage/logging_tests.rs
crates/{core,adaptive}/**/*

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

If crates/core or crates/adaptive changed, run the full validation matrix across Rust, Python, Go, and Node.js.

Files:

  • crates/core/src/logging/mod.rs
  • crates/core/src/logging/config.rs
  • crates/core/tests/coverage/logging_tests.rs
crates/{core,adaptive}/**/*.rs

⚙️ CodeRabbit configuration file

crates/{core,adaptive}/**/*.rs: Review the Rust runtime for async correctness, scope isolation, middleware ordering, and event lifecycle regressions.
Pay close attention to task-local/thread-local scope propagation, callback lifetimes, stream finalization, and root_uuid isolation.
Public API changes should preserve existing behavior unless tests and docs show the intended migration path.

Files:

  • crates/core/src/logging/mod.rs
  • crates/core/src/logging/config.rs
  • crates/core/tests/coverage/logging_tests.rs
🔇 Additional comments (4)
crates/core/src/logging/mod.rs (1)

33-54: 📐 Maintainability & Code Quality

Provide the required validation results before handoff.

  • crates/core/src/logging/mod.rs#L33-L54: run cargo fmt --all, cargo clippy --workspace --all-targets -- -D warnings, just test-rust, cargo deny check, validate-change, and the required full language matrix.
  • crates/core/src/logging/config.rs#L241-L241: include this core logging change in the same validation run.
  • crates/core/src/logging/config.rs#L274-L274: include this core logging change in the same validation run.
  • crates/cli/src/configuration/logging.rs#L18-L18: run the required Rust formatter, clippy, and test target.
  • crates/cli/src/configuration/logging.rs#L30-L30: run the required Rust formatter, clippy, and test target.
  • crates/cli/src/configuration/mod.rs#L107-L107: run the required Rust formatter, clippy, and test target.

As per coding guidelines, “Any Rust change must run just test-rust,” cargo fmt --all, and cargo clippy --workspace --all-targets -- -D warnings; core changes also require broader validation.

Source: Coding guidelines

crates/core/tests/coverage/logging_tests.rs (2)

12-29: 📐 Maintainability & Code Quality

Confirm the required Rust validation matrix completed.

Please verify cargo fmt --all, cargo clippy --workspace --all-targets -- -D warnings, just test-rust, validate-change, the full Rust/Python/Go/Node matrix, and uv run pre-commit run --all-files.

As per coding guidelines, “Any Rust change must run just test-rust,” “also run cargo fmt --all,” and “also run cargo clippy --workspace --all-targets -- -D warnings.”

Source: Coding guidelines


808-832: LGTM!

Also applies to: 974-1004

crates/cli/tests/coverage/shared/config_tests.rs (1)

3123-3161: LGTM!

Comment thread crates/cli/tests/coverage/shared/config_tests.rs
Comment thread crates/cli/tests/coverage/shared/config_tests.rs
Comment thread crates/core/tests/coverage/logging_tests.rs
@willkill07

Copy link
Copy Markdown
Member

/ok to test 697a2cb

Signed-off-by: Eric Evans <194135482+ericevans-nv@users.noreply.github.com>
@willkill07

Copy link
Copy Markdown
Member

/ok to test 6c5e76c

Signed-off-by: Eric Evans <194135482+ericevans-nv@users.noreply.github.com>
@willkill07

Copy link
Copy Markdown
Member

/ok to test 7b1a0cc

@Salonijain27 Salonijain27 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Approved from a dependency point of view

@afourniernv

Copy link
Copy Markdown
Contributor

/ok to test a443ada

@afourniernv

Copy link
Copy Markdown
Contributor

/merge

@rapids-bot
rapids-bot Bot merged commit 51b6215 into NVIDIA:main Jul 16, 2026
67 of 68 checks passed
@coderabbitai coderabbitai Bot mentioned this pull request Jul 16, 2026
2 tasks
rapids-bot Bot pushed a commit that referenced this pull request Jul 16, 2026
#### Overview

Documents the operational logging configuration and source-selection behavior introduced by #413. This docs-only PR should merge after or with #413 so the documented options match released CLI and library behavior.

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

#### Details

- Document always-on stderr logging, built-in defaults, and the configuration-editing commands that intentionally skip logging initialization.
- Explain the single-source precedence across CLI options, environment variables, discovered `config.toml`, and defaults.
- Document direct CLI and environment settings, absolute TOML configuration paths, and the shared Rust `LoggingRuntime` entry points.
- Update the `[logging]` and `[[logging.sinks]]` example for asynchronous file delivery and the fixed 8,192-entry queue safety limit.

#### Where should the reviewer start?

- `docs/nemo-relay-cli/basic-usage.mdx`

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

- Relates to #413
- Relates to RELAY-451



## Summary by CodeRabbit

* **Documentation**
  * Added an “Operational Logging” page and expanded Basic Usage to explain when operational logging is initialized and how to configure it.
  * Clarified that runtime logging setup is handled during operational command execution, while configuration-related commands avoid logging initialization to prevent blocking repairs.
  * Documented the precedence order for logging settings (CLI `--log-*` / `--log-config-path`, then `NEMO_RELAY_LOG*` env vars, then `[logging]` in resolved `config.toml`, then defaults).
  * Added guidance on normal runtime environment variables (including when `OTEL_*` applies) and detailed logging schema/sink options.

Authors:
  - Eric Evans II (https://github.com/ericevans-nv)

Approvers:
  - Will Killian (https://github.com/willkill07)
  - Maryam Najafian (https://github.com/mnajafian-nv)
  - https://github.com/lvojtku

URL: #419
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Feature a new feature lang:rust PR changes/introduces Rust code size:XXL PR is very large

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants