Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 39 additions & 0 deletions test/e2e/support/pi-agent-qualification-events.test.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,17 @@
// SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
// SPDX-License-Identifier: Apache-2.0

import fs from "node:fs";
import path from "node:path";

import { describe, expect, it } from "vitest";

import {
catalogueTarget,
catalogueTargetsForChangedFiles,
} from "../../../tools/e2e/target-catalogue.mts";
import { REPO_ROOT } from "../fixtures/paths.ts";

import {
derivePiImageSourcePaths,
parsePiJsonEvents,
Expand Down Expand Up @@ -61,6 +70,36 @@ describe("Pi qualification event oracle", () => {
);
});

it.each(["pi-agent-qualification-amd64", "pi-agent-qualification-arm64"])(
"%s keeps every real Pi image source in its PR target ownership boundary",
(targetId) => {
const dockerfiles = ["agents/pi/Dockerfile", "agents/pi/Dockerfile.base"].map((file) =>
fs.readFileSync(path.join(REPO_ROOT, file), "utf8"),
);
const imageSources = derivePiImageSourcePaths(dockerfiles);
const target = catalogueTarget(targetId);
const uncovered = imageSources.filter(
(source) =>
!target.owningPaths.some((owner) => {
const normalizedOwner = owner.replace(/\/$/u, "");
return source === normalizedOwner || source.startsWith(`${normalizedOwner}/`);
}),
);

expect(uncovered, `${target.id} must own every Pi Docker COPY input`).toEqual([]);
},
);

it("selects both Pi qualification targets for a copied blueprint source", () => {
expect(
catalogueTargetsForChangedFiles(["nemoclaw-blueprint/scripts/nemotron-inference-fix.js"]).map(
(target) => target.id,
),
).toEqual(
expect.arrayContaining(["pi-agent-qualification-amd64", "pi-agent-qualification-arm64"]),
);
});

it("accepts one successful read and an exact final response", () => {
const events = parsePiJsonEvents(eventStream());

Expand Down
30 changes: 28 additions & 2 deletions tools/e2e/target-catalogue.mts
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,32 @@ const nonInteractive = {
NEMOCLAW_ACCEPT_THIRD_PARTY_SOFTWARE: "1",
} as const;

// Keep every checked-in input copied by the Pi Dockerfiles in the PR selection boundary.
// test/e2e/support/pi-agent-qualification-events.test.ts verifies this list against the
// real Dockerfiles so a new COPY instruction cannot silently reuse a stale image receipt.
const PI_IMAGE_SOURCE_OWNING_PATHS = [
".dockerignore",
"agents/pi/",
"nemoclaw-blueprint/",
"scripts/lib/bundled-npm-package.mts",
"scripts/lib/entrypoint-env-wrapper.sh",
"scripts/lib/patch-bundled-npm-ip-address.mts",
"scripts/lib/reviewed-npm-archive.mts",
"scripts/lib/sandbox-rlimits.sh",
"scripts/managed-bootstrap-entrypoint.c",
"scripts/managed-bootstrap-trampoline.sh",
"scripts/managed-startup-hold.sh",
"scripts/patch-bundled-npm-brace-expansion.mts",
"scripts/patch-bundled-npm-tar.mts",
"scripts/security/build-native-security-packages.sh",
"scripts/security/build-perl-security-packages.sh",
"scripts/security/patches/libssh2-1.11.1-cve-2026.patch",
"scripts/security/patches/perl-5.44.0-net-ping-capability-tests.patch",
"scripts/security/patches/python3.13-htmlparser-cve-2026-15308.patch",
"scripts/upgrade-bundled-npm.mts",
"tools/mcp-tool-discovery-runtime/reviewed-runtime-bundle/managed-startup-image-runtime.bundle",
] as const;

function commonEgressTarget(options: {
displayName: string;
environment?: Readonly<Record<string, string>>;
Expand Down Expand Up @@ -1165,7 +1191,7 @@ export const E2E_TARGET_CATALOGUE: readonly E2eCatalogueTarget[] = [
runner: "ubuntu-24.04",
shard: "linux-amd64",
owningPaths: [
"agents/pi/",
...PI_IMAGE_SOURCE_OWNING_PATHS,
"ci/pi-agent-qualification-v1-linux-amd64.json",
"src/lib/agent/candidate-authority.ts",
"src/lib/agent/candidate.ts",
Expand Down Expand Up @@ -1199,7 +1225,7 @@ export const E2E_TARGET_CATALOGUE: readonly E2eCatalogueTarget[] = [
runner: "ubuntu-24.04-arm",
shard: "linux-arm64",
owningPaths: [
"agents/pi/",
...PI_IMAGE_SOURCE_OWNING_PATHS,
"ci/pi-agent-qualification-v1-linux-arm64.json",
"src/lib/agent/candidate-authority.ts",
"src/lib/agent/candidate.ts",
Expand Down
Loading