fix(dcode): route fetch_url through managed proxy - #6495
Conversation
Signed-off-by: Aaron Erickson <aerickson@nvidia.com>
|
Auto-sync is disabled for draft pull requests in this repository. Workflows must be run manually. Contributors can view more details about this message here. |
|
Note Reviews pausedIt 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 Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughThis PR adds a NemoClaw-managed trusted-proxy ChangesManaged Deep Agents Code updates
Estimated code review effort: 4 (Complex) | ~60 minutes Sequence Diagram(s)sequenceDiagram
participant start.sh
participant managed-dcode-runtime.py
participant tools.py
participant requests
participant CA bundle
start.sh->>managed-dcode-runtime.py: export trusted proxy URL
managed-dcode-runtime.py->>managed-dcode-runtime.py: managed_fetch_proxy_url()
managed-dcode-runtime.py->>tools.py: managed_fetch_with_redirects(url)
tools.py->>CA bundle: validate managed trust path
tools.py->>requests: Session(trust_env=False)
requests-->>tools.py: response / redirect
tools.py->>tools.py: validate hop URL and follow redirects
Suggested labels: Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
Code Coverage OverviewLanguages: TypeScript TypeScript / code-coverage/pluginThe overall coverage remains at 96%, unchanged from the TypeScript / code-coverage/cliThe overall coverage in the Show a code coverage summary of the most impacted files.
Updated |
|
🌿 Preview your docs: https://nvidia-preview-pr-6495.docs.buildwithfern.com/nemoclaw |
E2E Advisor RecommendationRequired E2E: Dispatch hint: Full advisor summaryE2E Recommendation AdvisorBase: Required E2E
Optional E2E
New E2E recommendations
Dispatch hint
|
E2E Target RecommendationRequired E2E targets: Dispatch required E2E targets:
Full E2E target advisor summaryE2E Target AdvisorBase: Required E2E targets
Optional E2E targets
Relevant changed files
|
PR Review Advisor — No blocking findingsMerge posture: No blocking advisor findings Action checklist
Test follow-ups to resolve or justifyIf these cover changed behavior, prefer adding them in this PR; otherwise state why existing coverage is enough or link the follow-up.
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. |
PR Review Advisor (Nemotron Ultra) — Changes requestedMerge posture: Do not merge yet Action checklist
Findings index
🚨 Required before mergeAddress these before merging unless a maintainer explicitly overrides the advisor with rationale.
|
Signed-off-by: Aaron Erickson <aerickson@nvidia.com>
E2E Target Results — ❌ Some jobs failedRun: 28973221328
|
Signed-off-by: Aaron Erickson <aerickson@nvidia.com>
E2E Target Results — ❌ Some jobs failedRun: 28974434860
|
Signed-off-by: Aaron Erickson <aerickson@nvidia.com>
E2E Target Results — ❌ Some jobs failedRun: 28974811698
|
Signed-off-by: Aaron Erickson <aerickson@nvidia.com>
Signed-off-by: Aaron Erickson <aerickson@nvidia.com>
There was a problem hiding this comment.
Actionable comments posted: 3
🧹 Nitpick comments (4)
test/e2e/support/platform-parity-cloud-experimental.test.ts (1)
250-264: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winSource-text assertions instead of behavioral coverage.
This test only checks that literal strings exist/don't exist in the shell script's source (
toContain/not.toContain), rather than exercising actualfetch_url_probe/expect_fetch_blockedruntime behavior. It locks in implementation text and would pass even if the denial-classification logic were broken, as long as the strings remain present.As per path instructions for
**/*.test.{ts,js,mts,mjs,cts,cjs}: "Prefer observable outcomes through the public boundary over source-text, private-shape, or mock-call assertions," and "Flag copied production algorithms, broad mocks that bypass the behavior under test, and conditionals that make a test pass without exercising its claim." Consider extending the self-test harness (as done for the command-shape test above) to actually feed a mocked/fixture blocked response throughfetch_url_probe/expect_fetch_blockedand assert on the classification outcome, rather than grepping script source.Note: the static-analysis path-traversal hint on
fs.readFileSynchere is a false positive — the path is a hardcoded literal, not user-controlled input.🤖 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 `@test/e2e/support/platform-parity-cloud-experimental.test.ts` around lines 250 - 264, The test is asserting shell-script source text instead of the actual fetch blocking behavior, so it can pass without exercising the classification logic. Update the e2e parity test around fetch_url_probe/expect_fetch_blocked to run the behavior through the existing self-test harness with a mocked or fixture blocked response, and assert on the resulting denial classification for the relevant cases. Keep the focus on observable outcomes from expect_fetch_blocked rather than checking for literal strings in 06-deepagents-code-python-egress.sh.Source: Path instructions
test/langchain-deepagents-code-proxy-launcher.test.ts (1)
24-24: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winDuplicate env-var-name literal instead of importing the shared constant.
TRUSTED_FETCH_PROXY_ENV_NAMEis redefined here as a raw string literal, duplicating the exported constant intest/helpers/langchain-deepagents-code-headless.ts:30, whichtest/langchain-deepagents-code-fetch-proxy.test.tsalready imports directly. Two independent copies of this literal can silently drift.♻️ Proposed fix
-const TRUSTED_FETCH_PROXY_ENV_NAME = "DEEPAGENTS_CODE_FETCH_URL_TRUSTED_PROXY_URL"; +import { TRUSTED_FETCH_PROXY_ENV_NAME } from "./helpers/langchain-deepagents-code-headless.ts";🤖 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 `@test/langchain-deepagents-code-proxy-launcher.test.ts` at line 24, The test is reintroducing the trusted proxy env var name as a raw string literal instead of reusing the shared constant, which can drift from the canonical value. Update the launcher test to import and use TRUSTED_FETCH_PROXY_ENV_NAME from the shared helper module used by the fetch-proxy test, and remove the duplicate local definition so the constant is defined in one place only.test/langchain-deepagents-code-fetch-proxy.test.ts (1)
137-158: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick winTest title overstates coverage — this only checks source text, not runtime behavior.
The test claims to "exercise actual fetch_url success and denied-host paths," but the body only does
toContainchecks against the raw text of06-deepagents-code-python-egress.sh; no probe is actually executed and no fetch_url outcome is observed here. As per path instructions, prefer observable outcomes over source-text assertions, and flag conditionals/checks that let a test pass without exercising its claim.Consider renaming the title to reflect what is actually verified (e.g., "asserts the egress check script wires expected fetch_url probes and hosts") and rely on the e2e pipeline execution of the shell script for the actual behavioral proof.
🤖 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 `@test/langchain-deepagents-code-fetch-proxy.test.ts` around lines 137 - 158, The test name overstates what is verified because this spec only inspects the contents of 06-deepagents-code-python-egress.sh via string assertions and never exercises fetch_url at runtime. Update the test title in langchain-deepagents-code-fetch-proxy.test.ts to match the actual behavior, and keep the assertions focused on the script wiring by referencing the existing fetch_url_probe_source and expect_fetch_blocked checks rather than claiming success/denial execution. If runtime coverage is intended, move that proof to the e2e path that runs the shell script instead of this text-based test.Source: Path instructions
agents/langchain-deepagents-code/managed-dcode-runtime.py (1)
1072-1104: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick winClose the
requests.Sessionto avoid leaking connection-pool resources.
managed_fetch_with_redirectscreates a freshSessionon every call but never closes it, so the underlying urllib3 connection pool (sockets/file descriptors) lingers until GC. On a long-running agent making repeatedfetch_urlcalls this accumulates. Use a context manager.♻️ Scope the session to a `with` block
current_url = url - session = requests.Session() - # Disable every requests environment-derived session setting, including - # proxy/NO_PROXY, netrc, and CA-bundle discovery. Each request receives the - # sole root-verified proxy mapping explicitly below. The separately - # selected CA bundle establishes TLS transport trust only; it cannot choose - # a proxy or authorize a destination under OpenShell policy. - session.trust_env = False - proxies = {"http": proxy_url, "https": proxy_url} - for _hop in range(max_redirects + 1): - validate_url(current_url) - response = session.get( - current_url, - timeout=timeout, - headers={"User-Agent": "Mozilla/5.0 (compatible; DeepAgents/1.0)"}, - allow_redirects=False, - proxies=proxies, - verify=ca_bundle, - ) - if 300 <= response.status_code < 400: - location = response.headers.get("Location") - if not location: - raise validation_error( - f"Redirect response (status {response.status_code}) is missing a Location header" - ) - current_url = urljoin(current_url, location) - continue - response.raise_for_status() - return response - - raise requests.exceptions.TooManyRedirects( - f"Exceeded {max_redirects} redirects" - ) + proxies = {"http": proxy_url, "https": proxy_url} + with requests.Session() as session: + # Disable every requests environment-derived session setting, including + # proxy/NO_PROXY, netrc, and CA-bundle discovery. Each request receives + # the sole root-verified proxy mapping explicitly below. The separately + # selected CA bundle establishes TLS transport trust only; it cannot + # choose a proxy or authorize a destination under OpenShell policy. + session.trust_env = False + for _hop in range(max_redirects + 1): + validate_url(current_url) + response = session.get( + current_url, + timeout=timeout, + headers={"User-Agent": "Mozilla/5.0 (compatible; DeepAgents/1.0)"}, + allow_redirects=False, + proxies=proxies, + verify=ca_bundle, + ) + if 300 <= response.status_code < 400: + location = response.headers.get("Location") + if not location: + raise validation_error( + f"Redirect response (status {response.status_code}) is missing a Location header" + ) + current_url = urljoin(current_url, location) + continue + response.raise_for_status() + return response + + raise requests.exceptions.TooManyRedirects( + f"Exceeded {max_redirects} redirects" + )🤖 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/managed-dcode-runtime.py` around lines 1072 - 1104, `managed_fetch_with_redirects` creates a new `requests.Session` but never closes it, which can leak connection-pool resources during repeated fetches. Update the session handling in `managed_fetch_with_redirects` to scope `session` with a context manager so it is always closed after use, while keeping the existing redirect loop, proxy setup, and request behavior unchanged.
🤖 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 1292-1294: The drift check for TOOLS_PATCH is incomplete because
it only guards _fetch_with_redirects; update the _require_functions call in
patch-managed-deepagents-code.py to also require _MAX_FETCH_REDIRECTS and
_UrlValidationError from tools.py so the patch fails fast if any of those
symbols are renamed. Make the check alongside the existing _fetch_with_redirects
gate in the same helper path.
In `@docs/reference/network-policies.mdx`:
- Around line 97-101: The paragraph in the network policies MDX source is
wrapped across multiple lines in a way that splits sentences, which violates the
one-sentence-per-line guideline. Reflow the text in the affected paragraph so
each sentence in the description of the raw.githubusercontent.com route is on
its own line, keeping the content unchanged while preserving the existing
markdown structure in the network-policies document.
- Around line 94-95: The PyPI policy description is inconsistent between the
docs table and the actual policy definition. Update the `pypi` entry in
`docs/reference/network-policies.mdx` to match the methods allowed in
`agents/langchain-deepagents-code/policy-additions.yaml` by reflecting only the
permitted method(s), or adjust the YAML policy if the docs are meant to be the
source of truth. Keep the `pypi` row and its method text aligned so
`network-policies.mdx` and `policy-additions.yaml` describe the same behavior.
---
Nitpick comments:
In `@agents/langchain-deepagents-code/managed-dcode-runtime.py`:
- Around line 1072-1104: `managed_fetch_with_redirects` creates a new
`requests.Session` but never closes it, which can leak connection-pool resources
during repeated fetches. Update the session handling in
`managed_fetch_with_redirects` to scope `session` with a context manager so it
is always closed after use, while keeping the existing redirect loop, proxy
setup, and request behavior unchanged.
In `@test/e2e/support/platform-parity-cloud-experimental.test.ts`:
- Around line 250-264: The test is asserting shell-script source text instead of
the actual fetch blocking behavior, so it can pass without exercising the
classification logic. Update the e2e parity test around
fetch_url_probe/expect_fetch_blocked to run the behavior through the existing
self-test harness with a mocked or fixture blocked response, and assert on the
resulting denial classification for the relevant cases. Keep the focus on
observable outcomes from expect_fetch_blocked rather than checking for literal
strings in 06-deepagents-code-python-egress.sh.
In `@test/langchain-deepagents-code-fetch-proxy.test.ts`:
- Around line 137-158: The test name overstates what is verified because this
spec only inspects the contents of 06-deepagents-code-python-egress.sh via
string assertions and never exercises fetch_url at runtime. Update the test
title in langchain-deepagents-code-fetch-proxy.test.ts to match the actual
behavior, and keep the assertions focused on the script wiring by referencing
the existing fetch_url_probe_source and expect_fetch_blocked checks rather than
claiming success/denial execution. If runtime coverage is intended, move that
proof to the e2e path that runs the shell script instead of this text-based
test.
In `@test/langchain-deepagents-code-proxy-launcher.test.ts`:
- Line 24: The test is reintroducing the trusted proxy env var name as a raw
string literal instead of reusing the shared constant, which can drift from the
canonical value. Update the launcher test to import and use
TRUSTED_FETCH_PROXY_ENV_NAME from the shared helper module used by the
fetch-proxy test, and remove the duplicate local definition so the constant is
defined in one place only.
🪄 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: 7dd93960-0384-4d3b-82ff-c9cb7374d1a2
📒 Files selected for processing (16)
agents/langchain-deepagents-code/dcode-launcher.shagents/langchain-deepagents-code/dependency-review.mdagents/langchain-deepagents-code/managed-dcode-runtime.pyagents/langchain-deepagents-code/patch-managed-deepagents-code.pyagents/langchain-deepagents-code/policy-additions.yamlagents/langchain-deepagents-code/start.shdocs/reference/network-policies.mdxtest/e2e/e2e-cloud-experimental/checks/06-deepagents-code-python-egress.shtest/e2e/support/platform-parity-cloud-experimental.test.tstest/helpers/langchain-deepagents-code-headless.tstest/helpers/langchain-deepagents-code-patch-fixture.tstest/langchain-deepagents-code-direct-module-patch.test.tstest/langchain-deepagents-code-fetch-proxy.test.tstest/langchain-deepagents-code-image.test.tstest/langchain-deepagents-code-progressive-tool-disclosure.test.tstest/langchain-deepagents-code-proxy-launcher.test.ts
💤 Files with no reviewable changes (1)
- test/langchain-deepagents-code-image.test.ts
Signed-off-by: cjagwani <cjagwani@nvidia.com>
Signed-off-by: Aaron Erickson <aerickson@nvidia.com>
Signed-off-by: Aaron Erickson <aerickson@nvidia.com>
E2E Target Results —
|
| Job | Result |
|---|---|
| live |
Signed-off-by: Aaron Erickson <aerickson@nvidia.com>
There was a problem hiding this comment.
🧹 Nitpick comments (1)
test/langchain-deepagents-code-proxy-launcher.test.ts (1)
80-89: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winSilent no-op risk: marker/marker_dir
.replace()calls lack pre-assertions.
String.replace()no-ops silently if the target literal (MANAGED_OBSERVABILITY_MARKER=...at Line 87,local marker_dir=/sandbox/.deepagentsat Line 116) drifts indcode-launcher.sh/start.sh. If that happens, the fixture keeps the real production path instead of the test-scoped one, and the test would still "pass" without exercising the intended isolated behavior.test/helpers/langchain-deepagents-code-headless.ts(Lines 56-58, 80-83) now guards equivalent replacements withexpect(original).toContain(...)— apply the same pattern here for consistency and drift detection.As per path instructions,
**/*.test.{ts,js,mts,mjs,cts,cjs}: "Flag copied production algorithms, broad mocks that bypass the behavior under test, and conditionals that make a test pass without exercising its claim."♻️ Proposed guard additions
const fixture = replaceManagedProxyFileConstants( readAgentFile("dcode-launcher.sh") .replace( + // guard: fail fast if the upstream constant literal drifted 'readonly MANAGED_DCODE_WRAPPER="/usr/local/lib/nemoclaw/dcode-wrapper.sh"', `readonly MANAGED_DCODE_WRAPPER="${probePath}"`, ) .replace( 'readonly MANAGED_OBSERVABILITY_MARKER="/sandbox/.deepagents/.nemoclaw-observability-enabled"', `readonly MANAGED_OBSERVABILITY_MARKER="${observabilityMarkerPath(tempDir)}"`, ), tempDir, );+ expect(readAgentFile("start.sh")).toContain("local marker_dir=/sandbox/.deepagents"); const fixture = replaceManagedProxyFileConstants(readAgentFile("start.sh"), tempDir) .replace("local target=/tmp/nemoclaw-proxy-env.sh", `local target="${envFile}"`) .replace( 'tmp="$(mktemp /tmp/nemoclaw-proxy-env.XXXXXX)"', `tmp="$(mktemp "${ephemeralDir}/nemoclaw-proxy-env.XXXXXX")"`, ) .replace("local marker_dir=/sandbox/.deepagents", `local marker_dir="${markerDir}"`);Also applies to: 110-116
🤖 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 `@test/langchain-deepagents-code-proxy-launcher.test.ts` around lines 80 - 89, The fixture setup in the code proxy launcher test silently falls back if the string replacements stop matching, so add pre-assertions before each .replace in the dcode-launcher.sh and start.sh preparation to verify the original literals are present. Use the same guard pattern already used in test/helpers/langchain-deepagents-code-headless.ts by checking the source content contains the expected MANAGED_OBSERVABILITY_MARKER and marker_dir values before replacing them, so drift in replaceManagedProxyFileConstants and related test fixture setup fails loudly instead of masking a real path leak.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.
Nitpick comments:
In `@test/langchain-deepagents-code-proxy-launcher.test.ts`:
- Around line 80-89: The fixture setup in the code proxy launcher test silently
falls back if the string replacements stop matching, so add pre-assertions
before each .replace in the dcode-launcher.sh and start.sh preparation to verify
the original literals are present. Use the same guard pattern already used in
test/helpers/langchain-deepagents-code-headless.ts by checking the source
content contains the expected MANAGED_OBSERVABILITY_MARKER and marker_dir values
before replacing them, so drift in replaceManagedProxyFileConstants and related
test fixture setup fails loudly instead of masking a real path leak.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Enterprise
Run ID: 501c5400-b6e7-45d1-83a8-99d60bc35d86
📒 Files selected for processing (14)
agents/langchain-deepagents-code/dcode-launcher.shagents/langchain-deepagents-code/dependency-review.mdagents/langchain-deepagents-code/start.shsrc/lib/actions/sandbox/snapshot.test.tssrc/lib/actions/sandbox/snapshot.tssrc/lib/onboard/sandbox-create-launch-observability.test.tssrc/lib/onboard/sandbox-create-launch.tstest/dcode-managed-exec.test.tstest/e2e/e2e-cloud-experimental/checks/09-deepagents-code-tavily-opt-in.shtest/e2e/e2e-cloud-experimental/checks/11-deepagents-code-observability.shtest/e2e/support/platform-parity-cloud-experimental.test.tstest/helpers/langchain-deepagents-code-headless.tstest/langchain-deepagents-code-fetch-proxy.test.tstest/langchain-deepagents-code-proxy-launcher.test.ts
✅ Files skipped from review due to trivial changes (1)
- agents/langchain-deepagents-code/dependency-review.md
🚧 Files skipped from review as they are similar to previous changes (2)
- test/e2e/support/platform-parity-cloud-experimental.test.ts
- test/langchain-deepagents-code-fetch-proxy.test.ts
E2E Target Results —
|
| Job | Result |
|---|---|
| live |
Signed-off-by: Aaron Erickson <aerickson@nvidia.com>
E2E Target Results — ✅ All selected jobs passedRun: 28983472430
|
E2E Target Results — ❌ Some jobs failedRun: 28983839955
|
E2E Target Results — ❌ Some jobs failedRun: 28984380880
|
Signed-off-by: Aaron Erickson <aerickson@nvidia.com>
Signed-off-by: Aaron Erickson <aerickson@nvidia.com>
E2E Target Results — ✅ All selected jobs passedRun: 28985115884
|
E2E Target Results — ❌ Some jobs failedRun: 28985313040
|
E2E Target Results — ✅ All selected jobs passedRun: 28985558470
|
E2E Target Results — ✅ All selected jobs passedRun: 28985313040
|
<!-- markdownlint-disable MD041 --> ## Summary This follow-up keeps the v0.0.78 release notes synchronized with PR #6495, which merged after the original release-prep docs refresh. The deeper network-policy reference already documents the exact endpoint, methods, and managed binaries. ## Changes - #6495 -> `docs/about/release-notes.mdx`: Add policy-routed repository reads to the v0.0.78 lead and explain that managed Deep Agents Code `fetch_url` uses NemoClaw's policy proxy with read-only `raw.githubusercontent.com` access. - Reviewed #6534 against the existing backup/restore and lifecycle documentation; no additional prose is needed because it restores the documented contract. ## Type of Change - [ ] Code change (feature, bug fix, or refactor) - [ ] Code change with doc updates - [x] Doc only (prose changes, no code sample modifications) - [ ] Doc only (includes code sample changes) ## Quality Gates <!-- Check exactly one tests line and one docs line. Check other lines when applicable. Add every requested justification or approval reference. --> - [ ] Tests added or updated for changed behavior - [ ] Existing tests cover changed behavior — justification: - [x] Tests not applicable — justification: release-note prose only; no code sample or generated behavior changed. - [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 <!-- Check each applicable item only when supported by the requested evidence. Run targeted tests once per relevant change set and rerun after later edits or hook autofixes that can affect the tested behavior. Do not rerun hook-covered checks. --> - [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 — tests are not applicable to prose-only release notes - [ ] 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) --- <!-- DCO sign-off is required in this PR description, and every commit must appear as Verified in GitHub. Run: git config user.name && git config user.email --> Signed-off-by: Charan Jagwani <cjagwani@nvidia.com> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Documentation** * Updated release notes to reflect new opt-in thread-scoped auto-approval and policy-routed repository reads. * Added notes about sandboxed `fetch_url` handling for GitHub source access and the allowed GitHub request types. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
## Summary Route managed Deep Agents Code `fetch_url` requests through NemoClaw's policy proxy instead of the package's direct DNS-pinning transport. The direct transport is valid outside the sandbox, but it cannot resolve destinations in the managed proxy-only network path and produces misleading DNS failures while proxy-aware tools continue to work. The adapter is limited to the pinned `deepagents-code==0.1.34` managed image. Unmanaged imports retain the upstream transport. ## Source boundary and lifecycle - Invalid state: DCode 0.1.34 disables ambient proxies and performs local DNS pinning for `fetch_url`; managed NemoClaw egress and destination resolution must instead pass through the policy proxy. - Source boundary: NemoClaw owns the image, launchers, and policy contract, but not the hash-locked third-party `fetch_url` implementation. - Integrity boundary: the runtime independently reconstructs the proxy URL from root-owned, mode-0444 host/port files and requires the explicit managed and conventional proxy variables to match. Requests ambient proxy discovery and `NO_PROXY` bypass remain disabled on every redirect hop. - Removal condition: delete the exact-version adapter when a pinned DCode release provides a supported policy-proxy transport with equivalent redirect validation and fail-closed behavior. ## Changes - Patch the exact DCode 0.1.34 `fetch_url` redirect path only in managed launches. - Fail closed on forged proxy environments, unsafe root-owned proxy files, malformed targets/proxies, credentialed redirects, and redirect-limit drift. - Open the configured CA bundle with no-follow and metadata checks, pin that validated file descriptor for the whole redirect chain, and rewind per hop; concurrent path mutation can yield only the original trust bytes or a generic validation failure. - Normalize initial and redirect target validation to generic non-reflecting errors, including IDNA failures. - Allow `raw.githubusercontent.com` only for GET/HEAD so DCode can follow GitHub file links and read repository source; repository/ref/path segments vary by task, so the host route is constrained by method and managed binary. - Require the live egress check to receive a nonempty 2xx body, and explicitly deny an unapproved host, cloud metadata, and loopback. - Recognize a strictly validated managed-policy denial when curl interleaves the proxy JSON body with its own stderr text; keep the existing size bound, exact error code, and structured denial-detail checks. - Preserve the credential-free observability enable bit across environment- less policy restarts, with explicit `1`/`0` on create/rebuild/clone paths. - Document the managed network-policy behavior and adapter lifecycle. ## Automated advisor dispositions - `PRA-1` — justified as intentional. Underscores are accepted only for controlled internal/container proxy aliases, preserving parity with the host-side validator. The value is reconstructed from canonical root-owned mode-0444 files and selects the managed proxy endpoint, not a fetch destination. Cross-boundary tests cover `proxy_name` and the full port range. - `PRA-2` — justified per RFC 3986. Userinfo exists only in the URI authority; `@` and `:` after the authority are ordinary path characters and can occur in repository paths. Every hop still rejects authority userinfo, requires HTTPS, validates host and port, uses the explicit policy proxy as the destination/SSRF authority, and returns validation errors without reflecting the candidate URL. Tests cover allowed path data and rejected authority credentials. - `PRA-2` (final 204 finding) — intentionally retained. This is a GET/read acceptance check for the approved raw GitHub README, not a generic HTTP reachability check. A 204 or zero-length body cannot satisfy the repository- source reading use case and would mask an empty fetch; HEAD is not used. The dependency review and change summary document the nonempty 2xx contract, and deterministic success/denial self-tests cover classifier behavior. - Runtime follow-up — satisfied on final head: all four required targets (DCode, cloud-onboard, network-policy, and snapshot) passed in [run 28985313040, attempt 2](https://github.com/NVIDIA/NemoClaw/actions/runs/28985313040). The failed first cloud-onboard attempt was a GitHub HTTP 429 before NemoClaw ran; an isolated exact-head [retry](https://github.com/NVIDIA/NemoClaw/actions/runs/28985558470) also passed. ## 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) - [ ] Sensitive-path review completed or maintainer-approved waiver recorded — reviewer/approval link/justification: pending maintainer review - [ ] 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 — initial combined suites passed 169/169 and the post-hook subset passed 43/43; the final current-main focused suite passed 308 tests with 1 intentional skip; `npm run check:diff` and `npm run build:cli` passed - [x] Applicable broad gate passed — final exact-head regular CI completed with 42 passes and 2 expected skips; DCode, cloud-onboard, network-policy, and snapshot all passed in [run 28985313040, attempt 2](https://github.com/NVIDIA/NemoClaw/actions/runs/28985313040) - [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) — 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: Aaron Erickson <aerickson@nvidia.com> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added managed fetch support for Deep Agents Code, including trusted proxy handling, redirect-aware fetching, and stricter network policy controls. * Expanded network access to allow read-only access to `raw.githubusercontent.com` for repository file retrieval. * Improved observability marker handling so state is preserved more reliably across restarts. * **Bug Fixes** * Strengthened protection against malformed redirects, unsafe proxy overrides, and unexpected network destinations. * Improved policy denial detection so mixed or interleaved error output is classified more accurately. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Signed-off-by: Aaron Erickson <aerickson@nvidia.com> Signed-off-by: cjagwani <cjagwani@nvidia.com> Co-authored-by: cjagwani <cjagwani@nvidia.com> Co-authored-by: Carlos Villela <cvillela@nvidia.com>
<!-- markdownlint-disable MD041 --> ## Summary This follow-up keeps the v0.0.78 release notes synchronized with PR NVIDIA#6495, which merged after the original release-prep docs refresh. The deeper network-policy reference already documents the exact endpoint, methods, and managed binaries. ## Changes - NVIDIA#6495 -> `docs/about/release-notes.mdx`: Add policy-routed repository reads to the v0.0.78 lead and explain that managed Deep Agents Code `fetch_url` uses NemoClaw's policy proxy with read-only `raw.githubusercontent.com` access. - Reviewed NVIDIA#6534 against the existing backup/restore and lifecycle documentation; no additional prose is needed because it restores the documented contract. ## Type of Change - [ ] Code change (feature, bug fix, or refactor) - [ ] Code change with doc updates - [x] Doc only (prose changes, no code sample modifications) - [ ] Doc only (includes code sample changes) ## Quality Gates <!-- Check exactly one tests line and one docs line. Check other lines when applicable. Add every requested justification or approval reference. --> - [ ] Tests added or updated for changed behavior - [ ] Existing tests cover changed behavior — justification: - [x] Tests not applicable — justification: release-note prose only; no code sample or generated behavior changed. - [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 <!-- Check each applicable item only when supported by the requested evidence. Run targeted tests once per relevant change set and rerun after later edits or hook autofixes that can affect the tested behavior. Do not rerun hook-covered checks. --> - [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 — tests are not applicable to prose-only release notes - [ ] 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) --- <!-- DCO sign-off is required in this PR description, and every commit must appear as Verified in GitHub. Run: git config user.name && git config user.email --> Signed-off-by: Charan Jagwani <cjagwani@nvidia.com> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Documentation** * Updated release notes to reflect new opt-in thread-scoped auto-approval and policy-routed repository reads. * Added notes about sandboxed `fetch_url` handling for GitHub source access and the allowed GitHub request types. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
Summary
Route managed Deep Agents Code
fetch_urlrequests through NemoClaw's policyproxy instead of the package's direct DNS-pinning transport. The direct
transport is valid outside the sandbox, but it cannot resolve destinations in
the managed proxy-only network path and produces misleading DNS failures while
proxy-aware tools continue to work.
The adapter is limited to the pinned
deepagents-code==0.1.34managed image.Unmanaged imports retain the upstream transport.
Source boundary and lifecycle
pinning for
fetch_url; managed NemoClaw egress and destination resolutionmust instead pass through the policy proxy.
not the hash-locked third-party
fetch_urlimplementation.root-owned, mode-0444 host/port files and requires the explicit managed and
conventional proxy variables to match. Requests ambient proxy discovery and
NO_PROXYbypass remain disabled on every redirect hop.release provides a supported policy-proxy transport with equivalent redirect
validation and fail-closed behavior.
Changes
fetch_urlredirect path only in managed launches.malformed targets/proxies, credentialed redirects, and redirect-limit drift.
validated file descriptor for the whole redirect chain, and rewind per hop;
concurrent path mutation can yield only the original trust bytes or a generic
validation failure.
errors, including IDNA failures.
raw.githubusercontent.comonly for GET/HEAD so DCode can follow GitHubfile links and read repository source; repository/ref/path segments vary by
task, so the host route is constrained by method and managed binary.
deny an unapproved host, cloud metadata, and loopback.
proxy JSON body with its own stderr text; keep the existing size bound, exact
error code, and structured denial-detail checks.
less policy restarts, with explicit
1/0on create/rebuild/clone paths.Automated advisor dispositions
PRA-1— justified as intentional. Underscores are accepted only forcontrolled internal/container proxy aliases, preserving parity with the
host-side validator. The value is reconstructed from canonical root-owned
mode-0444 files and selects the managed proxy endpoint, not a fetch
destination. Cross-boundary tests cover
proxy_nameand the full port range.PRA-2— justified per RFC 3986. Userinfo exists only in the URI authority;@and:after the authority are ordinary path characters and can occurin repository paths. Every hop still rejects authority userinfo, requires
HTTPS, validates host and port, uses the explicit policy proxy as the
destination/SSRF authority, and returns validation errors without reflecting
the candidate URL. Tests cover allowed path data and rejected authority
credentials.
PRA-2(final 204 finding) — intentionally retained. This is a GET/readacceptance check for the approved raw GitHub README, not a generic HTTP
reachability check. A 204 or zero-length body cannot satisfy the repository-
source reading use case and would mask an empty fetch; HEAD is not used. The
dependency review and change summary document the nonempty 2xx contract, and
deterministic success/denial self-tests cover classifier behavior.
(DCode, cloud-onboard, network-policy, and snapshot) passed in
run 28985313040, attempt 2.
The failed first cloud-onboard attempt was a GitHub HTTP 429 before NemoClaw
ran; an isolated exact-head retry
also passed.
Type of Change
Quality Gates
Verification
Verifiedin GitHubpre-commit,commit-msg, andpre-pushhooks passed, ornpm run check:diffpassed when hooks were skipped or unavailablenpm run check:diffandnpm run build:clipassednpm run docsbuilds without warnings (doc changes only) — 0 errors and 2 pre-existing Fern warningsSigned-off-by: Aaron Erickson aerickson@nvidia.com
Summary by CodeRabbit
New Features
raw.githubusercontent.comfor repository file retrieval.Bug Fixes