Skip to content

fix(docker): classify OpenClaw patch drift#3869

Merged
ericksoa merged 4 commits into
NVIDIA:mainfrom
yimoj:fix/3713-dockerfile-openclaw-patch-drift
May 21, 2026
Merged

fix(docker): classify OpenClaw patch drift#3869
ericksoa merged 4 commits into
NVIDIA:mainfrom
yimoj:fix/3713-dockerfile-openclaw-patch-drift

Conversation

@yimoj

@yimoj yimoj commented May 20, 2026

Copy link
Copy Markdown
Contributor

Summary

Classifies the compiled OpenClaw fetch-guard dist during the sandbox image build so known compatible layouts apply or skip patches explicitly, while unknown drift fails with OpenClaw version and dist details. This keeps mutable base-image/OpenClaw drift from producing opaque Dockerfile failures.

Related Issue

Fixes #3713

Changes

  • Add version-aware Dockerfile classification for the OpenClaw media fetch export patch and explicit proxy validator patch.
  • Preserve fail-closed behavior for unknown strict-fetch and proxy-validator layouts, with actionable error output.
  • Expand the fetch-guard regression test to exercise apply, skip, unknown-shape, and spoofed-shape paths without touching global OpenClaw state.

Type of Change

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

Verification

  • npx prek run --all-files passes
  • npm test passes
  • Tests added or updated for new or changed behavior
  • No secrets, API keys, or credentials committed
  • Docs updated for user-facing behavior changes
  • make 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 focused verification run:

  • /home/yimoj/.npm/_npx/52027bd8fc0022aa/node_modules/node/bin/node ./node_modules/vitest/vitest.mjs run test/fetch-guard-patch-regression.test.ts
  • git diff --check
  • hadolint Dockerfile
  • Extracted Dockerfile fetch-guard patch block against openclaw@2026.4.24, openclaw@2026.5.18, openclaw@2026.5.19-beta.1, openclaw@2026.5.19-beta.2, and a no-strict-layout mutation of openclaw@2026.5.18
  • codex review -c sandbox_mode="danger-full-access" --uncommitted ran twice with bounded timeouts; the first actionable probe found a Patch 2 spoofed-shape skip issue, which is fixed and covered by regression tests. The final rerun timed out while invoking broad npm test and emitted no final findings block or additional actionable finding in the saved log.

Signed-off-by: Yimo Jiang yimoj@nvidia.com

Summary by CodeRabbit

  • Chores

    • Improved build-time patch validation: conditional application, safer skip behavior, and clearer failure diagnostics when distribution shapes are ambiguous.
  • Tests

    • Expanded regression suite to cover patch application, skip conditions, idempotency, and explicit failure scenarios across varied distribution shapes.

Review Change Stack

Signed-off-by: Yimo Jiang <yimoj@nvidia.com>
@yimoj yimoj self-assigned this May 20, 2026
@coderabbitai

coderabbitai Bot commented May 20, 2026

Copy link
Copy Markdown
Contributor
📝 Walkthrough

Walkthrough

Refactors the Dockerfile OpenClaw fetch-guard patch into a build-time classifier that applies, skips, or fails with diagnostics based on dist shape, and adds sandboxed test helpers plus comprehensive regression tests covering all patch outcomes.

Changes

Fetch-guard patch classification and test coverage

Layer / File(s) Summary
Patch 1 and Patch 2 refactoring with classification logic
Dockerfile
Refactors both patches to classify dist shape. Patch 1 searches for strict fetch export alias or media-fetch guard references and conditionally rewrites, skips, or fails. Patch 2 idempotently injects an env-gated bypass into assertExplicitProxyAllowed, verifies injection, and conditionally skips or fails based on proxy-validation references. Shared patch_fail helper reports OpenClaw version and dist path on failure.
Test sandbox setup and patch execution helpers
test/fetch-guard-patch-regression.test.ts
Creates temp OpenClaw global and bin/shim directories, writes the blueprint YAML, and replaces Dockerfile paths with sandbox paths. Introduces createSedWrapper() to emulate sed -i -E via Perl and runFetchGuardPatchBlock() to execute the Dockerfile patch with stubbed openclaw --version and a fake sed on PATH.
Regression tests for patch behavior across scenarios
test/fetch-guard-patch-regression.test.ts
Refactors strict-media-fetch rewrite test to use runFetchGuardPatchBlock() and adds many regression tests validating patch application when targets exist, skipping when strict exports are absent, fail-closed behavior when targets disappear while related references remain, and edge cases (comment-only matches, missing private-proxy allowance, unrelated reviewed-shape code).

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Suggested labels

Sandbox

Suggested reviewers

  • ericksoa

Poem

🐰 I hopped through code with careful sniff,
Found guards to patch and tests to whiff,
I wrapped a sed, I stubbed a bin,
Ran sandboxed checks with a tiny grin,
Now builds decide if patches win.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'fix(docker): classify OpenClaw patch drift' clearly and concisely summarizes the main change—adding version-aware classification for OpenClaw patches in the Dockerfile.
Linked Issues check ✅ Passed The pull request addresses all primary objectives from issue #3713: adds version-aware classification to detect compatible OpenClaw layouts, applies or skips patches accordingly, preserves fail-closed behavior with actionable diagnostics, and includes comprehensive regression tests.
Out of Scope Changes check ✅ Passed All changes are directly related to the linked issue objectives: Dockerfile refactoring for OpenClaw patch classification and expanded regression tests to validate the new behavior across multiple scenarios.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ESLint skipped: no ESLint configuration detected in root package.json. To enable, add eslint to devDependencies.


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

@yimoj yimoj added the v0.0.48 Release target label May 20, 2026
@wscurran

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
Dockerfile (1)

713-721: Verify the new healthcheck does not rely on an unstated base-image dependency.

curl is not installed anywhere in this Dockerfile, so this probe now depends on whatever sandbox-base happens to contain. Please validate it against the oldest supported base tag, or switch the probe to python3 to keep it self-contained. Also cover this with the recommended Docker E2E jobs before merge. As per coding guidelines: Dockerfile: 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` around lines 713 - 721, The HEALTHCHECK now uses curl but the
Dockerfile never installs curl, creating an unstated base-image dependency;
update the HEALTHCHECK to use the existing python3 binary (replace the curl call
with a small python3 HTTP probe) or explicitly install curl earlier in the
Dockerfile so the probe is self-contained; locate the HEALTHCHECK block (symbol:
HEALTHCHECK and the inline CMD that references curl) and either convert its
final line to a python3-based check that opens http://127.0.0.1:{port}/health or
add a package install step for curl in the image build and ensure you validate
the change against the oldest supported base tag and E2E Docker jobs before
merging.
🤖 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 `@Dockerfile`:
- Around line 713-721: The HEALTHCHECK now uses curl but the Dockerfile never
installs curl, creating an unstated base-image dependency; update the
HEALTHCHECK to use the existing python3 binary (replace the curl call with a
small python3 HTTP probe) or explicitly install curl earlier in the Dockerfile
so the probe is self-contained; locate the HEALTHCHECK block (symbol:
HEALTHCHECK and the inline CMD that references curl) and either convert its
final line to a python3-based check that opens http://127.0.0.1:{port}/health or
add a package install step for curl in the image build and ensure you validate
the change against the oldest supported base tag and E2E Docker jobs before
merging.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 1bf94adb-547b-4bb0-a1cc-f78ff7f06fee

📥 Commits

Reviewing files that changed from the base of the PR and between bee5322 and ee8b705.

📒 Files selected for processing (2)
  • Dockerfile
  • test/fetch-guard-patch-regression.test.ts

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

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

Inline comments:
In `@test/fetch-guard-patch-regression.test.ts`:
- Around line 174-187: The test currently checks that the set
REVIEWED_OPENCLAW_PATCH_CLASSIFIER_VERSIONS contains the blueprint-pinned
version but doesn't assert that the single
CURRENT_REVIEWED_OPENCLAW_PATCH_CLASSIFIER_VERSION equals that pinned version;
update the test (near readBlueprintMinOpenClawVersion /
readDockerfileBaseOpenClawVersion usage) to add an assertion that
CURRENT_REVIEWED_OPENCLAW_PATCH_CLASSIFIER_VERSION === blueprintMinVersion so
the declared "current reviewed classifier version" cannot drift from the pinned
OpenClaw version.
🪄 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: 6d00b0f7-56a0-4a7d-9eda-a18b55c2014d

📥 Commits

Reviewing files that changed from the base of the PR and between ee8b705 and c12cd8f.

📒 Files selected for processing (1)
  • test/fetch-guard-patch-regression.test.ts

Comment on lines +174 to +187
it("requires classifier review when the pinned OpenClaw build version changes", () => {
const reviewMessage =
"Update fetch-guard classifier expectations before changing the OpenClaw build version.";

const blueprintMinVersion = readBlueprintMinOpenClawVersion();
const baseImageVersion = readDockerfileBaseOpenClawVersion();

expect(baseImageVersion, "Dockerfile.base and blueprint must pin the same OpenClaw version.").toBe(
blueprintMinVersion,
);
expect([...REVIEWED_OPENCLAW_PATCH_CLASSIFIER_VERSIONS], reviewMessage).toContain(
blueprintMinVersion,
);
});

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Assert the “current reviewed classifier version” matches the pinned OpenClaw version.

Line 184 verifies the reviewed set contains the blueprint version, but it does not verify CURRENT_REVIEWED_OPENCLAW_PATCH_CLASSIFIER_VERSION is the same pinned version. That can let the execution version drift while this guard still passes.

Suggested patch
   expect([...REVIEWED_OPENCLAW_PATCH_CLASSIFIER_VERSIONS], reviewMessage).toContain(
     blueprintMinVersion,
   );
+  expect(
+    CURRENT_REVIEWED_OPENCLAW_PATCH_CLASSIFIER_VERSION,
+    "The current classifier test version must track the pinned OpenClaw version.",
+  ).toBe(blueprintMinVersion);
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
it("requires classifier review when the pinned OpenClaw build version changes", () => {
const reviewMessage =
"Update fetch-guard classifier expectations before changing the OpenClaw build version.";
const blueprintMinVersion = readBlueprintMinOpenClawVersion();
const baseImageVersion = readDockerfileBaseOpenClawVersion();
expect(baseImageVersion, "Dockerfile.base and blueprint must pin the same OpenClaw version.").toBe(
blueprintMinVersion,
);
expect([...REVIEWED_OPENCLAW_PATCH_CLASSIFIER_VERSIONS], reviewMessage).toContain(
blueprintMinVersion,
);
});
it("requires classifier review when the pinned OpenClaw build version changes", () => {
const reviewMessage =
"Update fetch-guard classifier expectations before changing the OpenClaw build version.";
const blueprintMinVersion = readBlueprintMinOpenClawVersion();
const baseImageVersion = readDockerfileBaseOpenClawVersion();
expect(baseImageVersion, "Dockerfile.base and blueprint must pin the same OpenClaw version.").toBe(
blueprintMinVersion,
);
expect([...REVIEWED_OPENCLAW_PATCH_CLASSIFIER_VERSIONS], reviewMessage).toContain(
blueprintMinVersion,
);
expect(
CURRENT_REVIEWED_OPENCLAW_PATCH_CLASSIFIER_VERSION,
"The current classifier test version must track the pinned OpenClaw version.",
).toBe(blueprintMinVersion);
});
🤖 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/fetch-guard-patch-regression.test.ts` around lines 174 - 187, The test
currently checks that the set REVIEWED_OPENCLAW_PATCH_CLASSIFIER_VERSIONS
contains the blueprint-pinned version but doesn't assert that the single
CURRENT_REVIEWED_OPENCLAW_PATCH_CLASSIFIER_VERSION equals that pinned version;
update the test (near readBlueprintMinOpenClawVersion /
readDockerfileBaseOpenClawVersion usage) to add an assertion that
CURRENT_REVIEWED_OPENCLAW_PATCH_CLASSIFIER_VERSION === blueprintMinVersion so
the declared "current reviewed classifier version" cannot drift from the pinned
OpenClaw version.

@wscurran wscurran added bug-fix PR fixes a bug or regression platform: container Affects Docker, containerd, Podman, or images and removed Docker labels Jun 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: packaging Packages, images, registries, installers, or distribution bug-fix PR fixes a bug or regression integration: openclaw OpenClaw integration behavior platform: container Affects Docker, containerd, Podman, or images v0.0.49 Release target

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[NeMoClaw][Environment][GitHub Issue #][Regression] Bug brief summary

4 participants