fix(dcode): publish and validate sandbox base image - #6469
Conversation
Signed-off-by: Aaron Erickson <aerickson@nvidia.com>
Code Coverage OverviewLanguages: TypeScript TypeScript / code-coverage/pluginThe overall coverage in the Show a code coverage summary of the most covered files.
TypeScript / code-coverage/cliThe overall coverage in the Show a code coverage summary of the most covered files.
Updated |
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 (Nemotron Ultra) — Changes requestedMerge posture: Do not merge yet Action checklist
Findings index
Review findings by urgency: 0 required fixes, 2 items to resolve/justify, 3 in-scope improvements
|
📝 WalkthroughWalkthroughThis PR adds CI support to build and push a base image for the langchain-deepagents-code agent, pins Docker action versions in existing workflow jobs, extends sandbox base-image resolution to hash and track extra input paths, and adds runtime version validation against the agent manifest. ChangesDeep Agents Code base image support
Estimated code review effort: 3 (Moderate) | ~25 minutes Sequence Diagram(s)sequenceDiagram
participant GitHub Actions
participant base-image.yaml
participant check-production-build-args.sh
participant docker/build-push-action
participant GHCR
GitHub Actions->>base-image.yaml: push affecting workflow or Deep Agents inputs
base-image.yaml->>check-production-build-args.sh: validate production build args
base-image.yaml->>docker/build-push-action: build langchain-deepagents-code-sandbox-base
docker/build-push-action->>GHCR: push multi-arch image
sequenceDiagram
participant ensureAgentBaseImage
participant resolveSandboxBaseImage
participant Docker
ensureAgentBaseImage->>resolveSandboxBaseImage: create options with expectedVersion and inputPaths
resolveSandboxBaseImage->>Docker: run python3 importlib.metadata.version("deepagents-code")
Docker-->>resolveSandboxBaseImage: installed package version
resolveSandboxBaseImage-->>ensureAgentBaseImage: validateImage result / missing expectedVersion error
Suggested labels: Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
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. |
There was a problem hiding this comment.
🧹 Nitpick comments (3)
src/lib/sandbox-base-image-resolution.test.ts (1)
237-267: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick winTest outcome doesn't actually depend on the lockfile wiring.
toBeNull()here is guaranteed solely by the forced docker mock failures (status: 1), independent of whetherinputPathsis threaded through correctly. If the lockfile were silently dropped frominputPathsinresolveSandboxBaseImage, this test would still pass — the only evidence that dependency-lock tracking works comes from thetoHaveBeenCalledWithmock-call assertions, which lock in an implementation detail rather than an observable behavior difference.Consider making
sourceMocks.inputsDirty/inputsChangedreturn different values conditioned on whether the lockfile path is present, so the returned resolution result (nullvs. an actual image) diverges based on correct wiring — that would give real behavioral confidence instead of relying purely on call-argument assertions.Example approach
- dockerMocks.imageInspect.mockReturnValue({ status: 1 }); - dockerMocks.pull.mockReturnValue({ status: 1 }); + dockerMocks.imageInspect.mockReturnValue({ status: 0 }); + sourceMocks.inputsDirty.mockImplementation((_cwd, _env, paths) => + paths.includes(lockfile), + ); const options = resolutionOptions();Then assert the resolved result differs when the lockfile is included vs. omitted.
🤖 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/sandbox-base-image-resolution.test.ts` around lines 237 - 267, The test currently only proves the docker mock fails, not that resolveSandboxBaseImage threads lockfile paths through inputPaths correctly. Update the sandbox-base-image-resolution test setup so sourceMocks.inputsDirty and inputsChanged return different values depending on whether the lockfile path is present, using the resolveSandboxBaseImage flow to make the result itself diverge (null versus a resolved image) when lockfile wiring is correct or broken. Keep the existing identifiers like resolveSandboxBaseImage, sourceMocks.inputsDirty, and sourceMocks.inputsChanged, but shift the assertion from only mock-call arguments to an observable outcome difference.Source: Path instructions
src/lib/agent/base-image.ts (1)
145-159: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winConsider extracting shared docker-probe logic.
deepAgentsCodeBaseImageMatchesVersionduplicates thedockerCapture(..., { ignoreError: true, timeout: 20_000 })pattern already used inhermesBaseImageSupportsMcp. A small shared helper (e.g.,runPythonProbeInImage(imageRef, entrypoint, script)) would reduce duplication as more agent-specific validators are added.Also applies to: 161-182
🤖 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/agent/base-image.ts` around lines 145 - 159, Extract the repeated docker probe invocation shared by hermesBaseImageSupportsMcp and deepAgentsCodeBaseImageMatchesVersion into a helper such as runPythonProbeInImage that wraps dockerCapture with ignoreError and timeout, then have both validators call it with their imageRef, entrypoint, and probe script. Keep the existing behavior unchanged while centralizing the shared probe setup so future validators can reuse the same path.src/lib/agent/base-image.test.ts (1)
98-112: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winMock-call assertion locks in the internal docker command shape.
Asserting the exact args array passed to
dockerCaptureties this test to the internal implementation ofdeepAgentsCodeBaseImageMatchesVersion; any refactor (e.g., extracting a shared docker-probe helper) that keepsvalidateImagebehavior correct would still break this test. Consider dropping this assertion and relying on thevalidateImagereturn-value checks already present at lines 99 and 115 for behavioral confidence.As per path instructions, "Prefer observable outcomes through the public boundary over source-text, private-shape, or mock-call assertions."
🤖 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/agent/base-image.test.ts` around lines 98 - 112, The test for deepAgentsCodeBaseImageMatchesVersion is over-specifying the internal docker command by asserting the exact dockerCapture call shape, which makes it brittle to refactors. Update base-image.test.ts to focus on the observable behavior of validateImage and remove the mock-call assertion against dockerCapture, keeping the return-value checks around validateImage as the public boundary validation.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 `@src/lib/agent/base-image.test.ts`:
- Around line 98-112: The test for deepAgentsCodeBaseImageMatchesVersion is
over-specifying the internal docker command by asserting the exact dockerCapture
call shape, which makes it brittle to refactors. Update base-image.test.ts to
focus on the observable behavior of validateImage and remove the mock-call
assertion against dockerCapture, keeping the return-value checks around
validateImage as the public boundary validation.
In `@src/lib/agent/base-image.ts`:
- Around line 145-159: Extract the repeated docker probe invocation shared by
hermesBaseImageSupportsMcp and deepAgentsCodeBaseImageMatchesVersion into a
helper such as runPythonProbeInImage that wraps dockerCapture with ignoreError
and timeout, then have both validators call it with their imageRef, entrypoint,
and probe script. Keep the existing behavior unchanged while centralizing the
shared probe setup so future validators can reuse the same path.
In `@src/lib/sandbox-base-image-resolution.test.ts`:
- Around line 237-267: The test currently only proves the docker mock fails, not
that resolveSandboxBaseImage threads lockfile paths through inputPaths
correctly. Update the sandbox-base-image-resolution test setup so
sourceMocks.inputsDirty and inputsChanged return different values depending on
whether the lockfile path is present, using the resolveSandboxBaseImage flow to
make the result itself diverge (null versus a resolved image) when lockfile
wiring is correct or broken. Keep the existing identifiers like
resolveSandboxBaseImage, sourceMocks.inputsDirty, and sourceMocks.inputsChanged,
but shift the assertion from only mock-call arguments to an observable outcome
difference.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Enterprise
Run ID: 69f68664-f3c7-41fe-b010-452daaa4e6e7
📒 Files selected for processing (10)
.github/workflows/base-image.yamlsrc/lib/agent/base-image.test.tssrc/lib/agent/base-image.tssrc/lib/sandbox-base-image-resolution.test.tssrc/lib/sandbox-base-image.tssrc/lib/sandbox-base-image/resolution-key.test.tssrc/lib/sandbox-base-image/resolution-key.tssrc/lib/sandbox-base-image/types.tstest/dcode-base-image-workflow.test.tstest/openclaw-dependency-review.test.ts
Signed-off-by: Aaron Erickson <aerickson@nvidia.com>
There was a problem hiding this comment.
🧹 Nitpick comments (1)
.github/workflows/base-image.yaml (1)
219-220: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick winGHA cache will collide across the three build jobs.
type=ghawithout ascopedefaults tobuildkitfor every job, sobuild-and-push,build-and-push-hermes, and this newbuild-and-push-langchain-deepagents-codejob will thrash each other's cache — only the last job to finish in a run gets a hit, per docker/build-push-action#867 ("only the job that finished last in the previous run gets a cache hit").♻️ Proposed fix: scope the cache per image
cache-from: type=gha - cache-to: type=gha,mode=max + cache-from: type=gha,scope=langchain-deepagents-code + cache-to: type=gha,mode=max,scope=langchain-deepagents-codeApply analogous
scope=values to thebuild-and-pushandbuild-and-push-hermesjobs as well.🤖 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 @.github/workflows/base-image.yaml around lines 219 - 220, The GitHub Actions cache configuration is shared across multiple build jobs, so the new job will overwrite cache entries used by build-and-push and build-and-push-hermes. Update the cache-from and cache-to settings in each build job to use a unique scope per image/job, using the existing build-and-push, build-and-push-hermes, and build-and-push-langchain-deepagents-code job definitions as the places to apply the change.
🤖 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 @.github/workflows/base-image.yaml:
- Around line 219-220: The GitHub Actions cache configuration is shared across
multiple build jobs, so the new job will overwrite cache entries used by
build-and-push and build-and-push-hermes. Update the cache-from and cache-to
settings in each build job to use a unique scope per image/job, using the
existing build-and-push, build-and-push-hermes, and
build-and-push-langchain-deepagents-code job definitions as the places to apply
the change.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Enterprise
Run ID: 87012d0c-e880-4b72-9b53-ea7ed7b843f2
📒 Files selected for processing (5)
.github/workflows/base-image.yamlsrc/lib/agent/base-image.test.tssrc/lib/agent/base-image.tssrc/lib/sandbox-base-image-resolution.test.tstest/dcode-base-image-workflow.test.ts
🚧 Files skipped from review as they are similar to previous changes (3)
- src/lib/agent/base-image.test.ts
- test/dcode-base-image-workflow.test.ts
- src/lib/agent/base-image.ts
E2E Target Results — ✅ All selected jobs passedRun: 28947533169
|
Signed-off-by: Aaron Erickson <aerickson@nvidia.com>
E2E Target Results — ✅ All selected jobs passedRun: 28948929160
|
There was a problem hiding this comment.
🧹 Nitpick comments (1)
src/lib/sandbox-base-image-agent-resolution.test.ts (1)
66-95: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winTest only checks mock call arguments, not an observable behavior change.
Both
sourceMocks.inputsDirtyandsourceMocks.inputsChangedreturnfalsethroughout this test, so the assertions at Lines 87-94 only confirm thatdockerfilePath/lockfileare forwarded as arguments — they never prove that a dirty/diverged lockfile actually changes resolution behavior (e.g., forces a rebuild or a different cache key). Thenullresult here is caused solely by the pull failing (Line 68), unrelated to the dirty/divergence claim in the test title.Consider adding a case where
inputsDirty/inputsChangedreturntrueand asserting a resulting behavioral difference (e.g., resolution key changes, or a cached candidate is bypassed), to give real confidence in the "#6456" tracking behavior rather than only pinning call arguments.As per path instructions, "Prefer observable outcomes through the public boundary over source-text, private-shape, or mock-call assertions" for test files.
🤖 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/sandbox-base-image-agent-resolution.test.ts` around lines 66 - 95, The test in resolveSandboxBaseImage only verifies that inputsDirty and inputsChanged receive the lockfile arguments, but it does not prove any observable change in resolveSandboxBaseImage behavior. Update this test to exercise a case where sourceMocks.inputsDirty and sourceMocks.inputsChanged return true, then assert a public-facing outcome such as a different resolution result, cache-key behavior, or bypassed candidate in resolveSandboxBaseImage; keep the existing lockfile setup and use the resolveSandboxBaseImage, inputsDirty, and inputsChanged symbols to anchor the case.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 `@src/lib/sandbox-base-image-agent-resolution.test.ts`:
- Around line 66-95: The test in resolveSandboxBaseImage only verifies that
inputsDirty and inputsChanged receive the lockfile arguments, but it does not
prove any observable change in resolveSandboxBaseImage behavior. Update this
test to exercise a case where sourceMocks.inputsDirty and
sourceMocks.inputsChanged return true, then assert a public-facing outcome such
as a different resolution result, cache-key behavior, or bypassed candidate in
resolveSandboxBaseImage; keep the existing lockfile setup and use the
resolveSandboxBaseImage, inputsDirty, and inputsChanged symbols to anchor the
case.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Enterprise
Run ID: 5832e9e7-0975-4f96-b578-a99e68b37adf
📒 Files selected for processing (5)
src/lib/agent/base-image.test.tssrc/lib/agent/base-image.tssrc/lib/agent/deep-agents-code-base-image.test.tssrc/lib/agent/deep-agents-code-base-image.tssrc/lib/sandbox-base-image-agent-resolution.test.ts
<!-- markdownlint-disable MD041 --> ## Summary Adds the v0.0.77 release-note section from the shipped release announcement and release commit range. This is post-release docs recovery, so the PR is labeled for the next patch release train. ## Changes - Added `v0.0.77` to `docs/about/release-notes.mdx` with links to the deeper Deep Agents, architecture, inference, security, and agent-docs pages. - Source summary: - #6469 -> `docs/about/release-notes.mdx`: Documents Deep Agents Code base-image publication and stale-version validation. - #6471 -> `docs/about/release-notes.mdx`: Documents the managed runtime disabling LangGraph CLI analytics. - #6462 -> `docs/about/release-notes.mdx`: Documents the TUI, launch banner, and model-identity provider display behavior. - #6460 -> `docs/about/release-notes.mdx`: Documents bounded, best-effort OTLP trace credential scrubbing and the remaining collector-side redaction requirement. - #6423 -> `docs/about/release-notes.mdx`: Documents the checked-in loopback-only local credential form used by starter prompts. ## 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 runtime behavior or code samples 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 — command/result or justification: tests not applicable for release-note prose only. - [ ] 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) - [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) Verification note: `npm run docs` passed. `fern check --warnings` reports the existing light-mode accent color contrast warning: `2.41:1`, expected at least `3:1`. --- <!-- 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: Miyoung Choi <miyoungc@nvidia.com> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Documentation** * Added a new release-notes entry for **v0.0.77** at the top of the changelog. * Highlighted improved package validation, tighter handling of telemetry and trace data, and safer starter prompt behavior with stronger redaction and local-only submission. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
<!-- markdownlint-disable MD041 --> ## Summary Publishes the LangChain Deep Agents Code sandbox base image from the same main/tag workflow used by the other supported agents, closing the release-pipeline gap that left v0.0.76 resolving an obsolete `deepagents-code` 0.1.12 base. Base resolution now verifies the installed DCode distribution against the active manifest and fingerprints both the manifest and dependency lock so version or transitive dependency drift fails closed before final-image construction. ## Related Issue Refs NVIDIA#6456. Keep the issue open until the exact-main image run succeeds, the new GHCR package is public, and a clean ARM64 v0.0.76 install is revalidated. ## Changes - Add a guarded, multi-architecture GHCR publisher for `langchain-deepagents-code-sandbox-base` with `latest`, release-tag, and short-SHA metadata. - Trigger base-image publication when the workflow, DCode base Dockerfile, manifest, or dependency lock changes, so merging this fix immediately publishes `latest`. - Reject published, cached, or overridden DCode bases unless `/opt/venv` contains the manifest-required `deepagents-code` version; the metadata-only probe is networkless, capability-dropped, no-new-privileges, and read-only. - Include the DCode manifest and dependency lock in base-resolution identity plus dirty/main-divergence checks, preventing version and transitive lock changes from reusing stale images. - Pin every Docker action in the package-writing workflow to an immutable commit. - Add focused resolver, workflow, source-invariant, and build-guard regression coverage for NVIDIA#6456. ## Design Notes - The invalid state is a published or cached DCode image whose installed `deepagents-code` version differs from `manifest.yaml` `expected_version`. The manifest is the runtime acceptance contract and `requirements.lock` is the immutable image-build input; they serve different consumers and cannot safely be collapsed in this release fix. Their named invariant test runs in every PR's integration CI, so drift is merge-blocking. Remove the duplicated-field guard only when build tooling generates both consumers from one authoritative source. - Global `Dockerfile.base` and blueprint inputs intentionally remain in every agent resolution key under the resolver's pre-existing conservative policy. NVIDIA#6456 adds the DCode manifest/lock inputs without redefining cross-agent invalidation; removal requires a dedicated per-agent cache-policy design with migration and regression coverage. - DCode validation and DCode-specific resolution options are isolated in `deep-agents-code-base-image.ts`; the shared base-image module only selects those options. Hermes remains separate because it validates a different capability contract. - On exact head `29c17cd5`, `base-image.ts` is 378 lines versus 373 on `main`, and the generic resolver test is 452 lines versus 452 on `main`; the prior monolith findings are resolved by the focused DCode module and agent-resolution test file. - `dockerCapture` exposes stdout, not an exit-status result. Empty output therefore means the container or metadata probe may have failed and is rejected with a warning; a non-empty wrong version follows the distinct stale-version path. Expanding the Docker adapter result type is outside this publication fix. - `/opt/venv/bin/python3` is the DCode base Dockerfile's declared virtual-environment interpreter. Using the absolute path avoids `PATH` ambiguity; a future layout change intentionally fails closed, and the exact-head DCode onboarding E2E exercises the real image contract. - The `deepagents-code` distribution identifier comes from the top-level hash-locked requirement and is checked against the manifest version by required integration CI; any future package rename fails closed. - Coverage deliberately splits the two public contracts: focused DCode tests exercise manifest-to-validator binding, while the agent-resolution suite proves a pulled image is rejected when its supplied validator fails. Exact-head DCode onboarding and sandbox-rebuild E2E supply the composed runtime check. - The composed override/cache contract is covered at stable public seams: the DCode helper test binds the manifest version to the locked-down probe, the agent provisioning test passes that validator to resolution, the resolver test rejects an overridden candidate when validation fails, and the resolution-metadata test revalidates a cached hint before reuse. Exact-head DCode onboarding E2E validates the assembled runtime path; duplicating those private seams in one synthetic test would add coupling without a new behavior assertion. - Manifest/lock synchronization is CI-enforced: `test/dcode-base-image-workflow.test.ts` is in the integration project, `.github/actions/ci-cli-coverage-shard/action.yaml` runs both `--project cli` and `--project integration` for code PRs, and the required aggregate `cli-tests` check passed on this exact head. - Missing in-repo agent inputs are retained by normalization and hashed as `<missing>` by the resolution key. Only empty, repository-root, or out-of-repository paths are rejected, which is the intentional path-traversal boundary rather than silent missing-file handling. - The metadata probe has no network, capabilities, privilege escalation, writable root filesystem, or host mounts. Keeping the image's default user avoids requiring arbitrary override images to define a `sandbox` account; the command is read-only and fail-closed. - Image references are non-secret resolver inputs and are intentionally included in validation diagnostics so operators can identify a bad explicit override or cached tag; secret-bearing process output still passes through the existing runner redaction boundary. - Separate publisher jobs intentionally preserve package-specific failures, reruns, and tag observability. Converting all existing publishers to a matrix changes the release contract across three packages and is a separate workflow refactor, not prerequisite work for NVIDIA#6456. - `packages: write` is the minimum permission needed to publish the requested GHCR image and is pre-existing for this dedicated workflow; the only other workflow permission is `contents: read`, publisher jobs are repository-guarded, and all Docker actions are immutable-pinned. - PR NVIDIA#5755 is already conflicting with current `main`; its checkout dependency bump must rebase independently. PR NVIDIA#6469 remains mergeable and does not need to absorb that unrelated dependency update. ## Type of Change - [x] 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 <!-- Check exactly one tests line and one docs line. Check other lines when applicable. Add every requested justification or approval reference. --> - [x] Tests added or updated for changed behavior - [ ] Existing tests cover changed behavior — justification: - [ ] Tests not applicable — justification: - [ ] Docs updated for user-facing behavior changes - [x] Docs not applicable — justification: restores the documented hash-locked DCode runtime and stale-base fallback contracts without changing commands, flags, configuration, defaults, or policy. - [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 human review of base-image selection and release publication on this exact head. - [ ] 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 — exact head `29c17cd5`: changed resolver/base-image/workflow suites passed 56/56; the parent DCode image contract suites passed 83/83; JS-config and CLI typechecks, `npm run checks`, YAML/Biome validation, normal hooks, secret scan, import/shape checks, and test-size budgets passed. Exact-head [E2E run 28948929160](https://github.com/NVIDIA/NemoClaw/actions/runs/28948929160) passed DCode cloud onboarding and sandbox rebuild. - [ ] Applicable broad gate passed — `npm test` for broad runtime/test-harness changes; `npm run check` for repo-wide validation/coverage changes — command/result: - [ ] 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) - [ ] 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: Aaron Erickson <aerickson@nvidia.com> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Expanded automated image publishing to cover an additional agent base image and related dependency updates. * Base image rebuilds now respond to more relevant file changes, helping keep published images current. * **Bug Fixes** * Improved base image validation so outdated images are rejected more reliably. * Resolution logic now tracks dependency lockfile changes, reducing stale image reuse. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Signed-off-by: Aaron Erickson <aerickson@nvidia.com>
<!-- markdownlint-disable MD041 --> ## Summary Adds the v0.0.77 release-note section from the shipped release announcement and release commit range. This is post-release docs recovery, so the PR is labeled for the next patch release train. ## Changes - Added `v0.0.77` to `docs/about/release-notes.mdx` with links to the deeper Deep Agents, architecture, inference, security, and agent-docs pages. - Source summary: - NVIDIA#6469 -> `docs/about/release-notes.mdx`: Documents Deep Agents Code base-image publication and stale-version validation. - NVIDIA#6471 -> `docs/about/release-notes.mdx`: Documents the managed runtime disabling LangGraph CLI analytics. - NVIDIA#6462 -> `docs/about/release-notes.mdx`: Documents the TUI, launch banner, and model-identity provider display behavior. - NVIDIA#6460 -> `docs/about/release-notes.mdx`: Documents bounded, best-effort OTLP trace credential scrubbing and the remaining collector-side redaction requirement. - NVIDIA#6423 -> `docs/about/release-notes.mdx`: Documents the checked-in loopback-only local credential form used by starter prompts. ## 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 runtime behavior or code samples 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 — command/result or justification: tests not applicable for release-note prose only. - [ ] 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) - [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) Verification note: `npm run docs` passed. `fern check --warnings` reports the existing light-mode accent color contrast warning: `2.41:1`, expected at least `3:1`. --- <!-- 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: Miyoung Choi <miyoungc@nvidia.com> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Documentation** * Added a new release-notes entry for **v0.0.77** at the top of the changelog. * Highlighted improved package validation, tighter handling of telemetry and trace data, and safer starter prompt behavior with stronger redaction and local-only submission. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
Summary
Publishes the LangChain Deep Agents Code sandbox base image from the same main/tag workflow used by the other supported agents, closing the release-pipeline gap that left v0.0.76 resolving an obsolete
deepagents-code0.1.12 base. Base resolution now verifies the installed DCode distribution against the active manifest and fingerprints both the manifest and dependency lock so version or transitive dependency drift fails closed before final-image construction.Related Issue
Refs #6456. Keep the issue open until the exact-main image run succeeds, the new GHCR package is public, and a clean ARM64 v0.0.76 install is revalidated.
Changes
langchain-deepagents-code-sandbox-basewithlatest, release-tag, and short-SHA metadata.latest./opt/venvcontains the manifest-requireddeepagents-codeversion; the metadata-only probe is networkless, capability-dropped, no-new-privileges, and read-only.Design Notes
deepagents-codeversion differs frommanifest.yamlexpected_version. The manifest is the runtime acceptance contract andrequirements.lockis the immutable image-build input; they serve different consumers and cannot safely be collapsed in this release fix. Their named invariant test runs in every PR's integration CI, so drift is merge-blocking. Remove the duplicated-field guard only when build tooling generates both consumers from one authoritative source.Dockerfile.baseand blueprint inputs intentionally remain in every agent resolution key under the resolver's pre-existing conservative policy. [DGX Spark][DGX Station][Onboard] Published Deep Agents base image fails NemoClaw v0.0.76 version check #6456 adds the DCode manifest/lock inputs without redefining cross-agent invalidation; removal requires a dedicated per-agent cache-policy design with migration and regression coverage.deep-agents-code-base-image.ts; the shared base-image module only selects those options. Hermes remains separate because it validates a different capability contract.29c17cd5,base-image.tsis 378 lines versus 373 onmain, and the generic resolver test is 452 lines versus 452 onmain; the prior monolith findings are resolved by the focused DCode module and agent-resolution test file.dockerCaptureexposes stdout, not an exit-status result. Empty output therefore means the container or metadata probe may have failed and is rejected with a warning; a non-empty wrong version follows the distinct stale-version path. Expanding the Docker adapter result type is outside this publication fix./opt/venv/bin/python3is the DCode base Dockerfile's declared virtual-environment interpreter. Using the absolute path avoidsPATHambiguity; a future layout change intentionally fails closed, and the exact-head DCode onboarding E2E exercises the real image contract.deepagents-codedistribution identifier comes from the top-level hash-locked requirement and is checked against the manifest version by required integration CI; any future package rename fails closed.test/dcode-base-image-workflow.test.tsis in the integration project,.github/actions/ci-cli-coverage-shard/action.yamlruns both--project cliand--project integrationfor code PRs, and the required aggregatecli-testscheck passed on this exact head.<missing>by the resolution key. Only empty, repository-root, or out-of-repository paths are rejected, which is the intentional path-traversal boundary rather than silent missing-file handling.sandboxaccount; the command is read-only and fail-closed.packages: writeis the minimum permission needed to publish the requested GHCR image and is pre-existing for this dedicated workflow; the only other workflow permission iscontents: read, publisher jobs are repository-guarded, and all Docker actions are immutable-pinned.main; its checkout dependency bump must rebase independently. PR fix(dcode): publish and validate sandbox base image #6469 remains mergeable and does not need to absorb that unrelated dependency update.Type of Change
Quality Gates
Verification
Verifiedin GitHubpre-commit,commit-msg, andpre-pushhooks passed, ornpm run check:diffpassed when hooks were skipped or unavailable29c17cd5: changed resolver/base-image/workflow suites passed 56/56; the parent DCode image contract suites passed 83/83; JS-config and CLI typechecks,npm run checks, YAML/Biome validation, normal hooks, secret scan, import/shape checks, and test-size budgets passed. Exact-head E2E run 28948929160 passed DCode cloud onboarding and sandbox rebuild.npm testfor broad runtime/test-harness changes;npm run checkfor repo-wide validation/coverage changes — command/result:npm run docsbuilds without warnings (doc changes only)Signed-off-by: Aaron Erickson aerickson@nvidia.com
Summary by CodeRabbit
New Features
Bug Fixes