Skip to content

Commit fa7cb73

Browse files
authored
fix(cli): preserve platform base resolution metadata (#9400)
<!-- markdownlint-disable MD041 --> ## Summary Pass the Deep Agents Code publication contract's validated `linux/amd64` platform reference into onboarding instead of its multi-platform index reference. The complete index contract remains the publication evidence, while the runtime now receives the exact platform digest that its evidence gate already requires. ## Related Issue Fixes #9386 ## Changes - Export `platformReferences["linux/amd64"]` as the existing `dcode_base_ref` workflow output while retaining the complete multi-platform contract as evidence. - Run the locked-down import proof against that same exact platform reference. - Require the live DCode evidence environment to match the validated platform reference and add regression coverage that rejects the publication index. ## 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: - [x] Sensitive paths changed (security, policy, credentials, preflight, onboarding, inference, runner, sandbox, or messaging) - [x] Sensitive-path review completed or maintainer-approved waiver recorded — reviewer/approval link/justification: the publication contract already validates both immutable platform references. This change uses its exact `linux/amd64` reference for the existing import proof and onboarding output, preserves the full contract as evidence, and makes the live evidence parser reject the index reference. - [ ] Non-success, skipped, or missing CI check accepted by maintainer — check name, approval link, and follow-up issue: ## DGX Station Hardware Evidence - [ ] Tested on DGX Station - Tested commit: Not applicable; `scripts/prepare-dgx-station-host.sh` is unchanged. - Station profile/scenario: Not applicable. - Result: Not applicable. - Supporting evidence: Not applicable. ## 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, or `npm run validate:pr` passed after refreshing `origin/main` when hooks were skipped or unavailable - [x] Targeted behavior tests pass for the current change set, or tests are marked not applicable above — `vitest run --project e2e-support test/e2e/support/dcode-base-image-contract.test.ts test/e2e/support/dcode-base-image-runtime-evidence.test.ts test/e2e/support/base-image-publication-workflow-boundary.test.ts test/e2e/support/e2e-operations-workflow-boundary.test.ts` (135 passed) - [x] Applicable broad gate passed — `npm run test-size:check` (22 passed) and `npm run build:cli` passed - [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](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 - **Improvements** - Onboarding now uses a platform-specific base image reference for `linux/amd64`. - Docker validation and runtime evidence checks consistently verify the selected platform reference. - Published image contract output now reports the platform-specific base reference while preserving complete contract details. - **Tests** - Added end-to-end coverage for platform reference selection, Docker invocation, and rejection of generic publication references. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Signed-off-by: Aaron Erickson <aerickson@nvidia.com>
1 parent c60aff9 commit fa7cb73

4 files changed

Lines changed: 65 additions & 19 deletions

File tree

test/e2e/live/dcode-base-image-runtime-evidence.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import fs from "node:fs";
66
import { readSandboxBaseImageResolutionMetadata } from "../../../src/lib/sandbox-base-image/label-codec.ts";
77
import type { SandboxBaseImageResolutionMetadata } from "../../../src/lib/sandbox-base-image/types.ts";
88
import {
9+
DCODE_BASE_IMAGE_ONBOARD_PLATFORM,
910
type DcodeBaseImageContract,
1011
type DcodePlatform,
1112
parseDcodeBaseImageContract,
@@ -76,9 +77,12 @@ export function parseDcodeBaseImagePublicationEvidence(
7677
);
7778
}
7879
const contract = parseDcodeBaseImageContract(evidence.base);
79-
if (requireDcodeBaseImageReference(environment) !== contract.reference) {
80+
if (
81+
requireDcodeBaseImageReference(environment) !==
82+
contract.platformReferences[DCODE_BASE_IMAGE_ONBOARD_PLATFORM]
83+
) {
8084
throw new Error(
81-
"Deep Agents Code onboarding reference does not match the published base contract",
85+
`Deep Agents Code onboarding reference does not match the published ${DCODE_BASE_IMAGE_ONBOARD_PLATFORM} base contract`,
8286
);
8387
}
8488
return contract;

test/e2e/support/dcode-base-image-contract.test.ts

Lines changed: 43 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,15 @@
11
// SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
22
// SPDX-License-Identifier: Apache-2.0
33

4+
import { mkdtempSync, readFileSync, rmSync, writeFileSync } from "node:fs";
5+
import { tmpdir } from "node:os";
6+
import { join } from "node:path";
7+
48
import { describe, expect, it, vi } from "vitest";
59

610
import {
11+
DCODE_BASE_IMAGE_ONBOARD_PLATFORM,
12+
main,
713
validateDcodeBaseImageContract,
814
validateDcodeBaseImageImports,
915
} from "../../../tools/e2e/dcode-base-image-contract.mts";
@@ -57,15 +63,16 @@ describe("Deep Agents Code E2E base contract", () => {
5763
expect(() => validateDcodeBaseImageContract(contract(override), expected)).toThrow(message);
5864
});
5965

60-
it("proves both imports from the exact digest in a locked-down container (#9049)", () => {
66+
it("proves both imports from the selected platform digest in a locked-down container (#9386)", () => {
6167
const runDocker = vi.fn(() => "nemoclaw-dcode-base-imports-ok");
62-
validateDcodeBaseImageImports(`${IMAGE}@${DIGEST}`, runDocker);
68+
const platformReference = `${IMAGE}@sha256:${"c".repeat(64)}`;
69+
validateDcodeBaseImageImports(platformReference, runDocker);
6370

6471
expect(runDocker).toHaveBeenCalledWith([
6572
"run",
6673
"--rm",
6774
"--platform",
68-
"linux/amd64",
75+
DCODE_BASE_IMAGE_ONBOARD_PLATFORM,
6976
"--network",
7077
"none",
7178
"--cap-drop",
@@ -77,13 +84,45 @@ describe("Deep Agents Code E2E base contract", () => {
7784
"999:999",
7885
"--entrypoint",
7986
"/opt/venv/bin/python3",
80-
`${IMAGE}@${DIGEST}`,
87+
platformReference,
8188
"-I",
8289
"-c",
8390
'import deepagents; import deepagents_code; print("nemoclaw-dcode-base-imports-ok")',
8491
]);
8592
});
8693

94+
it("emits the selected platform reference while preserving the full contract (#9386)", () => {
95+
const directory = mkdtempSync(join(tmpdir(), "nemoclaw-dcode-base-contract-"));
96+
const contractPath = join(directory, "contract.json");
97+
const outputPath = join(directory, "github-output");
98+
const contractValue = contract();
99+
const platformReference = `${IMAGE}@sha256:${"c".repeat(64)}`;
100+
const runDocker = vi.fn(() => "nemoclaw-dcode-base-imports-ok");
101+
try {
102+
writeFileSync(contractPath, JSON.stringify(contractValue), "utf8");
103+
104+
main(
105+
[contractPath],
106+
{
107+
GITHUB_OUTPUT: outputPath,
108+
PUBLICATION_HEAD_SHA: HEAD_SHA,
109+
PUBLICATION_RUN_ATTEMPT: String(RUN_ATTEMPT),
110+
PUBLICATION_RUN_ID: String(RUN_ID),
111+
},
112+
runDocker,
113+
);
114+
115+
const [baseReferenceOutput, contractOutput] = readFileSync(outputPath, "utf8")
116+
.trim()
117+
.split("\n");
118+
expect(baseReferenceOutput).toBe(`base_ref=${platformReference}`);
119+
expect(JSON.parse(String(contractOutput).slice("contract=".length))).toEqual(contractValue);
120+
expect(runDocker).toHaveBeenCalledWith(expect.arrayContaining([platformReference]));
121+
} finally {
122+
rmSync(directory, { force: true, recursive: true });
123+
}
124+
});
125+
87126
it("rejects missing or noisy import evidence (#9049)", () => {
88127
expect(() => validateDcodeBaseImageImports(`${IMAGE}@${DIGEST}`, () => "")).toThrow(
89128
/did not prove both required imports/u,

test/e2e/support/dcode-base-image-runtime-evidence.test.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ const PUBLICATION_REVISION = "e".repeat(40);
2323

2424
function publicationEnvironment(overrides: NodeJS.ProcessEnv = {}): NodeJS.ProcessEnv {
2525
return {
26-
[DCODE_BASE_IMAGE_ENV]: INDEX_REFERENCE,
26+
[DCODE_BASE_IMAGE_ENV]: AMD64_REFERENCE,
2727
...overrides,
2828
};
2929
}
@@ -99,15 +99,15 @@ describe("Deep Agents Code published base runtime evidence", () => {
9999
});
100100
});
101101

102-
it("rejects a valid official reference that differs from the publication contract", () => {
102+
it("rejects the publication index instead of the validated platform reference (#9386)", () => {
103103
expect(() =>
104104
parseDcodeBaseImagePublicationEvidence(
105105
publicationEvidence(),
106106
publicationEnvironment({
107-
[DCODE_BASE_IMAGE_ENV]: `${DCODE_BASE_IMAGE}@sha256:${"f".repeat(64)}`,
107+
[DCODE_BASE_IMAGE_ENV]: INDEX_REFERENCE,
108108
}),
109109
),
110-
).toThrow(/does not match the published base contract/);
110+
).toThrow(/does not match the published linux\/amd64 base contract/);
111111
});
112112

113113
it("prefers the selected manual candidate over the trusted workflow SHA", () => {
@@ -192,7 +192,7 @@ describe("Deep Agents Code published base runtime evidence", () => {
192192
loadDcodeBaseImagePublicationEvidence(
193193
DCODE_BASE_IMAGE_TARGET_ID,
194194
`/missing-dcode-base-evidence-${process.pid}.json`,
195-
{ [DCODE_BASE_IMAGE_ENV]: INDEX_REFERENCE },
195+
{ [DCODE_BASE_IMAGE_ENV]: AMD64_REFERENCE },
196196
),
197197
).toBeUndefined();
198198
});
@@ -204,7 +204,7 @@ describe("Deep Agents Code published base runtime evidence", () => {
204204
`/missing-dcode-base-evidence-${process.pid}.json`,
205205
{
206206
GITHUB_ACTIONS: "true",
207-
[DCODE_BASE_IMAGE_ENV]: INDEX_REFERENCE,
207+
[DCODE_BASE_IMAGE_ENV]: AMD64_REFERENCE,
208208
},
209209
),
210210
).toThrow(/GitHub Actions run is missing published base evidence/);

tools/e2e/dcode-base-image-contract.mts

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import { fileURLToPath } from "node:url";
99
const AGENT = "langchain-deepagents-code";
1010
const IMAGE = "ghcr.io/nvidia/nemoclaw/langchain-deepagents-code-sandbox-base";
1111
const PLATFORMS = ["linux/amd64", "linux/arm64"] as const;
12+
export const DCODE_BASE_IMAGE_ONBOARD_PLATFORM = "linux/amd64" as const;
1213
const DIGEST_PATTERN = /^sha256:[0-9a-f]{64}$/u;
1314
const SHA_PATTERN = /^[0-9a-f]{40}$/u;
1415
const IMPORT_MARKER = "nemoclaw-dcode-base-imports-ok";
@@ -120,10 +121,7 @@ export function validateDcodeBaseImageContract(
120121
if (contract.sourceRevision !== expected.headSha) {
121122
throw new Error("base contract source revision does not match the selected publication");
122123
}
123-
if (
124-
contract.run.id !== expected.runId ||
125-
contract.run.attempt !== expected.runAttempt
126-
) {
124+
if (contract.run.id !== expected.runId || contract.run.attempt !== expected.runAttempt) {
127125
throw new Error("base contract run does not match the selected publication");
128126
}
129127
return contract;
@@ -172,7 +170,11 @@ function requiredInteger(value: string | undefined, label: string): number {
172170
return positiveInteger(Number(value), label);
173171
}
174172

175-
export function main(argv = process.argv.slice(2), env = process.env): void {
173+
export function main(
174+
argv = process.argv.slice(2),
175+
env = process.env,
176+
runDocker?: (args: string[]) => string,
177+
): void {
176178
if (argv.length !== 1) throw new Error("expected one managed base contract path");
177179
const outputPath = env.GITHUB_OUTPUT ?? "";
178180
if (!outputPath || outputPath.includes("\r") || outputPath.includes("\n")) {
@@ -186,10 +188,11 @@ export function main(argv = process.argv.slice(2), env = process.env): void {
186188
headSha: env.PUBLICATION_HEAD_SHA ?? "",
187189
},
188190
);
189-
validateDcodeBaseImageImports(contract.reference);
191+
const baseReference = contract.platformReferences[DCODE_BASE_IMAGE_ONBOARD_PLATFORM];
192+
validateDcodeBaseImageImports(baseReference, runDocker);
190193
appendFileSync(
191194
outputPath,
192-
`base_ref=${contract.reference}\ncontract=${JSON.stringify(contract)}\n`,
195+
`base_ref=${baseReference}\ncontract=${JSON.stringify(contract)}\n`,
193196
"utf8",
194197
);
195198
}

0 commit comments

Comments
 (0)