Files
pikasTech-unidesk/scripts/src/platform-infra-pipelines-as-code-source-artifact.test.ts
T

1071 lines
55 KiB
TypeScript

import { describe, expect, test } from "bun:test";
import { spawnSync } from "node:child_process";
import { chmodSync, mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from "node:fs";
import { tmpdir } from "node:os";
import { resolve } from "node:path";
import { rootPath } from "./config";
import { applyNodeRuntimeDeployYamlOverlay, nodeRuntimeDeployYamlOverlayShellScript } from "./hwlab-node/deploy-overlay";
import { hwlabRuntimePipelineProvenance } from "./hwlab-node/pipeline-provenance";
import { nodeRuntimeFeatureConfigSchemaStage, nodeRuntimePipelinePostprocessScript, nodeRuntimePipelineProvenancePostprocessScript } from "./hwlab-node/render";
import { nodeRuntimeRenderOverlay } from "./hwlab-node/web-probe";
import { hwlabRuntimeLaneSpecForNode, parseHwlabRuntimePipelineProvenance } from "./hwlab-node-lanes";
import { pipelineProvenanceAnnotationKeys, pipelineProvenanceAnnotations } from "./pipeline-provenance";
import {
assertPacSourceArtifactVerifyWorktree,
canonicalSha256,
canonicalizePacPipelineSpec,
firstPacSourceArtifactDrift,
pacSourceArtifactSafeError,
pacSourceArtifactProvenanceFromManifest,
pipelineRunLabels,
pipelineRunWorkspaces,
pacValueEvidence,
pacSourceArtifactYaml,
optionalPipelineRunWorkspaces,
parsePacSourceArtifactOptions,
sourceArtifactRuntimeAlignment,
} from "./platform-infra-pipelines-as-code-source-artifact";
import {
pacRuntimeSafeReason,
pacRuntimeSafePath,
pacRuntimeSourceArtifactItem,
pacRuntimeTransportFailureReason,
renderPacSourceArtifactRuntimeObserverShell,
} from "./platform-infra-pipelines-as-code";
import {
canonicalPacPipelineSha256 as nativeCanonicalSha256,
canonicalizePacPipelineSpec as nativeCanonicalize,
observePacSourceArtifactRuntime,
selectPipelineRunBySourceCommit,
} from "../native/cicd/pac-source-artifact-runtime.mjs";
import { renderGitOpsResources } from "../native/cicd/publish-unidesk-host-gitops.mjs";
const sourceCommit = "a".repeat(40);
const provenance = {
configRef: "config/example.yaml#lanes.nc01",
effectiveConfigSha256: "sha256:config",
renderer: "agentrun-control-plane",
mode: "embedded-pipeline-spec",
};
const desiredSpec = { params: [], tasks: [] };
const runtimeWrapperSpec = {
taskRunTemplate: {
serviceAccountName: "agentrun-nc01-v02-tekton-runner",
podTemplate: { hostNetwork: true, dnsPolicy: "ClusterFirstWithHostNet", securityContext: { fsGroup: 1000 } },
},
params: [],
workspaces: [],
};
function manifestAnnotations(): Record<string, string> {
return {
"unidesk.ai/owning-config-ref": provenance.configRef,
"unidesk.ai/effective-config-sha256": provenance.effectiveConfigSha256,
"unidesk.ai/source-artifact-renderer": provenance.renderer,
"unidesk.ai/source-artifact-mode": provenance.mode,
};
}
function pipeline(): Record<string, unknown> {
return {
metadata: { name: "agentrun-nc01-v02-ci-image-publish", annotations: manifestAnnotations() },
spec: desiredSpec,
};
}
function pipelineRun(name: string, creationTimestamp: string, spec: Record<string, unknown> = desiredSpec): Record<string, unknown> {
return {
metadata: {
name,
creationTimestamp,
labels: { "pipelinesascode.tekton.dev/sha": sourceCommit },
annotations: manifestAnnotations(),
},
spec: { pipelineSpec: spec, ...structuredClone(runtimeWrapperSpec) },
};
}
function runtimeInput(commit: string | null = sourceCommit): Record<string, unknown> {
return {
namespace: "agentrun-ci",
pipeline: "agentrun-nc01-v02-ci-image-publish",
pipelineRunPrefix: "agentrun-nc01-v02-ci",
desiredSpec,
desiredWrapper: { mode: "embedded-pipeline-spec", executionMode: "pipeline-spec", spec: runtimeWrapperSpec },
provenance,
sourceCommit: commit,
};
}
describe("PaC source artifact CLI contract", () => {
test("accepts PikaOA test runtime provenance", () => {
const expected = {
configRef: "config/pikaoa.yaml#testRuntime.targets.NC01",
effectiveConfigSha256: `sha256:${"a".repeat(64)}`,
renderer: "pikaoa-test-runtime",
mode: "embedded-pipeline-spec",
} as const;
const manifest = {
metadata: { annotations: pipelineProvenanceAnnotations(expected) },
};
expect(pacSourceArtifactProvenanceFromManifest(manifest)).toEqual(expected);
});
test("uses PikaOA-specific PipelineRun labels", () => {
const binding = { consumer: { id: "pikaoa-test-nc01", node: "NC01" } } as Parameters<typeof pipelineRunLabels>[0];
expect(pipelineRunLabels(binding, "pikaoa")).toEqual({
"app.kubernetes.io/name": "pikaoa-test-nc01-pac",
"app.kubernetes.io/part-of": "pikaoa",
"unidesk.ai/source-commit": "{{ revision }}",
"pikaoa.unidesk.io/source-commit": "{{ revision }}",
"pikaoa.unidesk.io/trigger": "pipelines-as-code",
});
});
test("maps the PikaOA shared workspace to the declared RWO PVC size", () => {
const binding = {
consumer: { sourceArtifact: { renderer: "pikaoa-test-runtime" } },
repository: { params: { workspace_pvc_size: "8Gi" } },
} as Parameters<typeof pipelineRunWorkspaces>[0];
expect(pipelineRunWorkspaces(binding, { workspaces: [{ name: "workspace" }] })).toEqual([{
name: "workspace",
volumeClaimTemplate: {
spec: {
accessModes: ["ReadWriteOnce"],
resources: { requests: { storage: "8Gi" } },
},
},
}]);
});
test("omits empty PipelineRun workspaces and preserves declared bindings", () => {
expect(optionalPipelineRunWorkspaces([])).toEqual({});
const workspaces = [{ name: "source", emptyDir: {} }];
expect(optionalPipelineRunWorkspaces(workspaces)).toEqual({ workspaces });
});
test("verify-runtime requires and normalizes a full source commit", () => {
expect(() => parsePacSourceArtifactOptions([
"verify-runtime", "--target", "NC01", "--consumer", "agentrun-nc01-v02", "--source-worktree", "/tmp/repo",
])).toThrow("source-commit-required");
const parsed = parsePacSourceArtifactOptions([
"verify-runtime", "--target", "NC01", "--consumer", "agentrun-nc01-v02", "--source-worktree", "/tmp/repo", "--source-commit", sourceCommit.toUpperCase(),
]);
expect(parsed.sourceCommit).toBe(sourceCommit);
expect(() => parsePacSourceArtifactOptions([
"plan", "--target", "NC01", "--consumer", "agentrun-nc01-v02", "--source-worktree", "/tmp/repo", "--source-commit", sourceCommit,
])).toThrow("accepted only");
});
test("real outer CLI returns bounded scoped help for both help positions", () => {
for (const tail of [["--help"], ["check", "--help"]]) {
const result = spawnSync("bun", ["scripts/cli.ts", "platform-infra", "pipelines-as-code", "source-artifact", ...tail], {
cwd: rootPath(), encoding: "utf8", timeout: 30_000,
});
expect(result.status).toBe(0);
expect(result.stdout).toContain("PAC SOURCE ARTIFACT");
expect(result.stdout).toContain("verify-runtime");
expect(result.stdout).toContain("--source-commit <full-sha>");
expect(result.stdout.split("\n").length).toBeLessThan(25);
expect(result.stdout).not.toContain("platform-infra sub2api plan");
}
});
test("predictable validation failures omit stack and rendered specs", () => {
const result = spawnSync("bun", [
"scripts/cli.ts", "platform-infra", "pipelines-as-code", "source-artifact", "plan",
"--target", "NC01", "--consumer", "agentrun-nc01-v02", "--source-worktree", rootPath(),
], { cwd: rootPath(), encoding: "utf8", timeout: 30_000 });
expect(result.status).toBe(1);
expect(result.stdout).toContain("code=source-worktree-origin-mismatch");
expect(result.stdout).toContain("observedUrlFingerprint=sha256:");
expect(result.stdout).not.toContain("observedOwnerRepo");
expect(result.stdout).not.toContain("stack");
expect(result.stdout).not.toContain("taskSpec");
expect(result.stdout.length).toBeLessThan(1500);
});
test("default, JSON, and full failures never disclose a malicious origin", () => {
const temporary = mkdtempSync(resolve(tmpdir(), "unidesk-pac-origin-test-"));
const secrets = [
"review-user",
"REVIEW_SUPER_SECRET",
"QUERY_SUPER_SECRET",
"Authorization",
"https://review-user:REVIEW_SUPER_SECRET@example.invalid/pikasTech/agentrun.git?token=QUERY_SUPER_SECRET",
];
try {
for (const args of [
["init"],
["config", "user.email", "pac-test@example.invalid"],
["config", "user.name", "PaC Test"],
]) expect(spawnSync("git", args, { cwd: temporary, encoding: "utf8" }).status).toBe(0);
writeFileSync(resolve(temporary, "README.md"), "fixture\n");
expect(spawnSync("git", ["add", "README.md"], { cwd: temporary, encoding: "utf8" }).status).toBe(0);
expect(spawnSync("git", ["commit", "-m", "fixture"], { cwd: temporary, encoding: "utf8" }).status).toBe(0);
expect(spawnSync("git", ["remote", "add", "origin", secrets[4] as string], { cwd: temporary, encoding: "utf8" }).status).toBe(0);
const origins = [
secrets[4] as string,
"audit@example.invalid:pikasTech/agentrun.git?token=SCP_QUERY_SUPER_SECRET",
"https://review-user:REVIEW_SUPER_SECRET@github.com/pikasTech/agentrun.git",
"https://github.com/pikasTech/agentrun.git?token=QUERY_SUPER_SECRET",
"https://github.com/pikasTech/agentrun.git#QUERY_SUPER_SECRET",
];
for (const origin of origins) {
expect(spawnSync("git", ["remote", "set-url", "origin", origin], { cwd: temporary, encoding: "utf8" }).status).toBe(0);
for (const outputFlag of [null, "--json", "--full"] as const) {
const args = [
"scripts/cli.ts", "platform-infra", "pipelines-as-code", "source-artifact", "plan",
"--target", "NC01", "--consumer", "agentrun-nc01-v02", "--source-worktree", temporary,
];
if (outputFlag !== null) args.push(outputFlag);
const result = spawnSync("bun", args, { cwd: rootPath(), encoding: "utf8", timeout: 30_000 });
const output = `${result.stdout}\n${result.stderr}`;
expect(result.status).toBe(1);
expect(output).toContain("source-worktree-origin-mismatch");
expect(output).toContain("observedUrlFingerprint");
expect(output).not.toContain("observedOwnerRepo");
for (const secret of [...secrets, "SCP_QUERY_SUPER_SECRET"]) expect(output).not.toContain(secret);
}
}
} finally {
rmSync(temporary, { recursive: true, force: true });
}
}, 15_000);
test("verification requires a clean worktree at the exact requested commit", () => {
const exact = { head: sourceCommit, clean: true, matchesSourceCommit: true };
expect(() => assertPacSourceArtifactVerifyWorktree("verify-runtime", sourceCommit, exact)).not.toThrow();
expect(() => assertPacSourceArtifactVerifyWorktree("status", sourceCommit, { ...exact, clean: false })).not.toThrow();
expect(() => assertPacSourceArtifactVerifyWorktree("verify-runtime", sourceCommit, { ...exact, clean: false })).toThrow("source-worktree-not-clean");
expect(() => assertPacSourceArtifactVerifyWorktree("verify-runtime", sourceCommit, { ...exact, head: "b".repeat(40), matchesSourceCommit: false })).toThrow("source-worktree-commit-mismatch");
});
test("taskRunTemplate operational facts are declared in owning YAML", () => {
const document = Bun.YAML.parse(readFileSync(rootPath("config", "platform-infra", "pipelines-as-code.yaml"), "utf8")) as Record<string, any>;
const consumers = document.consumers as Array<Record<string, any>>;
for (const template of ["templates.consumers.agentrunV02", "templates.consumers.hwlabV03"]) {
const sourceArtifact = consumers.find((item) => item.extends === template && item.variables?.NODE === "NC01")?.sourceArtifact;
expect(sourceArtifact?.taskRunTemplate).toEqual({ hostNetwork: true, dnsPolicy: "ClusterFirstWithHostNet", fsGroup: 1000 });
}
for (const id of ["platform-infra-sub2rank-nc01", "selfmedia-nc01"]) {
const sourceArtifact = consumers.find((item) => item.id === id)?.sourceArtifact;
expect(sourceArtifact?.taskRunTemplate).toEqual({ hostNetwork: true, dnsPolicy: "ClusterFirstWithHostNet", fsGroup: 1000 });
}
});
test("undeclared JD01 source artifact owner fails closed", () => {
const result = spawnSync("bun", [
"scripts/cli.ts", "platform-infra", "pipelines-as-code", "source-artifact", "plan",
"--target", "JD01", "--consumer", "agentrun-jd01-v02", "--source-worktree", rootPath(),
], { cwd: rootPath(), encoding: "utf8", timeout: 30_000 });
expect(result.status).toBe(1);
expect(result.stdout).toContain("code=source-artifact-operation-failed");
expect(result.stdout).toContain("evidence=type=string");
});
});
describe("HWLAB YAML-owned Pipeline provenance", () => {
const ownerPath = "lanes.v03.targets.NC01.pipelineProvenance";
const configRef = "config/hwlab-node-lanes.yaml#lanes.v03.targets.NC01";
test("target owner parser fails closed for missing or inconsistent contracts", () => {
expect(() => parseHwlabRuntimePipelineProvenance(undefined, ownerPath, configRef)).toThrow("must be declared by the target owner");
expect(() => parseHwlabRuntimePipelineProvenance({
configRef: "config/hwlab-node-lanes.yaml#lanes.v03.targets.JD01",
renderer: "hwlab-runtime-lane",
mode: "remote-pipeline-annotation",
}, ownerPath, configRef)).toThrow(`must equal ${configRef}`);
expect(() => parseHwlabRuntimePipelineProvenance({
configRef,
renderer: "another-renderer",
mode: "remote-pipeline-annotation",
}, ownerPath, configRef)).toThrow("renderer must be one of hwlab-runtime-lane");
expect(() => parseHwlabRuntimePipelineProvenance({
configRef,
renderer: "hwlab-runtime-lane",
mode: "embedded-pipeline-spec",
}, ownerPath, configRef)).toThrow("mode must be one of remote-pipeline-annotation");
});
test("runtime GitOps guard keeps Tekton scripts below the owning YAML budget", () => {
const temporary = mkdtempSync(resolve(tmpdir(), "unidesk-hwlab-runtime-gitops-guard-"));
try {
const spec = hwlabRuntimeLaneSpecForNode("v03", "NC01");
const budget = spec.pipelineProvenance?.maxInlineScriptBytes;
expect(budget).toBeNumber();
const overlay = nodeRuntimeRenderOverlay(spec);
const pipelineDir = resolve(temporary, spec.tektonDir);
const pipelinePath = resolve(pipelineDir, "pipeline.yaml");
const configMapPath = resolve(pipelineDir, "runtime-gitops-scripts.yaml");
const gitMirrorDir = resolve(temporary, "devops-infra");
mkdirSync(pipelineDir, { recursive: true });
mkdirSync(gitMirrorDir, { recursive: true });
writeFileSync(resolve(gitMirrorDir, "git-mirror.yaml"), Bun.YAML.stringify({
apiVersion: "v1",
kind: "List",
items: [
{
apiVersion: "v1",
kind: "ConfigMap",
metadata: { name: overlay.gitMirror.syncConfigMapName },
data: {
"sync.sh": "#!/bin/sh\nset -eu\nrepo_url='ssh://git@github.com/pikasTech/HWLAB.git'\n",
"flush.sh": "#!/bin/sh\nset -eu\nremote='ssh://git@github.com/pikasTech/HWLAB.git'\n",
},
},
{
apiVersion: "apps/v1",
kind: "Deployment",
metadata: { name: overlay.gitMirror.serviceReadName },
spec: { template: { spec: { containers: [{ name: "git-mirror", env: [] }] } } },
},
],
}));
writeFileSync(pipelinePath, Bun.YAML.stringify({
apiVersion: "tekton.dev/v1",
kind: "Pipeline",
metadata: { name: spec.pipeline, namespace: "hwlab-ci" },
spec: { tasks: [{
name: "gitops-promote",
taskSpec: { steps: [{
name: "render",
script: [
"if [ -s /workspace/source/affected-services.json ] && node - /workspace/source/affected-services.json <<'NODE'",
"const fs = require(\"node:fs\");",
"const plan = JSON.parse(fs.readFileSync(process.argv[2], \"utf8\"));",
"const buildServices = Array.isArray(plan.buildServices) ? plan.buildServices : [];",
"const affectedServices = Array.isArray(plan.affectedServices) ? plan.affectedServices : [];",
"const willRunGitopsPromote = plan.ciCdPlan && plan.ciCdPlan.willRunGitopsPromote === true;",
"process.exit(!willRunGitopsPromote && buildServices.length === 0 && affectedServices.length === 0 ? 0 : 1);",
"NODE",
"then",
" printf 'false' > /tekton/results/runtime-ready-required || true",
" echo '{\"event\":\"gitops-promote\",\"status\":\"skipped\",\"reason\":\"no-build-no-rollout-plan\"}'",
" exit 0",
"fi",
"node scripts/run-bun.mjs scripts/gitops-render.mjs --use-deploy-images",
"node scripts/run-bun.mjs scripts/gitops-render.mjs --use-deploy-images --check",
"",
].join("\n"),
}] },
}] },
}));
const overlayBase64 = Buffer.from(JSON.stringify(overlay), "utf8").toString("base64");
const postprocessInput = [
"set -eu",
`render_dir=${JSON.stringify(temporary)}`,
`overlay_b64=${JSON.stringify(overlayBase64)}`,
...nodeRuntimePipelinePostprocessScript(nodeRuntimeFeatureConfigSchemaStage(spec)),
].join("\n");
const result = spawnSync("sh", [], {
cwd: rootPath(),
input: postprocessInput,
encoding: "utf8",
timeout: 30_000,
});
expect(result.status, result.stderr).toBe(0);
const guardedPipelineText = readFileSync(pipelinePath, "utf8");
const repeated = spawnSync("node", [
resolve(temporary, ".unidesk-runtime-gitops", "runtime-gitops-pipeline-guard.mjs"),
"--pipeline", pipelinePath,
], {
cwd: rootPath(),
env: { ...process.env, UNIDESK_RUNTIME_GITOPS_OVERLAY_B64: overlayBase64 },
encoding: "utf8",
timeout: 30_000,
});
expect(repeated.status, repeated.stderr).toBe(0);
expect(readFileSync(pipelinePath, "utf8")).toBe(guardedPipelineText);
const pipeline = Bun.YAML.parse(guardedPipelineText) as Record<string, any>;
const scripts = pipeline.spec.tasks.flatMap((task: Record<string, any>) => task.taskSpec.steps.map((step: Record<string, any>) => String(step.script ?? "")));
expect(Math.max(...scripts.map((script: string) => Buffer.byteLength(script)))).toBeLessThanOrEqual(budget as number);
expect(scripts.join("\n")).toContain("process.exit(buildServices.length === 0 && affectedServices.length === 0 ? 0 : 1);");
expect(scripts.join("\n")).not.toContain("!willRunGitopsPromote");
expect(scripts.join("\n")).toContain("no-build-no-rollout-plan-gitops-verify");
expect(scripts.join("\n")).not.toContain('"status":"skipped","reason":"no-build-no-rollout-plan"');
expect(scripts.join("\n")).toContain("UNIDESK_RUNTIME_GITOPS_OVERLAY_FILE=/etc/unidesk-cicd-runtime-gitops/runtime-gitops-overlay.json");
expect(scripts.join("\n")).toContain("export UNIDESK_AJV2020_BUNDLE='/etc/unidesk-cicd-runtime-gitops/ajv2020.min.js'");
expect(scripts.join("\n")).toContain("feature-config-schema-validation");
expect(scripts.join("\n")).toContain("cicd.feature_config.schema");
expect(scripts.join("\n")).toContain("export OTEL_EXPORTER_OTLP_TRACES_ENDPOINT='http://otel-collector.platform-infra.svc.cluster.local:4318/v1/traces'");
expect(scripts.join("\n")).toContain("export OTEL_SERVICE_NAME='unidesk-cicd'");
expect(scripts.join("\n")).toContain("export OTEL_TRACES_SAMPLER_ARG='1'");
expect(scripts.join("\n")).toContain("export OTEL_EXPORTER_TIMEOUT_MS='300'");
expect(scripts.join("\n")).toContain("feature-config-validator-process-failure");
expect(scripts.join("\n").indexOf("scripts/gitops-render.mjs --use-deploy-images"))
.toBeLessThan(scripts.join("\n").indexOf("feature-config-schema-validation"));
expect(scripts.join("\n")).not.toContain("NODE_UNIDESK_RUNTIME_GITOPS_POSTPROCESS");
expect(scripts.join("\n")).not.toContain("NODE_UNIDESK_RUNTIME_GITOPS_VERIFY");
expect(scripts.join("\n")).not.toContain("UNIDESK_RUNTIME_GITOPS_OVERLAY_B64=");
expect(scripts.join("\n")).not.toContain(Buffer.from(JSON.stringify(overlay.observability), "utf8").toString("base64"));
const configMap = Bun.YAML.parse(readFileSync(configMapPath, "utf8")) as Record<string, any>;
expect(configMap.metadata.labels["app.kubernetes.io/managed-by"]).toBe("unidesk-host-gitops");
expect(JSON.parse(configMap.data["runtime-gitops-overlay.json"])).toEqual({ runtimePath: overlay.runtimePath, observability: overlay.observability, codeAgentRuntime: overlay.codeAgentRuntime });
expect(Object.keys(configMap.data).sort()).toEqual([
"ajv2020.min.js",
"feature-config-schema-warning.mjs",
"runtime-gitops-observability.mjs",
"runtime-gitops-overlay.json",
"runtime-gitops-postprocess.mjs",
"runtime-gitops-verify.mjs",
]);
const hostConfig = Bun.YAML.parse(readFileSync(rootPath("config", "unidesk-host-k8s.yaml"), "utf8")) as Record<string, any>;
const runtimePaths = new Set(hostConfig.delivery.changeDetection.runtimePaths as string[]);
for (const inputPath of [
"bun.lock",
"config/hwlab-node-lanes.yaml",
"package.json",
"scripts/native/cicd/feature-config-schema-warning.mjs",
"scripts/native/hwlab/runtime-gitops-observability.mjs",
"scripts/native/hwlab/runtime-gitops-postprocess.mjs",
"scripts/native/hwlab/runtime-gitops-scripts-configmap.mjs",
"scripts/native/hwlab/runtime-gitops-verify.mjs",
"scripts/vendor/ajv-dist/8.17.1/ajv2020.min.js",
"scripts/vendor/ajv-dist/8.17.1/manifest.json",
"scripts/src/config.ts",
"scripts/src/hwlab-node/render.ts",
"scripts/src/hwlab-node-lanes.ts",
"scripts/src/platform-infra-pipelines-as-code.ts",
"scripts/src/yaml-composition.ts",
]) expect(runtimePaths.has(inputPath), inputPath).toBe(true);
expect(hostConfig.delivery.gitops.resources).toContainEqual({
id: "hwlab-nc01-v03-runtime-gitops-scripts",
renderer: "hwlab-runtime-gitops-scripts",
configRef: "config/hwlab-node-lanes.yaml#lanes.v03.targets.NC01",
manifestPath: "deploy/gitops/unidesk-host/hwlab-nc01-v03-runtime-gitops-scripts.yaml",
namespace: "hwlab-ci",
});
const gitopsResources = renderGitOpsResources(hostConfig.delivery.gitops, rootPath());
expect(gitopsResources).toHaveLength(1);
expect(gitopsResources[0]?.path).toBe("deploy/gitops/unidesk-host/hwlab-nc01-v03-runtime-gitops-scripts.yaml");
const gitopsConfigMap = Bun.YAML.parse(gitopsResources[0]?.content ?? "") as Record<string, any>;
expect(gitopsConfigMap.metadata.name).toBe("hwlab-nc01-v03-ci-image-publish-runtime-gitops-scripts");
expect(gitopsConfigMap.metadata.namespace).toBe("hwlab-ci");
expect(gitopsConfigMap.data["runtime-gitops-postprocess.mjs"]).toContain("UNIDESK_RUNTIME_GITOPS_OVERLAY_FILE");
expect(gitopsConfigMap.data["runtime-gitops-postprocess.mjs"].indexOf("UNIDESK_RUNTIME_GITOPS_OVERLAY_FILE"))
.toBeLessThan(gitopsConfigMap.data["runtime-gitops-postprocess.mjs"].indexOf("UNIDESK_RUNTIME_GITOPS_OVERLAY_B64"));
const legacyPayload = Buffer.from(JSON.stringify({ runtimePath: overlay.runtimePath, observability: overlay.observability }), "utf8").toString("base64");
const legacyPipeline = Bun.YAML.parse(readFileSync(pipelinePath, "utf8")) as Record<string, any>;
const legacyStep = legacyPipeline.spec.tasks[0].taskSpec.steps[0];
legacyStep.script = String(legacyStep.script).replaceAll(
"UNIDESK_RUNTIME_GITOPS_OVERLAY_FILE=/etc/unidesk-cicd-runtime-gitops/runtime-gitops-overlay.json",
`UNIDESK_RUNTIME_GITOPS_OVERLAY_B64='${legacyPayload}'`,
);
writeFileSync(pipelinePath, Bun.YAML.stringify(legacyPipeline));
const migrated = spawnSync("node", [
rootPath("scripts", "native", "hwlab", "runtime-gitops-pipeline-guard.mjs"),
"--pipeline", pipelinePath,
], {
cwd: rootPath(),
env: { ...process.env, UNIDESK_RUNTIME_GITOPS_OVERLAY_B64: Buffer.from(JSON.stringify(overlay), "utf8").toString("base64") },
encoding: "utf8",
timeout: 30_000,
});
expect(migrated.status).toBe(0);
const migratedText = readFileSync(pipelinePath, "utf8");
expect(migratedText).toContain("UNIDESK_RUNTIME_GITOPS_OVERLAY_FILE=/etc/unidesk-cicd-runtime-gitops/runtime-gitops-overlay.json");
expect(migratedText).not.toContain(legacyPayload);
} finally {
rmSync(temporary, { recursive: true, force: true });
}
});
test("normal control-plane postprocess writes exactly the shared four provenance fields", () => {
const temporary = mkdtempSync(resolve(tmpdir(), "unidesk-hwlab-pipeline-provenance-"));
try {
const spec = hwlabRuntimeLaneSpecForNode("v03", "NC01");
const overlay = nodeRuntimeRenderOverlay(spec);
const pipelineDir = resolve(temporary, spec.tektonDir);
const pipelinePath = resolve(pipelineDir, "pipeline.yaml");
mkdirSync(pipelineDir, { recursive: true });
writeFileSync(pipelinePath, Bun.YAML.stringify({
apiVersion: "tekton.dev/v1",
kind: "Pipeline",
metadata: { name: spec.pipeline, namespace: "hwlab-ci", annotations: { "fixture.example/keep": "true" } },
spec: { params: [], tasks: [] },
}));
const overlayBase64 = Buffer.from(JSON.stringify(overlay), "utf8").toString("base64");
const shell = [
`render_dir=${JSON.stringify(temporary)}`,
`overlay_b64=${JSON.stringify(overlayBase64)}`,
...nodeRuntimePipelineProvenancePostprocessScript(),
].join("\n");
const result = spawnSync("sh", [], { cwd: rootPath(), input: shell, encoding: "utf8", timeout: 30_000 });
expect(result.status).toBe(0);
const rendered = Bun.YAML.parse(readFileSync(pipelinePath, "utf8")) as Record<string, any>;
const annotations = rendered.metadata.annotations as Record<string, string>;
const provenanceKeySet = new Set<string>(Object.values(pipelineProvenanceAnnotationKeys));
const renderedProvenance = Object.fromEntries(Object.entries(annotations).filter(([key]) => provenanceKeySet.has(key)));
expect(renderedProvenance).toEqual(overlay.pipelineProvenanceAnnotations);
expect(Object.keys(renderedProvenance).sort()).toEqual(Object.values(pipelineProvenanceAnnotationKeys).sort());
expect(annotations["fixture.example/keep"]).toBe("true");
const invalidOverlay = { ...overlay, pipelineProvenanceAnnotations: { a: "1", b: "2", c: "3", d: "4" } };
const invalidShell = [
`render_dir=${JSON.stringify(temporary)}`,
`overlay_b64=${JSON.stringify(Buffer.from(JSON.stringify(invalidOverlay), "utf8").toString("base64"))}`,
...nodeRuntimePipelineProvenancePostprocessScript(),
].join("\n");
const invalid = spawnSync("sh", [], { cwd: rootPath(), input: invalidShell, encoding: "utf8", timeout: 30_000 });
expect(invalid.status).not.toBe(0);
expect(`${invalid.stdout}\n${invalid.stderr}`).toContain("shared four-key contract");
} finally {
rmSync(temporary, { recursive: true, force: true });
}
});
});
describe("Tekton admission canonicalization", () => {
const admitted = {
tasks: [{
name: "build",
taskSpec: {
metadata: {},
spec: null,
params: [{ name: "input", type: "string" }],
results: [{ name: "output", type: "string" }],
steps: [{ name: "step", computeResources: {} }],
sidecars: [{ name: "sidecar", computeResources: {} }],
},
}],
};
const desired = {
tasks: [{
name: "build",
taskSpec: {
params: [{ name: "input" }],
results: [{ name: "output" }],
steps: [{ name: "step" }],
sidecars: [{ name: "sidecar" }],
},
}],
};
test("removes exactly the six proven defaults and keeps local/native hashes equal", () => {
expect(canonicalizePacPipelineSpec(admitted)).toEqual(desired);
expect(nativeCanonicalize(admitted)).toEqual(desired);
expect(canonicalSha256(admitted)).toBe(canonicalSha256(desired));
expect(nativeCanonicalSha256(admitted)).toBe(canonicalSha256(admitted));
});
test("does not strip same-name fields outside the three Pipeline spec roots", () => {
const negative = {
unrelated: admitted,
tasks: [{ taskSpec: {
metadata: { labels: {} },
spec: {},
params: [{ type: "array" }],
results: [{ type: "object" }],
steps: [{ computeResources: { requests: { cpu: "1" } } }],
sidecars: [{ computeResources: { limits: { memory: "1Gi" } } }],
} }],
};
expect(canonicalizePacPipelineSpec(negative)).toEqual(negative);
expect(nativeCanonicalize(negative)).toEqual(negative);
});
test("normalizes equivalent PipelineRun timeout spellings without hiding different values", () => {
const seconds = { spec: { timeouts: { pipeline: "600s" } } };
const admitted = { spec: { timeouts: { pipeline: "10m0s" } } };
const different = { spec: { timeouts: { pipeline: "601s" } } };
const unrelated = { timeouts: { pipeline: "600s" } };
expect(canonicalizePacPipelineSpec(seconds)).toEqual(canonicalizePacPipelineSpec(admitted));
expect(nativeCanonicalize(seconds)).toEqual(nativeCanonicalize(admitted));
expect(canonicalSha256(seconds)).toBe(canonicalSha256(admitted));
expect(nativeCanonicalSha256(admitted)).toBe(canonicalSha256(seconds));
expect(firstPacSourceArtifactDrift(seconds, admitted)).toBeNull();
expect(firstPacSourceArtifactDrift(seconds, different)?.path).toBe("$.spec.timeouts.pipeline");
expect(canonicalizePacPipelineSpec(unrelated)).toEqual(unrelated);
expect(nativeCanonicalize(unrelated)).toEqual(unrelated);
});
test("removes only empty workspace claim metadata and status added by admission", () => {
const desired = { spec: { workspaces: [{ name: "source", volumeClaimTemplate: { spec: { accessModes: ["ReadWriteOnce"] } } }] } };
const admitted = { spec: { workspaces: [{ name: "source", volumeClaimTemplate: { metadata: {}, spec: { accessModes: ["ReadWriteOnce"] }, status: {} } }] } };
const labeled = { spec: { workspaces: [{ name: "source", volumeClaimTemplate: { metadata: { labels: { owner: "test" } }, spec: { accessModes: ["ReadWriteOnce"] } } }] } };
expect(canonicalizePacPipelineSpec(admitted)).toEqual(canonicalizePacPipelineSpec(desired));
expect(nativeCanonicalize(admitted)).toEqual(nativeCanonicalize(desired));
expect(firstPacSourceArtifactDrift(desired, admitted)).toBeNull();
expect(firstPacSourceArtifactDrift(desired, labeled)?.path).toBe("$.spec.workspaces[0].volumeClaimTemplate.metadata");
});
});
describe("source artifact serialization", () => {
test("remote Pipeline artifacts are deterministic reviewable multi-line YAML", () => {
const manifest = {
apiVersion: "tekton.dev/v1",
kind: "Pipeline",
metadata: { name: "fixture" },
spec: { params: [{ name: "revision", type: "string" }], tasks: [{ name: "build", taskSpec: { steps: [{ name: "build", script: "set -eu\necho ok\n" }] } }] },
};
const first = pacSourceArtifactYaml(manifest);
const second = pacSourceArtifactYaml(manifest);
expect(first).toBe(second);
expect(first.split("\n").length).toBeGreaterThan(10);
expect(first).toContain("apiVersion: tekton.dev/v1\nkind: Pipeline\n");
expect(Bun.YAML.parse(first)).toEqual(manifest);
});
test("empty mappings and sequences have stable whitespace without changing structure", () => {
const manifest = {
apiVersion: "tekton.dev/v1",
kind: "PipelineRun",
metadata: {},
spec: { params: [], workspaces: [], pipelineSpec: { tasks: [] } },
};
const serialized = pacSourceArtifactYaml(manifest);
expect(serialized).not.toMatch(/[\t ]+$/m);
expect(serialized.endsWith("\n")).toBe(true);
expect(serialized.endsWith("\n\n")).toBe(false);
expect(Bun.YAML.parse(serialized)).toEqual(manifest);
});
test("multi-line script scalar preserves trailing spaces and tabs exactly", () => {
const script = [
"#!/bin/sh ",
"printf 'mapping-looking scalar: ' ",
"metadata: ",
" {}",
"printf 'tab follows'\t",
"",
].join("\n");
const manifest = {
apiVersion: "tekton.dev/v1",
kind: "Pipeline",
metadata: { name: "scalar-round-trip" },
spec: { tasks: [{ name: "build", taskSpec: { steps: [{ name: "build", script }] } }] },
};
const serialized = pacSourceArtifactYaml(manifest);
const parsed = Bun.YAML.parse(serialized) as typeof manifest;
expect(parsed).toEqual(manifest);
expect(parsed.spec.tasks[0]?.taskSpec.steps[0]?.script).toBe(script);
expect(Buffer.from(parsed.spec.tasks[0]?.taskSpec.steps[0]?.script ?? "")).toEqual(Buffer.from(script));
expect(serialized.endsWith("\n")).toBe(true);
expect(serialized.endsWith("\n\n")).toBe(false);
});
test("round-trip failure exposes only secret-safe drift evidence", () => {
const secret = "ROUND_TRIP_SCRIPT_SECRET_DO_NOT_PRINT";
let reads = 0;
const spec: Record<string, unknown> = {};
Object.defineProperty(spec, "script", {
enumerable: true,
get: () => {
reads += 1;
return reads <= 2 ? secret : "changed-after-serialization";
},
});
let thrown: unknown;
try {
pacSourceArtifactYaml({ apiVersion: "tekton.dev/v1", kind: "Pipeline", spec });
} catch (error) {
thrown = error;
}
expect(thrown).toBeInstanceOf(Error);
const safe = pacSourceArtifactSafeError(thrown);
const serializedError = JSON.stringify({
message: thrown instanceof Error ? thrown.message : String(thrown),
direct: thrown,
safe,
});
expect(safe.code).toBe("source-artifact-yaml-round-trip-failed");
expect(serializedError).not.toContain(secret);
expect(serializedError).not.toContain("changed-after-serialization");
expect(serializedError).toContain("sha256");
});
});
describe("runtime source-commit selection", () => {
test("same-commit retries select the newest only when spec and provenance agree", () => {
const oldRun = pipelineRun("agentrun-nc01-v02-ci-old", "2026-07-10T00:00:00Z");
const newRun = pipelineRun("agentrun-nc01-v02-ci-new", "2026-07-11T00:00:00Z");
const selected = selectPipelineRunBySourceCommit([oldRun, newRun], "agentrun-nc01-v02-ci", sourceCommit);
expect(selected.kind).toBe("ok");
expect(selected.run.metadata.name).toBe("agentrun-nc01-v02-ci-new");
const observed = observePacSourceArtifactRuntime(runtimeInput(), (args: string[], label: string) => label === "pipeline-get"
? { kind: "ok", value: pipeline() }
: { kind: "ok", value: { items: [oldRun, newRun] } });
expect(observed.embedded.status).toBe("aligned");
expect(observed.embedded.name).toBe("agentrun-nc01-v02-ci-new");
expect(observed.embedded.candidateCount).toBe(2);
expect(observed.embedded.sourceCommit).toBe(sourceCommit);
});
test("same-commit conflicting embedded specs fail closed", () => {
const observed = observePacSourceArtifactRuntime(runtimeInput(), (_args: string[], label: string) => label === "pipeline-get"
? { kind: "ok", value: pipeline() }
: { kind: "ok", value: { items: [
pipelineRun("agentrun-nc01-v02-ci-old", "2026-07-10T00:00:00Z"),
pipelineRun("agentrun-nc01-v02-ci-new", "2026-07-11T00:00:00Z", { params: [], tasks: [{ name: "changed" }] }),
] } });
expect(observed.embedded.status).toBe("unavailable");
expect(observed.embedded.reason).toBe("source-commit-run-conflict:2");
expect(observed.embedded.candidateCount).toBe(2);
});
test("embedded mode compares the complete PipelineRun wrapper", () => {
const run = pipelineRun("agentrun-nc01-v02-ci-wrapper", "2026-07-11T00:00:00Z");
(run.spec as Record<string, any>).taskRunTemplate.serviceAccountName = "wrong-service-account";
const observed = observePacSourceArtifactRuntime(runtimeInput(), (_args: string[], label: string) => label === "pipeline-get"
? { kind: "ok", value: pipeline() }
: { kind: "ok", value: { items: [run] } });
expect(observed.embedded.status).toBe("drifted");
expect(observed.embedded.firstDrift?.path).toBe("$.spec.taskRunTemplate.serviceAccountName");
});
test("remote mode validates Pipeline spec live and wrapper on the exact-commit Run", () => {
const spec = hwlabRuntimeLaneSpecForNode("v03", "NC01");
const remoteProvenance = hwlabRuntimePipelineProvenance(spec);
const overlay = nodeRuntimeRenderOverlay(spec);
const remoteAnnotations = overlay.pipelineProvenanceAnnotations as Record<string, string>;
expect(spec.pipelineProvenance).toEqual({
configRef: "config/hwlab-node-lanes.yaml#lanes.v03.targets.NC01",
renderer: "hwlab-runtime-lane",
mode: "remote-pipeline-annotation",
maxInlineScriptBytes: 32768,
});
expect(spec.codeAgentRuntime?.kafkaEventBridge).toMatchObject({
enabled: true,
transactionalProjectorConsumerGroupId: "hwlab-v03-agentrun-event-projector",
hwlabEventConsumerGroupId: "hwlab-v03-workbench-live-sse",
});
expect(spec.codeAgentRuntime?.kafkaEventBridge).not.toHaveProperty("features");
expect(spec.codeAgentRuntime?.kafkaEventBridge).not.toHaveProperty("refreshReplay");
expect(remoteAnnotations).toEqual(pipelineProvenanceAnnotations(remoteProvenance));
expect(Object.keys(remoteAnnotations).sort()).toEqual(Object.values(pipelineProvenanceAnnotationKeys).sort());
expect(readFileSync(rootPath("scripts", "src", "hwlab-node", "render.ts"), "utf8")).not.toContain("overlay.sourceArtifactProvenance");
expect(readFileSync(rootPath("scripts", "src", "platform-infra-pipelines-as-code-source-artifact.ts"), "utf8")).not.toContain('"unidesk.ai/owning-config-ref"');
const wrapper = {
mode: "remote-pipeline-annotation",
executionMode: "pipeline-spec",
spec: { ...runtimeWrapperSpec, timeouts: { pipeline: "1h0m0s" } },
};
const run = {
metadata: {
name: "hwlab-nc01-v03-ci-poll-remote",
creationTimestamp: "2026-07-11T00:00:00Z",
labels: { "pipelinesascode.tekton.dev/sha": sourceCommit },
annotations: remoteAnnotations,
},
spec: { pipelineSpec: desiredSpec, ...wrapper.spec },
};
const input = {
...runtimeInput(),
pipeline: "hwlab-nc01-v03-ci-image-publish",
pipelineRunPrefix: "hwlab-nc01-v03-ci-poll",
provenance: remoteProvenance,
desiredWrapper: wrapper,
};
const observed = observePacSourceArtifactRuntime(input, (_args: string[], label: string) => label === "pipeline-get"
? { kind: "ok", value: { metadata: { name: input.pipeline, annotations: remoteAnnotations }, spec: desiredSpec } }
: { kind: "ok", value: { items: [run] } });
expect(observed.live.status).toBe("aligned");
expect(observed.live.provenanceAligned).toBe(true);
expect(observed.embedded.status).toBe("aligned");
expect(observed.embedded.provenanceAligned).toBe(true);
expect(observed.embedded.firstDrift).toBeNull();
});
test("NotFound, missing commit, and transport failures remain distinct", () => {
const noCommit = observePacSourceArtifactRuntime(runtimeInput(null), () => ({ kind: "not-found", reason: "pipeline-get-not-found" }));
expect(noCommit.live.status).toBe("missing");
expect(noCommit.live.reason).toBe("pipeline-get-not-found");
expect(noCommit.embedded.status).toBe("unavailable");
expect(noCommit.embedded.reason).toBe("source-commit-not-specified");
const secret = "Authorization: Bearer REVIEW_RUNTIME_SECRET https://review:password@example.invalid/path?token=QUERY_SECRET";
const transport = observePacSourceArtifactRuntime(runtimeInput(), () => ({ kind: "unavailable", reason: secret }));
expect(transport.live.status).toBe("unavailable");
expect(transport.embedded.status).toBe("unavailable");
expect(transport.live.reason).toMatch(/^runtime-observer-reason:type=string,length=\d+,sha256=[0-9a-f]{64}$/u);
expect(transport.embedded.reason).toMatch(/^runtime-observer-reason:type=string,length=\d+,sha256=[0-9a-f]{64}$/u);
expect(JSON.stringify(transport)).not.toContain(secret);
});
test("first drift reports structural evidence without script or token values", () => {
const expectedSecret = "Authorization: Bearer EXPECTED_SUPER_SECRET";
const actualSecret = "https://review-user:ACTUAL_SUPER_SECRET@example.invalid/path?token=QUERY_SUPER_SECRET";
const input = {
...runtimeInput(),
desiredSpec: { tasks: [{ taskSpec: { steps: [{ script: expectedSecret }] } }] },
};
const observed = observePacSourceArtifactRuntime(input, (_args: string[], label: string) => label === "pipeline-get"
? { kind: "ok", value: { metadata: { name: "pipeline", annotations: manifestAnnotations() }, spec: { tasks: [{ taskSpec: { steps: [{ script: actualSecret }] } }] } } }
: { kind: "ok", value: { items: [pipelineRun("agentrun-nc01-v02-ci-secret", "2026-07-11T00:00:00Z", { tasks: [{ taskSpec: { steps: [{ script: actualSecret }] } }] })] } });
const serialized = JSON.stringify(observed);
expect(observed.live.firstDrift?.path).toBe("$.tasks[0].taskSpec.steps[0].script");
expect(observed.live.firstDrift?.expected).toBe(pacValueEvidence(expectedSecret));
expect(observed.live.firstDrift?.actual).toBe(pacValueEvidence(actualSecret));
expect(serialized).not.toContain(expectedSecret);
expect(serialized).not.toContain(actualSecret);
expect(serialized).not.toContain("Authorization");
expect(serialized).not.toContain("QUERY_SUPER_SECRET");
});
test("unknown runtime keys and forged paths are fingerprinted", () => {
const maliciousKey = "HEADER_QUERY_SUPER_SECRET";
const local = firstPacSourceArtifactDrift({ tasks: [], [maliciousKey]: "expected" }, { tasks: [], [maliciousKey]: "actual" });
expect(local?.path).not.toContain(maliciousKey);
expect(local?.path).toContain("type=string,length=");
const maliciousInput = { ...runtimeInput(), desiredSpec: { ...desiredSpec, [maliciousKey]: "expected" } };
const observed = observePacSourceArtifactRuntime(maliciousInput, (_args: string[], label: string) => label === "pipeline-get"
? { kind: "ok", value: { ...pipeline(), spec: { ...desiredSpec, [maliciousKey]: "actual" } } }
: { kind: "ok", value: { items: [pipelineRun("agentrun-nc01-v02-ci-key", "2026-07-11T00:00:00Z", { ...desiredSpec, [maliciousKey]: "actual" })] } });
expect(JSON.stringify(observed)).not.toContain(maliciousKey);
expect(pacRuntimeSafePath(`$.${maliciousKey}`)).toBe(`path(${pacValueEvidence(`$.${maliciousKey}`)})`);
});
test("untrusted runtime annotations and identities are never echoed", () => {
const secret = "Authorization: Bearer OBSERVER_SUPER_SECRET https://u:p@example.invalid/x?token=QUERY_SECRET";
const annotations = {
...manifestAnnotations(),
"unidesk.ai/owning-config-ref": secret,
"unidesk.ai/effective-config-sha256": secret,
"unidesk.ai/source-artifact-renderer": secret,
};
const observed = observePacSourceArtifactRuntime(runtimeInput(), (_args: string[], label: string) => label === "pipeline-get"
? { kind: "ok", value: { metadata: { name: secret, annotations }, spec: desiredSpec } }
: { kind: "ok", value: { items: [{ ...pipelineRun("agentrun-nc01-v02-ci-annotation", "2026-07-11T00:00:00Z"), metadata: { name: secret, creationTimestamp: "2026-07-11T00:00:00Z", labels: { "pipelinesascode.tekton.dev/sha": sourceCommit }, annotations } }] } });
const serialized = JSON.stringify(observed);
expect(observed.live.provenanceAligned).toBe(false);
expect(observed.live.configRef).toBeNull();
expect(observed.live.effectiveConfigSha256).toBeNull();
expect(observed.live.name).toBeNull();
expect(serialized).not.toContain(secret);
expect(serialized).not.toContain("OBSERVER_SUPER_SECRET");
expect(serialized).not.toContain("QUERY_SECRET");
const forged = pacRuntimeSourceArtifactItem({
status: "drifted",
name: "observer-super-secret",
canonicalSha256: `sha256:${"c".repeat(64)}`,
firstDrift: { path: "$.HEADER_QUERY_SUPER_SECRET", expected: secret, actual: secret },
provenanceAligned: false,
configRef: "SECRET/TOKEN#QUERY",
effectiveConfigSha256: `sha256:${"d".repeat(64)}`,
renderer: provenance.renderer,
mode: provenance.mode,
sourceCommit: "e".repeat(40),
reason: secret,
candidateCount: 1,
}, {
configRef: provenance.configRef,
effectiveConfigSha256: `sha256:${"f".repeat(64)}`,
renderer: provenance.renderer,
mode: provenance.mode,
sourceCommit,
exactName: null,
namePrefix: "agentrun-nc01-v02-ci",
});
const forgedSerialized = JSON.stringify(forged);
expect(forged.name).toBeNull();
expect(forged.configRef).toBeNull();
expect(forged.effectiveConfigSha256).toBeNull();
expect(forged.provenanceAligned).toBe(false);
expect(forged.sourceCommit).toBeNull();
expect(forged.firstDrift?.path).not.toContain("HEADER_QUERY_SUPER_SECRET");
expect(forgedSerialized).not.toContain(secret);
expect(forgedSerialized).not.toContain("SECRET/TOKEN#QUERY");
const forgedAligned = pacRuntimeSourceArtifactItem({
status: "aligned",
provenanceAligned: true,
configRef: provenance.configRef,
effectiveConfigSha256: provenance.effectiveConfigSha256,
renderer: "forged-renderer",
mode: provenance.mode,
sourceCommit,
candidateCount: 1,
}, {
configRef: provenance.configRef,
effectiveConfigSha256: provenance.effectiveConfigSha256,
renderer: provenance.renderer,
mode: provenance.mode,
sourceCommit,
exactName: null,
namePrefix: null,
});
expect(forgedAligned.provenanceAligned).toBe(false);
});
test("typed runtime alignment never reports a synthetic pending state", () => {
const aligned = observePacSourceArtifactRuntime(runtimeInput(), (_args: string[], label: string) => label === "pipeline-get"
? { kind: "ok", value: pipeline() }
: { kind: "ok", value: { items: [pipelineRun("agentrun-nc01-v02-ci-aligned", "2026-07-11T00:00:00Z")] } });
const drifted = structuredClone(aligned);
drifted.embedded.status = "drifted";
const exact = { head: sourceCommit, clean: true, matchesSourceCommit: true };
expect(sourceArtifactRuntimeAlignment(null, exact, sourceCommit)).toBe("not-requested");
expect(sourceArtifactRuntimeAlignment(aligned, exact, sourceCommit)).toBe("aligned");
expect(sourceArtifactRuntimeAlignment(drifted, exact, sourceCommit)).toBe("drifted");
expect(sourceArtifactRuntimeAlignment(aligned, { ...exact, clean: false }, sourceCommit)).toBe("unavailable");
const embeddedOnly = { ...structuredClone(aligned), live: { ...aligned.live, status: "missing" as const, provenanceAligned: false } };
expect(sourceArtifactRuntimeAlignment(embeddedOnly, exact, sourceCommit, "embedded-pipeline-spec")).toBe("aligned");
expect(sourceArtifactRuntimeAlignment(embeddedOnly, exact, sourceCommit, "remote-pipeline-annotation")).toBe("missing");
expect(JSON.stringify([aligned, drifted])).not.toContain("pending");
});
test("local transport and remote observer failures retain only bounded evidence", () => {
const secret = "Authorization: Bearer TRANSPORT_SUPER_SECRET https://review:password@example.invalid/path?token=QUERY_SECRET";
const localReason = pacRuntimeTransportFailureReason({ exitCode: 126, stdout: secret, stderr: secret });
expect(localReason).toContain(pacValueEvidence(secret));
expect(localReason).not.toContain(secret);
expect(pacRuntimeSafeReason(secret)).toBe(`runtime-observer-reason:${pacValueEvidence(secret)}`);
const temporary = mkdtempSync(resolve(tmpdir(), "unidesk-pac-runtime-redaction-test-"));
try {
const bin = resolve(temporary, "bin");
mkdirSync(bin);
const kubectl = resolve(bin, "kubectl");
writeFileSync(kubectl, `#!/bin/sh\nprintf '%s\\n' '${secret}' >&2\nexit 126\n`);
chmodSync(kubectl, 0o755);
const shell = renderPacSourceArtifactRuntimeObserverShell(runtimeInput());
const result = spawnSync("sh", [], {
input: shell,
encoding: "utf8",
timeout: 30_000,
env: { ...process.env, PATH: `${bin}:${process.env.PATH ?? ""}` },
});
expect(result.status).toBe(0);
expect(result.stdout).toContain("command-failed:126:type=string");
expect(result.stdout).not.toContain(secret);
expect(result.stdout).not.toContain("Authorization");
expect(result.stdout).not.toContain("QUERY_SECRET");
} finally {
rmSync(temporary, { recursive: true, force: true });
}
});
test("temp-file transport handles a payload larger than the current 203 KiB HWLAB Pipeline", () => {
const observerSource = readFileSync(rootPath("scripts", "native", "cicd", "pac-source-artifact-runtime.mjs"), "utf8");
expect(observerSource).not.toMatch(/process\.env\.PAC_SOURCE_ARTIFACT_INPUT(?!_FILE)/u);
const temporary = mkdtempSync(resolve(tmpdir(), "unidesk-pac-runtime-test-"));
try {
const bin = resolve(temporary, "bin");
mkdirSync(bin);
const hugeSpec = { params: [], tasks: [{ name: "render", taskSpec: { steps: [{ name: "render", script: "x".repeat(220 * 1024) }] } }] };
const input = {
namespace: "hwlab-ci",
pipeline: "hwlab-nc01-v03-ci-image-publish",
pipelineRunPrefix: "hwlab-nc01-v03-ci-poll",
desiredSpec: hugeSpec,
desiredWrapper: { mode: "embedded-pipeline-spec", executionMode: "pipeline-spec", spec: runtimeWrapperSpec },
provenance,
sourceCommit,
};
expect(Buffer.byteLength(JSON.stringify(input), "utf8")).toBeGreaterThan(203 * 1024);
const pipelineFile = resolve(temporary, "pipeline.json");
const runsFile = resolve(temporary, "runs.json");
writeFileSync(pipelineFile, JSON.stringify({ metadata: { name: input.pipeline, annotations: manifestAnnotations() }, spec: hugeSpec }));
writeFileSync(runsFile, JSON.stringify({ items: [pipelineRun("hwlab-nc01-v03-ci-poll-large", "2026-07-11T00:00:00Z", hugeSpec)] }));
const kubectl = resolve(bin, "kubectl");
writeFileSync(kubectl, "#!/bin/sh\nset -eu\ncase \"$2\" in pipeline) cat \"$PAC_TEST_PIPELINE\" ;; pipelinerun) cat \"$PAC_TEST_RUNS\" ;; *) exit 2 ;; esac\n");
chmodSync(kubectl, 0o755);
const shell = renderPacSourceArtifactRuntimeObserverShell(input);
expect(shell).toContain("observer_input=$(mktemp)");
expect(shell).toContain("PAC_SOURCE_ARTIFACT_INPUT_FILE=\"$observer_input\"");
expect(shell).not.toContain("PAC_SOURCE_ARTIFACT_INPUT=");
const result = spawnSync("sh", [], {
input: shell,
encoding: "utf8",
timeout: 30_000,
maxBuffer: 8 * 1024 * 1024,
env: {
...process.env,
PATH: `${bin}:${process.env.PATH ?? ""}`,
PAC_TEST_PIPELINE: pipelineFile,
PAC_TEST_RUNS: runsFile,
},
});
expect(result.status).toBe(0);
const observed = JSON.parse(result.stdout) as Record<string, any>;
expect(observed.live.status).toBe("aligned");
expect(observed.embedded.status).toBe("aligned");
expect(observed.embedded.sourceCommit).toBe(sourceCommit);
} finally {
rmSync(temporary, { recursive: true, force: true });
}
});
});
describe("shared HWLAB deploy overlay", () => {
test("preserves exact undefined/null semantics without mutating its input", () => {
const document = {
nodes: { NC01: { keep: "node" } },
lanes: { v03: {
keep: "lane",
externalPostgres: { old: true },
runtimeStore: { old: true },
codeAgentRuntime: { old: true },
gitMirror: { old: true },
envRecipe: { keep: "recipe", downloadStack: { keep: "download" } },
} },
};
const overlay = {
nodeId: "NC01",
lane: "v03",
gitopsRoot: "deploy/gitops/node/nc01",
gitUrl: "git@example/HWLAB.git",
sourceBranch: "v0.3",
gitopsBranch: "v0.3-gitops",
runtimeNamespace: "hwlab-v03",
publicApiUrl: "https://api.example",
publicWebUrl: "https://web.example",
catalogPath: "deploy/artifacts/nc01.yaml",
runtimePath: "deploy/gitops/node/nc01/hwlab-v03",
observability: { enabled: true },
dockerProxyHttp: null,
dockerProxyHttps: null,
dockerNoProxyList: ["localhost"],
externalPostgres: null,
runtimeStore: null,
codeAgentRuntime: null,
deployYamlGitMirror: null,
};
const rendered = applyNodeRuntimeDeployYamlOverlay(document, overlay);
expect(document.lanes.v03.externalPostgres).toEqual({ old: true });
expect(rendered.lanes.v03).not.toHaveProperty("externalPostgres");
expect(rendered.lanes.v03.runtimeStore).toBeNull();
expect(rendered.lanes.v03.codeAgentRuntime).toBeNull();
expect(rendered.lanes.v03.gitMirror).toBeNull();
expect(rendered.lanes.v03.keep).toBe("lane");
expect(nodeRuntimeDeployYamlOverlayShellScript().join("\n")).not.toContain(": Record<string");
});
test("the runtime shell helper produces the same deploy.yaml object as the pure renderer", () => {
const temporary = mkdtempSync(resolve(tmpdir(), "unidesk-pac-overlay-test-"));
try {
mkdirSync(resolve(temporary, "deploy"));
const document = { nodes: { NC01: {} }, lanes: { v03: { envRecipe: { downloadStack: {} } } } };
const overlay = {
nodeId: "NC01", lane: "v03", gitopsRoot: "deploy/gitops/node/nc01", gitUrl: "git@example/HWLAB.git",
sourceBranch: "v0.3", gitopsBranch: "v0.3-gitops", runtimeNamespace: "hwlab-v03",
publicApiUrl: "https://api.example", publicWebUrl: "https://web.example", catalogPath: "deploy/artifacts/nc01.yaml",
runtimePath: "deploy/gitops/node/nc01/hwlab-v03", observability: { enabled: true },
dockerProxyHttp: "http://proxy", dockerProxyHttps: "http://proxy", dockerNoProxyList: ["localhost"],
externalPostgres: { host: "postgres" }, runtimeStore: { mode: "postgres" }, codeAgentRuntime: { enabled: true },
deployYamlGitMirror: { readUrl: "http://mirror" },
};
writeFileSync(resolve(temporary, "deploy", "deploy.yaml"), Bun.YAML.stringify(document));
const overlayBase64 = Buffer.from(JSON.stringify(overlay), "utf8").toString("base64");
const shell = [`overlay_b64='${overlayBase64}'`, ...nodeRuntimeDeployYamlOverlayShellScript()].join("\n");
const result = spawnSync("sh", [], {
cwd: temporary,
input: shell,
encoding: "utf8",
timeout: 30_000,
env: { ...process.env, NODE_PATH: resolve(rootPath(), "node_modules") },
});
expect(result.status).toBe(0);
const shellRendered = Bun.YAML.parse(readFileSync(resolve(temporary, "deploy", "deploy.yaml"), "utf8")) as Record<string, unknown>;
expect(shellRendered).toEqual(applyNodeRuntimeDeployYamlOverlay(document, overlay));
} finally {
rmSync(temporary, { recursive: true, force: true });
}
});
});