Skip to content

feat(dcode): add backend-neutral OTLP observability - #6340

Merged
apurvvkumaria merged 31 commits into
mainfrom
codex/dcode-backend-neutral-observability
Jul 8, 2026
Merged

feat(dcode): add backend-neutral OTLP observability#6340
apurvvkumaria merged 31 commits into
mainfrom
codex/dcode-backend-neutral-observability

Conversation

@cv

@cv cv commented Jul 6, 2026

Copy link
Copy Markdown
Collaborator

Summary

Add opt-in, backend-neutral observability for LangChain Deep Agents Code. Root-owned NeMo Relay instrumentation exports bounded model and tool content to a fixed host-local OTLP receiver, while an operator-owned collector holds backend credentials and forwards traces to LangSmith or another OTLP-compatible backend without rebuilding the sandbox.

Related Issue

Follow-up to #5621

Related to #3915

Changes

  • Add DCode-only --observability and --no-observability controls that are off by default and persist through resume, ready-sandbox drift, recreate, rebuild, snapshot clone, and registry recovery.
  • Instrument managed model, tool, subagent, and LangGraph execution. Export bounded prompts, model responses, tool arguments, and tool results; keep graph node scopes to bounded names, a static integration label, and status so they do not duplicate raw graph state.
  • Redact credential-shaped and control-plane fields and omit request headers, model settings, tool schemas, callback metadata, checkpoint and interrupt payloads, and original exception text. Preserve agent results and exact exception identity and traceback in agent execution.
  • Keep local observability failure diagnostics content-free: caught exception text and tracebacks are not logged, preventing ambient OTEL headers, certificate paths, and client-key paths from leaking through setup, export, callback, or cleanup failures.
  • Send OTLP/HTTP only to http://host.openshell.internal:4318/v1/traces, without custom, exporter, or authentication headers. Ignore ambient exporter configuration and fail open when trace delivery is unavailable.
  • Manage the exact observability-otlp-local policy for DCode, including add/remove reconciliation, managed-Python and endpoint restrictions, ready-state recreation, and suppression on the restricted tier.
  • Pin nemo-relay[langgraph]==0.4.0 and validate the real Relay integration during image builds. Add a composed live E2E contract covering OpenShell policy enforcement, launcher and direct execution, captured model/tool content, ambient-canary absence, and negative host, path, method, port, and binary cases.
  • Preserve exact inner command arguments after the documented sandbox exec -- boundary, and harden the live OTLP capture server to reject unexpected routes or exporter headers and persist only normalized metadata beside bounded protobuf bodies.
  • Document the complete host-collector workflow for LangSmith, including private bridge binding, host-only credentials, regional and self-hosted endpoints, verification, disabling, troubleshooting, and the trace-content security boundary.

Type of Change

  • Code change (feature, bug fix, or refactor)
  • Code change with doc updates
  • Doc only (prose changes, no code sample modifications)
  • Doc only (includes code sample changes)

Quality Gates

  • Tests added or updated for changed behavior
  • Existing tests cover changed behavior — justification:
  • Tests not applicable — justification:
  • Docs updated for user-facing behavior changes
  • Docs not applicable — justification:
  • Sensitive paths changed (security, policy, credentials, preflight, onboarding, inference, runner, sandbox, or messaging)
  • Sensitive-path review completed or maintainer-approved waiver recorded — reviewer/approval link/justification: completed a nine-category security review and an independent final-diff review with no actionable findings. The real nemo-relay==0.4.0 and langgraph==1.2.6 validator emitted nine OTLP requests totaling 9,060 protobuf bytes while enforcing unique OTLP attributes and proving content bounds and redaction, callback isolation, zero ambient-exporter canary traffic, and exact result and exception preservation. The composed live contract covers the OpenShell policy and runtime boundary. Arbitrary sandbox Python can still forge OTLP fields, so the host collector must not treat trace attributes as authenticated tenant identity.
  • Non-success, skipped, or missing CI check accepted by maintainer — check name, approval link, and follow-up issue:

Verification

  • PR description includes the DCO sign-off declaration and every commit appears as Verified in GitHub
  • Normal pre-commit, commit-msg, and pre-push hooks passed, or npm run check:diff passed when hooks were skipped or unavailable
  • Targeted behavior tests pass for the current change set, or tests are marked not applicable above — command/result or justification: 341/341 CLI feature tests, 123/123 integration and image tests, 44/44 E2E support tests, and 103/103 focused rebuild regression tests passed. The combined post-CI regression slice passed 105/105 after normal hooks. The current-head final-fix slice also passed 183/183 CLI, 22/22 E2E-support, 78/78 observability integration/image, and the policy-read discovery audit. The real Relay validator emitted nine requests totaling 9,060 bytes and enforced unique resource, scope, span, event, and link attributes. The final production-equivalent image build completed at sha256:11e48de2b7cbefe58e918d1d9fb303ce93229db2079a8a72446871dce39b0d3d. After merging current main and resolving its three rebuild conflicts, 137/137 focused rebuild tests passed locally, along with the CLI build, CLI type-check, and Biome checks. All applicable current-head PR checks passed (2 not-applicable checks were skipped). The composed cloud trace contract passed on attempt 2 in run 28847969488, and network-policy, sandbox-rebuild, onboard-resume, and onboard-repair passed in run 28847913562. The DCode-only shared-check regression passed 12/12 E2E-support tests, and the compacted managed-patch validation passed 34/34 integration tests. After the final two main synchronizations, focused post-merge tests passed: snapshot 45/45, sandbox 42/42, registry recovery 50/50, onboard integration 65/65, DCode integration 124/124, E2E support 12/12, and docs variants/routes/commands 26/26, plus CLI type-check, size budgets, local link checking, and npm run docs (0 errors; two pre-existing warnings). On final head 9ebf3f29d, Python compilation, Biome, and 114/114 focused observability, image, and direct-module integration tests passed. The new failure-log regression exposes all three OTEL canaries against the pre-fix source and proves they are absent after the fix. All required final-head CI checks passed; optional self-hosted E2E jobs were still queued for runner capacity when this evidence was recorded.
  • Applicable broad gate passed — npm test for broad runtime/test-harness changes; npm run check for repo-wide validation/coverage changes — command/result: under the repository-normal 022 umask, npm test completed with 13,560 passing and 36 skipped tests. Its sole failure is the untouched e2e-migration-source-of-truth check because openshell-gateway-upgrade-helpers.ts has a pre-existing local shellQuote; the same failure reproduces on origin/main, and no maintainer waiver is claimed here.
  • Quality Gates section completed with required justifications or waivers
  • No secrets, API keys, or credentials committed
  • npm run docs builds without warnings (doc changes only) — completed with 0 errors and two pre-existing repository warnings
  • Doc pages follow the style guide (doc changes only)
  • New doc pages include SPDX header and frontmatter (new pages only)

Additional current-head checks:

  • npm run build:cli
  • npm run typecheck:cli
  • npm run validate:configs (46/46)
  • npm run source-shape:check
  • npm run test-size:check
  • npm run docs (0 errors; two pre-existing warnings)
  • git diff --check

Signed-off-by: Carlos Villela cvillela@nvidia.com

Signed-off-by: Carlos Villela <cvillela@nvidia.com>
@cv cv self-assigned this Jul 6, 2026
@coderabbitai

coderabbitai Bot commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

This PR adds opt-in observability for Deep Agents Code across onboarding, session persistence, sandbox/rebuild flows, policy selection, runtime startup, and e2e validation, plus a local OTLP preset and updated docs.

Changes

Deep Agents Code observability runtime

Layer / File(s) Summary
Runtime module and container wiring
agents/langchain-deepagents-code/nemoclaw_observability.py, agents/langchain-deepagents-code/Dockerfile, agents/langchain-deepagents-code/dcode-launcher.sh, agents/langchain-deepagents-code/start.sh, agents/langchain-deepagents-code/requirements.in, agents/langchain-deepagents-code/dependency-review.md, agents/langchain-deepagents-code/validate-observability.py
Adds the managed observability module, image/startup wiring, dependency pinning, audit metadata, and standalone validation script.
Managed patcher integration
agents/langchain-deepagents-code/patch-managed-deepagents-code.py, test/langchain-deepagents-code-progressive-tool-disclosure.test.ts, test/langchain-deepagents-code-direct-module-patch.test.ts
Extends the patcher to install and validate the observability module and to inject observability middleware/callback handling, with failure-path coverage.
CLI and session state plumbing
src/lib/onboard/command-support.ts, src/lib/onboard/command.ts, src/lib/onboard/runtime-control-flow.ts, src/lib/onboard/session-bootstrap.ts, src/lib/onboard/session-updates.ts, src/lib/onboard/types.ts, src/lib/state/onboard-session.ts, src/lib/state/registry.ts, src/lib/onboard/machine/handlers/*.ts, src/lib/actions/sandbox/*.ts, src/lib/onboard/*.test.ts, src/lib/state/*.test.ts
Adds the CLI flag, validation, runtime-control helpers, session/state persistence, rebuild propagation, and sandbox/policy wiring for observability intent.
Observability-aware policy presets
src/lib/onboard/observability-policy-presets.ts, src/lib/onboard/policy-preset-reconciliation.ts, src/lib/onboard/policy-presets.ts, src/lib/onboard/policy-resume-selection.ts, src/lib/onboard/policy-selection.ts, src/lib/onboard/policy-tier-suppression.ts, src/lib/onboard/agent-policy-presets.ts, test/onboard-policy-suggestions.test.ts, src/lib/onboard/observability-policy-presets.test.ts, src/lib/onboard/policy-resume-selection.test.ts
Adds observability-specific preset utilities and threads them through suggestion, resume, selection, and tier-suppression logic.
Sandbox launch and rebuild propagation
src/lib/onboard.ts, src/lib/onboard/sandbox-create-launch.ts, src/lib/onboard/sandbox-registration.ts, src/lib/onboard/sandbox-create-launch-observability.test.ts, src/lib/onboard/sandbox-registration.test.ts, test/registry.test.ts, src/lib/actions/sandbox/rebuild-gpu-opt-out.ts, src/lib/actions/sandbox/rebuild-recreate-phase.ts, src/lib/actions/sandbox/rebuild-recreate-observability.test.ts, src/lib/actions/sandbox/rebuild-gpu-opt-out.test.ts, src/lib/onboard/machine/handlers/policies.ts, src/lib/onboard/machine/handlers/sandbox.ts, src/lib/onboard/machine/handlers/sandbox-dcode-selection.test.ts, src/lib/onboard/machine/handlers/sandbox-tool-disclosure.test.ts, src/lib/onboard/machine/handlers/sandbox.test.ts, src/lib/onboard/machine/handlers/policies-observability.test.ts
Propagates observability intent through sandbox launch, registration, machine handlers, and rebuild/recreate flows, with tests covering the resulting intent shape.
Local OTLP preset, docs, and contract tests
nemoclaw-blueprint/policies/presets/observability-otlp-local.yaml, test/observability-otlp-policy-preset.test.ts, docs/get-started/quickstart-langchain-deepagents-code.mdx, docs/reference/commands*.mdx, docs/reference/enterprise-readiness.mdx, docs/reference/network-policies.mdx, ci/test-file-size-budget.json, test/policies.test.ts, test/langchain-deepagents-code-image.test.ts
Defines the local OTLP preset and updates user-facing/reference documentation and preset contract tests around trace export behavior.
Observability harness and runtime tests
test/fixtures/deepagents-observability-harness.py, test/langchain-deepagents-code-observability.test.ts, test/langchain-deepagents-code-proxy-launcher.test.ts, src/lib/onboard/sandbox-create-launch-observability.test.ts
Adds Python/TypeScript tests for observability privacy, outage, construction, launcher-marker, and launch-env behavior.

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

Suggested labels: feature
Suggested reviewers: cjagwani, ericksoa

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title is concise and accurately summarizes the main change: adding backend-neutral OTLP observability for DCode.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/dcode-backend-neutral-observability

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

@github-actions

github-actions Bot commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

@github-code-quality

github-code-quality Bot commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

Code Coverage Overview

Languages: TypeScript

TypeScript / code-coverage/plugin

The overall coverage in the codex/dcode-backend-... branch is 96%. Coverage data for the main branch is not yet available.

Show a code coverage summary of the most covered files.
File main codex/dcode-backend-... ac1b478 +/-
nemoclaw/src/se...cret-scanner.ts 100%
nemoclaw/src/commands/slash.ts 100%
nemoclaw/src/li...bprocess-env.ts 100%
nemoclaw/src/bl...eprint/state.ts 98%
nemoclaw/src/onboard/config.ts 98%
nemoclaw/src/bl...int/snapshot.ts 97%
nemoclaw/src/bl...print/runner.ts 95%
nemoclaw/src/co...ration-state.ts 94%
nemoclaw/src/bl...ate-networks.ts 94%
nemoclaw/src/index.ts 94%

TypeScript / code-coverage/cli

The overall coverage in the codex/dcode-backend-... branch is 76%. Coverage data for the main branch is not yet available.

Show a code coverage summary of the most covered files.
File main codex/dcode-backend-... ac1b478 +/-
src/lib/onboard/preflight.ts 82%
src/lib/state/o...oard-session.ts 82%
src/lib/actions...all/run-plan.ts 81%
src/lib/actions...licy-channel.ts 79%
src/lib/actions...box/snapshot.ts 79%
src/lib/state/sandbox.ts 75%
src/lib/onboard...er-gpu-patch.ts 69%
src/lib/policy/index.ts 65%
src/lib/shields/index.ts 61%
src/lib/onboard.ts 28%

Updated July 08, 2026 00:08 UTC
Code Coverage is in Public Preview. Learn more and provide us with your feedback.

@github-advanced-security github-advanced-security AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

CodeQL found more than 20 potential problems in the proposed changes. Check the Files changed tab for more details.

Signed-off-by: Carlos Villela <cvillela@nvidia.com>
Comment thread test/fixtures/deepagents-observability-harness.py Fixed
Comment thread test/fixtures/deepagents-observability-harness.py Fixed
Comment thread test/fixtures/deepagents-observability-harness.py Fixed
Comment thread test/fixtures/deepagents-observability-harness.py Fixed
Comment thread test/fixtures/deepagents-observability-harness.py Fixed
Comment thread test/fixtures/deepagents-observability-harness.py Fixed
Comment thread agents/langchain-deepagents-code/nemoclaw_observability.py Fixed
Comment thread agents/langchain-deepagents-code/nemoclaw_observability.py Fixed
Comment thread agents/langchain-deepagents-code/nemoclaw_observability.py Fixed
Comment thread agents/langchain-deepagents-code/nemoclaw_observability.py Fixed
@github-actions

github-actions Bot commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

E2E Advisor Recommendation

Required E2E: onboard-resume, onboard-repair, cloud-onboard, ubuntu-repo-cloud-langchain-deepagents-code, sandbox-rebuild, network-policy, mcp-bridge, inference-routing, sandbox-operations
Optional E2E: snapshot-commands, credential-sanitization, security-posture

Dispatch hint: Run e2e.yaml twice because it forbids mixing jobs and targets: first with jobs=onboard-resume,onboard-repair,cloud-onboard,sandbox-rebuild,network-policy,mcp-bridge,inference-routing,sandbox-operations; then with targets=ubuntu-repo-cloud-langchain-deepagents-code. Optional follow-up jobs=snapshot-commands,credential-sanitization,security-posture.

Workflow run

Full advisor summary

E2E Recommendation Advisor

Base: origin/main
Head: HEAD
Confidence: high

Required E2E

  • onboard-resume (medium): Required by the onboarding resume rule because non-test changes touch onboarding machine resume orchestration, resume state/config, session bootstrap, and state transitions.
  • onboard-repair (medium): Required companion to onboard-resume for resume repair policy and broken/resumable onboarding state handling changed in this PR.
  • cloud-onboard (high): Hosted onboarding can be affected by changes to onboarding command flow, policy selection, session bootstrap, sandbox creation/launch, registry state, and observability flags.
  • ubuntu-repo-cloud-langchain-deepagents-code (high): Canonical registry live target for the changed LangChain Deep Agents Code image/runtime. It exercises hosted onboarding for the Deep Agents Code manifest and the cloud-experimental checks, including fresh re-onboard, security/egress, headless/TUI startup, and the new observability check.
  • sandbox-rebuild (medium): Required because rebuild pipeline, preflight, backup/restore, recreate, MCP, dcode recovery, and observability recreate phases changed; this is the direct live rebuild lifecycle coverage.
  • network-policy (high): Required because policy preset/binding/selection logic and the observability OTLP local network-policy preset changed, affecting sandbox egress boundaries.
  • mcp-bridge (high): Required because rebuild MCP phase and Deep Agents managed MCP/config boundaries changed; this job includes a Deep Agents Code MCP bridge scenario with real adapter tool calls, secret absence checks, restart, rotation, and rebuild.
  • inference-routing (medium): Required because managed Deep Agents proxy/base-url normalization, hosted inference routing, and related onboarding/registry code changed.
  • sandbox-operations (medium): Required for changed sandbox exec command and policy-hint handling, which can affect real sandbox lifecycle operations and user-facing sandbox command flows.

Optional E2E

  • snapshot-commands (medium): Useful adjacent confidence because snapshot action code changed, but sandbox-rebuild and sandbox-operations cover the higher-risk lifecycle paths.
  • credential-sanitization (medium): Useful additional confidence for the new Deep Agents observability redaction and credential-boundary changes, although the Deep Agents registry target and network-policy job are the primary required coverage.
  • security-posture (high): Useful broad security posture sweep for image/runtime boundary changes, especially because the PR modifies managed sandbox image startup, runtime env, and credential/security documentation.

New E2E recommendations

  • deepagents-observability-direct-exec-boundary (medium): This PR adds a marker-based recovery path so raw OpenShell exec of dcode can re-enable observability without inheriting the entrypoint environment. Existing coverage is embedded in the broader Deep Agents cloud-experimental target; a small free-standing live job would make this boundary easier to dispatch and diagnose without running the full Deep Agents target.
    • Suggested test: Add a dedicated live E2E job for Deep Agents Code observability direct-exec marker recovery and unsafe marker rejection.

Dispatch hint

  • Workflow: .github/workflows/e2e.yaml
  • jobs input: Run e2e.yaml twice because it forbids mixing jobs and targets: first with jobs=onboard-resume,onboard-repair,cloud-onboard,sandbox-rebuild,network-policy,mcp-bridge,inference-routing,sandbox-operations; then with targets=ubuntu-repo-cloud-langchain-deepagents-code. Optional follow-up jobs=snapshot-commands,credential-sanitization,security-posture.

@github-actions

github-actions Bot commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

E2E Target Recommendation

Required E2E targets: e2e-all, onboard-resume, onboard-repair
Optional E2E targets: None

Dispatch required E2E targets:

  • gh workflow run e2e.yaml --ref <pr-head-ref>
  • gh workflow run e2e.yaml --ref <pr-head-ref> --field jobs=onboard-resume
  • gh workflow run e2e.yaml --ref <pr-head-ref> --field jobs=onboard-repair

Workflow run

Full E2E target advisor summary

E2E Target Advisor

Base: origin/main
Head: HEAD
Confidence: high

Required E2E targets

  • e2e-all: Shared E2E fixture/support changes, cloud-experimental live helpers/checks, and the Deep Agents Code manifest/runtime surface can affect registry-driven target behavior; run the canonical E2E fan-out.
    • Dispatch: gh workflow run e2e.yaml --ref <pr-head-ref>
  • onboard-resume: Changes under src/lib/onboard/machine, sandbox resume handling, resume config, session bootstrap, and persisted onboarding state trigger the onboarding resume rule.
    • Dispatch: gh workflow run e2e.yaml --ref <pr-head-ref> --field jobs=onboard-resume
  • onboard-repair: The same resume/session state-machine paths can affect repair/backstop execution from persisted sessions, so onboard-repair is required and not optional.
    • Dispatch: gh workflow run e2e.yaml --ref <pr-head-ref> --field jobs=onboard-repair

Optional E2E targets

  • None.

Relevant changed files

  • agents/langchain-deepagents-code/Dockerfile
  • agents/langchain-deepagents-code/dcode-launcher.sh
  • agents/langchain-deepagents-code/nemoclaw_observability.py
  • agents/langchain-deepagents-code/patch-managed-deepagents-code.py
  • agents/langchain-deepagents-code/requirements.in
  • agents/langchain-deepagents-code/requirements.lock
  • agents/langchain-deepagents-code/start.sh
  • agents/langchain-deepagents-code/validate-observability.py
  • nemoclaw-blueprint/policies/presets/observability-otlp-local.yaml
  • src/commands/sandbox/exec.ts
  • src/commands/sandbox/rebuild.ts
  • src/lib/actions/sandbox/rebuild-backup-phase.ts
  • src/lib/actions/sandbox/rebuild-gpu-opt-out.ts
  • src/lib/actions/sandbox/rebuild-mcp-phase.ts
  • src/lib/actions/sandbox/rebuild-pipeline.ts
  • src/lib/actions/sandbox/rebuild-post-restore-phase.ts
  • src/lib/actions/sandbox/rebuild-preflight-confirmation.ts
  • src/lib/actions/sandbox/rebuild-preflight-phase.ts
  • src/lib/actions/sandbox/rebuild-preflight-target-phase.ts
  • src/lib/actions/sandbox/rebuild-recreate-phase.ts
  • src/lib/actions/sandbox/rebuild-restore-phase.ts
  • src/lib/actions/sandbox/snapshot.ts
  • src/lib/onboard.ts
  • src/lib/onboard/command.ts
  • src/lib/onboard/machine/core-flow-phases.ts
  • src/lib/onboard/machine/final-flow-phases.ts
  • src/lib/onboard/machine/handlers/policies.ts
  • src/lib/onboard/machine/handlers/sandbox-resume.ts
  • src/lib/onboard/machine/handlers/sandbox.ts
  • src/lib/onboard/policy-resume-selection.ts
  • src/lib/onboard/resume-config.ts
  • src/lib/onboard/runtime-control-flow.ts
  • src/lib/onboard/sandbox-create-launch.ts
  • src/lib/onboard/sandbox-create-plan.ts
  • src/lib/onboard/sandbox-registration.ts
  • src/lib/onboard/session-bootstrap.ts
  • src/lib/onboard/session-updates.ts
  • src/lib/onboard/types.ts
  • src/lib/state/onboard-session.ts
  • src/lib/state/registry.ts
  • test/e2e/e2e-cloud-experimental/checks/04-deepagents-code-fresh-reonboard.sh
  • test/e2e/e2e-cloud-experimental/checks/11-deepagents-code-observability.sh
  • test/e2e/fixtures/phases/onboarding.ts
  • test/e2e/live/cloud-experimental-check-list.ts
  • test/e2e/live/cloud-experimental-checks.ts
  • test/e2e/live/deepagents-observability-contract.ts
  • test/e2e/live/deepagents-otlp-capture-server.ts
  • test/e2e/live/otlp-trace-decoder.ts
  • test/e2e/manifests/langchain-deepagents-code-nvidia.yaml
  • test/e2e/support/deepagents-observability-contract-fixtures.ts
  • test/e2e/support/deepagents-observability-contract.test.ts
  • test/e2e/support/e2e-manifests.test.ts
  • test/e2e/support/e2e-phase-onboarding.test.ts
  • test/e2e/support/platform-parity-cloud-experimental.test.ts

Signed-off-by: Carlos Villela <cvillela@nvidia.com>
Comment thread agents/langchain-deepagents-code/nemoclaw_observability.py Fixed
Comment thread agents/langchain-deepagents-code/nemoclaw_observability.py Fixed
Comment thread agents/langchain-deepagents-code/nemoclaw_observability.py Fixed
Comment thread agents/langchain-deepagents-code/nemoclaw_observability.py Fixed
Comment thread agents/langchain-deepagents-code/nemoclaw_observability.py Fixed
Comment thread agents/langchain-deepagents-code/nemoclaw_observability.py Fixed
Comment thread test/fixtures/deepagents-observability-harness.py Fixed
Comment thread agents/langchain-deepagents-code/nemoclaw_observability.py Fixed
Comment thread agents/langchain-deepagents-code/nemoclaw_observability.py Fixed
Comment thread agents/langchain-deepagents-code/nemoclaw_observability.py Fixed
Comment thread test/fixtures/deepagents-observability-harness.py Fixed
Comment thread agents/langchain-deepagents-code/nemoclaw_observability.py Fixed
Comment thread agents/langchain-deepagents-code/nemoclaw_observability.py Fixed
Comment thread agents/langchain-deepagents-code/nemoclaw_observability.py Fixed
Comment thread test/langchain-deepagents-code-proxy-launcher.test.ts Fixed
@github-actions

github-actions Bot commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

E2E Target Results — ✅ All requested jobs passed

Run: 28821842176
Workflow ref: codex/dcode-backend-neutral-observability
Requested targets: (default — all supported)
Requested jobs: onboard-resume
Summary: 1 passed, 0 failed, 0 cancelled, 0 skipped

Job Result
onboard-resume ✅ success

@github-actions

github-actions Bot commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

PR Review Advisor — Changes requested

Merge posture: Do not merge yet
Primary next action: Resolve or justify PRA-1: Prove or narrow host-local OTLP RFC1918 allowed_ips.
Open items: 0 required · 1 warning · 1 suggestion · 4 test follow-ups
Since last review: 0 prior items resolved · 2 still apply · 0 new items found

Action checklist

  • PRA-1 Resolve or justify: Prove or narrow host-local OTLP RFC1918 allowed_ips in nemoclaw-blueprint/policies/presets/observability-otlp-local.yaml:20
  • PRA-T1 Add or justify test follow-up: Runtime validation
  • PRA-T2 Add or justify test follow-up: Acceptance clause
  • PRA-T3 Add or justify test follow-up: Acceptance clause
  • PRA-T4 Add or justify test follow-up: Snapshot observability policy reconciliation
  • PRA-2 In-scope improvement: Extract snapshot observability policy reconciliation in src/lib/actions/sandbox/snapshot.ts:580

Findings index

ID Severity Category Location Required action
PRA-1 Resolve/justify security nemoclaw-blueprint/policies/presets/observability-otlp-local.yaml:20 Either narrow allowed_ips to the exact host bridge/interface addresses OpenShell resolves for this endpoint, or add focused code/test evidence proving host.openshell.internal is pinned to intended host-local interfaces and rejects non-host private resolutions despite the broad RFC1918 ranges. Apply the same proof or narrowing to the custom host-gateway allowed_ips exemption.
PRA-2 Improvement architecture src/lib/actions/sandbox/snapshot.ts:580 Extract the built-in/custom observability preset reconciliation helper into a focused snapshot policy reconciliation module invoked from the same post-restore point, preserving the exact current behavior in this PR unless there is a concrete reason it must remain inline.
Review findings by urgency: 0 required fixes, 1 item to resolve/justify, 1 in-scope improvement

⚠️ Resolve or justify before merge

Investigate these in the current review; either fix them, explain why they are not applicable, or document the accepted risk.

PRA-1 Resolve/justify — Prove or narrow host-local OTLP RFC1918 allowed_ips

  • Location: nemoclaw-blueprint/policies/presets/observability-otlp-local.yaml:20
  • Category: security
  • Problem: The opt-in DCode observability preset pins the OTLP hostname, port, method/path, and managed Python binary, but it still allowlists all RFC1918 ranges for host.openshell.internal. The custom preset guard also exempts any endpoint whose host normalizes to host.openshell.internal, and the unit test accepts broad private ranges for that custom host-gateway shape. The live check proves the current resolved address is assigned to a host interface and covers alternate host/path/method/port/binary denials, but it does not prove OpenShell denies host.openshell.internal when it resolves or rebinds to a different non-host private address inside those broad ranges.
  • Impact: If OpenShell host-alias resolution drifts, is influenced, or races, an observability-enabled DCode sandbox could send OTLP-shaped POST traffic from /opt/venv/bin/python3 to an unintended RFC1918 service on port 4318. That weakens the sandbox SSRF boundary and could disclose bounded prompt, model, or tool trace content to the wrong private service even though exporter credentials and headers are stripped.
  • Recommended action: Either narrow allowed_ips to the exact host bridge/interface addresses OpenShell resolves for this endpoint, or add focused code/test evidence proving host.openshell.internal is pinned to intended host-local interfaces and rejects non-host private resolutions despite the broad RFC1918 ranges. Apply the same proof or narrowing to the custom host-gateway allowed_ips exemption.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Read nemoclaw-blueprint/policies/presets/observability-otlp-local.yaml lines 13-25, src/lib/policy/index.ts around HOST_GATEWAY_BRIDGE_HOST and networkPoliciesHasAllowedIps, src/lib/policy/preset-allowed-ips.test.ts around the host-gateway exemption, and test/e2e/e2e-cloud-experimental/checks/11-deepagents-code-observability.sh around bind-IP and negative-route checks.
  • Missing regression test: Add or identify `observability-otlp-local rejects host.openshell.internal when resolution is not the host bridge address`, using the shortest OpenShell policy-resolution seam to map host.openshell.internal to a non-host RFC1918 address and asserting the OTLP request is denied before any collector receives traffic.
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Read nemoclaw-blueprint/policies/presets/observability-otlp-local.yaml lines 13-25, src/lib/policy/index.ts around HOST_GATEWAY_BRIDGE_HOST and networkPoliciesHasAllowedIps, src/lib/policy/preset-allowed-ips.test.ts around the host-gateway exemption, and test/e2e/e2e-cloud-experimental/checks/11-deepagents-code-observability.sh around bind-IP and negative-route checks.
  • Evidence: The preset contains allowed_ips [10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16]. src/lib/policy/index.ts permits allowed_ips for endpoint host host.openshell.internal. src/lib/policy/preset-allowed-ips.test.ts accepts a custom host-gateway preset with broad private ranges. The live check validates the current resolved address and route negatives, but does not simulate a non-host private resolution.

💡 In-scope improvements

These are lower-risk, not throwaway. Prefer fixing them in this PR when they are local to changed code; defer only with rationale or a linked follow-up.

PRA-2 Improvement — Extract snapshot observability policy reconciliation

  • Location: src/lib/actions/sandbox/snapshot.ts:580
  • Category: architecture
  • Problem: reconcileSnapshotPolicyPresets remains inline in the already-large snapshot action module. The block is cohesive and security-sensitive: it computes custom policy ownership, decides built-in observability add/remove behavior, inspects exact live content, avoids replacing same-name custom content, suppresses restricted-tier built-ins, and preserves registry attribution when removal absence cannot be proved.
  • Impact: Keeping policy preservation/removal logic inside the monolithic snapshot command makes future review harder because the same file also handles restore preflight, destructive destination handling, filesystem restore, mutable permission repair, custom-policy replay, and prompts.
  • Suggested action: Extract the built-in/custom observability preset reconciliation helper into a focused snapshot policy reconciliation module invoked from the same post-restore point, preserving the exact current behavior in this PR unless there is a concrete reason it must remain inline.
  • Expected follow-up: Prefer a current-PR fix when local to changed code; defer only with rationale or linked follow-up.
  • Verification: Read src/lib/actions/sandbox/snapshot.ts from reconcileSnapshotPolicyPresets through its add/remove loops and compare the single call site near the post-restore section. The dependency surface is narrow: registry, policies, parsed snapshot state, tier normalization, and observability preset constants.
  • Missing regression test: Retain or move the existing snapshot tests for same-name custom observability ownership, restricted-tier built-in suppression, failed removal preserving registry attribution, and drifted or uninspectable built-in content being left unchanged.
  • Done when: The local improvement is applied, or the PR notes why it should be deferred.
  • Evidence: Current head still has customOwnsObservability, shouldEnableBuiltinObservability, exact-content inspection, post-removal state checks, add/remove loops, and registry attribution restoration inline in src/lib/actions/sandbox/snapshot.ts. The diff grows snapshot.ts to 1086 lines and snapshot.test.ts to 1500 lines.
Simplification opportunities: 1 possible cut

These are safe simplification checks only. Do not remove validation, security controls, data-loss prevention, or required tests.

  • PRA-2 shrink (src/lib/actions/sandbox/snapshot.ts:580): Move reconcileSnapshotPolicyPresets and its local observability add/remove bookkeeping out of src/lib/actions/sandbox/snapshot.ts.
    • Replacement: Create a focused snapshot policy reconciliation helper/module with the same inputs and call it from the existing post-restore point.
    • Safety boundary: Preserve exact-content ownership checks, no-delete-on-drift behavior, restricted-tier suppression, custom-policy replay ordering, and registry attribution restoration until absence is verified.
Test follow-ups to resolve or justify

If these cover changed behavior, prefer adding them in this PR; otherwise state why existing coverage is enough or link the follow-up.

  • PRA-T1 Runtime validation — observability-otlp-local rejects host.openshell.internal when resolution is not the host bridge address. This PR changes sandbox image/runtime code, OpenShell network policy, DCode monkeypatching, OTLP trace export, rebuild/snapshot lifecycle recovery, and E2E live helpers. The PR adds extensive unit, image-build, integration, and live-contract coverage; the remaining runtime validation gap is the host-alias private-resolution edge in the OTLP policy.
  • PRA-T2 Acceptance clause — No deterministic linked issue clauses were available. — add test evidence or identify existing coverage. The deterministic validation context reported linkedIssues: []; PR body references to other issues were treated as untrusted scope hints rather than acceptance clauses.
  • PRA-T3 Acceptance clause — Send OTLP/HTTP only to `http://host.openshell.internal:4318/v1/traces\`, without custom, exporter, or authentication headers. Ignore ambient exporter configuration and fail open when trace delivery is unavailable. — add test evidence or identify existing coverage. Diff evidence fixes _OTLP_ENDPOINT, sets config.headers = {}, strips ambient OTEL_* during subscriber construction, and adds unit/image/live checks for ambient canaries and wrong host/path/method/port/binary denials. The clause is not fully proven under resolution drift because the policy still permits broad RFC1918 allowed_ips for host.openshell.internal without a non-host-private denial proof.
  • PRA-T4 Snapshot observability policy reconciliation — Existing snapshot tests cover same-name custom observability ownership, restricted-tier suppression, failed removal preserving registry attribution, and drifted or uninspectable built-in content being left unchanged.. src/lib/actions/sandbox/snapshot.ts still defines reconcileSnapshotPolicyPresets inline at line 580 and handles customOwnsObservability, shouldEnableBuiltinObservability, exact-content state, add/remove loops, and attribution restoration locally.
Since last review details

Current findings, using the urgency labels above:

PRA-1 Resolve/justify — Prove or narrow host-local OTLP RFC1918 allowed_ips

  • Location: nemoclaw-blueprint/policies/presets/observability-otlp-local.yaml:20
  • Category: security
  • Problem: The opt-in DCode observability preset pins the OTLP hostname, port, method/path, and managed Python binary, but it still allowlists all RFC1918 ranges for host.openshell.internal. The custom preset guard also exempts any endpoint whose host normalizes to host.openshell.internal, and the unit test accepts broad private ranges for that custom host-gateway shape. The live check proves the current resolved address is assigned to a host interface and covers alternate host/path/method/port/binary denials, but it does not prove OpenShell denies host.openshell.internal when it resolves or rebinds to a different non-host private address inside those broad ranges.
  • Impact: If OpenShell host-alias resolution drifts, is influenced, or races, an observability-enabled DCode sandbox could send OTLP-shaped POST traffic from /opt/venv/bin/python3 to an unintended RFC1918 service on port 4318. That weakens the sandbox SSRF boundary and could disclose bounded prompt, model, or tool trace content to the wrong private service even though exporter credentials and headers are stripped.
  • Recommended action: Either narrow allowed_ips to the exact host bridge/interface addresses OpenShell resolves for this endpoint, or add focused code/test evidence proving host.openshell.internal is pinned to intended host-local interfaces and rejects non-host private resolutions despite the broad RFC1918 ranges. Apply the same proof or narrowing to the custom host-gateway allowed_ips exemption.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Read nemoclaw-blueprint/policies/presets/observability-otlp-local.yaml lines 13-25, src/lib/policy/index.ts around HOST_GATEWAY_BRIDGE_HOST and networkPoliciesHasAllowedIps, src/lib/policy/preset-allowed-ips.test.ts around the host-gateway exemption, and test/e2e/e2e-cloud-experimental/checks/11-deepagents-code-observability.sh around bind-IP and negative-route checks.
  • Missing regression test: Add or identify `observability-otlp-local rejects host.openshell.internal when resolution is not the host bridge address`, using the shortest OpenShell policy-resolution seam to map host.openshell.internal to a non-host RFC1918 address and asserting the OTLP request is denied before any collector receives traffic.
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Read nemoclaw-blueprint/policies/presets/observability-otlp-local.yaml lines 13-25, src/lib/policy/index.ts around HOST_GATEWAY_BRIDGE_HOST and networkPoliciesHasAllowedIps, src/lib/policy/preset-allowed-ips.test.ts around the host-gateway exemption, and test/e2e/e2e-cloud-experimental/checks/11-deepagents-code-observability.sh around bind-IP and negative-route checks.
  • Evidence: The preset contains allowed_ips [10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16]. src/lib/policy/index.ts permits allowed_ips for endpoint host host.openshell.internal. src/lib/policy/preset-allowed-ips.test.ts accepts a custom host-gateway preset with broad private ranges. The live check validates the current resolved address and route negatives, but does not simulate a non-host private resolution.

PRA-2 Improvement — Extract snapshot observability policy reconciliation

  • Location: src/lib/actions/sandbox/snapshot.ts:580
  • Category: architecture
  • Problem: reconcileSnapshotPolicyPresets remains inline in the already-large snapshot action module. The block is cohesive and security-sensitive: it computes custom policy ownership, decides built-in observability add/remove behavior, inspects exact live content, avoids replacing same-name custom content, suppresses restricted-tier built-ins, and preserves registry attribution when removal absence cannot be proved.
  • Impact: Keeping policy preservation/removal logic inside the monolithic snapshot command makes future review harder because the same file also handles restore preflight, destructive destination handling, filesystem restore, mutable permission repair, custom-policy replay, and prompts.
  • Suggested action: Extract the built-in/custom observability preset reconciliation helper into a focused snapshot policy reconciliation module invoked from the same post-restore point, preserving the exact current behavior in this PR unless there is a concrete reason it must remain inline.
  • Expected follow-up: Prefer a current-PR fix when local to changed code; defer only with rationale or linked follow-up.
  • Verification: Read src/lib/actions/sandbox/snapshot.ts from reconcileSnapshotPolicyPresets through its add/remove loops and compare the single call site near the post-restore section. The dependency surface is narrow: registry, policies, parsed snapshot state, tier normalization, and observability preset constants.
  • Missing regression test: Retain or move the existing snapshot tests for same-name custom observability ownership, restricted-tier built-in suppression, failed removal preserving registry attribution, and drifted or uninspectable built-in content being left unchanged.
  • Done when: The local improvement is applied, or the PR notes why it should be deferred.
  • Evidence: Current head still has customOwnsObservability, shouldEnableBuiltinObservability, exact-content inspection, post-removal state checks, add/remove loops, and registry attribution restoration inline in src/lib/actions/sandbox/snapshot.ts. The diff grows snapshot.ts to 1086 lines and snapshot.test.ts to 1500 lines.

Workflow run details

This is an automated, non-binding review; it still expects maintainers and agents to respond to each required or warning item. Treat suggestions as current-PR improvements when they touch changed code; defer only with maintainer rationale or a linked follow-up. A human maintainer must make the final merge decision.

@github-actions

github-actions Bot commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

E2E Target Results — ✅ All requested jobs passed

Run: 28821842163
Workflow ref: codex/dcode-backend-neutral-observability
Requested targets: (default — all supported)
Requested jobs: onboard-repair
Summary: 1 passed, 0 failed, 0 cancelled, 0 skipped

Job Result
onboard-repair ✅ success

@github-actions

github-actions Bot commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

E2E Target Results — ❌ Some jobs failed

Run: 28821842089
Workflow ref: codex/dcode-backend-neutral-observability
Requested targets: ubuntu-repo-cloud-langchain-deepagents-code
Requested jobs: (default — all default-enabled free-standing jobs; explicit-only jobs openshell-gateway-auth-contract, mcp-bridge-dev, hermes-gpu-startup, sandbox-rlimits-connect, and jetson-nvmap-gpu are skipped unless selected)
Summary: 0 passed, 1 failed, 0 cancelled, 0 skipped

Job Result
live ❌ failure

Failed jobs: live. Check run artifacts for logs.

@github-actions

github-actions Bot commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

PR Review Advisor (Nemotron Ultra) — Blocked

Merge posture: Do not merge until addressed
Primary next action: Fix PRA-8: Broad RFC1918 allowed_ips creates SSRF attack surface; then add or justify PRA-T1.
Open items: 8 required · 14 warnings · 4 suggestions · 8 test follow-ups
Since last review: 0 prior items resolved · 11 still apply · 15 new items found

Action checklist

  • PRA-8 Fix: Broad RFC1918 allowed_ips creates SSRF attack surface in nemoclaw-blueprint/policies/presets/observability-otlp-local.yaml:12
  • PRA-9 Fix: raise_redacted() missing 'from None' defeats exception redaction boundary in agents/langchain-deepagents-code/nemoclaw_observability.py:723
  • PRA-10 Fix: Marker file recovery has TOCTOU race condition in agents/langchain-deepagents-code/dcode-launcher.sh:17
  • PRA-11 Fix: Global os.environ mutation race in _new_managed_subscriber in agents/langchain-deepagents-code/nemoclaw_observability.py:1009
  • PRA-12 Fix: Test file grew by 457 lines exceeding monolith threshold in src/lib/actions/sandbox/snapshot.test.ts:1
  • PRA-13 Fix: Test file grew by 327 lines exceeding monolith threshold in src/lib/onboard/machine/handlers/sandbox.test.ts:1
  • PRA-14 Fix: Test file grew by 326 lines exceeding monolith threshold in src/lib/actions/sandbox/rebuild-restore-phase.test.ts:1
  • PRA-15 Fix: Observability reconciliation logic not extracted from snapshot.ts in src/lib/actions/sandbox/snapshot.ts:580
  • PRA-1 Resolve or justify: Source-of-truth review needed: _safe_identifier (agents/langchain-deepagents-code/nemoclaw_observability.py:117)
  • PRA-2 Resolve or justify: Source-of-truth review needed: _capture_jsonable (agents/langchain-deepagents-code/nemoclaw_observability.py:216)
  • PRA-3 Resolve or justify: Source-of-truth review needed: _safe_object_attribute (agents/langchain-deepagents-code/nemoclaw_observability.py:321)
  • PRA-4 Resolve or justify: Source-of-truth review needed: _new_managed_subscriber (agents/langchain-deepagents-code/nemoclaw_observability.py:1009)
  • PRA-5 Resolve or justify: Source-of-truth review needed: raise_redacted (agents/langchain-deepagents-code/nemoclaw_observability.py:723)
  • PRA-6 Resolve or justify: Source-of-truth review needed: dcode-launcher.sh marker recovery (agents/langchain-deepagents-code/dcode-launcher.sh:17)
  • PRA-7 Resolve or justify: Source-of-truth review needed: observability-otlp-local.yaml allowed_ips CIDRs (nemoclaw-blueprint/policies/presets/observability-otlp-local.yaml:8)
  • PRA-16 Resolve or justify: Marker file recovery workaround needs complete source-of-truth justification in agents/langchain-deepagents-code/dcode-launcher.sh:17
  • PRA-17 Resolve or justify: Broad CIDR allowance needs complete source-of-truth justification in nemoclaw-blueprint/policies/presets/observability-otlp-local.yaml:8
  • PRA-18 Resolve or justify: _safe_identifier function needs source-of-truth justification in agents/langchain-deepagents-code/nemoclaw_observability.py:117
  • PRA-T1 Add or justify test follow-up: Runtime validation
  • PRA-T2 Add or justify test follow-up: Runtime validation
  • PRA-T3 Add or justify test follow-up: Runtime validation
  • PRA-T4 Add or justify test follow-up: Runtime validation
  • PRA-T5 Add or justify test follow-up: Runtime validation
  • PRA-T6 Add or justify test follow-up: Policy preset test does not verify allowed_ips CIDR restriction
  • PRA-T7 Add or justify test follow-up: Acceptance clause
  • PRA-T8 Add or justify test follow-up: Acceptance clause
  • PRA-22 In-scope improvement: MetadataOnlyCallbackManager single-use abstraction could be inlined in agents/langchain-deepagents-code/nemoclaw_observability.py:583
  • PRA-23 In-scope improvement: Expected OTLP request count is undocumented magic number in agents/langchain-deepagents-code/validate-observability.py:43
  • PRA-24 In-scope improvement: deepagents-observability-harness.py duplicates validate-observability.py logic in test/fixtures/deepagents-observability-harness.py:1
  • PRA-25 In-scope improvement: E2E observability validation lacks fast unit gate in CI in test/langchain-deepagents-code-observability.test.ts:1

Findings index

ID Severity Category Location Required action
PRA-1 Resolve/justify architecture Identify the invalid state, source boundary, source-fix constraint, regression test, and removal condition before merging the localized behavior.
PRA-2 Resolve/justify architecture Identify the invalid state, source boundary, source-fix constraint, regression test, and removal condition before merging the localized behavior.
PRA-3 Resolve/justify architecture Identify the invalid state, source boundary, source-fix constraint, regression test, and removal condition before merging the localized behavior.
PRA-4 Resolve/justify architecture Identify the invalid state, source boundary, source-fix constraint, regression test, and removal condition before merging the localized behavior.
PRA-5 Resolve/justify architecture Identify the invalid state, source boundary, source-fix constraint, regression test, and removal condition before merging the localized behavior.
PRA-6 Resolve/justify architecture Identify the invalid state, source boundary, source-fix constraint, regression test, and removal condition before merging the localized behavior.
PRA-7 Resolve/justify architecture Identify the invalid state, source boundary, source-fix constraint, regression test, and removal condition before merging the localized behavior.
PRA-8 Required security nemoclaw-blueprint/policies/presets/observability-otlp-local.yaml:12 Restrict allowed_ips to only predictable gateway IPs (e.g., 172.17.0.1 for default Docker bridge, 10.0.2.2 for common Podman/VM bridges). If broader ranges are operationally required, add structured source-of-truth comment in the preset linking to test/observability-otlp-policy-preset.test.ts which denies alternate hosts/paths and documents why broad CIDRs are required. Evaluate whether OpenShell's SSRF guard can enforce DNS-only resolution for host.openshell.internal.
PRA-9 Required security agents/langchain-deepagents-code/nemoclaw_observability.py:723 Change line 723 to: raise RuntimeError(_REDACTED_EXCEPTION_MESSAGE) from None
PRA-10 Required security agents/langchain-deepagents-code/dcode-launcher.sh:17 Use atomic read: read -r val < "$MANAGED_OBSERVABILITY_MARKER" && [ "$val" = "1" ] && export NEMOCLAW_OBSERVABILITY=1. Add source-of-truth comment documenting: invalid state (marker tampering/symlink swap), source boundary (start.sh writes marker), why not fixed upstream (OpenShell cannot propagate entrypoint env), regression test (proxy-launcher tests cover exact values and unsafe file types), removal condition (OpenShell propagates the bit to every exec/login process).
PRA-11 Required security agents/langchain-deepagents-code/nemoclaw_observability.py:1009 Use contextvars.ContextVar for ambient OTEL env manipulation, or construct the subscriber in a subprocess/isolated environment. If keeping current approach, document why _lifecycle_lock + try/finally is sufficient (but note _lifecycle_lock only guards _lifecycle state, not os.environ).
PRA-12 Required correctness src/lib/actions/sandbox/snapshot.test.ts:1 Extract snapshot/restore/rebuild test helpers into shared fixtures. Split into create.test.ts, list.test.ts, restore.test.ts, and reconcile.test.ts. Offset growth by removing duplicated setup.
PRA-13 Required correctness src/lib/onboard/machine/handlers/sandbox.test.ts:1 Split sandbox.test.ts by concern: sandbox-create.test.ts, sandbox-resume.test.ts, sandbox-dcode.test.ts, sandbox-policy.test.ts, sandbox-observability.test.ts. Extract shared fixtures to test/helpers/sandbox-onboard-fixtures.ts.
PRA-14 Required correctness src/lib/actions/sandbox/rebuild-restore-phase.test.ts:1 Extract observability-specific rebuild tests into dedicated test file (e.g., rebuild-observability-reconciliation.test.ts). Share common harness setup with existing rebuild tests.
PRA-15 Required correctness src/lib/actions/sandbox/snapshot.ts:580 Extract reconcileSnapshotPolicyPresets and reconcileSnapshotCustomPolicies into src/lib/actions/sandbox/snapshot-policy-reconciliation.ts. Observability-specific logic delegates to observability-policy-presets.ts.
PRA-16 Resolve/justify architecture agents/langchain-deepagents-code/dcode-launcher.sh:17 Expand comment with explicit link to proxy-launcher test 'recovers only the exact entrypoint observability bit for raw dcode exec' and 'ignores tampered and non-regular observability markers'. File tracking issue for OpenShell env propagation.
PRA-17 Resolve/justify architecture nemoclaw-blueprint/policies/presets/observability-otlp-local.yaml:8 Expand preset comment with structured source-of-truth block: invalid state (DNS rebinding to internal IPs), source boundary (policy preset is host-controlled), why not source fix (gateway IPs vary by host/network), regression test (observability-otlp-policy-preset.test.ts denies alternate hosts/paths), removal condition (OpenShell provides stable gateway IP or DNS-only resolution for host.openshell.internal).
PRA-18 Resolve/justify architecture agents/langchain-deepagents-code/nemoclaw_observability.py:117 Add structured source-of-truth comment at _safe_identifier function with five elements explicitly linking to validate-observability.py tests.
PRA-19 Resolve/justify architecture agents/langchain-deepagents-code/nemoclaw_observability.py:1009 Add structured source-of-truth comment at _new_managed_subscriber with five elements explicitly linking to validate-observability.py _set_validation_environment.
PRA-20 Resolve/justify architecture agents/langchain-deepagents-code/nemoclaw_observability.py:723 Add structured source-of-truth comment at raise_redacted method with five elements. Fix the missing 'from None' (PRA-9) first.

🚨 Required before merge

Address these before merging unless a maintainer explicitly overrides the advisor with rationale.

PRA-8 Required — Broad RFC1918 allowed_ips creates SSRF attack surface

  • Location: nemoclaw-blueprint/policies/presets/observability-otlp-local.yaml:12
  • Category: security
  • Problem: Policy preset allows all RFC1918 private address space (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16) for OTLP export. A compromised agent could exfiltrate traces to any internal host via DNS rebinding or direct IP access. The preset already enforces host.openshell.internal, port 4318, POST /v1/traces, and python3* binary; IP allowlist should be limited to predictable gateway IPs only.
  • Impact: SSRF attack surface allowing trace exfiltration to any internal host on RFC1918 networks, bypassing host/port/method/path/binary restrictions.
  • Required action: Restrict allowed_ips to only predictable gateway IPs (e.g., 172.17.0.1 for default Docker bridge, 10.0.2.2 for common Podman/VM bridges). If broader ranges are operationally required, add structured source-of-truth comment in the preset linking to test/observability-otlp-policy-preset.test.ts which denies alternate hosts/paths and documents why broad CIDRs are required. Evaluate whether OpenShell's SSRF guard can enforce DNS-only resolution for host.openshell.internal.
  • Expected follow-up: Fix before merge or get explicit maintainer override.
  • Verification: Read nemoclaw-blueprint/policies/presets/observability-otlp-local.yaml lines 8-16; check test/observability-otlp-policy-preset.test.ts for denial cases
  • Missing regression test: test/observability-otlp-policy-preset.test.ts already denies alternate hosts/paths — extend to verify allowed_ips CIDR restriction or document operational requirement
  • Done when: The required change is committed and verification passes: Read nemoclaw-blueprint/policies/presets/observability-otlp-local.yaml lines 8-16; check test/observability-otlp-policy-preset.test.ts for denial cases.
  • Evidence: Policy preset lines 12-15: allowed_ips: [10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16]

PRA-9 Required — raise_redacted() missing 'from None' defeats exception redaction boundary

  • Location: agents/langchain-deepagents-code/nemoclaw_observability.py:723
  • Category: security
  • Problem: raise_redacted() raises RuntimeError(_REDACTED_EXCEPTION_MESSAGE) without 'from None', leaving __context__ chain intact. Relay or downstream serializers could traverse __context__ and leak original exception text (which may contain secrets) into OTLP. The comment acknowledges this but the fix is missing.
  • Impact: Original exception text (potentially containing secrets, credentials, or sensitive data) could leak into OTLP traces via __context__ chain traversal.
  • Required action: Change line 723 to: raise RuntimeError(_REDACTED_EXCEPTION_MESSAGE) from None
  • Expected follow-up: Fix before merge or get explicit maintainer override.
  • Verification: grep -n 'raise_redacted' agents/langchain-deepagents-code/nemoclaw_observability.py
  • Missing regression test: validate-observability.py _assert_original_exception verifies exception identity — add assertion that raised redacted exception has no __context__ or __cause__
  • Done when: The required change is committed and verification passes: grep -n 'raise_redacted' agents/langchain-deepagents-code/nemoclaw_observability.py.
  • Evidence: Line 723: raise RuntimeError(_REDACTED_EXCEPTION_MESSAGE) — missing 'from None'

PRA-10 Required — Marker file recovery has TOCTOU race condition

  • Location: agents/langchain-deepagents-code/dcode-launcher.sh:17
  • Category: security
  • Problem: Marker file recovery has TOCTOU race: check [ -f ] && [ ! -L ] && [ $(<file) = 1 ] performs three separate syscalls. An attacker with sandbox filesystem access could swap the marker between checks (symlink swap, content change) to inject NEMOCLAW_OBSERVABILITY=1 without the credential-free marker.
  • Impact: Attacker could inject observability opt-in without valid marker, potentially enabling trace export without host consent.
  • Required action: Use atomic read: read -r val < "$MANAGED_OBSERVABILITY_MARKER" && [ "$val" = "1" ] && export NEMOCLAW_OBSERVABILITY=1. Add source-of-truth comment documenting: invalid state (marker tampering/symlink swap), source boundary (start.sh writes marker), why not fixed upstream (OpenShell cannot propagate entrypoint env), regression test (proxy-launcher tests cover exact values and unsafe file types), removal condition (OpenShell propagates the bit to every exec/login process).
  • Expected follow-up: Fix before merge or get explicit maintainer override.
  • Verification: Read agents/langchain-deepagents-code/dcode-launcher.sh lines 15-22; check test/langchain-deepagents-code-proxy-launcher.test.ts for marker recovery tests
  • Missing regression test: proxy-launcher tests should cover symlink swap and content tampering between stat and read
  • Done when: The required change is committed and verification passes: Read agents/langchain-deepagents-code/dcode-launcher.sh lines 15-22; check test/langchain-deepagents-code-proxy-launcher.test.ts for marker recovery tests.
  • Evidence: Lines 17-22: three separate checks [ -f ] && [ ! -L ] && [ $(<file) = 1 ]

PRA-11 Required — Global os.environ mutation race in _new_managed_subscriber

  • Location: agents/langchain-deepagents-code/nemoclaw_observability.py:1009
  • Category: security
  • Problem: _new_managed_subscriber mutates global os.environ (pops OTEL_* vars, constructs subscriber, restores) without thread safety. Concurrent initialize_observability() calls or other threads reading os.environ during the window will see corrupted environment. _lifecycle_lock only guards _lifecycle state, not os.environ.
  • Impact: Concurrent observability initialization could corrupt ambient OTEL environment for other threads, causing credential leakage or initialization failures.
  • Required action: Use contextvars.ContextVar for ambient OTEL env manipulation, or construct the subscriber in a subprocess/isolated environment. If keeping current approach, document why _lifecycle_lock + try/finally is sufficient (but note _lifecycle_lock only guards _lifecycle state, not os.environ).
  • Expected follow-up: Fix before merge or get explicit maintainer override.
  • Verification: Read agents/langchain-deepagents-code/nemoclaw_observability.py lines 1005-1030; search for other os.environ mutations in the module
  • Missing regression test: Add concurrency test for initialize_observability() with multiple threads racing to verify os.environ isolation
  • Done when: The required change is committed and verification passes: Read agents/langchain-deepagents-code/nemoclaw_observability.py lines 1005-1030; search for other os.environ mutations in the module.
  • Evidence: Lines 1012-1028: os.environ.pop() then restore in try/finally without thread isolation

PRA-12 Required — Test file grew by 457 lines exceeding monolith threshold

  • Location: src/lib/actions/sandbox/snapshot.test.ts:1
  • Category: correctness
  • Problem: Test file grew by 457 lines (1043 -> 1500), exceeding monolith threshold. Contains mixed snapshot create/list/restore/reconcile tests with duplicated setup.
  • Impact: Monolith test file reduces maintainability, slows test execution, and makes focused testing difficult.
  • Required action: Extract snapshot/restore/rebuild test helpers into shared fixtures. Split into create.test.ts, list.test.ts, restore.test.ts, and reconcile.test.ts. Offset growth by removing duplicated setup.
  • Expected follow-up: Fix before merge or get explicit maintainer override.
  • Verification: wc -l src/lib/actions/sandbox/snapshot.test.ts; grep -c 'describe\|it(' src/lib/actions/sandbox/snapshot.test.ts
  • Missing regression test: Shared fixtures in test/helpers/ should cover common snapshot setup; each split file should have focused scope
  • Done when: The required change is committed and verification passes: wc -l src/lib/actions/sandbox/snapshot.test.ts; grep -c 'describe\|it(' src/lib/actions/sandbox/snapshot.test.ts.
  • Evidence: Monolith delta +457 lines (1500 total)

PRA-13 Required — Test file grew by 327 lines exceeding monolith threshold

  • Location: src/lib/onboard/machine/handlers/sandbox.test.ts:1
  • Category: correctness
  • Problem: Test file grew by 327 lines (879 -> 1206), exceeding monolith threshold. Mixes sandbox create, resume, DCode, policy, and observability tests.
  • Impact: Monolith test file reduces maintainability and makes focused testing difficult.
  • Required action: Split sandbox.test.ts by concern: sandbox-create.test.ts, sandbox-resume.test.ts, sandbox-dcode.test.ts, sandbox-policy.test.ts, sandbox-observability.test.ts. Extract shared fixtures to test/helpers/sandbox-onboard-fixtures.ts.
  • Expected follow-up: Fix before merge or get explicit maintainer override.
  • Verification: wc -l src/lib/onboard/machine/handlers/sandbox.test.ts; grep -c 'describe\|it(' src/lib/onboard/machine/handlers/sandbox.test.ts
  • Missing regression test: Each split file should have focused describe blocks; shared fixtures should eliminate duplicate sandbox/createDeps setup
  • Done when: The required change is committed and verification passes: wc -l src/lib/onboard/machine/handlers/sandbox.test.ts; grep -c 'describe\|it(' src/lib/onboard/machine/handlers/sandbox.test.ts.
  • Evidence: Monolith delta +327 lines (1206 total)

PRA-14 Required — Test file grew by 326 lines exceeding monolith threshold

  • Location: src/lib/actions/sandbox/rebuild-restore-phase.test.ts:1
  • Category: correctness
  • Problem: Test file grew by 326 lines (148 -> 474), exceeding monolith threshold. Observability-specific rebuild tests mixed with generic restore tests.
  • Impact: Monolith test file reduces maintainability; observability tests should be separated.
  • Required action: Extract observability-specific rebuild tests into dedicated test file (e.g., rebuild-observability-reconciliation.test.ts). Share common harness setup with existing rebuild tests.
  • Expected follow-up: Fix before merge or get explicit maintainer override.
  • Verification: wc -l src/lib/actions/sandbox/rebuild-restore-phase.test.ts; grep -c 'observability' src/lib/actions/sandbox/rebuild-restore-phase.test.ts
  • Missing regression test: New rebuild-observability-reconciliation.test.ts should import shared harness from test/helpers/rebuild-flow-test-harness.ts
  • Done when: The required change is committed and verification passes: wc -l src/lib/actions/sandbox/rebuild-restore-phase.test.ts; grep -c 'observability' src/lib/actions/sandbox/rebuild-restore-phase.test.ts.
  • Evidence: Monolith delta +326 lines (474 total)

PRA-15 Required — Observability reconciliation logic not extracted from snapshot.ts

  • Location: src/lib/actions/sandbox/snapshot.ts:580
  • Category: correctness
  • Problem: reconcileSnapshotPolicyPresets (200+ lines) and observability reconciliation logic remain in snapshot.ts instead of being extracted to snapshot-policy-reconciliation.ts as previously required. observability-policy-presets.ts exists but reconciliation is not delegated.
  • Impact: Monolith growth in snapshot.ts; reconciliation logic not modularized for reuse or independent testing.
  • Required action: Extract reconcileSnapshotPolicyPresets and reconcileSnapshotCustomPolicies into src/lib/actions/sandbox/snapshot-policy-reconciliation.ts. Observability-specific logic delegates to observability-policy-presets.ts.
  • Expected follow-up: Fix before merge or get explicit maintainer override.
  • Verification: grep -n 'reconcileSnapshotPolicyPresets' src/lib/actions/sandbox/snapshot.ts; find src -name '*snapshot-policy*'
  • Missing regression test: New snapshot-policy-reconciliation.test.ts should cover preset reconciliation independently of snapshot create/restore flow
  • Done when: The required change is committed and verification passes: grep -n 'reconcileSnapshotPolicyPresets' src/lib/actions/sandbox/snapshot.ts; find src -name '*snapshot-policy*'.
  • Evidence: Function at line 580 spans 200+ lines; no snapshot-policy-reconciliation.ts exists
Review findings by urgency: 8 required fixes, 14 items to resolve/justify, 4 in-scope improvements

⚠️ Resolve or justify before merge

Investigate these in the current review; either fix them, explain why they are not applicable, or document the accepted risk.

PRA-1 Resolve/justify — Source-of-truth review needed: _safe_identifier (agents/langchain-deepagents-code/nemoclaw_observability.py:117)

  • Location: not file-specific
  • Category: architecture
  • Problem: The advisor marked localized patch analysis as needs_followup.
  • Impact: A localized workaround can preserve or hide an invalid state when the source boundary is unclear.
  • Recommended action: Identify the invalid state, source boundary, source-fix constraint, regression test, and removal condition before merging the localized behavior.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Inspect the localized patch and source-of-truth review fields for a concrete invalid state, source boundary, source-fix constraint, regression test, and removal condition.
  • Missing regression test: validate-observability.py _safe_names and _assert_capture_traversal_bounds
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Inspect the localized patch and source-of-truth review fields for a concrete invalid state, source boundary, source-fix constraint, regression test, and removal condition.
  • Evidence: Function lacks structured source-of-truth comment; boundary conditions tested in validate-observability.py

PRA-2 Resolve/justify — Source-of-truth review needed: _capture_jsonable (agents/langchain-deepagents-code/nemoclaw_observability.py:216)

  • Location: not file-specific
  • Category: architecture
  • Problem: The advisor marked localized patch analysis as needs_followup.
  • Impact: A localized workaround can preserve or hide an invalid state when the source boundary is unclear.
  • Recommended action: Identify the invalid state, source boundary, source-fix constraint, regression test, and removal condition before merging the localized behavior.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Inspect the localized patch and source-of-truth review fields for a concrete invalid state, source boundary, source-fix constraint, regression test, and removal condition.
  • Missing regression test: _assert_capture_traversal_bounds (shared/cyclic/large)
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Inspect the localized patch and source-of-truth review fields for a concrete invalid state, source boundary, source-fix constraint, regression test, and removal condition.
  • Evidence: Comment at lines 216-218 documents fallback; _assert_capture_traversal_bounds validates

PRA-3 Resolve/justify — Source-of-truth review needed: _safe_object_attribute (agents/langchain-deepagents-code/nemoclaw_observability.py:321)

  • Location: not file-specific
  • Category: architecture
  • Problem: The advisor marked localized patch analysis as needs_followup.
  • Impact: A localized workaround can preserve or hide an invalid state when the source boundary is unclear.
  • Recommended action: Identify the invalid state, source boundary, source-fix constraint, regression test, and removal condition before merging the localized behavior.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Inspect the localized patch and source-of-truth review fields for a concrete invalid state, source boundary, source-fix constraint, regression test, and removal condition.
  • Missing regression test: _bounded_langchain_message uses it for content/name/tool_calls/artifact
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Inspect the localized patch and source-of-truth review fields for a concrete invalid state, source boundary, source-fix constraint, regression test, and removal condition.
  • Evidence: Function at line 321 uses object.__getattribute__; lacks structured source-of-truth comment

PRA-4 Resolve/justify — Source-of-truth review needed: _new_managed_subscriber (agents/langchain-deepagents-code/nemoclaw_observability.py:1009)

  • Location: not file-specific
  • Category: architecture
  • Problem: The advisor marked localized patch analysis as needs_followup.
  • Impact: A localized workaround can preserve or hide an invalid state when the source boundary is unclear.
  • Recommended action: Identify the invalid state, source boundary, source-fix constraint, regression test, and removal condition before merging the localized behavior.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Inspect the localized patch and source-of-truth review fields for a concrete invalid state, source boundary, source-fix constraint, regression test, and removal condition.
  • Missing regression test: _set_validation_environment canary test
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Inspect the localized patch and source-of-truth review fields for a concrete invalid state, source boundary, source-fix constraint, regression test, and removal condition.
  • Evidence: Function at line 1009 mutates os.environ; canary test validates isolation

PRA-5 Resolve/justify — Source-of-truth review needed: raise_redacted (agents/langchain-deepagents-code/nemoclaw_observability.py:723)

  • Location: not file-specific
  • Category: architecture
  • Problem: The advisor marked localized patch analysis as needs_followup.
  • Impact: A localized workaround can preserve or hide an invalid state when the source boundary is unclear.
  • Recommended action: Identify the invalid state, source boundary, source-fix constraint, regression test, and removal condition before merging the localized behavior.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Inspect the localized patch and source-of-truth review fields for a concrete invalid state, source boundary, source-fix constraint, regression test, and removal condition.
  • Missing regression test: _assert_original_exception verifies identity, _EXCEPTION_SECRET absent from OTLP
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Inspect the localized patch and source-of-truth review fields for a concrete invalid state, source boundary, source-fix constraint, regression test, and removal condition.
  • Evidence: Method at line 723 missing 'from None'; lacks structured source-of-truth comment

PRA-6 Resolve/justify — Source-of-truth review needed: dcode-launcher.sh marker recovery (agents/langchain-deepagents-code/dcode-launcher.sh:17)

  • Location: not file-specific
  • Category: architecture
  • Problem: The advisor marked localized patch analysis as needs_followup.
  • Impact: A localized workaround can preserve or hide an invalid state when the source boundary is unclear.
  • Recommended action: Identify the invalid state, source boundary, source-fix constraint, regression test, and removal condition before merging the localized behavior.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Inspect the localized patch and source-of-truth review fields for a concrete invalid state, source boundary, source-fix constraint, regression test, and removal condition.
  • Missing regression test: Proxy-launcher tests: exact value recovery, unsafe file type rejection
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Inspect the localized patch and source-of-truth review fields for a concrete invalid state, source boundary, source-fix constraint, regression test, and removal condition.
  • Evidence: Comment block lines 11-22 has 5 elements but removal condition untracked in issue

PRA-7 Resolve/justify — Source-of-truth review needed: observability-otlp-local.yaml allowed_ips CIDRs (nemoclaw-blueprint/policies/presets/observability-otlp-local.yaml:8)

  • Location: not file-specific
  • Category: architecture
  • Problem: The advisor marked localized patch analysis as needs_followup.
  • Impact: A localized workaround can preserve or hide an invalid state when the source boundary is unclear.
  • Recommended action: Identify the invalid state, source boundary, source-fix constraint, regression test, and removal condition before merging the localized behavior.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Inspect the localized patch and source-of-truth review fields for a concrete invalid state, source boundary, source-fix constraint, regression test, and removal condition.
  • Missing regression test: observability-otlp-policy-preset.test.ts denies alternate hosts/paths
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Inspect the localized patch and source-of-truth review fields for a concrete invalid state, source boundary, source-fix constraint, regression test, and removal condition.
  • Evidence: Comment lines 8-11 mention variance but not specific IPs or removal tracking

PRA-16 Resolve/justify — Marker file recovery workaround needs complete source-of-truth justification

  • Location: agents/langchain-deepagents-code/dcode-launcher.sh:17
  • Category: architecture
  • Problem: Marker file recovery workaround needs complete source-of-truth justification. Comment has 5 elements but removal condition ('OpenShell propagates the bit to every exec/login process') is not tracked in any issue or milestone.
  • Impact: Workaround lacks tracking for removal; removal condition not actionable.
  • Recommended action: Expand comment with explicit link to proxy-launcher test 'recovers only the exact entrypoint observability bit for raw dcode exec' and 'ignores tampered and non-regular observability markers'. File tracking issue for OpenShell env propagation.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Read dcode-launcher.sh lines 11-22; check test/langchain-deepagents-code-proxy-launcher.test.ts for marker recovery test names
  • Missing regression test: Proxy-launcher tests must cover exact value recovery and unsafe file type rejection
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Read dcode-launcher.sh lines 11-22; check test/langchain-deepagents-code-proxy-launcher.test.ts for marker recovery test names.
  • Evidence: Comment block lines 11-22 has 5 elements but removal condition untracked

PRA-17 Resolve/justify — Broad CIDR allowance needs complete source-of-truth justification

  • Location: nemoclaw-blueprint/policies/presets/observability-otlp-local.yaml:8
  • Category: architecture
  • Problem: Broad CIDR allowance needs complete source-of-truth justification. Preset comment mentions 'Docker/Podman bridge gateway addresses vary by host and network' but doesn't specify which IPs are actually needed, why host.openshell.internal DNS resolution isn't sufficient, or track removal condition.
  • Impact: Workaround lacks specificity on required IPs and removal tracking.
  • Recommended action: Expand preset comment with structured source-of-truth block: invalid state (DNS rebinding to internal IPs), source boundary (policy preset is host-controlled), why not source fix (gateway IPs vary by host/network), regression test (observability-otlp-policy-preset.test.ts denies alternate hosts/paths), removal condition (OpenShell provides stable gateway IP or DNS-only resolution for host.openshell.internal).
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Read observability-otlp-local.yaml comment block; check test/observability-otlp-policy-preset.test.ts
  • Missing regression test: Policy preset test should verify allowed_ips matches only required gateway IPs
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Read observability-otlp-local.yaml comment block; check test/observability-otlp-policy-preset.test.ts.
  • Evidence: Comment lines 8-11 mention variance but not specific IPs or removal tracking

PRA-18 Resolve/justify — _safe_identifier function needs source-of-truth justification

  • Location: agents/langchain-deepagents-code/nemoclaw_observability.py:117
  • Category: architecture
  • Problem: _safe_identifier function needs source-of-truth justification. Invalid state: attacker-controlled model/tool/graph names with control chars, overlength, truncation sentinel. Source boundary: Relay/guardrails receive untrusted identifiers. Why not source fix: upstream Relay/LangGraph accept arbitrary strings. Regression test: validate-observability.py _safe_names and _assert_capture_traversal_bounds. Removal condition: Relay enforces identifier bounds natively.
  • Impact: Localized sanitization without documented source-of-truth boundary.
  • Recommended action: Add structured source-of-truth comment at _safe_identifier function with five elements explicitly linking to validate-observability.py tests.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Read nemoclaw_observability.py lines 115-125; check validate-observability.py _safe_names and _assert_capture_traversal_bounds
  • Missing regression test: validate-observability.py already covers boundary conditions — ensure it runs in CI gate
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Read nemoclaw_observability.py lines 115-125; check validate-observability.py _safe_names and _assert_capture_traversal_bounds.
  • Evidence: Function at line 117 lacks structured source-of-truth comment

PRA-19 Resolve/justify — _new_managed_subscriber needs source-of-truth justification for global os.environ mutation

  • Location: agents/langchain-deepagents-code/nemoclaw_observability.py:1009
  • Category: architecture
  • Problem: _new_managed_subscriber needs source-of-truth justification for global os.environ mutation. Invalid state: ambient OTEL_EXPORTER_OTLP_* headers/endpoints with credentials. Source boundary: Relay native exporter reads os.environ directly. Why not source fix: Relay 0.4 architecture; cannot change third-party. Regression test: validate-observability.py _set_validation_environment sets ambient canary, verifies it never reaches OTLP. Removal condition: Relay provides config-only exporter initialization without ambient env fallback.
  • Impact: Global os.environ mutation workaround without documented source-of-truth boundary.
  • Recommended action: Add structured source-of-truth comment at _new_managed_subscriber with five elements explicitly linking to validate-observability.py _set_validation_environment.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Read nemoclaw_observability.py lines 1005-1030; check validate-observability.py _set_validation_environment
  • Missing regression test: validate-observability.py canary test already validates ambient isolation — ensure it runs in CI gate
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Read nemoclaw_observability.py lines 1005-1030; check validate-observability.py _set_validation_environment.
  • Evidence: Function at line 1009 lacks structured source-of-truth comment

PRA-20 Resolve/justify — raise_redacted needs source-of-truth justification

  • Location: agents/langchain-deepagents-code/nemoclaw_observability.py:723
  • Category: architecture
  • Problem: raise_redacted needs source-of-truth justification. Invalid state: Relay callbacks expose exception text in OTLP. Source boundary: Relay middleware wraps handler exceptions. Why not source fix: Relay 0.4 serializes exception context. Regression test: validate-observability.py _assert_original_exception verifies exception identity preserved, _EXCEPTION_SECRET never reaches OTLP. Removal condition: Relay provides exception redaction hook.
  • Impact: Exception redaction workaround without documented source-of-truth boundary.
  • Recommended action: Add structured source-of-truth comment at raise_redacted method with five elements. Fix the missing 'from None' (PRA-9) first.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Read nemoclaw_observability.py lines 720-728; check validate-observability.py _assert_original_exception
  • Missing regression test: validate-observability.py already verifies exception redaction — ensure CI gate runs it
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Read nemoclaw_observability.py lines 720-728; check validate-observability.py _assert_original_exception.
  • Evidence: Method at line 723 lacks structured source-of-truth comment

PRA-21 Resolve/justify — test/policies.test.ts budget still 743 lines over default

  • Location: ci/test-file-size-budget.json:13
  • Category: scope
  • Problem: test/policies.test.ts budget still 2243 lines (legacyMaxLines), 743 lines over default 1500. Previous review noted this; not addressed.
  • Impact: Monolith test file persists without remediation.
  • Recommended action: Split test/policies.test.ts by policy domain or migrate tests to per-preset test files. Reduce legacyMaxLines or extract.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: wc -l test/policies.test.ts; check if any policy tests moved to observability-policy-presets.test.ts
  • Missing regression test: Policy tests should be organized by preset/feature, not monolithic
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: wc -l test/policies.test.ts; check if any policy tests moved to observability-policy-presets.test.ts.
  • Evidence: legacyMaxLines entry shows 2243 lines

PRA-26 Resolve/justify — Policy preset test does not verify allowed_ips CIDR restriction

  • Location: test/observability-otlp-policy-preset.test.ts:40
  • Category: tests
  • Problem: Policy preset test validates denial of alternate hosts/paths but does not verify allowed_ips CIDR restriction. If PRA-8 is fixed (CIDRs narrowed), test must assert the new allowed_ips values.
  • Impact: Fix for PRA-8 would not be regression-tested.
  • Recommended action: Add test case asserting allowed_ips equals the restricted gateway IP set (e.g., ['172.17.0.1', '10.0.2.2']).
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Read test/observability-otlp-policy-preset.test.ts lines 40-60
  • Missing regression test: New test case for allowed_ips exact values
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Read test/observability-otlp-policy-preset.test.ts lines 40-60.
  • Evidence: Test validates denials but not allowed_ips exact values

💡 In-scope improvements

These are lower-risk, not throwaway. Prefer fixing them in this PR when they are local to changed code; defer only with rationale or a linked follow-up.

PRA-22 Improvement — MetadataOnlyCallbackManager single-use abstraction could be inlined

  • Location: agents/langchain-deepagents-code/nemoclaw_observability.py:583
  • Category: correctness
  • Problem: MetadataOnlyCallbackManager is single-use abstraction (only instantiated once in new_metadata_only_callback_manager). Could be inlined to reduce indirection.
  • Impact: Unnecessary abstraction layer adds cognitive overhead.
  • Suggested action: Inline MetadataOnlyCallbackManager class directly in new_metadata_only_callback_manager, or justify why the abstraction boundary is needed.
  • Expected follow-up: Prefer a current-PR fix when local to changed code; defer only with rationale or linked follow-up.
  • Verification: grep -n 'MetadataOnlyCallbackManager' agents/langchain-deepagents-code/nemoclaw_observability.py
  • Missing regression test: None — refactor only
  • Done when: The local improvement is applied, or the PR notes why it should be deferred.
  • Evidence: Class defined at line 583, instantiated only at line 663

PRA-23 Improvement — Expected OTLP request count is undocumented magic number

  • Location: agents/langchain-deepagents-code/validate-observability.py:43
  • Category: correctness
  • Problem: Expected 13 OTLP requests (_EXPECTED_REQUEST_COUNT = 13) is an undocumented magic number. Test will break on legitimate observability changes without clear signal.
  • Impact: Maintenance burden when observability behavior changes legitimately.
  • Suggested action: Document why exactly 13 requests are expected (model calls × N + tool calls × M + graph events × K) or derive from test structure.
  • Expected follow-up: Prefer a current-PR fix when local to changed code; defer only with rationale or linked follow-up.
  • Verification: Read validate-observability.py line 43; count exercise_* function calls in main()
  • Missing regression test: None — documentation only
  • Done when: The local improvement is applied, or the PR notes why it should be deferred.
  • Evidence: Line 43: _EXPECTED_REQUEST_COUNT = 13 with no breakdown comment

PRA-24 Improvement — deepagents-observability-harness.py duplicates validate-observability.py logic

  • Location: test/fixtures/deepagents-observability-harness.py:1
  • Category: correctness
  • Problem: deepagents-observability-harness.py (1258 lines) duplicates validate-observability.py logic for E2E harness. Two copies of capture/boundary logic to maintain.
  • Impact: Duplicated logic increases maintenance burden and divergence risk.
  • Suggested action: Extract shared capture/boundary logic to a common module imported by both validate-observability.py and the E2E harness, or justify why E2E needs separate copy.
  • Expected follow-up: Prefer a current-PR fix when local to changed code; defer only with rationale or linked follow-up.
  • Verification: diff agents/langchain-deepagents-code/validate-observability.py test/fixtures/deepagents-observability-harness.py | head -100
  • Missing regression test: Shared module should have its own unit tests
  • Done when: The local improvement is applied, or the PR notes why it should be deferred.
  • Evidence: 1258-line test fixture duplicates capture/boundary/validation logic

PRA-25 Improvement — E2E observability validation lacks fast unit gate in CI

  • Location: test/langchain-deepagents-code-observability.test.ts:1
  • Category: correctness
  • Problem: New E2E test file (296 lines) for observability contract but no fast unit gate in CI. validate-observability.py runs at Docker build time only; no Vitest unit test exercises the observability initialization path.
  • Impact: No fast feedback for observability initialization regressions in CI.
  • Suggested action: Add Vitest unit test for initialize_observability() happy path and failure modes, running in CI without Docker. Keep E2E for wire-format validation.
  • Expected follow-up: Prefer a current-PR fix when local to changed code; defer only with rationale or linked follow-up.
  • Verification: Check .github/workflows for validate-observability.py execution; search for unit tests calling initialize_observability
  • Missing regression test: Add unit test in src/lib/onboard/ or test/ for observability initialization without Docker
  • Done when: The local improvement is applied, or the PR notes why it should be deferred.
  • Evidence: No Vitest unit test for initialize_observability; only Docker build-time validation
Simplification opportunities: 2 possible cuts, net -877 lines possible

These are safe simplification checks only. Do not remove validation, security controls, data-loss prevention, or required tests.

  • PRA-22 yagni (agents/langchain-deepagents-code/nemoclaw_observability.py:583): class MetadataOnlyCallbackManager(CallbackManager): ... (lines 583-660)
    • Replacement: Inline the class body directly in new_metadata_only_callback_manager() return statement
    • Net: -77 lines
    • Safety boundary: Must preserve exact CallbackManager subclass behavior: locked handler set, copy/merge semantics, handler rejection methods
  • PRA-24 shrink (test/fixtures/deepagents-observability-harness.py:1): test/fixtures/deepagents-observability-harness.py (1258 lines) and agents/langchain-deepagents-code/validate-observability.py (930 lines) — shared logic
    • Replacement: Create shared module (e.g., nemoclaw_observability_validation.py) with _CaptureBudget, _bounded_capture, _safe_identifier, _redact_capture_key, _assert_capture_traversal_bounds, _safe_names; both files import it
    • Net: -800 lines
    • Safety boundary: Must not weaken capture bounds, redaction, or identifier sanitization; both validation paths must remain functionally identical
Test follow-ups to resolve or justify

If these cover changed behavior, prefer adding them in this PR; otherwise state why existing coverage is enough or link the follow-up.

  • PRA-T1 Runtime validation — Concurrency test for initialize_observability() with multiple threads racing to verify os.environ isolation. Runtime/sandbox/infrastructure paths need behavioral runtime validation: Dockerfile, dcode-launcher.sh, nemoclaw_observability.py, patch-managed-deepagents-code.py, start.sh, requirements. validate-observability.py runs at build time only; no fast unit gate for initialize_observability(). Concurrent initialization untested. Marker file TOCTOU untested. allowed_ips restriction untested.
  • PRA-T2 Runtime validation — raise_redacted __context__ absence test: assert raised exception has __context__ is None and __cause__ is None. Runtime/sandbox/infrastructure paths need behavioral runtime validation: Dockerfile, dcode-launcher.sh, nemoclaw_observability.py, patch-managed-deepagents-code.py, start.sh, requirements. validate-observability.py runs at build time only; no fast unit gate for initialize_observability(). Concurrent initialization untested. Marker file TOCTOU untested. allowed_ips restriction untested.
  • PRA-T3 Runtime validation — Marker file TOCTOU test: symlink swap between -f check and read; content tampering. Runtime/sandbox/infrastructure paths need behavioral runtime validation: Dockerfile, dcode-launcher.sh, nemoclaw_observability.py, patch-managed-deepagents-code.py, start.sh, requirements. validate-observability.py runs at build time only; no fast unit gate for initialize_observability(). Concurrent initialization untested. Marker file TOCTOU untested. allowed_ips restriction untested.
  • PRA-T4 Runtime validation — allowed_ips CIDR restriction test: policy preset test asserts exact gateway IPs if PRA-8 fixed. Runtime/sandbox/infrastructure paths need behavioral runtime validation: Dockerfile, dcode-launcher.sh, nemoclaw_observability.py, patch-managed-deepagents-code.py, start.sh, requirements. validate-observability.py runs at build time only; no fast unit gate for initialize_observability(). Concurrent initialization untested. Marker file TOCTOU untested. allowed_ips restriction untested.
  • PRA-T5 Runtime validation — Observability initialization unit test (no Docker): initialize_observability() happy path + failure modes (missing nemo-relay, bad endpoint). Runtime/sandbox/infrastructure paths need behavioral runtime validation: Dockerfile, dcode-launcher.sh, nemoclaw_observability.py, patch-managed-deepagents-code.py, start.sh, requirements. validate-observability.py runs at build time only; no fast unit gate for initialize_observability(). Concurrent initialization untested. Marker file TOCTOU untested. allowed_ips restriction untested.
  • PRA-T6 Policy preset test does not verify allowed_ips CIDR restriction — Add test case asserting allowed_ips equals the restricted gateway IP set (e.g., ['172.17.0.1', '10.0.2.2']).
  • PRA-T7 Acceptance clause — Redact credential/control-plane fields; omit headers/settings/schemas/metadata/checkpoint/interrupt/exception text; preserve agent results + exception identity — add test evidence or identify existing coverage. Redaction: _redact_capture_key, _bounded_capture, _safe_identifier — but raise_redacted() missing from None (PRA-9); Exception identity: _RelayExceptionBoundary preserves __traceback__ and __cause__ — validated by validate-observability.py _assert_original_exception
  • PRA-T8 Acceptance clause — OTLP only to host.openshell.internal:4318/v1/traces, no custom/exporter/auth headers; ignore ambient OTEL; fail open — add test evidence or identify existing coverage. Endpoint hardcoded _OTLP_ENDPOINT; config.headers = {}; _new_managed_subscriber clears ambient OTEL_* — but race in os.environ mutation (PRA-11); Policy preset enforces host/port/method/path/binary — but broad allowed_ips (PRA-8)
Since last review details

Current findings, using the urgency labels above:

PRA-1 Resolve/justify — Source-of-truth review needed: _safe_identifier (agents/langchain-deepagents-code/nemoclaw_observability.py:117)

  • Location: not file-specific
  • Category: architecture
  • Problem: The advisor marked localized patch analysis as needs_followup.
  • Impact: A localized workaround can preserve or hide an invalid state when the source boundary is unclear.
  • Recommended action: Identify the invalid state, source boundary, source-fix constraint, regression test, and removal condition before merging the localized behavior.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Inspect the localized patch and source-of-truth review fields for a concrete invalid state, source boundary, source-fix constraint, regression test, and removal condition.
  • Missing regression test: validate-observability.py _safe_names and _assert_capture_traversal_bounds
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Inspect the localized patch and source-of-truth review fields for a concrete invalid state, source boundary, source-fix constraint, regression test, and removal condition.
  • Evidence: Function lacks structured source-of-truth comment; boundary conditions tested in validate-observability.py

PRA-2 Resolve/justify — Source-of-truth review needed: _capture_jsonable (agents/langchain-deepagents-code/nemoclaw_observability.py:216)

  • Location: not file-specific
  • Category: architecture
  • Problem: The advisor marked localized patch analysis as needs_followup.
  • Impact: A localized workaround can preserve or hide an invalid state when the source boundary is unclear.
  • Recommended action: Identify the invalid state, source boundary, source-fix constraint, regression test, and removal condition before merging the localized behavior.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Inspect the localized patch and source-of-truth review fields for a concrete invalid state, source boundary, source-fix constraint, regression test, and removal condition.
  • Missing regression test: _assert_capture_traversal_bounds (shared/cyclic/large)
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Inspect the localized patch and source-of-truth review fields for a concrete invalid state, source boundary, source-fix constraint, regression test, and removal condition.
  • Evidence: Comment at lines 216-218 documents fallback; _assert_capture_traversal_bounds validates

PRA-3 Resolve/justify — Source-of-truth review needed: _safe_object_attribute (agents/langchain-deepagents-code/nemoclaw_observability.py:321)

  • Location: not file-specific
  • Category: architecture
  • Problem: The advisor marked localized patch analysis as needs_followup.
  • Impact: A localized workaround can preserve or hide an invalid state when the source boundary is unclear.
  • Recommended action: Identify the invalid state, source boundary, source-fix constraint, regression test, and removal condition before merging the localized behavior.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Inspect the localized patch and source-of-truth review fields for a concrete invalid state, source boundary, source-fix constraint, regression test, and removal condition.
  • Missing regression test: _bounded_langchain_message uses it for content/name/tool_calls/artifact
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Inspect the localized patch and source-of-truth review fields for a concrete invalid state, source boundary, source-fix constraint, regression test, and removal condition.
  • Evidence: Function at line 321 uses object.__getattribute__; lacks structured source-of-truth comment

PRA-4 Resolve/justify — Source-of-truth review needed: _new_managed_subscriber (agents/langchain-deepagents-code/nemoclaw_observability.py:1009)

  • Location: not file-specific
  • Category: architecture
  • Problem: The advisor marked localized patch analysis as needs_followup.
  • Impact: A localized workaround can preserve or hide an invalid state when the source boundary is unclear.
  • Recommended action: Identify the invalid state, source boundary, source-fix constraint, regression test, and removal condition before merging the localized behavior.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Inspect the localized patch and source-of-truth review fields for a concrete invalid state, source boundary, source-fix constraint, regression test, and removal condition.
  • Missing regression test: _set_validation_environment canary test
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Inspect the localized patch and source-of-truth review fields for a concrete invalid state, source boundary, source-fix constraint, regression test, and removal condition.
  • Evidence: Function at line 1009 mutates os.environ; canary test validates isolation

PRA-5 Resolve/justify — Source-of-truth review needed: raise_redacted (agents/langchain-deepagents-code/nemoclaw_observability.py:723)

  • Location: not file-specific
  • Category: architecture
  • Problem: The advisor marked localized patch analysis as needs_followup.
  • Impact: A localized workaround can preserve or hide an invalid state when the source boundary is unclear.
  • Recommended action: Identify the invalid state, source boundary, source-fix constraint, regression test, and removal condition before merging the localized behavior.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Inspect the localized patch and source-of-truth review fields for a concrete invalid state, source boundary, source-fix constraint, regression test, and removal condition.
  • Missing regression test: _assert_original_exception verifies identity, _EXCEPTION_SECRET absent from OTLP
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Inspect the localized patch and source-of-truth review fields for a concrete invalid state, source boundary, source-fix constraint, regression test, and removal condition.
  • Evidence: Method at line 723 missing 'from None'; lacks structured source-of-truth comment

PRA-6 Resolve/justify — Source-of-truth review needed: dcode-launcher.sh marker recovery (agents/langchain-deepagents-code/dcode-launcher.sh:17)

  • Location: not file-specific
  • Category: architecture
  • Problem: The advisor marked localized patch analysis as needs_followup.
  • Impact: A localized workaround can preserve or hide an invalid state when the source boundary is unclear.
  • Recommended action: Identify the invalid state, source boundary, source-fix constraint, regression test, and removal condition before merging the localized behavior.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Inspect the localized patch and source-of-truth review fields for a concrete invalid state, source boundary, source-fix constraint, regression test, and removal condition.
  • Missing regression test: Proxy-launcher tests: exact value recovery, unsafe file type rejection
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Inspect the localized patch and source-of-truth review fields for a concrete invalid state, source boundary, source-fix constraint, regression test, and removal condition.
  • Evidence: Comment block lines 11-22 has 5 elements but removal condition untracked in issue

PRA-7 Resolve/justify — Source-of-truth review needed: observability-otlp-local.yaml allowed_ips CIDRs (nemoclaw-blueprint/policies/presets/observability-otlp-local.yaml:8)

  • Location: not file-specific
  • Category: architecture
  • Problem: The advisor marked localized patch analysis as needs_followup.
  • Impact: A localized workaround can preserve or hide an invalid state when the source boundary is unclear.
  • Recommended action: Identify the invalid state, source boundary, source-fix constraint, regression test, and removal condition before merging the localized behavior.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Inspect the localized patch and source-of-truth review fields for a concrete invalid state, source boundary, source-fix constraint, regression test, and removal condition.
  • Missing regression test: observability-otlp-policy-preset.test.ts denies alternate hosts/paths
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Inspect the localized patch and source-of-truth review fields for a concrete invalid state, source boundary, source-fix constraint, regression test, and removal condition.
  • Evidence: Comment lines 8-11 mention variance but not specific IPs or removal tracking

PRA-8 Required — Broad RFC1918 allowed_ips creates SSRF attack surface

  • Location: nemoclaw-blueprint/policies/presets/observability-otlp-local.yaml:12
  • Category: security
  • Problem: Policy preset allows all RFC1918 private address space (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16) for OTLP export. A compromised agent could exfiltrate traces to any internal host via DNS rebinding or direct IP access. The preset already enforces host.openshell.internal, port 4318, POST /v1/traces, and python3* binary; IP allowlist should be limited to predictable gateway IPs only.
  • Impact: SSRF attack surface allowing trace exfiltration to any internal host on RFC1918 networks, bypassing host/port/method/path/binary restrictions.
  • Required action: Restrict allowed_ips to only predictable gateway IPs (e.g., 172.17.0.1 for default Docker bridge, 10.0.2.2 for common Podman/VM bridges). If broader ranges are operationally required, add structured source-of-truth comment in the preset linking to test/observability-otlp-policy-preset.test.ts which denies alternate hosts/paths and documents why broad CIDRs are required. Evaluate whether OpenShell's SSRF guard can enforce DNS-only resolution for host.openshell.internal.
  • Expected follow-up: Fix before merge or get explicit maintainer override.
  • Verification: Read nemoclaw-blueprint/policies/presets/observability-otlp-local.yaml lines 8-16; check test/observability-otlp-policy-preset.test.ts for denial cases
  • Missing regression test: test/observability-otlp-policy-preset.test.ts already denies alternate hosts/paths — extend to verify allowed_ips CIDR restriction or document operational requirement
  • Done when: The required change is committed and verification passes: Read nemoclaw-blueprint/policies/presets/observability-otlp-local.yaml lines 8-16; check test/observability-otlp-policy-preset.test.ts for denial cases.
  • Evidence: Policy preset lines 12-15: allowed_ips: [10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16]

PRA-9 Required — raise_redacted() missing 'from None' defeats exception redaction boundary

  • Location: agents/langchain-deepagents-code/nemoclaw_observability.py:723
  • Category: security
  • Problem: raise_redacted() raises RuntimeError(_REDACTED_EXCEPTION_MESSAGE) without 'from None', leaving __context__ chain intact. Relay or downstream serializers could traverse __context__ and leak original exception text (which may contain secrets) into OTLP. The comment acknowledges this but the fix is missing.
  • Impact: Original exception text (potentially containing secrets, credentials, or sensitive data) could leak into OTLP traces via __context__ chain traversal.
  • Required action: Change line 723 to: raise RuntimeError(_REDACTED_EXCEPTION_MESSAGE) from None
  • Expected follow-up: Fix before merge or get explicit maintainer override.
  • Verification: grep -n 'raise_redacted' agents/langchain-deepagents-code/nemoclaw_observability.py
  • Missing regression test: validate-observability.py _assert_original_exception verifies exception identity — add assertion that raised redacted exception has no __context__ or __cause__
  • Done when: The required change is committed and verification passes: grep -n 'raise_redacted' agents/langchain-deepagents-code/nemoclaw_observability.py.
  • Evidence: Line 723: raise RuntimeError(_REDACTED_EXCEPTION_MESSAGE) — missing 'from None'

PRA-10 Required — Marker file recovery has TOCTOU race condition

  • Location: agents/langchain-deepagents-code/dcode-launcher.sh:17
  • Category: security
  • Problem: Marker file recovery has TOCTOU race: check [ -f ] && [ ! -L ] && [ $(<file) = 1 ] performs three separate syscalls. An attacker with sandbox filesystem access could swap the marker between checks (symlink swap, content change) to inject NEMOCLAW_OBSERVABILITY=1 without the credential-free marker.
  • Impact: Attacker could inject observability opt-in without valid marker, potentially enabling trace export without host consent.
  • Required action: Use atomic read: read -r val < "$MANAGED_OBSERVABILITY_MARKER" && [ "$val" = "1" ] && export NEMOCLAW_OBSERVABILITY=1. Add source-of-truth comment documenting: invalid state (marker tampering/symlink swap), source boundary (start.sh writes marker), why not fixed upstream (OpenShell cannot propagate entrypoint env), regression test (proxy-launcher tests cover exact values and unsafe file types), removal condition (OpenShell propagates the bit to every exec/login process).
  • Expected follow-up: Fix before merge or get explicit maintainer override.
  • Verification: Read agents/langchain-deepagents-code/dcode-launcher.sh lines 15-22; check test/langchain-deepagents-code-proxy-launcher.test.ts for marker recovery tests
  • Missing regression test: proxy-launcher tests should cover symlink swap and content tampering between stat and read
  • Done when: The required change is committed and verification passes: Read agents/langchain-deepagents-code/dcode-launcher.sh lines 15-22; check test/langchain-deepagents-code-proxy-launcher.test.ts for marker recovery tests.
  • Evidence: Lines 17-22: three separate checks [ -f ] && [ ! -L ] && [ $(<file) = 1 ]

PRA-11 Required — Global os.environ mutation race in _new_managed_subscriber

  • Location: agents/langchain-deepagents-code/nemoclaw_observability.py:1009
  • Category: security
  • Problem: _new_managed_subscriber mutates global os.environ (pops OTEL_* vars, constructs subscriber, restores) without thread safety. Concurrent initialize_observability() calls or other threads reading os.environ during the window will see corrupted environment. _lifecycle_lock only guards _lifecycle state, not os.environ.
  • Impact: Concurrent observability initialization could corrupt ambient OTEL environment for other threads, causing credential leakage or initialization failures.
  • Required action: Use contextvars.ContextVar for ambient OTEL env manipulation, or construct the subscriber in a subprocess/isolated environment. If keeping current approach, document why _lifecycle_lock + try/finally is sufficient (but note _lifecycle_lock only guards _lifecycle state, not os.environ).
  • Expected follow-up: Fix before merge or get explicit maintainer override.
  • Verification: Read agents/langchain-deepagents-code/nemoclaw_observability.py lines 1005-1030; search for other os.environ mutations in the module
  • Missing regression test: Add concurrency test for initialize_observability() with multiple threads racing to verify os.environ isolation
  • Done when: The required change is committed and verification passes: Read agents/langchain-deepagents-code/nemoclaw_observability.py lines 1005-1030; search for other os.environ mutations in the module.
  • Evidence: Lines 1012-1028: os.environ.pop() then restore in try/finally without thread isolation

PRA-12 Required — Test file grew by 457 lines exceeding monolith threshold

  • Location: src/lib/actions/sandbox/snapshot.test.ts:1
  • Category: correctness
  • Problem: Test file grew by 457 lines (1043 -> 1500), exceeding monolith threshold. Contains mixed snapshot create/list/restore/reconcile tests with duplicated setup.
  • Impact: Monolith test file reduces maintainability, slows test execution, and makes focused testing difficult.
  • Required action: Extract snapshot/restore/rebuild test helpers into shared fixtures. Split into create.test.ts, list.test.ts, restore.test.ts, and reconcile.test.ts. Offset growth by removing duplicated setup.
  • Expected follow-up: Fix before merge or get explicit maintainer override.
  • Verification: wc -l src/lib/actions/sandbox/snapshot.test.ts; grep -c 'describe\|it(' src/lib/actions/sandbox/snapshot.test.ts
  • Missing regression test: Shared fixtures in test/helpers/ should cover common snapshot setup; each split file should have focused scope
  • Done when: The required change is committed and verification passes: wc -l src/lib/actions/sandbox/snapshot.test.ts; grep -c 'describe\|it(' src/lib/actions/sandbox/snapshot.test.ts.
  • Evidence: Monolith delta +457 lines (1500 total)

PRA-13 Required — Test file grew by 327 lines exceeding monolith threshold

  • Location: src/lib/onboard/machine/handlers/sandbox.test.ts:1
  • Category: correctness
  • Problem: Test file grew by 327 lines (879 -> 1206), exceeding monolith threshold. Mixes sandbox create, resume, DCode, policy, and observability tests.
  • Impact: Monolith test file reduces maintainability and makes focused testing difficult.
  • Required action: Split sandbox.test.ts by concern: sandbox-create.test.ts, sandbox-resume.test.ts, sandbox-dcode.test.ts, sandbox-policy.test.ts, sandbox-observability.test.ts. Extract shared fixtures to test/helpers/sandbox-onboard-fixtures.ts.
  • Expected follow-up: Fix before merge or get explicit maintainer override.
  • Verification: wc -l src/lib/onboard/machine/handlers/sandbox.test.ts; grep -c 'describe\|it(' src/lib/onboard/machine/handlers/sandbox.test.ts
  • Missing regression test: Each split file should have focused describe blocks; shared fixtures should eliminate duplicate sandbox/createDeps setup
  • Done when: The required change is committed and verification passes: wc -l src/lib/onboard/machine/handlers/sandbox.test.ts; grep -c 'describe\|it(' src/lib/onboard/machine/handlers/sandbox.test.ts.
  • Evidence: Monolith delta +327 lines (1206 total)

PRA-14 Required — Test file grew by 326 lines exceeding monolith threshold

  • Location: src/lib/actions/sandbox/rebuild-restore-phase.test.ts:1
  • Category: correctness
  • Problem: Test file grew by 326 lines (148 -> 474), exceeding monolith threshold. Observability-specific rebuild tests mixed with generic restore tests.
  • Impact: Monolith test file reduces maintainability; observability tests should be separated.
  • Required action: Extract observability-specific rebuild tests into dedicated test file (e.g., rebuild-observability-reconciliation.test.ts). Share common harness setup with existing rebuild tests.
  • Expected follow-up: Fix before merge or get explicit maintainer override.
  • Verification: wc -l src/lib/actions/sandbox/rebuild-restore-phase.test.ts; grep -c 'observability' src/lib/actions/sandbox/rebuild-restore-phase.test.ts
  • Missing regression test: New rebuild-observability-reconciliation.test.ts should import shared harness from test/helpers/rebuild-flow-test-harness.ts
  • Done when: The required change is committed and verification passes: wc -l src/lib/actions/sandbox/rebuild-restore-phase.test.ts; grep -c 'observability' src/lib/actions/sandbox/rebuild-restore-phase.test.ts.
  • Evidence: Monolith delta +326 lines (474 total)

PRA-15 Required — Observability reconciliation logic not extracted from snapshot.ts

  • Location: src/lib/actions/sandbox/snapshot.ts:580
  • Category: correctness
  • Problem: reconcileSnapshotPolicyPresets (200+ lines) and observability reconciliation logic remain in snapshot.ts instead of being extracted to snapshot-policy-reconciliation.ts as previously required. observability-policy-presets.ts exists but reconciliation is not delegated.
  • Impact: Monolith growth in snapshot.ts; reconciliation logic not modularized for reuse or independent testing.
  • Required action: Extract reconcileSnapshotPolicyPresets and reconcileSnapshotCustomPolicies into src/lib/actions/sandbox/snapshot-policy-reconciliation.ts. Observability-specific logic delegates to observability-policy-presets.ts.
  • Expected follow-up: Fix before merge or get explicit maintainer override.
  • Verification: grep -n 'reconcileSnapshotPolicyPresets' src/lib/actions/sandbox/snapshot.ts; find src -name '*snapshot-policy*'
  • Missing regression test: New snapshot-policy-reconciliation.test.ts should cover preset reconciliation independently of snapshot create/restore flow
  • Done when: The required change is committed and verification passes: grep -n 'reconcileSnapshotPolicyPresets' src/lib/actions/sandbox/snapshot.ts; find src -name '*snapshot-policy*'.
  • Evidence: Function at line 580 spans 200+ lines; no snapshot-policy-reconciliation.ts exists

PRA-16 Resolve/justify — Marker file recovery workaround needs complete source-of-truth justification

  • Location: agents/langchain-deepagents-code/dcode-launcher.sh:17
  • Category: architecture
  • Problem: Marker file recovery workaround needs complete source-of-truth justification. Comment has 5 elements but removal condition ('OpenShell propagates the bit to every exec/login process') is not tracked in any issue or milestone.
  • Impact: Workaround lacks tracking for removal; removal condition not actionable.
  • Recommended action: Expand comment with explicit link to proxy-launcher test 'recovers only the exact entrypoint observability bit for raw dcode exec' and 'ignores tampered and non-regular observability markers'. File tracking issue for OpenShell env propagation.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Read dcode-launcher.sh lines 11-22; check test/langchain-deepagents-code-proxy-launcher.test.ts for marker recovery test names
  • Missing regression test: Proxy-launcher tests must cover exact value recovery and unsafe file type rejection
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Read dcode-launcher.sh lines 11-22; check test/langchain-deepagents-code-proxy-launcher.test.ts for marker recovery test names.
  • Evidence: Comment block lines 11-22 has 5 elements but removal condition untracked

PRA-17 Resolve/justify — Broad CIDR allowance needs complete source-of-truth justification

  • Location: nemoclaw-blueprint/policies/presets/observability-otlp-local.yaml:8
  • Category: architecture
  • Problem: Broad CIDR allowance needs complete source-of-truth justification. Preset comment mentions 'Docker/Podman bridge gateway addresses vary by host and network' but doesn't specify which IPs are actually needed, why host.openshell.internal DNS resolution isn't sufficient, or track removal condition.
  • Impact: Workaround lacks specificity on required IPs and removal tracking.
  • Recommended action: Expand preset comment with structured source-of-truth block: invalid state (DNS rebinding to internal IPs), source boundary (policy preset is host-controlled), why not source fix (gateway IPs vary by host/network), regression test (observability-otlp-policy-preset.test.ts denies alternate hosts/paths), removal condition (OpenShell provides stable gateway IP or DNS-only resolution for host.openshell.internal).
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Read observability-otlp-local.yaml comment block; check test/observability-otlp-policy-preset.test.ts
  • Missing regression test: Policy preset test should verify allowed_ips matches only required gateway IPs
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Read observability-otlp-local.yaml comment block; check test/observability-otlp-policy-preset.test.ts.
  • Evidence: Comment lines 8-11 mention variance but not specific IPs or removal tracking

PRA-18 Resolve/justify — _safe_identifier function needs source-of-truth justification

  • Location: agents/langchain-deepagents-code/nemoclaw_observability.py:117
  • Category: architecture
  • Problem: _safe_identifier function needs source-of-truth justification. Invalid state: attacker-controlled model/tool/graph names with control chars, overlength, truncation sentinel. Source boundary: Relay/guardrails receive untrusted identifiers. Why not source fix: upstream Relay/LangGraph accept arbitrary strings. Regression test: validate-observability.py _safe_names and _assert_capture_traversal_bounds. Removal condition: Relay enforces identifier bounds natively.
  • Impact: Localized sanitization without documented source-of-truth boundary.
  • Recommended action: Add structured source-of-truth comment at _safe_identifier function with five elements explicitly linking to validate-observability.py tests.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Read nemoclaw_observability.py lines 115-125; check validate-observability.py _safe_names and _assert_capture_traversal_bounds
  • Missing regression test: validate-observability.py already covers boundary conditions — ensure it runs in CI gate
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Read nemoclaw_observability.py lines 115-125; check validate-observability.py _safe_names and _assert_capture_traversal_bounds.
  • Evidence: Function at line 117 lacks structured source-of-truth comment

PRA-19 Resolve/justify — _new_managed_subscriber needs source-of-truth justification for global os.environ mutation

  • Location: agents/langchain-deepagents-code/nemoclaw_observability.py:1009
  • Category: architecture
  • Problem: _new_managed_subscriber needs source-of-truth justification for global os.environ mutation. Invalid state: ambient OTEL_EXPORTER_OTLP_* headers/endpoints with credentials. Source boundary: Relay native exporter reads os.environ directly. Why not source fix: Relay 0.4 architecture; cannot change third-party. Regression test: validate-observability.py _set_validation_environment sets ambient canary, verifies it never reaches OTLP. Removal condition: Relay provides config-only exporter initialization without ambient env fallback.
  • Impact: Global os.environ mutation workaround without documented source-of-truth boundary.
  • Recommended action: Add structured source-of-truth comment at _new_managed_subscriber with five elements explicitly linking to validate-observability.py _set_validation_environment.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Read nemoclaw_observability.py lines 1005-1030; check validate-observability.py _set_validation_environment
  • Missing regression test: validate-observability.py canary test already validates ambient isolation — ensure it runs in CI gate
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Read nemoclaw_observability.py lines 1005-1030; check validate-observability.py _set_validation_environment.
  • Evidence: Function at line 1009 lacks structured source-of-truth comment

PRA-20 Resolve/justify — raise_redacted needs source-of-truth justification

  • Location: agents/langchain-deepagents-code/nemoclaw_observability.py:723
  • Category: architecture
  • Problem: raise_redacted needs source-of-truth justification. Invalid state: Relay callbacks expose exception text in OTLP. Source boundary: Relay middleware wraps handler exceptions. Why not source fix: Relay 0.4 serializes exception context. Regression test: validate-observability.py _assert_original_exception verifies exception identity preserved, _EXCEPTION_SECRET never reaches OTLP. Removal condition: Relay provides exception redaction hook.
  • Impact: Exception redaction workaround without documented source-of-truth boundary.
  • Recommended action: Add structured source-of-truth comment at raise_redacted method with five elements. Fix the missing 'from None' (PRA-9) first.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Read nemoclaw_observability.py lines 720-728; check validate-observability.py _assert_original_exception
  • Missing regression test: validate-observability.py already verifies exception redaction — ensure CI gate runs it
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Read nemoclaw_observability.py lines 720-728; check validate-observability.py _assert_original_exception.
  • Evidence: Method at line 723 lacks structured source-of-truth comment

Workflow run details

This is an automated, non-binding review; it still expects maintainers and agents to respond to each required or warning item. Treat suggestions as current-PR improvements when they touch changed code; defer only with maintainer rationale or a linked follow-up. A human maintainer must make the final merge decision.

@github-actions

github-actions Bot commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

E2E Target Results — ✅ All requested jobs passed

Run: 28821842214
Workflow ref: codex/dcode-backend-neutral-observability
Requested targets: (default — all supported)
Requested jobs: network-policy
Summary: 1 passed, 0 failed, 0 cancelled, 0 skipped

Job Result
network-policy ✅ success

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🧹 Nitpick comments (3)
src/lib/actions/sandbox/rebuild-recreate-phase.ts (1)

68-256: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

No dedicated test coverage included for this file's observability propagation.

Unlike the sibling changes in this cohort (onboard-session.test.ts, resume-config.test.ts, sandbox-registration.test.ts), no test exercises runRebuildRecreatePhase's new observabilityEnabled propagation into the rebuilt session. As per path instructions, destructive sandbox lifecycle operations should "cover failure, recovery, rebuild, and resume behavior."

Do you want me to draft a test asserting the recreated session's observabilityEnabled matches recreateOptions.observabilityEnabled across the success and onboardFailed rollback paths?

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

In `@src/lib/actions/sandbox/rebuild-recreate-phase.ts` around lines 68 - 256, Add
dedicated coverage for runRebuildRecreatePhase to verify observabilityEnabled is
propagated from recreateOptions.observabilityEnabled into the rebuilt session
via onboardSession.updateSession/createSession, and that this value remains
correct through both the success path and the onboardFailed recovery path. Use
the runRebuildRecreatePhase function and the onboardSession session update logic
as anchors when adding the test cases.

Source: Path instructions

agents/langchain-deepagents-code/patch-managed-deepagents-code.py (1)

1018-1044: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Duplicate module-install/validate logic; extract a shared helper.

The observability module install/validate block (Lines 1018-1044) is a near-verbatim duplicate of the middleware install/validate block at Lines 1000-1017, differing only by variable names and error text. Extracting a small _install_managed_module(name, root)-style helper would remove the duplication and keep future modules (there may be more) consistent by construction.

♻️ Proposed helper extraction
+def _install_module(module_name: str, root: Path) -> tuple[Path, str]:
+    source_path = Path(__file__).with_name(module_name)
+    destination_path = root / module_name
+    if not source_path.is_file():
+        raise RuntimeError(f"NemoClaw source not found for {module_name} at {source_path}")
+    source = source_path.read_text(encoding="utf-8")
+    compile(source, str(destination_path), "exec")
+    if destination_path.exists() or destination_path.is_symlink():
+        if (
+            not destination_path.is_file()
+            or destination_path.is_symlink()
+            or destination_path.read_text(encoding="utf-8") != source
+        ):
+            raise RuntimeError(
+                f"Refusing to overwrite unexpected module at {destination_path}"
+            )
+    return destination_path, source
+
     module_source_path = Path(__file__).with_name(MIDDLEWARE_MODULE)
-    module_destination_path = root / MIDDLEWARE_MODULE
-    if not module_source_path.is_file():
-        raise RuntimeError(
-            f"NemoClaw middleware source not found at {module_source_path}"
-        )
-    module_source = module_source_path.read_text(encoding="utf-8")
-    compile(module_source, str(module_destination_path), "exec")
-    if module_destination_path.exists() or module_destination_path.is_symlink():
-        if (
-            not module_destination_path.is_file()
-            or module_destination_path.is_symlink()
-            or module_destination_path.read_text(encoding="utf-8") != module_source
-        ):
-            raise RuntimeError(
-                f"Refusing to overwrite unexpected middleware at {module_destination_path}"
-            )
-
-    observability_source_path = Path(__file__).with_name(OBSERVABILITY_MODULE)
-    observability_destination_path = root / OBSERVABILITY_MODULE
-    if not observability_source_path.is_file():
-        raise RuntimeError(
-            f"NemoClaw observability source not found at {observability_source_path}"
-        )
-    observability_source = observability_source_path.read_text(encoding="utf-8")
-    compile(
-        observability_source,
-        str(observability_destination_path),
-        "exec",
-    )
-    if (
-        observability_destination_path.exists()
-        or observability_destination_path.is_symlink()
-    ):
-        if (
-            not observability_destination_path.is_file()
-            or observability_destination_path.is_symlink()
-            or observability_destination_path.read_text(encoding="utf-8")
-            != observability_source
-        ):
-            raise RuntimeError(
-                "Refusing to overwrite unexpected observability module at "
-                f"{observability_destination_path}"
-            )
+    module_destination_path, module_source = _install_module(MIDDLEWARE_MODULE, root)
+    observability_destination_path, observability_source = _install_module(
+        OBSERVABILITY_MODULE, root
+    )
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@agents/langchain-deepagents-code/patch-managed-deepagents-code.py` around
lines 1018 - 1044, The observability module install/validate block duplicates
the middleware module logic, so extract the shared flow into a helper such as
the existing managed-module install path in patch-managed-deepagents-code.py.
Refactor the repeated sequence in the observability handling to call a common
helper that takes the module name and destination root, while preserving the
current validation and error messages for both modules. Keep the helper reusable
for future managed modules so the install/check behavior stays consistent in one
place.
docs/get-started/quickstart-langchain-deepagents-code.mdx (1)

186-186: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Consider code-formatting the tier name.

"Restricted" refers to a literal policy tier value (elsewhere referenced in code as restricted/RESTRICTED_TIER_NAME). Per docs path instructions, literal values should use code formatting.

As per path instructions ("Use code formatting for commands, paths, flags, environment variables, file names, and literal values.").

✏️ Suggested tweak
-The Restricted policy tier suppresses the required egress preset even when the opt-in is recorded.
+The `restricted` policy tier suppresses the required egress preset even when the opt-in is recorded.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/get-started/quickstart-langchain-deepagents-code.mdx` at line 186, The
docs text uses the literal policy tier name without code formatting, so update
the mention of the Restricted tier in this section to use inline code styling.
Keep the wording the same, but format the literal tier value consistently with
the nearby `restricted`/`RESTRICTED_TIER_NAME` references so it matches the docs
style guidance.

Source: Path instructions

🤖 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 `@agents/langchain-deepagents-code/patch-managed-deepagents-code.py`:
- Around line 494-517: The current use of with_config() in create_cli_agent only
adds new_metadata_only_callback_handler() on top of existing callbacks, so it
does not guarantee metadata-only tracing. Update the create_cli_agent path to
use a stronger isolation point than layering callbacks on the returned agent,
ensuring any compiled-agent or outer-config tracers are excluded when
observability_active is true. Keep the observability and progressive disclosure
handling around _nemoclaw_original_create_cli_agent, but adjust the
post-processing of result so the metadata-only behavior is enforced by the agent
construction path rather than merged configuration.

In `@docs/reference/commands.mdx`:
- Line 203: The quickstart link target in the documentation is wrong because the
current relative path points through a non-existent openclaw segment. Update the
Quickstart with LangChain Deep Agents Code reference in the affected docs
content to use the correct
../../get-started/quickstart-langchain-deepagents-code#export-traces-through-a-local-collector
target, and make sure both occurrences of this link in commands.mdx use the same
corrected path.

In `@nemoclaw-blueprint/policies/presets/observability-otlp-local.yaml`:
- Around line 9-24: Expand the observability-otlp-local preset tests to cover
blocked scenarios as well as the allowed case: add negative-path assertions for
non-POST methods, mismatched paths, and alternate hosts against the
observability-otlp-local network_policies entry so only the intended /v1/traces
POST on host.openshell.internal is permitted. Also add checks that preset
rendering and any related logging paths do not include credentials, tokens, or
other secret-like values, using the observability-otlp-local preset name and its
endpoint/rule shape to locate the relevant assertions.

---

Nitpick comments:
In `@agents/langchain-deepagents-code/patch-managed-deepagents-code.py`:
- Around line 1018-1044: The observability module install/validate block
duplicates the middleware module logic, so extract the shared flow into a helper
such as the existing managed-module install path in
patch-managed-deepagents-code.py. Refactor the repeated sequence in the
observability handling to call a common helper that takes the module name and
destination root, while preserving the current validation and error messages for
both modules. Keep the helper reusable for future managed modules so the
install/check behavior stays consistent in one place.

In `@docs/get-started/quickstart-langchain-deepagents-code.mdx`:
- Line 186: The docs text uses the literal policy tier name without code
formatting, so update the mention of the Restricted tier in this section to use
inline code styling. Keep the wording the same, but format the literal tier
value consistently with the nearby `restricted`/`RESTRICTED_TIER_NAME`
references so it matches the docs style guidance.

In `@src/lib/actions/sandbox/rebuild-recreate-phase.ts`:
- Around line 68-256: Add dedicated coverage for runRebuildRecreatePhase to
verify observabilityEnabled is propagated from
recreateOptions.observabilityEnabled into the rebuilt session via
onboardSession.updateSession/createSession, and that this value remains correct
through both the success path and the onboardFailed recovery path. Use the
runRebuildRecreatePhase function and the onboardSession session update logic as
anchors when adding the test cases.
🪄 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: CHILL

Plan: Enterprise

Run ID: 66943a62-7453-4941-bdef-4ce0a474f283

📥 Commits

Reviewing files that changed from the base of the PR and between 34f504e and 653e6c2.

⛔ Files ignored due to path filters (1)
  • agents/langchain-deepagents-code/requirements.lock is excluded by !**/*.lock
📒 Files selected for processing (60)
  • agents/langchain-deepagents-code/Dockerfile
  • agents/langchain-deepagents-code/dcode-launcher.sh
  • agents/langchain-deepagents-code/dependency-review.md
  • agents/langchain-deepagents-code/nemoclaw_observability.py
  • agents/langchain-deepagents-code/patch-managed-deepagents-code.py
  • agents/langchain-deepagents-code/requirements.in
  • agents/langchain-deepagents-code/start.sh
  • ci/test-file-size-budget.json
  • docs/get-started/quickstart-langchain-deepagents-code.mdx
  • docs/reference/commands-nemohermes.mdx
  • docs/reference/commands.mdx
  • docs/reference/enterprise-readiness.mdx
  • docs/reference/network-policies.mdx
  • nemoclaw-blueprint/policies/presets/observability-otlp-local.yaml
  • src/lib/actions/sandbox/rebuild-gpu-opt-out.test.ts
  • src/lib/actions/sandbox/rebuild-gpu-opt-out.ts
  • src/lib/actions/sandbox/rebuild-recreate-phase.ts
  • src/lib/onboard.ts
  • src/lib/onboard/agent-policy-presets.ts
  • src/lib/onboard/command-support.ts
  • src/lib/onboard/command.test.ts
  • src/lib/onboard/command.ts
  • src/lib/onboard/machine/handlers/policies.test.ts
  • src/lib/onboard/machine/handlers/policies.ts
  • src/lib/onboard/machine/handlers/sandbox-dcode-selection.test.ts
  • src/lib/onboard/machine/handlers/sandbox-tool-disclosure.test.ts
  • src/lib/onboard/machine/handlers/sandbox.test.ts
  • src/lib/onboard/machine/handlers/sandbox.ts
  • src/lib/onboard/observability-policy-presets.test.ts
  • src/lib/onboard/observability-policy-presets.ts
  • src/lib/onboard/policy-presets.ts
  • src/lib/onboard/policy-resume-selection.test.ts
  • src/lib/onboard/policy-resume-selection.ts
  • src/lib/onboard/policy-selection.ts
  • src/lib/onboard/policy-tier-suppression.ts
  • src/lib/onboard/resume-config.test.ts
  • src/lib/onboard/resume-config.ts
  • src/lib/onboard/runtime-control-flow.test.ts
  • src/lib/onboard/runtime-control-flow.ts
  • src/lib/onboard/sandbox-create-launch.test.ts
  • src/lib/onboard/sandbox-create-launch.ts
  • src/lib/onboard/sandbox-registration.test.ts
  • src/lib/onboard/sandbox-registration.ts
  • src/lib/onboard/session-bootstrap.test.ts
  • src/lib/onboard/session-bootstrap.ts
  • src/lib/onboard/session-updates.ts
  • src/lib/onboard/types.ts
  • src/lib/state/onboard-session.test.ts
  • src/lib/state/onboard-session.ts
  • src/lib/state/registry.ts
  • test/fixtures/deepagents-observability-harness.py
  • test/langchain-deepagents-code-direct-module-patch.test.ts
  • test/langchain-deepagents-code-image.test.ts
  • test/langchain-deepagents-code-observability.test.ts
  • test/langchain-deepagents-code-progressive-tool-disclosure.test.ts
  • test/langchain-deepagents-code-proxy-launcher.test.ts
  • test/observability-otlp-policy-preset.test.ts
  • test/onboard-policy-suggestions.test.ts
  • test/policies.test.ts
  • test/registry.test.ts
💤 Files with no reviewable changes (1)
  • test/policies.test.ts

Comment thread agents/langchain-deepagents-code/patch-managed-deepagents-code.py
Comment thread docs/reference/commands.mdx Outdated
Comment thread nemoclaw-blueprint/policies/presets/observability-otlp-local.yaml
Signed-off-by: Carlos Villela <cvillela@nvidia.com>
Comment thread agents/langchain-deepagents-code/nemoclaw_observability.py Fixed
Comment thread agents/langchain-deepagents-code/nemoclaw_observability.py Fixed
Comment thread agents/langchain-deepagents-code/nemoclaw_observability.py Fixed
Comment thread agents/langchain-deepagents-code/validate-observability.py Fixed
Comment thread test/fixtures/deepagents-observability-harness.py Fixed
Comment thread test/fixtures/deepagents-observability-harness.py Fixed
@github-actions

github-actions Bot commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

E2E Target Results — ✅ All selected jobs passed

Run: 28824072355
Workflow ref: codex/dcode-backend-neutral-observability
Requested targets: ubuntu-repo-cloud-langchain-deepagents-code
Requested jobs: (default — all default-enabled free-standing jobs; explicit-only jobs openshell-gateway-auth-contract, mcp-bridge-dev, hermes-gpu-startup, sandbox-rlimits-connect, and jetson-nvmap-gpu are skipped unless selected)
Summary: 1 passed, 0 failed, 0 cancelled, 0 skipped

Job Result
live ✅ success

@cv

cv commented Jul 6, 2026

Copy link
Copy Markdown
Collaborator Author

Review follow-up for 9aff318fe:

GPT advisor

  • PRA-1 / PRA-3 / PRA-T8 (patch source of truth): expanded the adjacent source-boundary comment to name the upstream hook gap, NemoClaw-owned image boundary, fail-closed tests, and removal condition. The patcher now requires exactly one progressive-disclosure marker and one observability marker, with partial-install regression tests.
  • PRA-2 / PRA-T1 / PRA-T5 / PRA-T7 (real exporter proof): every DCode image build now runs validate-observability.py against the real pinned nemo-relay==0.4.0 and langgraph==1.2.6. Before substituting loopback, it asserts the production endpoint. It then observes exactly seven POST /v1/traces requests (7,277 protobuf bytes), only standard transport headers, no prompt/output/tool/error/ambient/truncation sentinels, sanitized identifiers, exact original exception identity/traceback restoration, and zero requests to a hostile loopback canary. The Docker build, launcher-marker contract, exact OpenShell policy shape, and cloud DCode target provide separate fail-closed proofs without introducing a second runtime observability implementation.
  • PRA-4 (policy-selection hotspot): extracted shared preset reconciliation into policy-preset-reconciliation.ts; policy-selection.ts is now 446 lines versus 501 at the base. Explicit custom/interactive web-search behavior remains preserved while inactive observability is always pruned.
  • PRA-T2 (rebuild): added focused recreate tests for success and inner-onboard failure/rollback/relock/bail, asserting durable observabilityEnabled: true at every checkpoint. Existing tier/resume tests cover required-preset addition and restricted suppression.
  • PRA-T3 (policy skip): documented the deliberate contract: NEMOCLAW_POLICY_MODE=skip performs no policy mutation, so a new sandbox cannot reach the collector; the exporter fails open. Existing skip-path tests enforce the no-touch behavior.
  • PRA-T4: real-Relay and stub tests now send 200-character/control-character model, sync-tool, async-tool, and graph names and assert bounded sanitized values before Relay.
  • PRA-T6: the PR only marks its issue references as related/follow-up; it intentionally does not claim a deterministic closing acceptance clause.

Nemotron advisor

  • PRA-1 / PRA-9 (launcher marker): added the invalid-state/source-boundary/removal-condition comment. The launcher requires a regular non-symlink file with exact content; regression tests cover tampered content and a non-regular directory marker, which exercises the -f rejection used for FIFOs/devices too.
  • PRA-2 / PRA-8 (identifiers): all model, sync/async tool, and graph identifiers are sanitized and capped at 128 characters before Relay; hostile 200-character/control-name cases pass through the real wire validator.
  • PRA-3 / PRA-10 (bridge addresses): Docker/Podman host-gateway addresses are not stable enough to pin one IP. The preset documents why RFC1918 resolution is needed for OpenShell SSRF validation. In OpenShell policy semantics, allowed_ips constrains current DNS answers for the endpoint's exact host; it does not authorize direct-IP or alternate-host egress. Hostname, port, method, exact path, and managed-Python binary remain independent controls. Tests deny alternate host/method/path/suffix and reject credential/header-like preset configuration.
  • PRA-4 (diagnostic error): the implementation already takes the advisor's “or structured error code” branch: NEMOCLAW_DCODE_OPERATION_FAILED. A random per-span ID would add high-cardinality data but would not be present in the restored original exception or a safe host log, so it would not actually correlate anything. Tests also prove the Relay-visible error has no __context__ or __cause__.
  • PRA-5 / PRA-6 / PRA-7 (growth): extracted the new tests into focused files; the legacy launch and policy-handler tests are exactly their 390/381-line base sizes. The source helper extraction reduces policy-selection.ts below its 501-line base.
  • PRA-11: the pinned lock audit still passes with no known vulnerabilities; the uv tool run spelling is the supported command used to perform it.
  • PRA-12: the quickstart now shows nemo-deepagents onboard --observability directly.
  • PRA-13: exact individual marker checks and missing-marker regression cases are included.
  • Current-head PRA-3 (446-line policy selection): this PR reduced the file by 55 lines below its 501-line base and moved the repeated reconciliation concern out. Further agent-specific decomposition is broader than this observability change; the repository growth guard passes.
  • Current-head PRA-4 / PRA-T4 (marker matrix): the launcher suite covers missing marker/noncanonical opt-in, exact regular marker 1, wrong content, and a non-regular directory; the production condition independently rejects symlinks with ! -L and all non-regular types with -f.
  • Current-head PRA-5 / PRA-7 / PRA-T3 (identifier unit proof): the focused TypeScript test drives the isolated Python harness with control characters plus a 200-character value and asserts the exact sanitized 128-character model/sync-tool/async-tool/graph results. The image-build validator repeats the assertion on real Relay bytes, so another direct-import test would duplicate a stronger existing assertion.
  • Current-head PRA-8 / PRA-T5 (patch placement): the patcher compiles the entire inserted patch, requires the exact full AGENT_PATCH once, validates pinned upstream symbols/methods with AST, validates each marker once, and executes the patched factories in wiring tests. Marker-only AST placement would be weaker than that combined proof.
  • Current-head PRA-9 / PRA-T6 (subprocess cost): the three isolated scenarios complete in about 141 ms total. Process isolation is intentional because the module owns one-shot globals, environment restoration, subscriber registration, and atexit state; a shared-process variant would be less faithful for negligible savings.

CodeRabbit / callback isolation

The graph now receives a directly replaced locked callback manager rather than layering with_config({callbacks: ...}) onto existing callbacks. The build validator exercises pinned LangGraph's actual managed-root self-config-first merge with hostile callback lists and managers, then real sync/async LangChain callback configuration; only the managed metadata-only handler survives while tags/metadata remain. This claim is deliberately scoped to NemoClaw's pinned managed-root DCode invocation path, not arbitrary embedding inside an inherited third-party runnable context.

Final evidence: 195/195 focused integration tests, 5/5 focused CLI lifecycle tests, CLI build/type-check, 46/46 config schemas, source-shape/test-size gates, normal pre-commit/commit-msg/pre-push hooks, docs with 0 errors (two existing warnings), both production sandbox-image builds, and the cloud DCode live E2E on runtime head 90a00d10f all pass. The only later change renames two test titles.

Final-head advisor residuals (374d9e374)

  • GPT PRA-1 / PRA-T1–T4: accepted as a composed-runtime residual, not described as one combined E2E proof. A deterministic PR test that simultaneously runs a host collector, creates an OpenShell sandbox, applies live policy, invokes a credentialed model/tool turn through direct dcode exec, and inspects protobuf privacy would require a new live target and external inference. The current split proof fails closed at each boundary: production x86/ARM images execute the real pinned Relay wire validator; launcher tests execute entrypoint-marker and direct-exec recovery; policy tests enforce exact host/port/method/path/binary and negative host/path/method cases; lifecycle tests prove opt-in/preset persistence; and cloud DCode E2E proves the resulting image still onboards and runs. The remaining cross-boundary wiring risk is explicit and accepted for this PR.
  • GPT PRA-T5: no closing issue acceptance clause is claimed; the PR marks its references as related/follow-up only.
  • Nemotron PRA-3: NEMOCLAW_DCODE_OPERATION_FAILED is the requested structured error code. A random ID would have no matching safe host log or restored-exception field, so it would increase cardinality without enabling correlation.
  • Nemotron PRA-4 / PRA-2 / PRA-7 / PRA-10: allowed_ips validates current DNS answers for the endpoint's exact host; it does not grant arbitrary-IP or alternate-host egress. Docker/Podman gateway addresses vary across supported hosts, so RFC1918 ranges are the operational constraint until OpenShell exposes a stable gateway address or DNS-only host-gateway primitive. The preset comment records this, and the policy contract denies alternate hosts, methods, paths, and suffixes.
  • Nemotron PRA-5: no from None change is made. In Python, raising from None inside an exception handler suppresses display but still retains the original object in __context__; it would not establish the claimed privacy property. The structural callback context manager deliberately raises only after the handler's exception block, and both the harness and real serialized Relay bytes prove __context__/__cause__ and the original sentinel are absent.
  • Nemotron PRA-1 / PRA-6 / PRA-9: identifier normalization is ordinary validation at the third-party callback boundary, not a localized source workaround. Focused and real-wire tests already assert exact 128-character sanitized values for hostile model, sync/async tool, and graph identifiers.
  • Nemotron PRA-8 / PRA-13 / PRA-19: reconciliation extraction is complete for this scope: policy-selection.ts is 55 lines below its base, calls the extracted helpers, and 195 focused tests plus the repository growth guard pass. Further agent-wide decomposition is unrelated refactoring.
  • Nemotron PRA-11: the launcher has the full invalid-state/source-boundary/source-fix/test/removal-condition comment and its marker matrix is covered.
  • Nemotron PRA-12 / PRA-18: _lifecycle_lock is held across the entire ambient-environment removal, subscriber construction, and restoration. Initialization is one-shot and the duplicate-initialize path is exercised. Another test would restate Python RLock behavior without covering arbitrary unrelated threads that read process environment.
  • Nemotron PRA-14: seven requests are the pinned Relay 0.4 conformance result of the explicit model/tool/graph success and failure operations in the validator; the assertion and operation sequence are the maintained executable mapping.
  • Nemotron PRA-15: there is no supported legacy tracing workflow to migrate. The replaced text said tracing was unsupported; the new section is the first supported workflow and explicitly explains that native LangSmith remains disabled while host-side LangSmith export works.
  • Nemotron PRA-16: exact full-patch presence, compilation, pinned upstream AST symbol/method gates, individual marker counts, missing-marker regressions, and executable factory wiring provide stronger placement evidence than a marker-location-only AST check.
  • Nemotron PRA-17: all three process-isolated scenarios complete in roughly 141 ms; isolation is intentional for module globals, environment, subscriber, and atexit state.

Signed-off-by: Carlos Villela <cvillela@nvidia.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

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

Inline comments:
In `@test/observability-otlp-policy-preset.test.ts`:
- Around line 99-119: Update the new test titles in
observability-otlp-policy-preset.test.ts to follow the behavior-oriented naming
rule with a local issue reference suffix. In the it.each block for the denies
cases and the it block for exporter credential/header configuration, append the
required final “(`#1234`)” style suffix to each title so they comply with the test
naming guideline while keeping the existing behavior-focused wording.
🪄 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: CHILL

Plan: Enterprise

Run ID: f50b601c-662f-4acf-8986-ec7052c23eb1

📥 Commits

Reviewing files that changed from the base of the PR and between 653e6c2 and 9aff318.

📒 Files selected for processing (18)
  • agents/langchain-deepagents-code/Dockerfile
  • agents/langchain-deepagents-code/dcode-launcher.sh
  • agents/langchain-deepagents-code/nemoclaw_observability.py
  • agents/langchain-deepagents-code/patch-managed-deepagents-code.py
  • agents/langchain-deepagents-code/validate-observability.py
  • docs/get-started/quickstart-langchain-deepagents-code.mdx
  • nemoclaw-blueprint/policies/presets/observability-otlp-local.yaml
  • src/lib/actions/sandbox/rebuild-recreate-observability.test.ts
  • src/lib/onboard/machine/handlers/policies-observability.test.ts
  • src/lib/onboard/policy-preset-reconciliation.ts
  • src/lib/onboard/policy-selection.ts
  • src/lib/onboard/sandbox-create-launch-observability.test.ts
  • test/fixtures/deepagents-observability-harness.py
  • test/langchain-deepagents-code-image.test.ts
  • test/langchain-deepagents-code-observability.test.ts
  • test/langchain-deepagents-code-progressive-tool-disclosure.test.ts
  • test/langchain-deepagents-code-proxy-launcher.test.ts
  • test/observability-otlp-policy-preset.test.ts
✅ Files skipped from review due to trivial changes (1)
  • src/lib/onboard/sandbox-create-launch-observability.test.ts
🚧 Files skipped from review as they are similar to previous changes (7)
  • test/langchain-deepagents-code-image.test.ts
  • nemoclaw-blueprint/policies/presets/observability-otlp-local.yaml
  • agents/langchain-deepagents-code/Dockerfile
  • test/langchain-deepagents-code-observability.test.ts
  • agents/langchain-deepagents-code/dcode-launcher.sh
  • docs/get-started/quickstart-langchain-deepagents-code.mdx
  • src/lib/onboard/policy-selection.ts

Comment thread test/observability-otlp-policy-preset.test.ts
Signed-off-by: Carlos Villela <cvillela@nvidia.com>
@github-actions

github-actions Bot commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

E2E Target Results — ✅ All selected jobs passed

Run: 28824587990
Workflow ref: codex/dcode-backend-neutral-observability
Requested targets: ubuntu-repo-cloud-langchain-deepagents-code
Requested jobs: (default — all default-enabled free-standing jobs; explicit-only jobs openshell-gateway-auth-contract, mcp-bridge-dev, hermes-gpu-startup, sandbox-rlimits-connect, and jetson-nvmap-gpu are skipped unless selected)
Summary: 1 passed, 0 failed, 0 cancelled, 0 skipped

Job Result
live ✅ success

@github-actions

github-actions Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

E2E Target Results — ❌ Some jobs failed

Run: 28897942322
Workflow ref: codex/dcode-backend-neutral-observability
Requested targets: (default — all supported)
Requested jobs: full-e2e
Summary: 0 passed, 1 failed, 0 cancelled, 0 skipped

Job Result
full-e2e ❌ failure

Failed jobs: full-e2e. Check run artifacts for logs.

cv added 2 commits July 7, 2026 14:02
Signed-off-by: Carlos Villela <cvillela@nvidia.com>
Signed-off-by: Carlos Villela <cvillela@nvidia.com>
@cv

cv commented Jul 7, 2026

Copy link
Copy Markdown
Collaborator Author

Final-head automated-review follow-up for 9ebf3f29d:

  • Addressed the GPT advisor failure-log warning by removing exception payloads and tracebacks from all managed observability failure diagnostics while retaining stable warning/debug messages.
  • Added a regression that injects ambient OTEL header, certificate, and client-key canaries into a subscriber registration exception; the test proves none reach local logs and still verifies fail-open rollback.
  • Focused validation passed: Python compilation, Biome, and 114/114 observability/image/direct-module integration tests. An independent review found no issues, and the docs audit found no user-facing documentation change necessary.
  • The refreshed GPT advisor explicitly marks the logging item resolved and reports no new findings. Remaining GPT/Nemotron items are unchanged from the prior disposition: the deliberate fixed host-gateway route, optional snapshot extraction, and heuristic findings already covered by lifecycle locking, redacted-exception tests, marker semantics, real Relay validation, and enforced file-size budgets.

Prior detailed disposition: #6340 (comment)

@cv
cv requested a review from apurvvkumaria July 7, 2026 21:50

@apurvvkumaria apurvvkumaria 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.

Requesting changes at exact head 9ebf3f29db2a3796b6d19ca160604c59352f1606.

I found the following correctness and security blockers:

  1. P1 — Exception redaction can be bypassed.
    agents/langchain-deepagents-code/nemoclaw_observability.py:695-717 reads error.__traceback__ and calls error.with_traceback(...) through subclass dispatch. I reproduced a custom exception replacing the traceback lookup with a secret-bearing error; Relay observed that replacement unredacted and the agent lost the original exception. The restore path also clears an original explicit __cause__ through from None. Use base-class dispatch and add hostile-exception/cause-preservation tests.

  2. P1 — Optional tracing is not fail-open for valid Python values or Relay failures.
    nemoclaw_observability.py:125-132,194-199,727-861 passes arbitrary-size integers and lone Unicode surrogates into Relay. With the exact pinned nemo-relay==0.4.0, 10**1000 and "\ud800" tool arguments fail before the handler runs, while a huge-integer result fails after the handler runs and discards the completed result. Generic Relay failures have the same pre-/post-callback behavior because only application-callback errors are suppressed. Normalize values into Relay's JSON domain, then ensure instrumentation failures invoke the handler exactly once or return its saved result.

  3. P1 — Custom OTLP policy ownership can be misclassified and overwritten.
    src/lib/policy/index.ts:1257-1275 says it checks one exact live network-policy key, but src/lib/policy/gateway-state.ts:64-94 requires every key in the custom preset to match. If an unrelated second key drifts—or inspection is temporarily unavailable—the still-exact operator-owned observability-otlp-local entry is treated as unowned. Policy selection can then apply the built-in preset, and the merge at src/lib/policy/index.ts:536-543,1058 overwrites the custom content. Compare only the requested key and treat an unreadable ownership state as an abort, not “unowned.”

  4. P1 — Recovery guidance drops an explicit observability opt-out.
    The MCP safety redirect at src/lib/onboard.ts:2656-2663 prints a rebuild command without --observability/--no-observability. The failed-rebuild retry at src/lib/actions/sandbox/rebuild-recreate-phase.ts:105-126,212-232 does the same while failing to preserve explicit provenance. Repro: enabled DCode with managed MCP, request --no-observability, then follow the printed command; rebuild succeeds with observability still enabled. Carry the authoritative intent and render the matching flag in both retry forms.

  5. P2 — Legacy snapshot clones enable instrumentation without the required policy.
    src/lib/actions/sandbox/snapshot.ts:233-304 starts and records an observability-enabled clone, but snapshot.ts:580-584 skips all reconciliation when an older snapshot lacks policyPresets. A balanced DCode clone restores successfully while every trace is denied because observability-otlp-local is absent. Reconcile the managed observability binding independently of historical generic preset metadata.

  6. P2 — Interrupted Restricted onboarding can resume as Balanced.
    The resolved normal-onboarding tier is not persisted during sandbox registration (src/lib/onboard/machine/handlers/sandbox.ts:679-685, src/lib/onboard.ts:3016-3019). If Restricted, observability-enabled onboarding is interrupted after sandbox creation but before policy completion, a later noninteractive resume without the original environment defaults to Balanced at src/lib/onboard/policy-selection-prompts.ts:82-96 and can add OTLP egress. Persist the resolved tier before the sandbox step becomes resumable.

Verification performed: exact pinned-Relay reproductions for findings 1 and 2, existing privacy/outage/construction/logging harnesses, Python syntax, git diff --check, policy/lifecycle tracing, and a clean synthetic merge with current main.

The visible exact-head checks are green, but the composed DCode/live lifecycle runs requested by the E2E advisor are stale or missing on final head. Please rerun the full required live set after addressing these findings.

cv added 2 commits July 7, 2026 16:29
Signed-off-by: Carlos Villela <cvillela@nvidia.com>
Signed-off-by: Carlos Villela <cvillela@nvidia.com>
Comment thread agents/langchain-deepagents-code/nemoclaw_observability.py Fixed
Comment thread agents/langchain-deepagents-code/nemoclaw_observability.py Fixed
Comment thread agents/langchain-deepagents-code/nemoclaw_observability.py Fixed
Comment thread agents/langchain-deepagents-code/nemoclaw_observability.py Fixed
Comment thread agents/langchain-deepagents-code/nemoclaw_observability.py Fixed
Comment thread agents/langchain-deepagents-code/nemoclaw_observability.py Fixed
Comment thread test/fixtures/deepagents-observability-harness.py Fixed
Comment thread test/fixtures/deepagents-observability-harness.py
Comment thread test/fixtures/deepagents-observability-harness.py
Comment thread test/fixtures/deepagents-observability-harness.py Fixed
Comment thread test/fixtures/deepagents-observability-harness.py Fixed
Comment thread test/fixtures/deepagents-observability-harness.py
Comment thread test/fixtures/deepagents-observability-harness.py
Comment thread test/fixtures/deepagents-observability-harness.py Fixed
cv added 2 commits July 7, 2026 16:54
Signed-off-by: Carlos Villela <cvillela@nvidia.com>
Signed-off-by: Carlos Villela <cvillela@nvidia.com>
Comment thread test/fixtures/deepagents-observability-harness.py
Comment thread test/fixtures/deepagents-observability-harness.py
@github-actions

github-actions Bot commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

E2E Target Results — ❌ Some jobs failed

Run: 28907036255
Workflow ref: codex/dcode-backend-neutral-observability
Requested targets: (default — all supported)
Requested jobs: (default — all default-enabled free-standing jobs; explicit-only jobs openshell-gateway-auth-contract, mcp-bridge-dev, hermes-gpu-startup, sandbox-rlimits-connect, and jetson-nvmap-gpu are skipped unless selected)
Summary: 33 passed, 1 failed, 36 cancelled, 5 skipped

Job Result
agent-turn-latency ⚠️ cancelled
bedrock-runtime-compatible-anthropic ✅ success
brave-search ✅ success
channels-add-remove ⚠️ cancelled
channels-stop-start ⚠️ cancelled
cloud-inference ✅ success
cloud-onboard ⚠️ cancelled
common-egress-agent ⚠️ cancelled
concurrent-gateway-ports ✅ success
credential-migration ✅ success
credential-sanitization ✅ success
cron-preflight-inference-local ✅ success
device-auth-health ✅ success
diagnostics ✅ success
docs-validation ✅ success
double-onboard ⚠️ cancelled
full-e2e ✅ success
gateway-drift-preflight ✅ success
gateway-guard-recovery ⚠️ cancelled
gateway-health-honest ✅ success
generate-matrix ✅ success
gpu-double-onboard ⚠️ cancelled
gpu-e2e ⚠️ cancelled
hermes-dashboard ⚠️ cancelled
hermes-discord ⚠️ cancelled
hermes-e2e ⚠️ cancelled
hermes-gpu-startup ⏭️ skipped
hermes-inference-switch ⚠️ cancelled
hermes-shields-config ⚠️ cancelled
hermes-slack ✅ success
inference-routing ✅ success
issue-2478-crash-loop-recovery ⚠️ cancelled
issue-4434-tui-unreachable-inference ✅ success
issue-4462-scope-upgrade-approval ⚠️ cancelled
jetson-nvmap-gpu ⏭️ skipped
kimi-inference-compat ✅ success
launchable-smoke ✅ success
live ✅ success
mcp-bridge ⚠️ cancelled
mcp-bridge-dev ⏭️ skipped
messaging-compatible-endpoint ✅ success
messaging-providers ⚠️ cancelled
model-router-provider-routed-inference ⚠️ cancelled
network-policy ⚠️ cancelled
ollama-auth-proxy ✅ success
onboard-negative-paths ✅ success
onboard-repair ✅ success
onboard-resume ✅ success
openclaw-discord-pairing ⚠️ cancelled
openclaw-inference-switch ❌ failure
openclaw-skill-cli ✅ success
openclaw-slack-pairing ⚠️ cancelled
openclaw-tui-chat-correlation ✅ success
openshell-gateway-auth-contract ⏭️ skipped
openshell-gateway-upgrade ⚠️ cancelled
openshell-version-pin ✅ success
overlayfs-autofix ✅ success
rebuild-hermes ⚠️ cancelled
rebuild-hermes-stale-base ⚠️ cancelled
rebuild-openclaw ⚠️ cancelled
sandbox-operations ⚠️ cancelled
sandbox-rebuild ⚠️ cancelled
sandbox-rlimits-connect ⏭️ skipped
sandbox-survival ⚠️ cancelled
security-posture ⚠️ cancelled
sessions-agents-cli ⚠️ cancelled
shields-config ⚠️ cancelled
skill-agent ✅ success
snapshot-commands ✅ success
spark-install ✅ success
state-backup-restore ⚠️ cancelled
telegram-injection ✅ success
token-rotation ⚠️ cancelled
tunnel-lifecycle ⚠️ cancelled
upgrade-stale-sandbox ⚠️ cancelled

Explicit-only jobs skipped: openshell-gateway-auth-contract (default dispatch excludes the resource-heavy OpenShell auth-contract probe unless selected; validate with jobs=openshell-gateway-auth-contract or targets=openshell-gateway-auth-contract), mcp-bridge-dev (default dispatch excludes moving OpenShell dev artifacts unless explicitly selected; validate with jobs=mcp-bridge-dev or targets=mcp-bridge-dev), hermes-gpu-startup (default dispatch excludes this explicit-only job unless selected; validate with jobs=hermes-gpu-startup or targets=hermes-gpu-startup), sandbox-rlimits-connect (default dispatch excludes the destructive rlimit fork/connect probe unless selected; validate with jobs=sandbox-rlimits-connect or targets=sandbox-rlimits-connect), jetson-nvmap-gpu (default dispatch excludes Jetson until a stable Jetson runner is available; validate with jobs=jetson-nvmap-gpu or targets=jetson-nvmap-gpu).

Failed jobs: openclaw-inference-switch. Check run artifacts for logs.

@cv

cv commented Jul 8, 2026

Copy link
Copy Markdown
Collaborator Author

Current-head automated-advisor disposition for ac1b478:

  • GPT PRA-1 / Nemotron PRA-8, PRA-17, and related tests: justified without changing the CIDRs. In pinned OpenShell v0.0.72, Docker and Podman inject the exact host.openshell.internal alias, and the proxy reads the entrypoint root /etc/hosts before DNS, validates the returned addresses against allowed_ips, then connects that same pinned list. DCode runs nonroot under strict Landlock with /etc read-only; the canonical DCode target proves that boundary before its observability check. The policy independently pins the exact host, port 4318, POST method, /v1/traces path, and managed-Python binary, with negative host/port/method/path/binary tests. Gateway addresses vary across supported Docker/Podman networks and OpenShell exposes no attested stable gateway-IP primitive, so guessed exact CIDRs would be nonportable. Accepted residual: a trusted host-root, driver, or operator can remap the alias; those actors already own the sandbox runtime and host collector TCB.
  • Nemotron PRA-9: not applicable. raise_redacted runs only after leaving the handler exception block, so the constant Relay-visible exception has no original context. Adding from None would suppress display but would not erase an existing context. The harness and real Relay validator assert empty Relay-visible cause/context while restore_original preserves the application exception identity, traceback, explicit cause, and context as required by the human review.
  • Nemotron PRA-10: not applicable. The suggested read redirection is not an atomic anti-symlink primitive. The marker is explicitly not an authorization boundary and exports only literal 1 after regular-file, non-symlink, and exact-content checks; host-owned network policy controls OTLP egress. Existing launcher tests cover missing, tampered, symlink, and non-regular markers.
  • Nemotron PRA-11: not applicable as described. initialize_observability holds the lifecycle RLock across ambient-variable removal, subscriber construction, and try/finally restoration. Initialization is one-shot. A ContextVar cannot isolate a third-party exporter that reads os.environ; the real validator proves ambient endpoint/header/certificate canaries never escape.
  • Nemotron PRA-12 through PRA-14: these are file-organization preferences, not correctness failures. The repository growth guard and approved size budgets pass; snapshot.test.ts is exactly at its explicit 1,500-line budget.
  • GPT PRA-2 / Nemotron PRA-15: valid maintainability follow-up, deliberately deferred. The human review correctness gap for legacy snapshots is fixed and covered for legacy/recorded add, disabled removal, failed or lying removal, stale attribution, exact custom ownership, unreadable ownership abort, drift/no-delete, and restricted suppression. Moving roughly 130 security-sensitive lines now would add behavior-neutral churn after exact-head review validation.
  • The remaining source-boundary and simplification items repeat prior dispositions and existing executable coverage; they identify no new current-head correctness gap.

All 40 applicable PR checks pass, all 63 review threads are resolved, the head is GitHub Verified, and the branch is conflict-free. Final-head required live E2E follow-up is still running; I will post its settled evidence with the human-review response.

@cv
cv requested a review from apurvvkumaria July 8, 2026 00:12
@github-actions

github-actions Bot commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

E2E Target Results — ✅ All selected jobs passed

Run: 28907688897
Workflow ref: codex/dcode-backend-neutral-observability
Requested targets: ubuntu-repo-cloud-langchain-deepagents-code
Requested jobs: (default — all default-enabled free-standing jobs; explicit-only jobs openshell-gateway-auth-contract, mcp-bridge-dev, hermes-gpu-startup, sandbox-rlimits-connect, and jetson-nvmap-gpu are skipped unless selected)
Summary: 1 passed, 0 failed, 0 cancelled, 0 skipped

Job Result
live ✅ success

@github-actions

github-actions Bot commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

E2E Target Results — ❌ Some jobs failed

Run: 28907262073
Workflow ref: codex/dcode-backend-neutral-observability
Requested targets: (default — all supported)
Requested jobs: (default — all default-enabled free-standing jobs; explicit-only jobs openshell-gateway-auth-contract, mcp-bridge-dev, hermes-gpu-startup, sandbox-rlimits-connect, and jetson-nvmap-gpu are skipped unless selected)
Summary: 35 passed, 31 failed, 4 cancelled, 5 skipped

Job Result
agent-turn-latency ❌ failure
bedrock-runtime-compatible-anthropic ✅ success
brave-search ✅ success
channels-add-remove ✅ success
channels-stop-start ✅ success
cloud-inference ✅ success
cloud-onboard ❌ failure
common-egress-agent ✅ success
concurrent-gateway-ports ✅ success
credential-migration ❌ failure
credential-sanitization ❌ failure
cron-preflight-inference-local ❌ failure
device-auth-health ✅ success
diagnostics ❌ failure
docs-validation ✅ success
double-onboard ✅ success
full-e2e ❌ failure
gateway-drift-preflight ✅ success
gateway-guard-recovery ❌ failure
gateway-health-honest ✅ success
generate-matrix ✅ success
gpu-double-onboard ⚠️ cancelled
gpu-e2e ✅ success
hermes-dashboard ❌ failure
hermes-discord ❌ failure
hermes-e2e ❌ failure
hermes-gpu-startup ⏭️ skipped
hermes-inference-switch ❌ failure
hermes-shields-config ❌ failure
hermes-slack ✅ success
inference-routing ✅ success
issue-2478-crash-loop-recovery ✅ success
issue-4434-tui-unreachable-inference ✅ success
issue-4462-scope-upgrade-approval ❌ failure
jetson-nvmap-gpu ⏭️ skipped
kimi-inference-compat ✅ success
launchable-smoke ❌ failure
live ❌ failure
mcp-bridge ⚠️ cancelled
mcp-bridge-dev ⏭️ skipped
messaging-compatible-endpoint ✅ success
messaging-providers ✅ success
model-router-provider-routed-inference ✅ success
network-policy ✅ success
ollama-auth-proxy ✅ success
onboard-negative-paths ✅ success
onboard-repair ✅ success
onboard-resume ✅ success
openclaw-discord-pairing ✅ success
openclaw-inference-switch ❌ failure
openclaw-skill-cli ✅ success
openclaw-slack-pairing ✅ success
openclaw-tui-chat-correlation ❌ failure
openshell-gateway-auth-contract ⏭️ skipped
openshell-gateway-upgrade ⚠️ cancelled
openshell-version-pin ✅ success
overlayfs-autofix ✅ success
rebuild-hermes ❌ failure
rebuild-hermes-stale-base ❌ failure
rebuild-openclaw ❌ failure
sandbox-operations ❌ failure
sandbox-rebuild ❌ failure
sandbox-rlimits-connect ⏭️ skipped
sandbox-survival ❌ failure
security-posture ❌ failure
sessions-agents-cli ✅ success
shields-config ❌ failure
skill-agent ❌ failure
snapshot-commands ✅ success
spark-install ❌ failure
state-backup-restore ❌ failure
telegram-injection ✅ success
token-rotation ⚠️ cancelled
tunnel-lifecycle ❌ failure
upgrade-stale-sandbox ❌ failure

Explicit-only jobs skipped: openshell-gateway-auth-contract (default dispatch excludes the resource-heavy OpenShell auth-contract probe unless selected; validate with jobs=openshell-gateway-auth-contract or targets=openshell-gateway-auth-contract), mcp-bridge-dev (default dispatch excludes moving OpenShell dev artifacts unless explicitly selected; validate with jobs=mcp-bridge-dev or targets=mcp-bridge-dev), hermes-gpu-startup (default dispatch excludes this explicit-only job unless selected; validate with jobs=hermes-gpu-startup or targets=hermes-gpu-startup), sandbox-rlimits-connect (default dispatch excludes the destructive rlimit fork/connect probe unless selected; validate with jobs=sandbox-rlimits-connect or targets=sandbox-rlimits-connect), jetson-nvmap-gpu (default dispatch excludes Jetson until a stable Jetson runner is available; validate with jobs=jetson-nvmap-gpu or targets=jetson-nvmap-gpu).

Failed jobs: agent-turn-latency, cloud-onboard, credential-migration, credential-sanitization, cron-preflight-inference-local, diagnostics, full-e2e, gateway-guard-recovery, hermes-dashboard, hermes-discord, hermes-e2e, hermes-inference-switch, hermes-shields-config, issue-4462-scope-upgrade-approval, launchable-smoke, live, openclaw-inference-switch, openclaw-tui-chat-correlation, rebuild-hermes, rebuild-hermes-stale-base, rebuild-openclaw, sandbox-operations, sandbox-rebuild, sandbox-survival, security-posture, shields-config, skill-agent, spark-install, state-backup-restore, tunnel-lifecycle, upgrade-stale-sandbox. Check run artifacts for logs.

@github-actions

github-actions Bot commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

E2E Target Results — ✅ All requested jobs passed

Run: 28907786669
Workflow ref: codex/dcode-backend-neutral-observability
Requested targets: (default — all supported)
Requested jobs: cloud-onboard,sandbox-rebuild,sandbox-operations
Summary: 3 passed, 0 failed, 0 cancelled, 0 skipped

Job Result
cloud-onboard ✅ success
sandbox-operations ✅ success
sandbox-rebuild ✅ success

@github-actions

github-actions Bot commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

E2E Target Results — ⚠️ Run cancelled — no signal

Run: 28907936688
Workflow ref: codex/dcode-backend-neutral-observability
Requested targets: (default — all supported)
Requested jobs: cloud-onboard,sandbox-rebuild,sandbox-operations
Summary: 0 passed, 0 failed, 3 cancelled, 0 skipped

Job Result
cloud-onboard ⚠️ cancelled
sandbox-operations ⚠️ cancelled
sandbox-rebuild ⚠️ cancelled

@apurvvkumaria
apurvvkumaria merged commit 9cb567f into main Jul 8, 2026
392 of 434 checks passed
@apurvvkumaria
apurvvkumaria deleted the codex/dcode-backend-neutral-observability branch July 8, 2026 00:25
@cv cv mentioned this pull request Jul 8, 2026
22 tasks
apurvvkumaria added a commit that referenced this pull request Jul 8, 2026
<!-- markdownlint-disable MD041 -->
## Summary

Prepares the user-facing documentation for NemoClaw v0.0.76 and closes
the release-prep documentation gate. It adds the release highlights,
documents the arm64 Local NIM warning and expanded image cleanup
behavior, and fixes agent-specific command headings in generated guides.

## Changes

- Add the v0.0.76 release-notes section and move the shared-gateway
route containment entry out of the v0.0.74 history where it was
incorrectly placed.
- Document the advisory Linux arm64 Local NIM manifest warning in the
canonical platform matrix and local-inference guidance.
- Document that `gc` scans both gateway-built and locally prebuilt
sandbox image repositories.
- Keep OpenClaw and Hermes session headings out of the generated Deep
Agents command guide.
- Add a focused variant regression test for the agent-specific session
headings.

### Source summary

| Merged sources | Documentation coverage |
| --- | --- |
| [#6414](#6414),
[#6418](#6418),
[#6416](#6416),
[#6344](#6344) | v0.0.76 release
notes and the Deep Agents quickstart/inference routes |
| [#6340](#6340) | v0.0.76
release notes and existing Deep Agents observability guidance |
| [#6338](#6338),
[#6378](#6378),
[#6297](#6297) | v0.0.76 release
notes and existing inference/troubleshooting guidance |
| [#6362](#6362) | v0.0.76
release notes and existing lifecycle, command, and credential guidance |
| [#6330](#6330),
[#6307](#6307),
[#6008](#6008) | v0.0.76 release
notes and existing security, troubleshooting, and command guidance |
| [#6382](#6382) | v0.0.76
release notes and existing MCP/command guidance |
| [#6326](#6326),
[#5868](#5868),
[#5539](#5539) | v0.0.76 release
notes, platform matrix, inference options, and local-inference guidance
|
| [#6396](#6396),
[#6390](#6390),
[#6007](#6007) | v0.0.76 release
notes and existing messaging guidance |
| [#5388](#5388),
[#6249](#6249),
[#6303](#6303),
[#6306](#6306) | v0.0.76 release
notes and command/lifecycle guidance |

## Type of Change

- [ ] Code change (feature, bug fix, or refactor)
- [x] Code change with doc updates
- [ ] Doc only (prose changes, no code sample modifications)
- [ ] Doc only (includes code sample changes)

## Quality Gates

- [x] Tests added or updated for changed behavior
- [ ] Existing tests cover changed behavior — justification:
- [ ] Tests not applicable — justification:
- [x] Docs updated for user-facing behavior changes
- [ ] Docs not applicable — justification:
- [ ] Sensitive paths changed (security, policy, credentials, preflight,
onboarding, inference, runner, sandbox, or messaging)
- [ ] Sensitive-path review completed or maintainer-approved waiver
recorded — reviewer/approval link/justification:
- [ ] Non-success, skipped, or missing CI check accepted by maintainer —
check name, approval link, and follow-up issue:

## Verification

- [x] PR description includes the DCO sign-off declaration and every
commit appears as `Verified` in GitHub
- [x] Normal `pre-commit`, `commit-msg`, and `pre-push` hooks passed, or
`npm run check:diff` passed when hooks were skipped or unavailable
- [x] Targeted behavior tests pass for the current change set, or tests
are marked not applicable above — `npx vitest run --project integration
test/generate-platform-docs.test.ts test/agent-variant-docs.test.ts
test/sync-agent-variant-docs.test.ts` (3 files, 29 tests passed)
- [ ] Applicable broad gate passed — `npm test` for broad
runtime/test-harness changes; `npm run check` for repo-wide
validation/coverage changes — command/result:
- [x] Quality Gates section completed with required justifications or
waivers
- [x] No secrets, API keys, or credentials committed
- [ ] `npm run docs` builds without warnings (doc changes only) —
completed with 0 errors and 2 pre-existing Fern warnings
- [x] Doc pages follow the [style
guide](https://github.com/NVIDIA/NemoClaw/blob/main/docs/CONTRIBUTING.md)
(doc changes only)
- [ ] New doc pages include SPDX header and frontmatter (new pages only)

---
Signed-off-by: Apurv Kumaria <akumaria@nvidia.com>


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Documentation**
* Added v0.0.76 release notes content, and removed an older conflicting
bullet from the surrounding release history.
* Expanded Local NVIDIA NIM guidance across inference/provider docs,
including an advisory for Linux arm64 DGX Spark/DGX Station hosts when a
matching `linux/arm64` image manifest is unavailable.
* Updated the command reference for correct session-section rendering
and clarified `gc` image cleanup sources.
* **Tests**
* Added coverage ensuring Deep Agents omits sessions headings while
Hermes includes them.
* **CI**
* Refreshed Local NVIDIA NIM provider notes used in the platform matrix.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Signed-off-by: Apurv Kumaria <akumaria@nvidia.com>
Hadar301 pushed a commit to Hadar301/NemoClaw-OpenShift that referenced this pull request Jul 12, 2026
## Summary

Add opt-in, backend-neutral observability for LangChain Deep Agents
Code. Root-owned NeMo Relay instrumentation exports bounded model and
tool content to a fixed host-local OTLP receiver, while an
operator-owned collector holds backend credentials and forwards traces
to LangSmith or another OTLP-compatible backend without rebuilding the
sandbox.

## Related Issue

Follow-up to NVIDIA#5621

Related to NVIDIA#3915

## Changes

- Add DCode-only `--observability` and `--no-observability` controls
that are off by default and persist through resume, ready-sandbox drift,
recreate, rebuild, snapshot clone, and registry recovery.
- Instrument managed model, tool, subagent, and LangGraph execution.
Export bounded prompts, model responses, tool arguments, and tool
results; keep graph node scopes to bounded names, a static integration
label, and status so they do not duplicate raw graph state.
- Redact credential-shaped and control-plane fields and omit request
headers, model settings, tool schemas, callback metadata, checkpoint and
interrupt payloads, and original exception text. Preserve agent results
and exact exception identity and traceback in agent execution.
- Keep local observability failure diagnostics content-free: caught
exception text and tracebacks are not logged, preventing ambient OTEL
headers, certificate paths, and client-key paths from leaking through
setup, export, callback, or cleanup failures.
- Send OTLP/HTTP only to
`http://host.openshell.internal:4318/v1/traces`, without custom,
exporter, or authentication headers. Ignore ambient exporter
configuration and fail open when trace delivery is unavailable.
- Manage the exact `observability-otlp-local` policy for DCode,
including add/remove reconciliation, managed-Python and endpoint
restrictions, ready-state recreation, and suppression on the
`restricted` tier.
- Pin `nemo-relay[langgraph]==0.4.0` and validate the real Relay
integration during image builds. Add a composed live E2E contract
covering OpenShell policy enforcement, launcher and direct execution,
captured model/tool content, ambient-canary absence, and negative host,
path, method, port, and binary cases.
- Preserve exact inner command arguments after the documented `sandbox
exec --` boundary, and harden the live OTLP capture server to reject
unexpected routes or exporter headers and persist only normalized
metadata beside bounded protobuf bodies.
- Document the complete host-collector workflow for LangSmith, including
private bridge binding, host-only credentials, regional and self-hosted
endpoints, verification, disabling, troubleshooting, and the
trace-content security boundary.

## Type of Change

- [ ] Code change (feature, bug fix, or refactor)
- [x] Code change with doc updates
- [ ] Doc only (prose changes, no code sample modifications)
- [ ] Doc only (includes code sample changes)

## Quality Gates

- [x] Tests added or updated for changed behavior
- [ ] Existing tests cover changed behavior — justification:
- [ ] Tests not applicable — justification:
- [x] Docs updated for user-facing behavior changes
- [ ] Docs not applicable — justification:
- [x] Sensitive paths changed (security, policy, credentials, preflight,
onboarding, inference, runner, sandbox, or messaging)
- [x] Sensitive-path review completed or maintainer-approved waiver
recorded — reviewer/approval link/justification: completed a
nine-category security review and an independent final-diff review with
no actionable findings. The real `nemo-relay==0.4.0` and
`langgraph==1.2.6` validator emitted nine OTLP requests totaling 9,060
protobuf bytes while enforcing unique OTLP attributes and proving
content bounds and redaction, callback isolation, zero ambient-exporter
canary traffic, and exact result and exception preservation. The
composed live contract covers the OpenShell policy and runtime boundary.
Arbitrary sandbox Python can still forge OTLP fields, so the host
collector must not treat trace attributes as authenticated tenant
identity.
- [ ] Non-success, skipped, or missing CI check accepted by maintainer —
check name, approval link, and follow-up issue:

## Verification

- [x] PR description includes the DCO sign-off declaration and every
commit appears as `Verified` in GitHub
- [x] Normal `pre-commit`, `commit-msg`, and `pre-push` hooks passed, or
`npm run check:diff` passed when hooks were skipped or unavailable
- [x] Targeted behavior tests pass for the current change set, or tests
are marked not applicable above — command/result or justification:
341/341 CLI feature tests, 123/123 integration and image tests, 44/44
E2E support tests, and 103/103 focused rebuild regression tests passed.
The combined post-CI regression slice passed 105/105 after normal hooks.
The current-head final-fix slice also passed 183/183 CLI, 22/22
E2E-support, 78/78 observability integration/image, and the policy-read
discovery audit. The real Relay validator emitted nine requests totaling
9,060 bytes and enforced unique resource, scope, span, event, and link
attributes. The final production-equivalent image build completed at
`sha256:11e48de2b7cbefe58e918d1d9fb303ce93229db2079a8a72446871dce39b0d3d`.
After merging current `main` and resolving its three rebuild conflicts,
137/137 focused rebuild tests passed locally, along with the CLI build,
CLI type-check, and Biome checks. All applicable current-head PR checks
passed (2 not-applicable checks were skipped). The composed cloud trace
contract passed on attempt 2 in [run
28847969488](https://github.com/NVIDIA/NemoClaw/actions/runs/28847969488),
and `network-policy`, `sandbox-rebuild`, `onboard-resume`, and
`onboard-repair` passed in [run
28847913562](https://github.com/NVIDIA/NemoClaw/actions/runs/28847913562).
The DCode-only shared-check regression passed 12/12 E2E-support tests,
and the compacted managed-patch validation passed 34/34 integration
tests. After the final two `main` synchronizations, focused post-merge
tests passed: snapshot 45/45, sandbox 42/42, registry recovery 50/50,
onboard integration 65/65, DCode integration 124/124, E2E support 12/12,
and docs variants/routes/commands 26/26, plus CLI type-check, size
budgets, local link checking, and `npm run docs` (0 errors; two
pre-existing warnings). On final head `9ebf3f29d`, Python compilation,
Biome, and 114/114 focused observability, image, and direct-module
integration tests passed. The new failure-log regression exposes all
three OTEL canaries against the pre-fix source and proves they are
absent after the fix. All required final-head CI checks passed; optional
self-hosted E2E jobs were still queued for runner capacity when this
evidence was recorded.
- [ ] Applicable broad gate passed — `npm test` for broad
runtime/test-harness changes; `npm run check` for repo-wide
validation/coverage changes — command/result: under the
repository-normal `022` umask, `npm test` completed with 13,560 passing
and 36 skipped tests. Its sole failure is the untouched
`e2e-migration-source-of-truth` check because
`openshell-gateway-upgrade-helpers.ts` has a pre-existing local
`shellQuote`; the same failure reproduces on `origin/main`, and no
maintainer waiver is claimed here.
- [x] Quality Gates section completed with required justifications or
waivers
- [x] No secrets, API keys, or credentials committed
- [ ] `npm run docs` builds without warnings (doc changes only) —
completed with 0 errors and two pre-existing repository warnings
- [x] Doc pages follow the [style
guide](https://github.com/NVIDIA/NemoClaw/blob/main/docs/CONTRIBUTING.md)
(doc changes only)
- [ ] New doc pages include SPDX header and frontmatter (new pages only)

Additional current-head checks:

- `npm run build:cli`
- `npm run typecheck:cli`
- `npm run validate:configs` (46/46)
- `npm run source-shape:check`
- `npm run test-size:check`
- `npm run docs` (0 errors; two pre-existing warnings)
- `git diff --check`

---

Signed-off-by: Carlos Villela <cvillela@nvidia.com>

---------

Signed-off-by: Carlos Villela <cvillela@nvidia.com>
Hadar301 pushed a commit to Hadar301/NemoClaw-OpenShift that referenced this pull request Jul 12, 2026
<!-- markdownlint-disable MD041 -->
## Summary

Prepares the user-facing documentation for NemoClaw v0.0.76 and closes
the release-prep documentation gate. It adds the release highlights,
documents the arm64 Local NIM warning and expanded image cleanup
behavior, and fixes agent-specific command headings in generated guides.

## Changes

- Add the v0.0.76 release-notes section and move the shared-gateway
route containment entry out of the v0.0.74 history where it was
incorrectly placed.
- Document the advisory Linux arm64 Local NIM manifest warning in the
canonical platform matrix and local-inference guidance.
- Document that `gc` scans both gateway-built and locally prebuilt
sandbox image repositories.
- Keep OpenClaw and Hermes session headings out of the generated Deep
Agents command guide.
- Add a focused variant regression test for the agent-specific session
headings.

### Source summary

| Merged sources | Documentation coverage |
| --- | --- |
| [NVIDIA#6414](NVIDIA#6414),
[NVIDIA#6418](NVIDIA#6418),
[NVIDIA#6416](NVIDIA#6416),
[NVIDIA#6344](NVIDIA#6344) | v0.0.76 release
notes and the Deep Agents quickstart/inference routes |
| [NVIDIA#6340](NVIDIA#6340) | v0.0.76
release notes and existing Deep Agents observability guidance |
| [NVIDIA#6338](NVIDIA#6338),
[NVIDIA#6378](NVIDIA#6378),
[NVIDIA#6297](NVIDIA#6297) | v0.0.76 release
notes and existing inference/troubleshooting guidance |
| [NVIDIA#6362](NVIDIA#6362) | v0.0.76
release notes and existing lifecycle, command, and credential guidance |
| [NVIDIA#6330](NVIDIA#6330),
[NVIDIA#6307](NVIDIA#6307),
[NVIDIA#6008](NVIDIA#6008) | v0.0.76 release
notes and existing security, troubleshooting, and command guidance |
| [NVIDIA#6382](NVIDIA#6382) | v0.0.76
release notes and existing MCP/command guidance |
| [NVIDIA#6326](NVIDIA#6326),
[NVIDIA#5868](NVIDIA#5868),
[NVIDIA#5539](NVIDIA#5539) | v0.0.76 release
notes, platform matrix, inference options, and local-inference guidance
|
| [NVIDIA#6396](NVIDIA#6396),
[NVIDIA#6390](NVIDIA#6390),
[NVIDIA#6007](NVIDIA#6007) | v0.0.76 release
notes and existing messaging guidance |
| [NVIDIA#5388](NVIDIA#5388),
[NVIDIA#6249](NVIDIA#6249),
[NVIDIA#6303](NVIDIA#6303),
[NVIDIA#6306](NVIDIA#6306) | v0.0.76 release
notes and command/lifecycle guidance |

## Type of Change

- [ ] Code change (feature, bug fix, or refactor)
- [x] Code change with doc updates
- [ ] Doc only (prose changes, no code sample modifications)
- [ ] Doc only (includes code sample changes)

## Quality Gates

- [x] Tests added or updated for changed behavior
- [ ] Existing tests cover changed behavior — justification:
- [ ] Tests not applicable — justification:
- [x] Docs updated for user-facing behavior changes
- [ ] Docs not applicable — justification:
- [ ] Sensitive paths changed (security, policy, credentials, preflight,
onboarding, inference, runner, sandbox, or messaging)
- [ ] Sensitive-path review completed or maintainer-approved waiver
recorded — reviewer/approval link/justification:
- [ ] Non-success, skipped, or missing CI check accepted by maintainer —
check name, approval link, and follow-up issue:

## Verification

- [x] PR description includes the DCO sign-off declaration and every
commit appears as `Verified` in GitHub
- [x] Normal `pre-commit`, `commit-msg`, and `pre-push` hooks passed, or
`npm run check:diff` passed when hooks were skipped or unavailable
- [x] Targeted behavior tests pass for the current change set, or tests
are marked not applicable above — `npx vitest run --project integration
test/generate-platform-docs.test.ts test/agent-variant-docs.test.ts
test/sync-agent-variant-docs.test.ts` (3 files, 29 tests passed)
- [ ] Applicable broad gate passed — `npm test` for broad
runtime/test-harness changes; `npm run check` for repo-wide
validation/coverage changes — command/result:
- [x] Quality Gates section completed with required justifications or
waivers
- [x] No secrets, API keys, or credentials committed
- [ ] `npm run docs` builds without warnings (doc changes only) —
completed with 0 errors and 2 pre-existing Fern warnings
- [x] Doc pages follow the [style
guide](https://github.com/NVIDIA/NemoClaw/blob/main/docs/CONTRIBUTING.md)
(doc changes only)
- [ ] New doc pages include SPDX header and frontmatter (new pages only)

---
Signed-off-by: Apurv Kumaria <akumaria@nvidia.com>


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Documentation**
* Added v0.0.76 release notes content, and removed an older conflicting
bullet from the surrounding release history.
* Expanded Local NVIDIA NIM guidance across inference/provider docs,
including an advisory for Linux arm64 DGX Spark/DGX Station hosts when a
matching `linux/arm64` image manifest is unavailable.
* Updated the command reference for correct session-section rendering
and clarified `gc` image cleanup sources.
* **Tests**
* Added coverage ensuring Deep Agents omits sessions headings while
Hermes includes them.
* **CI**
* Refreshed Local NVIDIA NIM provider notes used in the platform matrix.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Signed-off-by: Apurv Kumaria <akumaria@nvidia.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: cli Command line interface, flags, terminal UX, or output area: observability Logging, metrics, tracing, diagnostics, or debug output feature PR adds or expands user-visible functionality integration: dcode LangChain Deep Code integration behavior

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants