Skip to content

fix(codex): stabilize plugin gateway bootstrap#395

Draft
willkill07 wants to merge 18 commits into
NVIDIA:mainfrom
willkill07:wkk_relay-447-codex-bootstrap
Draft

fix(codex): stabilize plugin gateway bootstrap#395
willkill07 wants to merge 18 commits into
NVIDIA:mainfrom
willkill07:wkk_relay-447-codex-bootstrap

Conversation

@willkill07

@willkill07 willkill07 commented Jul 9, 2026

Copy link
Copy Markdown
Member

Overview

Stabilize RELAY-447 Codex cold-start capture by making the required plugin MCP a lifecycle client for one shared Rust-native Relay gateway, and make plugin-owned hooks the only persistent Codex hook source.

  • 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

  • Keep nemo-relay mcp as the existing public command, but have each MCP client defer starting or reusing a detached nemo-relay --bind 127.0.0.1:47632 gateway until a valid MCP initialize request. MCP initialization waits for verified Relay readiness, authenticated heartbeats keep the shared gateway active, one coordinated restart is allowed, concurrent clients share the gateway, and the existing 300-second idle shutdown applies after client, hook, and model activity stops.
  • Separate the MCP implementation into bounded stdio transport, single-pass JSON-RPC protocol handling, session sequencing, and an RAII gateway lease. Separate shared sidecar behavior from plugin installation into an immutable gateway specification plus health, ownership/readiness state, and platform process modules. MCP and hook recovery now use the same lifecycle contract without reaching through plugin_shim internals.
  • Extend /healthz with Relay identity, version, bootstrap protocol, and a keyed bootstrap fingerprint so a foreign or differently configured listener is rejected. Managed children revalidate user/system config, environment, dynamic-plugin lifecycle generation, manifests, artifacts, and signatures after plugin activation and immediately before publishing ownership/readiness.
  • Resolve persistent plugin mode from system and user configuration only, start it from the user config directory, and retain nemo-relay run for project-specific configuration. Port-zero children publish their actual address through an atomic readiness-file handshake.
  • Harden lifecycle resources with advisory endpoint/HMAC locks, bounded MCP and hook frames, nonblocking child reaping, authenticated shutdown ownership, safe Windows job handling, typed state records, and regular-file/512 MiB limits for manifest, artifact, and signature reads.
  • Generate canonical, platform-quoted commands in the plugin's hooks/hooks.json; stop adding Relay groups to ~/.codex/hooks.json. Require the Codex 0.143 10-event baseline, verify every exact Relay hook Codex discovers (including version-dependent PostToolUseFailure, Notification, and SessionEnd), reject duplicates, and migrate only legacy Relay user-hook groups while preserving unrelated hooks and backups.
  • Snapshot every targeted hooks.state entry before trust changes. Installation and uninstall failures restore config, hooks, backups, and exact prior trust states through app-server, verify the rollback, and aggregate rollback errors.
  • Generate MCP env_vars for provider credentials, Relay runtime settings, OTLP/AWS/proxy/certificate variables, approved installed prefixes, and observability-referenced secret/header names. Internal bootstrap/worker variables are excluded and only names are stored. Doctor now reports missing environment names, unsupported Codex versions, and precise reinstall/upgrade remediation.
  • Update CLI, integration, and known-issues documentation for shared-sidecar behavior, plugin-owned hooks, user-level configuration, environment forwarding, concurrency, idle shutdown, and the pre-MCP /models limitation. Add the first-principles MCP bootstrap design and dependency boundaries.
  • Add exhaustive Rust coverage outside src/ and an opt-in real Codex E2E target that remains outside mandatory Rust CI.

Breaking changes: none.

Validation:

  • cargo fmt --all -- --check
  • cargo clippy --workspace --all-targets -- -D warnings
  • just test-rust (passes without Codex installed)
  • just docs
  • just docs-linkcheck
  • uv run pre-commit run --all-files
  • just test-codex-plugin-e2e with Codex 0.143: 10 cold codex exec "ping" runs plus two concurrent runs; all 12 produced one provider response and one matching balanced ATOF turn; SessionStart, UserPromptSubmit, and Stop were each invoked and completed exactly once; authorization/environment propagation, session isolation, gateway survival, and port cleanup passed; zero /models requests reached Relay
  • Three independent final reviews covering runtime lifecycle, Codex install/trust, and tests/docs reported no remaining actionable findings

Where should the reviewer start?

Start with docs/nemo-relay-cli/mcp-bootstrap-design.mdx for the lifecycle contract, then crates/cli/src/mcp.rs and crates/cli/src/mcp/gateway.rs for deferred acquisition and recovery, and crates/cli/src/sidecar.rs plus crates/cli/src/sidecar/health.rs, state.rs, and process.rs for shared gateway identity and ownership. The end-to-end acceptance test is scripts/test-codex-plugin-e2e.sh.

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

  • Relates to RELAY-447

@coderabbitai

coderabbitai Bot commented Jul 9, 2026

Copy link
Copy Markdown

Review Change Stack

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Enterprise

Run ID: 104997bc-79ab-4304-8b6a-2b272ea174fc

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Walkthrough

Adds native MCP transport and Codex plugin MCP packaging, plus Codex app-server trust verification, trust-aware install/uninstall/doctor plumbing, retry-aware hook forwarding updates, and matching tests/docs. Also refactors server idle shutdown readiness into an explicit helper with recheck coverage.

Changes

Codex MCP and trust flow

Layer / File(s) Summary
MCP subcommand and transport
crates/cli/Cargo.toml, crates/cli/src/config.rs, crates/cli/src/main.rs, crates/cli/src/mcp.rs, crates/cli/tests/cli_tests.rs, crates/cli/tests/coverage/main_tests.rs, crates/cli/tests/coverage/mcp_tests.rs
Adds the mcp subcommand, stdio JSON-RPC transport, gateway startup coordination, and command/test coverage for initialization and error handling.
Codex plugin MCP packaging
crates/cli/src/plugin_install/state.rs, crates/cli/src/plugin_install/host.rs, crates/cli/src/plugin_install/marketplace.rs, crates/cli/src/plugin_install/mod.rs, crates/cli/src/plugin_install/setup.rs, crates/cli/tests/coverage/installer_tests.rs, crates/cli/tests/coverage/plugin_install_tests.rs
Adds Codex MCP manifest/config generation, relay MCP validation, and readiness/packaging checks for the generated .mcp.json file.
Codex app-server client
crates/cli/src/plugin_shim/codex_app_server.rs
Adds the Codex app-server RPC client, hook metadata model, and hook list/trust/clear operations.
Codex trust orchestration
crates/cli/src/plugin_shim/codex.rs
Reworks Codex install and uninstall around trust snapshots, trust reporting, auto-trust verification, and trust-state cleanup.
Plugin shim wiring and forwarding
crates/cli/src/plugin_shim/mod.rs, crates/cli/src/plugin_shim/shared.rs
Wires the app-server module into the shim, changes hook forwarding retry behavior and error types, and extends doctor output with Codex hook-trust reporting.
Codex install and trust tests
crates/cli/tests/coverage/plugin_shim_tests.rs
Adds Codex app-server, hook forwarding, install, uninstall, and doctor coverage for the MCP and trust changes.
Codex installation docs
README.md, docs/nemo-relay-cli/plugin-installation.mdx, integrations/coding-agents/README.md, integrations/coding-agents/codex/.codex-plugin/plugin.json, integrations/coding-agents/codex/.mcp.json, integrations/coding-agents/codex/README.md, integrations/coding-agents/codex/hooks/hooks.json
Updates the Codex warnings and integration docs to describe trust verification, MCP startup, restart requirements, rollback behavior, and doctor JSON fields.

Estimated code review effort: 5 (Critical) | ~120 minutes

Server idle shutdown

Layer / File(s) Summary
Idle shutdown readiness helper
crates/cli/src/server.rs, crates/cli/tests/coverage/server_tests.rs
Moves idle shutdown decision logic into idle_shutdown_ready and rechecks activity after awaiting session state.

Estimated code review effort: 2 (Simple) | ~15 minutes

Sequence Diagram(s)

sequenceDiagram
  participant InstallFlow
  participant CodexAppServerClient
  participant CodexAppServer

  InstallFlow->>CodexAppServerClient: start()
  CodexAppServerClient->>CodexAppServer: initialize / initialized
  InstallFlow->>CodexAppServerClient: list_hooks(cwd)
  CodexAppServerClient->>CodexAppServer: hooks/list
  CodexAppServer-->>CodexAppServerClient: hooks metadata
  InstallFlow->>CodexAppServerClient: trust_hooks(hooks)
  CodexAppServerClient->>CodexAppServer: config/batchWrite (hooks.state)
Loading
sequenceDiagram
  participant HookWithIo
  participant PostHook
  participant EnsureSidecar

  HookWithIo->>PostHook: post_hook(payload)
  PostHook-->>HookWithIo: HookForwardError (retryable)
  HookWithIo->>EnsureSidecar: ensure_sidecar()
  EnsureSidecar-->>HookWithIo: Ok(())
  HookWithIo->>PostHook: post_hook(payload) retry
  PostHook-->>HookWithIo: result
Loading
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 64.15% 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
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.
Title check ✅ Passed The title follows Conventional Commits and summarizes the Codex bootstrap hardening change.
Description check ✅ Passed The description matches the required template with Overview, Details, reviewer start, checkboxes, and related issue information.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

@github-actions github-actions Bot added size:XL PR is extra large Bug issue describes bug; PR fixes bug lang:rust PR changes/introduces Rust code labels Jul 9, 2026
@github-actions

github-actions Bot commented Jul 9, 2026

Copy link
Copy Markdown

@willkill07 willkill07 force-pushed the wkk_relay-447-codex-bootstrap branch from 37d6608 to d8740a1 Compare July 9, 2026 02:05
@willkill07 willkill07 added this to the 0.6 milestone Jul 9, 2026
@willkill07 willkill07 self-assigned this Jul 9, 2026
@willkill07 willkill07 changed the title fix: harden Codex lazy bootstrap fix(codex): harden Codex lazy bootstrap Jul 9, 2026
@willkill07 willkill07 marked this pull request as ready for review July 9, 2026 14:06
@willkill07 willkill07 requested review from a team and lvojtku as code owners July 9, 2026 14:06

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

🤖 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/plugin_shim/shared.rs`:
- Around line 41-60: The sidecar lock acquisition loop in shared.rs can time out
before stale-lock recovery becomes eligible, so adjust the timing constants used
by ensure_sidecar and related lock handling: either increase
SIDECAR_LOCK_TIMEOUT to be at least as long as STALE_LOCK_AFTER, or reduce the
stale threshold so repair_stale_lock can reclaim an orphaned lock within the
same call. Keep the behavior around fs::create_dir, healthz, repair_stale_lock,
and sidecar_start_error consistent so retryable hook calls do not fail early
with “sidecar lock timed out”.

In `@README.md`:
- Around line 123-126: The README warning uses trust-state wording too broadly
and should match CodexHookTrustReport terminology. Update the text around the
install and doctor guidance so it distinguishes modified hooks from untrusted
hooks instead of collapsing them into one state, and make sure the wording
matches what nemo-relay doctor actually reports for generated, modified, and
manual/source-marketplace hooks.
🪄 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: f2e7bcd6-9e1a-48bf-93b6-e41075a2cd5d

📥 Commits

Reviewing files that changed from the base of the PR and between c83c8f2 and 1c9106d.

📒 Files selected for processing (11)
  • README.md
  • crates/cli/src/plugin_shim/codex.rs
  • crates/cli/src/plugin_shim/codex_app_server.rs
  • crates/cli/src/plugin_shim/mod.rs
  • crates/cli/src/plugin_shim/shared.rs
  • crates/cli/src/server.rs
  • crates/cli/tests/coverage/plugin_install_tests.rs
  • crates/cli/tests/coverage/plugin_shim_tests.rs
  • crates/cli/tests/coverage/server_tests.rs
  • docs/nemo-relay-cli/plugin-installation.mdx
  • integrations/coding-agents/codex/README.md
📜 Review details
🧰 Additional context used
📓 Path-based instructions (25)
**/*.{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:

  • README.md
  • integrations/coding-agents/codex/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:

  • README.md
  • integrations/coding-agents/codex/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:

  • README.md
  • integrations/coding-agents/codex/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:

  • README.md
  • integrations/coding-agents/codex/README.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:

  • README.md
  • integrations/coding-agents/codex/README.md
{README.md,docs/**/*.{md,rst,txt},fern/**/*}

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

Search and update documentation source for references to the old version in README.md, docs, and fern directories, updating current-version install commands, package examples, and configuration examples to <next-version>

Files:

  • README.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:

  • README.md
  • docs/nemo-relay-cli/plugin-installation.mdx
  • integrations/coding-agents/codex/README.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:

  • README.md
  • docs/nemo-relay-cli/plugin-installation.mdx
  • integrations/coding-agents/codex/README.md
{docs/**/*.md,README.md}

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

Update reference docs, language-binding docs, READMEs, and example documentation when the public surface or expected usage changes.

Files:

  • README.md
{README.md,docs/index.md}

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

Update entry-point docs when examples or reading paths change

Files:

  • README.md
**/*

📄 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:

  • README.md
  • crates/cli/tests/coverage/server_tests.rs
  • crates/cli/src/server.rs
  • docs/nemo-relay-cli/plugin-installation.mdx
  • integrations/coding-agents/codex/README.md
  • crates/cli/tests/coverage/plugin_install_tests.rs
  • crates/cli/src/plugin_shim/mod.rs
  • crates/cli/src/plugin_shim/shared.rs
  • crates/cli/src/plugin_shim/codex_app_server.rs
  • crates/cli/src/plugin_shim/codex.rs
  • crates/cli/tests/coverage/plugin_shim_tests.rs
README.md

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

If documentation examples or commands in README.md change, run the targeted docs checks appropriate to the change.

Files:

  • README.md
**

⚙️ CodeRabbit configuration file

**:

AGENTS.md

This file provides guidance to agents, including Claude Code and OpenAI Codex, when working in this repository.

Project Overview

NeMo Relay is a multi-language agent runtime framework for execution scopes, lifecycle events, middleware, plugins, and observability around tool and LLM calls. The core runtime is Rust. Primary supported bindings are Rust, Python, and Node.js. Go and the raw C FFI are experimental and source-first.

The shared runtime model is:

  1. Scope stacks decide where work belongs and which scope-local behavior is visible.
  2. Middleware registries decide what guardrails and intercepts run around managed calls.
  3. Plugins install reusable runtime behavior from configuration.
  4. Events record runtime behavior in ATOF form.
  5. Subscribers and exporters consume events in-process or export them to ATIF, OpenTelemetry, OpenInference, or other backends.

Repository Structure

The repository layout separates the Rust runtime, language bindings,
documentation, integrations, and agent-facing skills.

crates/
  core/       # Rust core runtime crate, published as nemo-relay
  adaptive/   # Adaptive runtime primitives and plugin components
  python/     # PyO3 native extension for the Python package
  ffi/        # Raw C ABI layer used by downstream bindings such as Go
  node/       # NAPI Node.js binding and JavaScript/TypeScript entry points
python/
  nemo_relay/  # Python wrapper package: scopes, tools, LLM, middleware, typed helpers, plugins, adaptive helpers
  tests/      # Python tests
go/
  nemo_relay/  # Experimental Go CGo binding and tests
fern/         # Fern documentation site
scripts/      # Stable wrappers and helper scripts; build/test/docs entry points live in justfile
skills/       # Published Codex/agent skills for NeMo Relay usage patterns

Prerequisites

Insta...

Files:

  • README.md
  • crates/cli/tests/coverage/server_tests.rs
  • crates/cli/src/server.rs
  • docs/nemo-relay-cli/plugin-installation.mdx
  • integrations/coding-agents/codex/README.md
  • crates/cli/tests/coverage/plugin_install_tests.rs
  • crates/cli/src/plugin_shim/mod.rs
  • crates/cli/src/plugin_shim/shared.rs
  • crates/cli/src/plugin_shim/codex_app_server.rs
  • crates/cli/src/plugin_shim/codex.rs
  • crates/cli/tests/coverage/plugin_shim_tests.rs
{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:

  • README.md
  • docs/nemo-relay-cli/plugin-installation.mdx
**/*.rs

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

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

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

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

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

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

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

Files:

  • crates/cli/tests/coverage/server_tests.rs
  • crates/cli/src/server.rs
  • crates/cli/tests/coverage/plugin_install_tests.rs
  • crates/cli/src/plugin_shim/mod.rs
  • crates/cli/src/plugin_shim/shared.rs
  • crates/cli/src/plugin_shim/codex_app_server.rs
  • crates/cli/src/plugin_shim/codex.rs
  • crates/cli/tests/coverage/plugin_shim_tests.rs
**/*.{rs,py}

📄 CodeRabbit inference engine (AGENTS.md)

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

Files:

  • crates/cli/tests/coverage/server_tests.rs
  • crates/cli/src/server.rs
  • crates/cli/tests/coverage/plugin_install_tests.rs
  • crates/cli/src/plugin_shim/mod.rs
  • crates/cli/src/plugin_shim/shared.rs
  • crates/cli/src/plugin_shim/codex_app_server.rs
  • crates/cli/src/plugin_shim/codex.rs
  • crates/cli/tests/coverage/plugin_shim_tests.rs
**/*.{rs,py,js,mjs,cjs,ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

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

Files:

  • crates/cli/tests/coverage/server_tests.rs
  • crates/cli/src/server.rs
  • crates/cli/tests/coverage/plugin_install_tests.rs
  • crates/cli/src/plugin_shim/mod.rs
  • crates/cli/src/plugin_shim/shared.rs
  • crates/cli/src/plugin_shim/codex_app_server.rs
  • crates/cli/src/plugin_shim/codex.rs
  • crates/cli/tests/coverage/plugin_shim_tests.rs
**/*.{rs,py,go,js,ts,c,h}

📄 CodeRabbit inference engine (CONTRIBUTING.md)

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

Files:

  • crates/cli/tests/coverage/server_tests.rs
  • crates/cli/src/server.rs
  • crates/cli/tests/coverage/plugin_install_tests.rs
  • crates/cli/src/plugin_shim/mod.rs
  • crates/cli/src/plugin_shim/shared.rs
  • crates/cli/src/plugin_shim/codex_app_server.rs
  • crates/cli/src/plugin_shim/codex.rs
  • crates/cli/tests/coverage/plugin_shim_tests.rs
**/*.{rs,go,js,ts}

📄 CodeRabbit inference engine (CONTRIBUTING.md)

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

Files:

  • crates/cli/tests/coverage/server_tests.rs
  • crates/cli/src/server.rs
  • crates/cli/tests/coverage/plugin_install_tests.rs
  • crates/cli/src/plugin_shim/mod.rs
  • crates/cli/src/plugin_shim/shared.rs
  • crates/cli/src/plugin_shim/codex_app_server.rs
  • crates/cli/src/plugin_shim/codex.rs
  • crates/cli/tests/coverage/plugin_shim_tests.rs
**/*.{rs,py,go,js,ts}

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

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

Files:

  • crates/cli/tests/coverage/server_tests.rs
  • crates/cli/src/server.rs
  • crates/cli/tests/coverage/plugin_install_tests.rs
  • crates/cli/src/plugin_shim/mod.rs
  • crates/cli/src/plugin_shim/shared.rs
  • crates/cli/src/plugin_shim/codex_app_server.rs
  • crates/cli/src/plugin_shim/codex.rs
  • crates/cli/tests/coverage/plugin_shim_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/server_tests.rs
  • crates/cli/tests/coverage/plugin_install_tests.rs
  • crates/cli/tests/coverage/plugin_shim_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/server.rs
  • crates/cli/src/plugin_shim/mod.rs
  • crates/cli/src/plugin_shim/shared.rs
  • crates/cli/src/plugin_shim/codex_app_server.rs
  • crates/cli/src/plugin_shim/codex.rs
**/*.mdx

📄 CodeRabbit inference engine (.agents/skills/review-doc-style/SKILL.md)

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

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

Files:

  • docs/nemo-relay-cli/plugin-installation.mdx
{docs,examples}/**/*

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

Update docs and examples.

Files:

  • docs/nemo-relay-cli/plugin-installation.mdx
docs/**/*

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

If documentation examples or commands under docs/ change, run the targeted docs checks appropriate to the change.

Files:

  • docs/nemo-relay-cli/plugin-installation.mdx
🔇 Additional comments (18)
crates/cli/src/server.rs (2)

300-314: LGTM!


316-335: 🩺 Stability & Availability

idle_shutdown_ready is reachable from server_tests.rs #[cfg(test)] #[path = "../tests/coverage/server_tests.rs"] mod tests; makes that file a child module, so the private helper is visible there.

			> Likely an incorrect or invalid review comment.
crates/cli/tests/coverage/server_tests.rs (1)

540-568: LGTM!

docs/nemo-relay-cli/plugin-installation.mdx (1)

81-99: LGTM!

Also applies to: 127-132, 165-167

integrations/coding-agents/codex/README.md (1)

46-63: LGTM!

Also applies to: 192-194, 292-304

crates/cli/src/plugin_shim/codex.rs (4)

117-122: Same let-chain / MSRV concern flagged in codex_app_server.rs Lines 158-160 applies here (&& let Some(client) = ...); resolve once by confirming the pinned toolchain is >= 1.88.


236-240: 🎯 Functional Correctness | ⚡ Quick win

Lexical path equality may reject legitimately-matching hooks.

Path::new(&hook.source_path) == hooks_path compares components lexically. If the app-server reports a canonicalized/symlink-resolved path (common on macOS, e.g. /var/private/var) while home_dir().join(".codex/hooks.json") is not resolved, this filter yields no hooks, and auto_trust_codex_hooks then fails with "missing required hooks". Consider comparing canonicalized paths (or file identity) when both exist.


22-59: LGTM!

Also applies to: 61-116, 123-135, 144-234, 245-302


42-43: 🗄️ Data Integrity & Integration

No rollback gap here
prepare_codex_config only parses and validates config.toml; it doesn’t mutate files, so taking snapshots afterward doesn’t miss any install-time changes.

			> Likely an incorrect or invalid review comment.
crates/cli/src/plugin_shim/codex_app_server.rs (3)

45-94: LGTM!

Also applies to: 96-122, 124-139, 141-147, 167-182, 184-197, 199-209, 211-225


158-160: 🎯 Functional Correctness

Let chains are supported by the pinned toolchain

rust-toolchain.toml pins Rust 1.93.0, so if let Some(errors) = ... && !errors.is_empty() is valid. The MSRV concern does not apply here. The same applies to crates/cli/src/plugin_shim/codex.rs.

			> Likely an incorrect or invalid review comment.

18-30: 🗄️ Data Integrity & Integration

No change needed The CodexHookMetadata field names are already mapped to the app-server’s camelCase schema by #[serde(rename_all = "camelCase")]; the snake_case Rust fields are correct here.

			> Likely an incorrect or invalid review comment.
crates/cli/src/plugin_shim/mod.rs (2)

101-110: LGTM!


202-223: LGTM!

Also applies to: 233-245

crates/cli/src/plugin_shim/shared.rs (1)

382-476: LGTM!

crates/cli/tests/coverage/plugin_shim_tests.rs (2)

17-140: LGTM!


311-403: LGTM!

Also applies to: 468-645, 985-1058

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

385-408: LGTM!

Comment thread crates/cli/src/plugin_shim/shared.rs Outdated
Comment thread README.md Outdated
@willkill07 willkill07 changed the title fix(codex): harden Codex lazy bootstrap fix(codex): launch native gateway from plugin MCP Jul 9, 2026
@willkill07 willkill07 marked this pull request as draft July 9, 2026 19:22
@github-actions

github-actions Bot commented Jul 9, 2026

Copy link
Copy Markdown

License Diff

Compared against origin/main.

Lockfile license changes

Lockfile License Changes

Rust

Added

  • fs2 0.4.3 (Apache-2.0)
  • winapi 0.3.9 (Apache-2.0)
  • winapi-i686-pc-windows-gnu 0.4.0 (Apache-2.0)
  • winapi-x86_64-pc-windows-gnu 0.4.0 (Apache-2.0)

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 (382 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 (378 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

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

🤖 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/plugin_install/host.rs`:
- Around line 293-296: The relay executable path handling in resolve_executable
should keep canonicalization for matching, but avoid serializing a Windows \\?\
path into the MCP config command. Update the host.rs flow around RELAY_COMMAND
so the value written to .mcp.json is normalized to a Windows-friendly path while
preserving the canonicalized form only for comparison/lookup. Use the existing
executable resolution and config-writing logic in this area to ensure the
serialized MCP command remains executable on Windows.

In `@crates/cli/src/plugin_install/mod.rs`:
- Around line 594-605: The Generated MCP server check builds the MCP config path
inline with a literal ".mcp.json", which is inconsistent with the other manifest
path helpers and may drift from PluginLayout::new. Add a dedicated
mcp_config_path helper near the existing path helpers and use it in the
readiness.plugin branch instead of calling plugin.join directly, keeping the
path construction centralized alongside marketplace_manifest_path and
plugin_manifest_path.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

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

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Enterprise

Run ID: 088df63e-c8eb-465a-9b69-608258e79bb2

📥 Commits

Reviewing files that changed from the base of the PR and between bc7e0a0 and 027d8ed.

📒 Files selected for processing (21)
  • crates/cli/Cargo.toml
  • crates/cli/src/config.rs
  • crates/cli/src/main.rs
  • crates/cli/src/mcp.rs
  • crates/cli/src/plugin_install/host.rs
  • crates/cli/src/plugin_install/marketplace.rs
  • crates/cli/src/plugin_install/mod.rs
  • crates/cli/src/plugin_install/setup.rs
  • crates/cli/src/plugin_install/state.rs
  • crates/cli/src/plugin_shim/codex.rs
  • crates/cli/src/server.rs
  • crates/cli/tests/cli_tests.rs
  • crates/cli/tests/coverage/installer_tests.rs
  • crates/cli/tests/coverage/main_tests.rs
  • crates/cli/tests/coverage/mcp_tests.rs
  • crates/cli/tests/coverage/plugin_install_tests.rs
  • integrations/coding-agents/README.md
  • integrations/coding-agents/codex/.codex-plugin/plugin.json
  • integrations/coding-agents/codex/.mcp.json
  • integrations/coding-agents/codex/README.md
  • integrations/coding-agents/codex/hooks/hooks.json
📜 Review details
⏰ Context from checks skipped due to timeout. (2)
  • GitHub Check: Check / Run
  • GitHub Check: Preview docs
🧰 Additional context used
📓 Path-based instructions (19)
**/*

📄 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:

  • integrations/coding-agents/codex/hooks/hooks.json
  • crates/cli/Cargo.toml
  • crates/cli/tests/coverage/main_tests.rs
  • crates/cli/src/plugin_install/setup.rs
  • crates/cli/src/main.rs
  • crates/cli/tests/cli_tests.rs
  • crates/cli/tests/coverage/mcp_tests.rs
  • crates/cli/src/config.rs
  • crates/cli/src/plugin_install/host.rs
  • crates/cli/src/plugin_install/state.rs
  • crates/cli/tests/coverage/installer_tests.rs
  • integrations/coding-agents/README.md
  • crates/cli/src/plugin_install/marketplace.rs
  • integrations/coding-agents/codex/README.md
  • crates/cli/src/plugin_install/mod.rs
  • crates/cli/src/mcp.rs
  • crates/cli/src/server.rs
  • crates/cli/tests/coverage/plugin_install_tests.rs
  • crates/cli/src/plugin_shim/codex.rs
**

⚙️ CodeRabbit configuration file

**:

AGENTS.md

This file provides guidance to agents, including Claude Code and OpenAI Codex, when working in this repository.

Project Overview

NeMo Relay is a multi-language agent runtime framework for execution scopes, lifecycle events, middleware, plugins, and observability around tool and LLM calls. The core runtime is Rust. Primary supported bindings are Rust, Python, and Node.js. Go and the raw C FFI are experimental and source-first.

The shared runtime model is:

  1. Scope stacks decide where work belongs and which scope-local behavior is visible.
  2. Middleware registries decide what guardrails and intercepts run around managed calls.
  3. Plugins install reusable runtime behavior from configuration.
  4. Events record runtime behavior in ATOF form.
  5. Subscribers and exporters consume events in-process or export them to ATIF, OpenTelemetry, OpenInference, or other backends.

Repository Structure

The repository layout separates the Rust runtime, language bindings,
documentation, integrations, and agent-facing skills.

crates/
  core/       # Rust core runtime crate, published as nemo-relay
  adaptive/   # Adaptive runtime primitives and plugin components
  python/     # PyO3 native extension for the Python package
  ffi/        # Raw C ABI layer used by downstream bindings such as Go
  node/       # NAPI Node.js binding and JavaScript/TypeScript entry points
python/
  nemo_relay/  # Python wrapper package: scopes, tools, LLM, middleware, typed helpers, plugins, adaptive helpers
  tests/      # Python tests
go/
  nemo_relay/  # Experimental Go CGo binding and tests
fern/         # Fern documentation site
scripts/      # Stable wrappers and helper scripts; build/test/docs entry points live in justfile
skills/       # Published Codex/agent skills for NeMo Relay usage patterns

Prerequisites

Insta...

Files:

  • integrations/coding-agents/codex/hooks/hooks.json
  • crates/cli/Cargo.toml
  • crates/cli/tests/coverage/main_tests.rs
  • crates/cli/src/plugin_install/setup.rs
  • crates/cli/src/main.rs
  • crates/cli/tests/cli_tests.rs
  • crates/cli/tests/coverage/mcp_tests.rs
  • crates/cli/src/config.rs
  • crates/cli/src/plugin_install/host.rs
  • crates/cli/src/plugin_install/state.rs
  • crates/cli/tests/coverage/installer_tests.rs
  • integrations/coding-agents/README.md
  • crates/cli/src/plugin_install/marketplace.rs
  • integrations/coding-agents/codex/README.md
  • crates/cli/src/plugin_install/mod.rs
  • crates/cli/src/mcp.rs
  • crates/cli/src/server.rs
  • crates/cli/tests/coverage/plugin_install_tests.rs
  • crates/cli/src/plugin_shim/codex.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/cli/Cargo.toml
**/*.toml

📄 CodeRabbit inference engine (CONTRIBUTING.md)

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

Files:

  • crates/cli/Cargo.toml
**/*.rs

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

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

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

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

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

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

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

Files:

  • crates/cli/tests/coverage/main_tests.rs
  • crates/cli/src/plugin_install/setup.rs
  • crates/cli/src/main.rs
  • crates/cli/tests/cli_tests.rs
  • crates/cli/tests/coverage/mcp_tests.rs
  • crates/cli/src/config.rs
  • crates/cli/src/plugin_install/host.rs
  • crates/cli/src/plugin_install/state.rs
  • crates/cli/tests/coverage/installer_tests.rs
  • crates/cli/src/plugin_install/marketplace.rs
  • crates/cli/src/plugin_install/mod.rs
  • crates/cli/src/mcp.rs
  • crates/cli/src/server.rs
  • crates/cli/tests/coverage/plugin_install_tests.rs
  • crates/cli/src/plugin_shim/codex.rs
**/*.{rs,py}

📄 CodeRabbit inference engine (AGENTS.md)

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

Files:

  • crates/cli/tests/coverage/main_tests.rs
  • crates/cli/src/plugin_install/setup.rs
  • crates/cli/src/main.rs
  • crates/cli/tests/cli_tests.rs
  • crates/cli/tests/coverage/mcp_tests.rs
  • crates/cli/src/config.rs
  • crates/cli/src/plugin_install/host.rs
  • crates/cli/src/plugin_install/state.rs
  • crates/cli/tests/coverage/installer_tests.rs
  • crates/cli/src/plugin_install/marketplace.rs
  • crates/cli/src/plugin_install/mod.rs
  • crates/cli/src/mcp.rs
  • crates/cli/src/server.rs
  • crates/cli/tests/coverage/plugin_install_tests.rs
  • crates/cli/src/plugin_shim/codex.rs
**/*.{rs,py,js,mjs,cjs,ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

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

Files:

  • crates/cli/tests/coverage/main_tests.rs
  • crates/cli/src/plugin_install/setup.rs
  • crates/cli/src/main.rs
  • crates/cli/tests/cli_tests.rs
  • crates/cli/tests/coverage/mcp_tests.rs
  • crates/cli/src/config.rs
  • crates/cli/src/plugin_install/host.rs
  • crates/cli/src/plugin_install/state.rs
  • crates/cli/tests/coverage/installer_tests.rs
  • crates/cli/src/plugin_install/marketplace.rs
  • crates/cli/src/plugin_install/mod.rs
  • crates/cli/src/mcp.rs
  • crates/cli/src/server.rs
  • crates/cli/tests/coverage/plugin_install_tests.rs
  • crates/cli/src/plugin_shim/codex.rs
**/*.{rs,py,go,js,ts,c,h}

📄 CodeRabbit inference engine (CONTRIBUTING.md)

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

Files:

  • crates/cli/tests/coverage/main_tests.rs
  • crates/cli/src/plugin_install/setup.rs
  • crates/cli/src/main.rs
  • crates/cli/tests/cli_tests.rs
  • crates/cli/tests/coverage/mcp_tests.rs
  • crates/cli/src/config.rs
  • crates/cli/src/plugin_install/host.rs
  • crates/cli/src/plugin_install/state.rs
  • crates/cli/tests/coverage/installer_tests.rs
  • crates/cli/src/plugin_install/marketplace.rs
  • crates/cli/src/plugin_install/mod.rs
  • crates/cli/src/mcp.rs
  • crates/cli/src/server.rs
  • crates/cli/tests/coverage/plugin_install_tests.rs
  • crates/cli/src/plugin_shim/codex.rs
**/*.{rs,go,js,ts}

📄 CodeRabbit inference engine (CONTRIBUTING.md)

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

Files:

  • crates/cli/tests/coverage/main_tests.rs
  • crates/cli/src/plugin_install/setup.rs
  • crates/cli/src/main.rs
  • crates/cli/tests/cli_tests.rs
  • crates/cli/tests/coverage/mcp_tests.rs
  • crates/cli/src/config.rs
  • crates/cli/src/plugin_install/host.rs
  • crates/cli/src/plugin_install/state.rs
  • crates/cli/tests/coverage/installer_tests.rs
  • crates/cli/src/plugin_install/marketplace.rs
  • crates/cli/src/plugin_install/mod.rs
  • crates/cli/src/mcp.rs
  • crates/cli/src/server.rs
  • crates/cli/tests/coverage/plugin_install_tests.rs
  • crates/cli/src/plugin_shim/codex.rs
**/*.{rs,py,go,js,ts}

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

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

Files:

  • crates/cli/tests/coverage/main_tests.rs
  • crates/cli/src/plugin_install/setup.rs
  • crates/cli/src/main.rs
  • crates/cli/tests/cli_tests.rs
  • crates/cli/tests/coverage/mcp_tests.rs
  • crates/cli/src/config.rs
  • crates/cli/src/plugin_install/host.rs
  • crates/cli/src/plugin_install/state.rs
  • crates/cli/tests/coverage/installer_tests.rs
  • crates/cli/src/plugin_install/marketplace.rs
  • crates/cli/src/plugin_install/mod.rs
  • crates/cli/src/mcp.rs
  • crates/cli/src/server.rs
  • crates/cli/tests/coverage/plugin_install_tests.rs
  • crates/cli/src/plugin_shim/codex.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/main_tests.rs
  • crates/cli/tests/cli_tests.rs
  • crates/cli/tests/coverage/mcp_tests.rs
  • crates/cli/tests/coverage/installer_tests.rs
  • crates/cli/tests/coverage/plugin_install_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/plugin_install/setup.rs
  • crates/cli/src/main.rs
  • crates/cli/src/config.rs
  • crates/cli/src/plugin_install/host.rs
  • crates/cli/src/plugin_install/state.rs
  • crates/cli/src/plugin_install/marketplace.rs
  • crates/cli/src/plugin_install/mod.rs
  • crates/cli/src/mcp.rs
  • crates/cli/src/server.rs
  • crates/cli/src/plugin_shim/codex.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/README.md
  • integrations/coding-agents/codex/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/README.md
  • integrations/coding-agents/codex/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/README.md
  • integrations/coding-agents/codex/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/README.md
  • integrations/coding-agents/codex/README.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:

  • integrations/coding-agents/README.md
  • integrations/coding-agents/codex/README.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:

  • integrations/coding-agents/README.md
  • integrations/coding-agents/codex/README.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:

  • integrations/coding-agents/README.md
  • integrations/coding-agents/codex/README.md
🔇 Additional comments (26)
crates/cli/src/server.rs (2)

53-63: LGTM!

Also applies to: 65-85, 87-91, 132-146, 178-188


148-164: 🩺 Stability & Availability

Readiness signal is correctly ordered. It fires after plugin/router setup and before axum::serve, and the MCP launcher only waits on it before starting stdio handling.

crates/cli/Cargo.toml (1)

53-53: LGTM!

crates/cli/src/config.rs (1)

72-83: LGTM!

crates/cli/src/main.rs (1)

17-17: LGTM!

Also applies to: 84-84

crates/cli/src/mcp.rs (2)

1-104: LGTM!

Also applies to: 131-187


105-129: 🗄️ Data Integrity & Integration

MCP stdio uses newline-delimited JSON, so read_line is the right framing here.

			> Likely an incorrect or invalid review comment.
integrations/coding-agents/codex/.mcp.json (1)

1-15: LGTM!

integrations/coding-agents/codex/README.md (1)

22-23: LGTM!

Also applies to: 48-68, 196-200, 227-227, 299-317, 338-342

integrations/coding-agents/codex/hooks/hooks.json (1)

2-151: LGTM!

crates/cli/tests/cli_tests.rs (1)

164-217: LGTM!

Also applies to: 1329-1329

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

86-96: LGTM!

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

1-201: LGTM!

Good coverage of readiness gating, EOF shutdown, and the plugin-activation error path — satisfies the path instruction to prefer lifecycle/error-path assertions over shallow smoke tests.

crates/cli/src/plugin_shim/codex.rs (3)

146-314: LGTM!

Trust classification, canonicalized path matching, missing-required computation, and the snapshot/rollback aggregation helpers all look correct and consistent with the PR's trust-hardening goals.


117-122: 🩺 Stability & Availability

No issue — the workspace targets Rust 1.93.0 and edition 2024, so this let chain is supported.


36-53: 🗄️ Data Integrity & Integration

Snapshot order is fine

prepare_codex_config only parses config.toml and returns an error on invalid TOML; it does not write to disk, so taking the snapshot afterward still captures the pre-install state.

			> Likely an incorrect or invalid review comment.
integrations/coding-agents/README.md (1)

25-36: LGTM!

Also applies to: 69-85

integrations/coding-agents/codex/.codex-plugin/plugin.json (1)

4-22: LGTM!

crates/cli/src/plugin_install/state.rs (1)

50-50: LGTM!

Also applies to: 74-83

crates/cli/src/plugin_install/host.rs (1)

319-338: LGTM! Mirrors the existing validate_relay_plugin_shim pattern and matches the mocked-failure test expectations.

crates/cli/src/plugin_install/marketplace.rs (2)

143-160: 🎯 Functional Correctness

Confirm the hardcoded MCP bind address doesn't drift from a single source of truth, and how port conflicts are handled.

NEMO_RELAY_GATEWAY_BIND is hardcoded here to a fixed port (127.0.0.1:47632), while docs describe the transparent-wrapper flow using a dynamic port. Since this config is marked "required": true, if config.rs/mcp.rs (default bind handling, not in this file set) ever changes the default bind or if the port is already in use (e.g., two installs, a leftover process), Codex startup could fail hard. Worth confirming this literal is sourced from (or kept in sync with) the same constant used by the mcp subcommand's default bind, and whether a bind failure is retried/surfaced gracefully.


20-28: LGTM! Consistent with updated tests (installer_tests.rs, plugin_install_tests.rs) confirming the generated .mcp.json content, manifest description/interface text, and the new Codex hooks-template behavior.

Also applies to: 49-51, 100-131, 176-176

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

361-369: LGTM! Correctly gates Codex plugin generation behind validate_relay_mcp, matching relay_without_native_mcp_fails_codex_install_before_generating_plugin.

crates/cli/src/plugin_install/setup.rs (1)

58-58: LGTM!

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

287-293: LGTM! Good coverage of the new MCP validation gate, generated config content, and readiness failure modes (missing config, mismatched binary), consistent with the source changes.

Also applies to: 346-362, 474-474, 529-534, 847-870, 1045-1069, 1444-1487

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

171-179: LGTM!

Also applies to: 228-245, 283-283

Comment thread crates/cli/src/plugin_install/host.rs Outdated
Comment thread crates/cli/src/plugin_install/mod.rs
Signed-off-by: Will Killian <wkillian@nvidia.com>
Signed-off-by: Will Killian <wkillian@nvidia.com>
Signed-off-by: Will Killian <wkillian@nvidia.com>
Signed-off-by: Will Killian <wkillian@nvidia.com>
Signed-off-by: Will Killian <wkillian@nvidia.com>
Signed-off-by: Will Killian <wkillian@nvidia.com>
@willkill07 willkill07 force-pushed the wkk_relay-447-codex-bootstrap branch from 027d8ed to f7779fc Compare July 9, 2026 21:47
@github-actions github-actions Bot added the lang:python PR changes/introduces Python code label Jul 9, 2026
@willkill07 willkill07 changed the title fix(codex): launch native gateway from plugin MCP fix(codex): stabilize plugin gateway bootstrap Jul 9, 2026
Signed-off-by: Will Killian <wkillian@nvidia.com>
@github-actions github-actions Bot added size:XXL PR is very large and removed size:XL PR is extra large labels Jul 9, 2026
Signed-off-by: Will Killian <wkillian@nvidia.com>
Signed-off-by: Will Killian <wkillian@nvidia.com>
Signed-off-by: Will Killian <wkillian@nvidia.com>
Signed-off-by: Will Killian <wkillian@nvidia.com>
Signed-off-by: Will Killian <wkillian@nvidia.com>
Signed-off-by: Will Killian <wkillian@nvidia.com>
Signed-off-by: Will Killian <wkillian@nvidia.com>
Signed-off-by: Will Killian <wkillian@nvidia.com>
Signed-off-by: Will Killian <wkillian@nvidia.com>
Signed-off-by: Will Killian <wkillian@nvidia.com>
Signed-off-by: Will Killian <wkillian@nvidia.com>
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:python PR changes/introduces Python code 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.

1 participant