feat(sandbox): add vi, jq, and dos2unix to base images - #3091
Conversation
Fixes #2999 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
📝 WalkthroughWalkthroughThree essential Linux utilities—dos2unix, jq, and vim-tiny—are pinned to specific Debian versions and added to the apt-get install block in two base Dockerfiles, addressing missing sandbox tools. ChangesBase Image Utilities
Estimated Code Review Effort🎯 1 (Trivial) | ⏱️ ~3 minutes Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
🧹 Nitpick comments (2)
Dockerfile.base (1)
55-71: Run container-level E2E jobs for this base-image layer change.Since this modifies sandbox base image contents, please run the recommended selective jobs before merge:
cloud-e2e,sandbox-survival-e2e,hermes-e2e,rebuild-openclaw-e2e.As per coding guidelines, "
Dockerfile.base: This file affects the sandbox container image. Layer ordering, permissions, and baked config changes are only testable with a real container build."🤖 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 `@Dockerfile.base` around lines 55 - 71, This change modifies the sandbox base image RUN apt-get layer (the RUN apt-get update && apt-get install -y ... block in Dockerfile.base) so before merging, trigger the prescribed container-level E2E jobs — run cloud-e2e, sandbox-survival-e2e, hermes-e2e, and rebuild-openclaw-e2e — to validate layer ordering, permissions, and baked config in a real container build; if any test fails, iterate on the package list or layer ordering in the RUN apt-get block and re-run the same E2E jobs until all pass.agents/hermes/Dockerfile.base (1)
32-49: Run Hermes-focused E2E workflows for this base-image update.For confidence on onboarding/probe/routing paths, run:
hermes-e2e,hermes-discord-e2e,rebuild-hermes-e2e,rebuild-hermes-stale-base-e2e.As per coding guidelines, "
agents/hermes/**: This directory contains the Hermes agent. Changes affect multi-agent onboarding, health probes, and inference routing."🤖 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/hermes/Dockerfile.base` around lines 32 - 49, Run Hermes-focused end-to-end tests to validate the base-image package changes in agents/hermes/Dockerfile.base: execute the hermes-e2e, hermes-discord-e2e, rebuild-hermes-e2e, and rebuild-hermes-stale-base-e2e workflows against the updated RUN apt-get ... block to confirm onboarding, probe, and routing paths still work for the Hermes agent after the package/version updates.
🤖 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 `@agents/hermes/Dockerfile.base`:
- Around line 32-49: Run Hermes-focused end-to-end tests to validate the
base-image package changes in agents/hermes/Dockerfile.base: execute the
hermes-e2e, hermes-discord-e2e, rebuild-hermes-e2e, and
rebuild-hermes-stale-base-e2e workflows against the updated RUN apt-get ...
block to confirm onboarding, probe, and routing paths still work for the Hermes
agent after the package/version updates.
In `@Dockerfile.base`:
- Around line 55-71: This change modifies the sandbox base image RUN apt-get
layer (the RUN apt-get update && apt-get install -y ... block in
Dockerfile.base) so before merging, trigger the prescribed container-level E2E
jobs — run cloud-e2e, sandbox-survival-e2e, hermes-e2e, and rebuild-openclaw-e2e
— to validate layer ordering, permissions, and baked config in a real container
build; if any test fails, iterate on the package list or layer ordering in the
RUN apt-get block and re-run the same E2E jobs until all pass.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Enterprise
Run ID: 22aca7fc-412e-4921-a327-6780b1700596
📒 Files selected for processing (2)
Dockerfile.baseagents/hermes/Dockerfile.base
## Summary - Bump the docs release metadata to `0.0.37`. - Document release-prep updates for messaging policy presets, sandbox runtime utilities, and the GPU CDI troubleshooting path. - Refresh generated `nemoclaw-user-*` skills from the updated docs. ## Source summary - #3159 -> `docs/reference/troubleshooting.md`: Documents the GPU CDI preflight warning and remediation for `nvidia.com/gpu=all` gateway start failures. - #2415 -> `docs/reference/network-policies.md`, `docs/manage-sandboxes/messaging-channels.md`, `docs/network-policy/customize-network-policy.md`: Clarifies that Telegram, Discord, and Slack egress comes from opt-in messaging presets, not the baseline policy. - #3091 -> `docs/deployment/sandbox-hardening.md`, `docs/network-policy/customize-network-policy.md`: Documents the retained sandbox utilities `vi`, `jq`, and `dos2unix` while keeping host-side policy files as the durable source of truth. ## Test plan - `python3 scripts/docs-to-skills.py docs/ .agents/skills/ --prefix nemoclaw-user` - `make docs` - `npm run build:cli` - `npm run typecheck:cli` - Commit and pre-push hooks: markdownlint, docs-to-skills verification, gitleaks, commitlint, CLI typecheck ## Skipped - #3193 and #3191 matched `docs/.docs-skip` entries for experimental shields/config paths. - #3200 and #3183 were test-only fixes. - #3189 and #3163 were internal documentation/refactor changes with no public docs impact. Made with [Cursor](https://cursor.com) <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Documentation** * Clarified which utilities remain in the sandbox runtime for lightweight inspection and cleanup * Noted that messaging endpoints (Discord, Slack, Telegram) are not in the baseline policy and that channel presets are applied during onboarding * Added GPU passthrough troubleshooting for gateway startup * Updated release/version bump and release-prep workflow guidance, including Discord preset description updates <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Cursor <cursoragent@cursor.com>
) ## Summary A fresh DCode sandbox has no `dos2unix`, while OpenClaw and Hermes sandboxes do. This adds the package to the Deep Agents Code base image with the same pinned form the other two images already use. ## Related Issue Closes #8691 ## Root Cause `dos2unix` reached the OpenClaw and Hermes base images in #3091 (2026-05-07) as a plain-apt entry. `agents/langchain-deepagents-code/Dockerfile.base` was created 46 days later in #5197 (2026-06-22), so it never inherited that line. #7563 then moved the DCode image onto the same reviewed-artifact boundary and carried the snapshot-pinned `jq` and `vim-tiny` packages across — but not the plain-apt `dos2unix`. That is exactly the reported probe output: `vi: OK`, `jq: OK`, `dos2unix: MISSING`. The two utilities that travelled arrive through the checksum-pinned snapshot path; the one that did not travel is the only one installed through plain apt. ## Changes - `agents/langchain-deepagents-code/Dockerfile.base`: add `"dos2unix=7.5.2-1*"` to the runtime apt layer, immediately after `e2fsprogs`, mirroring the position and pin used at `Dockerfile.base:130` and `agents/hermes/Dockerfile.base:105`. - `test/sandbox-base-security-packages.test.ts`: run the runtime apt layer of each managed base image and assert on the `apt-get install` invocation it actually issues. Parameterized over all three images and both architectures (6 cases), so it fails when an image stops installing the utility rather than only when the literal string leaves the Dockerfile. Verified to have teeth: deleting the pin from the Deep Agents Code base fails exactly the two Deep Agents Code cases and leaves the other four passing. The version pin transfers verbatim because the DCode runtime stage uses a base image digest byte-identical to OpenClaw's (`node:22-trixie-slim@sha256:e6d9a389...`). ## The wildcard is required, not stylistic Debian trixie ships `dos2unix` as `7.5.2-1` on amd64 but as the binNMU `7.5.2-1+b1` on arm64. An exact `dos2unix=7.5.2-1` pin builds on amd64 and fails on arm64 — the reporter's own platform (Jetson Thor). ## Two-architecture install evidence The patched runtime apt layer was built and run on both architectures from the pinned base image. This is a real install and a real conversion, not an `apt-get -s` simulation. ```text # amd64 — reporter's exact probe command ps: OK top: OK free: OK uptime: OK vmstat: OK dos2unix: OK dos2unix 7.5.2 (2024-01-22) printf 'a\r\nb\r\n' | dos2unix -> od -c: 0000000 a \n b \n # arm64 — the reporter's platform dpkg --print-architecture: arm64 command -v dos2unix: /usr/bin/dos2unix installed version: 7.5.2-1+b1 printf 'x\r\ny\r\n' | dos2unix -> od -c: 0000000 x \n y \n ``` For contrast, the exact pin fails on arm64 at resolution time: ```text arm64: E: Version '7.5.2-1' for 'dos2unix' was not found ``` Both architectures report `0 upgraded, 1 newly installed` — the package pulls no transitive dependencies, so image surface grows by `dos2unix` alone. ## Deliberately not changed - **Security-package inventory.** `dos2unix` is a plain apt package, not one of the 10 snapshot/rebuilt debs. OpenClaw installs it yet omits it from that inventory, and `test/sandbox-base-security-packages.test.ts` asserts the inventory with an exact `toEqual` — adding an entry there would break the contract. - **Docs.** `docs/deployment/sandbox-hardening.mdx:20` is the repo's only `dos2unix` prose. It declares `agent-variants: ["openclaw"]`, so it does not formally cover DCode today. After this change that sentence is true of all three images, so no doc text is left needing correction. Extending the page's variant scope needs a matching `docs/index.yml` entry and a new `configure-sandboxes` slug in the deepagents tree, or `scripts/sync-agent-variant-docs.mts` hard-fails — a separate change that equally affects Hermes. ## 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 - [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: the only `dos2unix` prose is `docs/deployment/sandbox-hardening.mdx:20`, which is `agent-variants: ["openclaw"]` scoped. This change makes that existing sentence true of all three images rather than requiring new or corrected text. Extending the page to the deepagents variant is a separate change that equally affects Hermes. - [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: requesting maintainer review. The change adds one Debian-pinned utility to the DCode sandbox base apt layer. It installs no setuid binaries and pulls no transitive dependencies on either architecture; it does not touch the reviewed snapshot/checksum path, the security-package inventory, capabilities, or network policy. - [ ] Non-success, skipped, or missing CI check accepted by maintainer — check name, approval link, and follow-up issue: ## Documentation Writer Review - [ ] Documentation writer subagent reviewed the completed changes - Result: `no-docs-needed` - Evidence: no documentation paths changed. The repo's only `dos2unix` prose is `docs/deployment/sandbox-hardening.mdx:20`, which this change makes accurate for all three managed images rather than requiring an edit. - Agent: Claude Code ## Verification - [x] PR description includes a `Signed-off-by:` line and every commit appears as `Verified` in GitHub - [x] Normal `pre-commit`, `commit-msg`, and `pre-push` hooks passed - [x] Targeted behavior tests pass for the current change set — `npx vitest run` over the base-image surface: 13 files, 184 tests passing (`sandbox-base-runtime-tools`, `sandbox-base-security-packages`, `dcode-base-image-workflow`, `langchain-deepagents-code-profile-build-gate`, `base-image-publication`, `src/lib/sandbox-base-image/**`, `deep-agents-code-base-image`) - [ ] Applicable broad gate passed — not applicable; this is a single-package Dockerfile change, not a broad runtime or test-harness change - [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) - [ ] Doc pages follow the style guide (doc changes only) - [ ] New doc pages include SPDX header and frontmatter (new pages only) Additional checks run locally: - `hadolint 2.14.0` (the checksum-pinned CI version) on the edited Dockerfile: exit 0, zero findings. `DL3008` is active — the quoted wildcard satisfies it. - `npm run typecheck`: clean. - Two-architecture build and probe of the patched apt layer, as quoted above. **CI timing note for reviewers:** PR CI does not build the edited file. `base-image.yaml` triggers on push-to-main, `v*` tags, and `workflow_dispatch` only. The `managed-images.yaml` pull_request lane fires on `agents/**` but resolves the already-published `langchain-deepagents-code-sandbox-base:latest` and builds only `agents/langchain-deepagents-code/Dockerfile` — it completed in about a minute on this PR, which is consistent with no base build. The `pr-self-hosted.yaml` `build-sandbox-images` jobs likewise resolve the published base and build the production `Dockerfile`. The two-architecture evidence above stands in for that gap; happy to trigger a `workflow_dispatch` base build if you want a real in-CI build before merge. Signed-off-by: Dongni Yang <dongniy@nvidia.com> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added `dos2unix` to the runtime environment for supported security images and architectures. * **Tests** * Added coverage to verify successful installation of the expected `dos2unix` package version. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Signed-off-by: Dongni Yang <dongniy@nvidia.com>
Summary
Adds three essential Linux tools —
vi(vim-tiny),jq, anddos2unix— to both the OpenClaw and Hermes sandbox base images. These tools are commonly expected in any interactive shell environment and are frequently needed for ad-hoc editing and data wrangling inside a running sandbox.Related Issue
Fixes #2999
Changes
Dockerfile.base: adddos2unix=7.4.3-1,jq=1.6-2.1+deb12u1,vim-tiny=2:9.0.1378-2+deb12u2(Debian bookworm, exact versions)agents/hermes/Dockerfile.base: same three packages added aftersocatType of Change
Verification
npx prek run --all-filespassesnpm testpassesmake docsbuilds without warnings (doc changes only)Signed-off-by: jason-ma-nv jama@nvidia.com
Summary by CodeRabbit