Files
pikasTech-unidesk/scripts/src/platform-infra-pac-provenance.test.ts
T
2026-07-15 08:40:48 +02:00

430 lines
25 KiB
TypeScript

import { expect, test } from "bun:test";
import { readFileSync } from "node:fs";
import { createRequire } from "node:module";
import { resolve } from "node:path";
import { resolveAgentRunLaneTarget } from "./agentrun-lanes";
import { renderAgentRunPipelineManifest } from "./agentrun-manifests";
import { renderPlatformInfraGiteaDesiredFragments } from "./platform-infra-gitea-desired-fragments";
import { pacConsumerRbacDesiredIdentity, renderPacConsumerRbacDesiredFragment } from "./platform-infra-pac-consumer-rbac";
import { parsePacAdmissionContract, readPacAdmissionContract, renderPacAdmissionDesiredFragment } from "./platform-infra-pac-provenance";
import { pacDebugFixtureDisclosure } from "./platform-infra-pipelines-as-code";
const root = resolve(import.meta.dir, "../..");
const evaluator = createRequire(import.meta.url)("../native/cicd/pac-status-evaluator.cjs") as {
evaluatePacAdmissionState: (input: Record<string, unknown>) => Record<string, any>;
evaluatePacStatus: (input: Record<string, unknown>) => Record<string, any>;
extractPacArtifactEvidence: (records: unknown[], logText: string) => Record<string, any>;
normalizeGitopsRevisionRelation: (input: Record<string, unknown>) => Record<string, any>;
taskTerminalRecord: (taskRun: Record<string, unknown>) => Record<string, any> | null;
runPacStatusFixtureChecks: () => { ok: boolean; checks: Array<{ id: string; ok: boolean }> };
};
function documents(value: string): any[] {
return value.split(/^---\s*$/mu).map((item) => item.trim()).filter(Boolean).map((item) => Bun.YAML.parse(item));
}
test("admission contract rejects malformed required declarations instead of silently downgrading", () => {
const source = Bun.YAML.parse(readFileSync(resolve(root, "config/platform-infra/pipelines-as-code.yaml"), "utf8")) as any;
const malformedRequired = structuredClone(source);
malformedRequired.consumers.find((item: any) => item.deliveryProvenance !== undefined).deliveryProvenance.required = "true";
expect(() => parsePacAdmissionContract(malformedRequired)).toThrow("deliveryProvenance.required must be boolean true or false");
const sharedDefault = structuredClone(source);
sharedDefault.consumers.find((item: any) => item.deliveryProvenance !== undefined).deliveryProvenance.executionServiceAccountName = "default";
expect(() => parsePacAdmissionContract(sharedDefault)).toThrow("must not reserve the shared default ServiceAccount");
const duplicatedServiceAccount = structuredClone(source);
const duplicatedRequiredConsumers = duplicatedServiceAccount.consumers.filter((item: any) => item.deliveryProvenance !== undefined);
duplicatedRequiredConsumers[1].deliveryProvenance.executionServiceAccountName = duplicatedRequiredConsumers[0].deliveryProvenance.executionServiceAccountName;
expect(() => parsePacAdmissionContract(duplicatedServiceAccount)).toThrow("executionServiceAccountName must be unique per target");
const denyingAdmission = structuredClone(source);
denyingAdmission.deliveryProvenance.admission.failurePolicy = "Fail";
denyingAdmission.deliveryProvenance.admission.validationActions = ["Deny"];
expect(() => parsePacAdmissionContract(denyingAdmission)).toThrow("validationActions must be exactly [Warn, Audit]");
});
test("admission queue transition contract rejects absent sources, unknown Tekton states, and duplicate transitions", () => {
const source = Bun.YAML.parse(readFileSync(resolve(root, "config/platform-infra/pipelines-as-code.yaml"), "utf8")) as any;
const absentSource = structuredClone(source);
absentSource.deliveryProvenance.queueTransition.allowed[0].fromSpecStatus = "absent";
expect(() => parsePacAdmissionContract(absentSource)).toThrow("fromSpecStatus must be a known Tekton v1 PipelineRun spec status");
const unknownTarget = structuredClone(source);
unknownTarget.deliveryProvenance.queueTransition.allowed[0].toSpecStatus = "UnknownStatus";
expect(() => parsePacAdmissionContract(unknownTarget)).toThrow("toSpecStatus must be a known Tekton v1 PipelineRun spec status or absent");
const duplicate = structuredClone(source);
duplicate.deliveryProvenance.queueTransition.allowed.push(structuredClone(duplicate.deliveryProvenance.queueTransition.allowed[0]));
expect(() => parsePacAdmissionContract(duplicate)).toThrow("deliveryProvenance.queueTransition.allowed must be unique");
});
test("versioned admission desired state reports controller proof and candidate drift without denying delivery", () => {
const contract = readPacAdmissionContract();
const owningYaml = Bun.YAML.parse(readFileSync(resolve(root, "config/platform-infra/pipelines-as-code.yaml"), "utf8")) as any;
expect(owningYaml.deliveryProvenance.terminalRoles).toBeUndefined();
expect(contract.policyName).toEndWith("-v2");
expect(contract.bindingName).toEndWith("-v2");
expect(contract.queueControllerUsername).toBe("system:serviceaccount:pipelines-as-code:pipelines-as-code-watcher");
expect(contract.allowedQueueTransitions).toEqual([{
fromSpecStatus: "PipelineRunPending",
toSpecStatus: "absent",
fromState: "queued",
toState: "started",
}]);
expect(contract.child.enabled).toBe(false);
expect(contract.consumers.map((item) => item.id)).toEqual(["agentrun-nc01-v02", "platform-infra-sub2rank-nc01", "selfmedia-nc01", "selfmedia-production-nc01", "pikaoa-test-nc01"]);
const items = documents(renderPacAdmissionDesiredFragment("NC01"));
expect(items.map((item) => item.kind)).toEqual(["ValidatingAdmissionPolicy", "ValidatingAdmissionPolicyBinding"]);
const policy = items[0];
const expressions = policy.spec.validations.map((item: any) => item.expression).join("\n");
const messages = policy.spec.validations.map((item: any) => item.message).join("\n");
expect(policy.spec.failurePolicy).toBe("Ignore");
expect(policy.spec.matchConstraints.matchPolicy).toBe("Equivalent");
expect(items[1].spec.validationActions).toEqual(["Warn", "Audit"]);
expect(policy.metadata.annotations["argocd.argoproj.io/sync-wave"]).toBe("0");
expect(items[1].metadata.annotations["argocd.argoproj.io/sync-wave"]).toBe("1");
expect(expressions).toContain("request.userInfo.username");
expect(expressions).toContain("spec.pipelineRef.name");
expect(expressions).toContain("spec.params == oldObject.spec.params");
expect(expressions).toContain("object.spec.pipelineRef == oldObject.spec.pipelineRef");
expect(expressions).not.toContain("object.spec == oldObject.spec");
expect(expressions).toContain("taskRunTemplate.serviceAccountName == oldObject.spec.taskRunTemplate.serviceAccountName");
expect(expressions).toContain("object.metadata.name.startsWith");
expect(expressions).toContain('object.metadata.labels["tekton.dev/pipeline"]');
expect(expressions).toContain("agentrun-nc01-v02-tekton-runner");
expect(expressions).toContain("sub2rank-nc01-tekton-runner");
expect(expressions).not.toContain('serviceAccountName == "default"');
expect(expressions).toContain("selfmedia-nc01-tekton-runner");
expect(messages).toContain("execution ServiceAccount");
expect(expressions).toContain(contract.child.parentUidAnnotation);
expect(expressions).toContain("oldObject");
expect(JSON.stringify(items)).not.toContain('"kind":"ServiceAccount"');
const specGuard = policy.spec.validations.find((item: any) => item.message.includes("PipelineRun spec fields are immutable"));
const queueGuard = policy.spec.validations.find((item: any) => item.message.includes("YAML-declared queue transition"));
const oldRun = { spec: { pipelineSpec: { tasks: [{ name: "plan-artifacts" }] }, workspaces: [], timeouts: { pipeline: "1h" } } };
const mutatedRun = structuredClone(oldRun);
mutatedRun.spec.pipelineSpec.tasks[0].name = "forged-task";
for (const field of ["managedBy", "params", "pipelineRef", "taskRunSpecs", "taskRunTemplate", "timeouts", "workspaces"]) {
expect(specGuard.expression).toContain(`has(object.spec.${field})`);
expect(specGuard.expression).toContain(`object.spec.${field} == oldObject.spec.${field}`);
}
expect(specGuard.expression).toContain("has(dyn(object.spec).pipelineSpec)");
expect(specGuard.expression).toContain("has(dyn(oldObject.spec).pipelineSpec)");
expect(specGuard.expression).toContain("dyn(object.spec).pipelineSpec == dyn(oldObject.spec).pipelineSpec");
expect(specGuard.expression).not.toContain("has(object.spec.pipelineSpec)");
expect(specGuard.expression).not.toContain("object.spec.pipelineSpec == oldObject.spec.pipelineSpec");
expect(specGuard.expression).not.toContain("pipelinesascode.tekton.dev/state");
expect(mutatedRun.spec).not.toEqual(oldRun.spec);
expect(queueGuard.expression).toContain('request.userInfo.username == "system:serviceaccount:pipelines-as-code:pipelines-as-code-watcher"');
expect(queueGuard.expression).toContain('oldObject.spec.status == "PipelineRunPending"');
expect(queueGuard.expression).toContain("!has(object.spec.status)");
expect(queueGuard.expression).toContain('oldObject.metadata.labels["pipelinesascode.tekton.dev/state"] == "queued"');
expect(queueGuard.expression).toContain('object.metadata.labels["pipelinesascode.tekton.dev/state"] == "started"');
expect(queueGuard.expression).toContain('oldObject.metadata.annotations["unidesk.ai/pac-admission-provenance"] == "admission-pac-v2:agentrun-nc01-v02"');
expect(queueGuard.expression).toContain('object.metadata.annotations["unidesk.ai/pac-admission-provenance"] == "admission-pac-v2:agentrun-nc01-v02"');
expect(queueGuard.expression).toContain("oldObject.metadata.name.startsWith");
expect(queueGuard.expression).toContain("object.metadata.name.startsWith");
expect(queueGuard.expression).toContain("oldObject.spec.taskRunTemplate.serviceAccountName");
expect(queueGuard.expression).toContain("object.spec.taskRunTemplate.serviceAccountName");
expect(queueGuard.expression.match(/admission-pac-v2:agentrun-nc01-v02/gu)).toHaveLength(2);
expect(queueGuard.expression.match(/pipelines-as-code-watcher/gu)).toHaveLength(1);
expect(queueGuard.expression.match(/agentrun-nc01-v02-tekton-runner/gu)).toHaveLength(2);
expect(queueGuard.expression.match(/sub2rank-nc01-tekton-runner/gu)).toHaveLength(2);
expect(queueGuard.expression.match(/selfmedia-nc01-tekton-runner/gu)).toHaveLength(2);
expect(queueGuard.expression).not.toContain("admission-pac-v1:");
expect(queueGuard.expression).not.toContain('== "Cancelled"');
});
test("required consumer default RBAC has one automatic desired owner per namespace and no Tekton mutation verbs", () => {
const rbac = documents(renderPacConsumerRbacDesiredFragment("NC01"));
expect(rbac.map((item) => item.kind)).toEqual(["Role", "RoleBinding", "Role", "RoleBinding", "Role", "RoleBinding", "Role", "RoleBinding"]);
expect(rbac.filter((item) => item.kind === "Role").map((item) => item.metadata.namespace)).toEqual(["agentrun-ci", "devops-infra", "selfmedia-ci", "pikaoa-ci"]);
for (const role of rbac.filter((item) => item.kind === "Role")) {
expect(role.metadata.annotations["argocd.argoproj.io/sync-wave"]).toBe("-1");
expect(role.metadata.annotations["unidesk.ai/effective-config-sha256"]).toBe(pacConsumerRbacDesiredIdentity("NC01").configSha256);
const verbs = role.rules.flatMap((rule: any) => rule.verbs);
for (const verb of ["create", "patch", "update", "delete", "deletecollection"]) expect(verbs).not.toContain(verb);
}
const desiredKinds = documents(renderPlatformInfraGiteaDesiredFragments("NC01")).map((item) => item.kind);
expect(desiredKinds).toEqual([
"Role",
"RoleBinding",
"Role",
"RoleBinding",
"Role",
"RoleBinding",
"Role",
"RoleBinding",
"ValidatingAdmissionPolicy",
"ValidatingAdmissionPolicyBinding",
"ServiceAccount",
"ConfigMap",
"Deployment",
]);
});
test("live admission evaluator reports exact desired drift as non-blocking warnings", () => {
const contract = readPacAdmissionContract();
const admission = documents(renderPacAdmissionDesiredFragment("NC01"));
const rbac = documents(renderPacConsumerRbacDesiredFragment("NC01"));
const policy = { ...admission[0], metadata: { ...admission[0].metadata, uid: "policy-uid", generation: 2, creationTimestamp: "2026-01-01T00:00:00Z" }, status: { observedGeneration: 2, typeChecking: { expressionWarnings: [] } } };
const binding = { ...admission[1], metadata: { ...admission[1].metadata, uid: "binding-uid", creationTimestamp: "2026-01-01T00:00:01Z" } };
const expected = {
targetId: "NC01",
policyName: contract.policyName,
bindingName: contract.bindingName,
version: contract.version,
controllerIdentity: contract.controllerUsername,
configSha256: policy.metadata.annotations["unidesk.ai/effective-config-sha256"],
rbacConfigSha256: rbac[0].metadata.annotations["unidesk.ai/effective-config-sha256"],
};
const input = { policy, binding, role: rbac[0], roleBinding: rbac[1], namespace: "agentrun-ci", defaultCanMutate: false, expected };
expect(evaluator.evaluatePacAdmissionState(input)).toMatchObject({ ready: true, blocking: false, warning: false, activeAfter: "2026-01-01T00:00:01Z", defaultCanMutate: false });
expect(evaluator.evaluatePacAdmissionState({
...input,
policy: {
...policy,
status: {
...policy.status,
typeChecking: {
expressionWarnings: [{
fieldRef: "spec.validations[7].expression",
warning: "undefined field 'pipelineSpec'",
}],
},
},
},
})).toMatchObject({ ready: false, blocking: false, warning: true, reasons: expect.arrayContaining(["policy-expression-warning"]) });
const apiDefaultedPolicy = {
...policy,
spec: {
...policy.spec,
matchConstraints: {
...policy.spec.matchConstraints,
namespaceSelector: {},
objectSelector: {},
resourceRules: policy.spec.matchConstraints.resourceRules.map((rule: any) => ({ ...rule, scope: "*" })),
},
},
};
expect(evaluator.evaluatePacAdmissionState({ ...input, policy: apiDefaultedPolicy })).toMatchObject({
ready: true,
liveSpecSha256: expected.configSha256,
});
expect(evaluator.evaluatePacAdmissionState({ ...input, defaultCanMutate: true })).toMatchObject({ ready: false, blocking: false, warning: true, reasons: expect.arrayContaining(["default-serviceaccount-can-mutate-tekton-runs"]) });
expect(evaluator.evaluatePacAdmissionState({ ...input, defaultCanMutate: null })).toMatchObject({ ready: false, blocking: false, warning: true, defaultCanMutate: null, reasons: expect.arrayContaining(["default-serviceaccount-mutation-probe-unavailable"]) });
expect(evaluator.evaluatePacAdmissionState({ ...input, role: { ...rbac[0], rules: [rbac[0].rules[0]] } })).toMatchObject({ ready: false, blocking: false, warning: true, reasons: expect.arrayContaining(["default-role-rules-mismatch"]) });
expect(evaluator.evaluatePacAdmissionState({ ...input, expected: { ...expected, configSha256: `sha256:${"0".repeat(64)}` } })).toMatchObject({ ready: false, blocking: false, warning: true, reasons: expect.arrayContaining(["policy-config-sha256-mismatch"]) });
const mutatedPolicy = {
...policy,
spec: {
...policy.spec,
validations: policy.spec.validations.map((item: any, index: number) => index === 0 ? { ...item, expression: "true" } : item),
},
};
expect(evaluator.evaluatePacAdmissionState({ ...input, policy: mutatedPolicy })).toMatchObject({
ready: false,
reasons: expect.arrayContaining(["admission-live-spec-sha256-mismatch"]),
});
expect(evaluator.evaluatePacAdmissionState({
...input,
policy: { ...policy, spec: { ...policy.spec, matchConditions: [{ name: "disable-enforcement", expression: "false" }] } },
})).toMatchObject({ ready: false, reasons: expect.arrayContaining(["admission-live-spec-sha256-mismatch"]) });
expect(evaluator.evaluatePacAdmissionState({
...input,
binding: { ...binding, spec: { ...binding.spec, matchResources: { namespaceSelector: { matchLabels: { disabled: "true" } } } } },
})).toMatchObject({ ready: false, reasons: expect.arrayContaining(["admission-live-spec-sha256-mismatch"]) });
expect(evaluator.evaluatePacAdmissionState({
...input,
policy: {
...apiDefaultedPolicy,
spec: {
...apiDefaultedPolicy.spec,
matchConstraints: {
...apiDefaultedPolicy.spec.matchConstraints,
namespaceSelector: { matchLabels: { disabled: "true" } },
},
},
},
})).toMatchObject({ ready: false, reasons: expect.arrayContaining(["admission-live-spec-sha256-mismatch"]) });
expect(evaluator.evaluatePacAdmissionState({
...input,
policy: {
...apiDefaultedPolicy,
spec: {
...apiDefaultedPolicy.spec,
matchConstraints: {
...apiDefaultedPolicy.spec.matchConstraints,
resourceRules: apiDefaultedPolicy.spec.matchConstraints.resourceRules.map((rule: any) => ({ ...rule, scope: "Namespaced" })),
},
},
},
})).toMatchObject({ ready: false, reasons: expect.arrayContaining(["admission-live-spec-sha256-mismatch"]) });
});
test("AgentRun owning renderer emits ordered terminal roles over the shared workspace without changing build and publish steps", () => {
const spec = resolveAgentRunLaneTarget({ node: "NC01", lane: "nc01-v02" }).spec;
const pipeline = renderAgentRunPipelineManifest(spec) as any;
const tasks = pipeline.spec.tasks;
expect(tasks.map((item: any) => item.name)).toEqual(["plan-artifacts", "collect-artifacts", "gitops-promote"]);
expect(tasks[0].runAfter).toBeUndefined();
expect(tasks[1].runAfter).toEqual(["plan-artifacts"]);
expect(tasks[2].runAfter).toEqual(["collect-artifacts"]);
for (const task of tasks) expect(task.workspaces).toEqual([{ name: "source", workspace: "source" }]);
expect(tasks[0].taskSpec.steps.map((item: any) => item.name)).toEqual(["source-checkout", "probe-env-image"]);
expect(tasks[1].taskSpec.steps.map((item: any) => item.name)).toEqual(["build-env-image"]);
expect(tasks[2].taskSpec.steps.map((item: any) => item.name)).toEqual(["publish-gitops"]);
expect(tasks[0].taskSpec.steps[1].script).toContain('"event":"pac-delivery-plan"');
expect(tasks[1].taskSpec.steps[0].script).toContain("buildctl-daemonless.sh");
expect(tasks[2].taskSpec.steps[0].script).toContain("gitops-publish");
});
test("AgentRun rendered delivery plan and real TaskRun terminals close the status evaluator gate", () => {
const spec = resolveAgentRunLaneTarget({ node: "NC01", lane: "nc01-v02" }).spec;
const pipeline = renderAgentRunPipelineManifest(spec) as any;
const tasks = pipeline.spec.tasks as any[];
const sourceCommit = "c".repeat(40);
const gitopsCommit = "b".repeat(40);
const digest = `sha256:${"a".repeat(64)}`;
const planPrintf = String(tasks[0].taskSpec.steps[1].script)
.split("\n")
.find((line) => line.startsWith("printf '{\"event\":\"pac-delivery-plan\""));
expect(planPrintf).toBeDefined();
const planResult = Bun.spawnSync({
cmd: ["sh", "-c", `build_services='["agentrun-mgr"]'; reused_services='[]'; ${planPrintf!.replaceAll("$(params.revision)", sourceCommit)}`],
stdout: "pipe",
stderr: "pipe",
});
expect(planResult.exitCode).toBe(0);
const plan = JSON.parse(planResult.stdout.toString().trim());
expect(plan).toMatchObject({ event: "pac-delivery-plan", sourceCommitId: sourceCommit, buildServices: ["agentrun-mgr"] });
const terminals = tasks.map((task) => evaluator.taskTerminalRecord({
apiVersion: "tekton.dev/v1",
kind: "TaskRun",
metadata: {
name: `fixture-${task.name}`,
labels: { "tekton.dev/pipelineTask": task.name },
},
status: {
conditions: [{ type: "Succeeded", status: "True", reason: "Succeeded" }],
results: [],
},
}));
expect(terminals).not.toContain(null);
const publish = {
ok: true,
status: "succeeded",
phase: "gitops-publish",
gitopsCommit,
sourceCommit,
imageStatus: "built",
digest,
valuesPrinted: false,
};
const artifact = evaluator.extractPacArtifactEvidence([plan, ...terminals, publish], "");
expect(artifact.sourceObservation).toMatchObject({
contract: "pac-delivery-plan-v1",
mode: "delivery",
valid: true,
terminal: {
planArtifacts: "succeeded",
collectArtifacts: "succeeded",
gitopsPromote: "succeeded",
},
terminalSources: {
planArtifacts: { markerSource: "pac-delivery-plan-structured-log" },
},
});
expect(evaluator.evaluatePacStatus({
sourceCommit,
artifact,
registryPresent: true,
argo: {
sync: "Synced",
health: "Healthy",
revision: gitopsCommit,
revisionRelation: { relation: "exact", expectedRevision: gitopsCommit, observedRevision: gitopsCommit },
},
runtime: { image: `registry/agentrun-mgr@${digest}`, digest, replicas: 1, readyReplicas: 1 },
})).toMatchObject({ ok: true, code: "pac-ready-gitops-exact" });
});
test("provenance fixtures keep outer PaC delivery eligible while reporting admission warnings", () => {
const result = evaluator.runPacStatusFixtureChecks();
expect(result.ok).toBe(true);
for (const id of ["gitops-only-registry-not-configured", "image-registry-missing-fails-closed", "equal-revisions-ignore-owning-git-fetch-failure", "different-revisions-fetch-failure-remains-unknown", "admission-provenance-verified", "pre-bootstrap-run-warning-only", "marker-mismatch-warning-only", "candidate-label-warning-only", "candidate-pipeline-ref-warning-only", "service-account-mismatch-warning-only", "policy-identity-mismatch-warning-only"]) {
expect(result.checks.find((item) => item.id === id)?.ok).toBe(true);
}
});
test("equal GitOps revisions stay exact when the supplemental owning Git fetch fails", () => {
const revision = "b".repeat(40);
const raw = {
relation: "unknown",
expectedRevision: revision,
observedRevision: revision,
proof: "unavailable",
reason: "owning-git-fetch-failed",
fetchOk: false,
};
const normalized = evaluator.normalizeGitopsRevisionRelation(raw);
expect(normalized).toMatchObject({
relation: "exact",
proof: "direct-revision-equality",
reason: "revisions-equal",
contextReason: "owning-git-fetch-failed",
warnings: [{
warning: true,
blocking: false,
code: "pac-owning-git-fetch-failed",
mutation: false,
valuesPrinted: false,
}],
valuesPrinted: false,
});
expect(evaluator.normalizeGitopsRevisionRelation(normalized)).toEqual(normalized);
const remote = readFileSync(resolve(root, "scripts/src/platform-infra-pipelines-as-code-remote.sh"), "utf8");
expect(remote).toContain("normalizeGitopsRevisionRelation({");
});
test("history evaluates admission and default RBAC in each consumer namespace", () => {
const remote = readFileSync(resolve(root, "scripts/src/platform-infra-pipelines-as-code-remote.sh"), "utf8");
expect(remote).toContain("consumer.admissionState = admissionStateForConsumer(consumer)");
expect(remote).toContain("kubectlJson(['-n', consumer.namespace, 'get', 'role', 'unidesk-pac-consumer-runner'");
expect(remote).toContain("kubectlJson(['-n', consumer.namespace, 'get', 'rolebinding', 'unidesk-pac-consumer-runner-default'");
expect(remote).toContain("defaultCanMutate(consumer.namespace)");
expect(remote).toContain("for verb in create patch update delete deletecollection; do");
expect(remote).toContain('timeout "$UNIDESK_PAC_WAIT_TIMEOUT_SECONDS" kubectl auth can-i');
expect(remote).toContain("for (const verb of ['create', 'patch', 'update', 'delete', 'deletecollection'])");
const defaultMutationProbe = remote.slice(remote.indexOf("function defaultCanMutate(namespace)"), remote.indexOf("function admissionStateForConsumer(consumer)"));
expect(defaultMutationProbe).toContain("timeout: waitTimeoutSeconds * 1000");
expect(defaultMutationProbe).not.toContain("timeout: 12000");
expect(remote).toContain("'delivery plan structured evidence is missing'");
expect(remote).toContain("'delivery plan source commit does not match the selected PipelineRun'");
expect(remote).not.toContain("'g14-ci-plan structured evidence is missing'");
expect(remote).not.toContain("for (const consumer of consumers) consumer.admissionState = admissionState");
expect(remote).toContain("consumer_bootstrap_state()");
expect(remote).toContain('get serviceaccount "$UNIDESK_PAC_RUNNER_SERVICE_ACCOUNT_NAME"');
expect(remote).toContain('get rolebinding "$UNIDESK_PAC_RUNNER_ROLE_BINDING_NAME"');
expect(remote).toContain('get secret "$UNIDESK_PAC_ARGO_REPOSITORY_SECRET_NAME"');
expect(remote).toContain("sa.automountServiceAccountToken === false");
expect(remote).toContain("const expectedKeys = ['password', 'url', 'username']");
expect(remote).toContain("passwordDecoded: false");
expect(remote).not.toContain("Buffer.from(argoSecret.data.password");
expect(remote).not.toContain("--from-literal=password=");
});
test("id-specific PaC debug keeps fixture failures but does not dump every passing check", () => {
const passing = Array.from({ length: 23 }, (_, index) => ({ id: `pass-${index}`, ok: true }));
expect(pacDebugFixtureDisclosure(passing, "agentrun-run")).toMatchObject({
fixtureGate: { ok: true, total: 23, passed: 23, failed: 0, disclosure: "failed-checks-only-for-id-specific-debug" },
checks: [],
});
const withFailure = [...passing, { id: "failed", ok: false }];
expect(pacDebugFixtureDisclosure(withFailure, "agentrun-run").checks).toEqual([{ id: "failed", ok: false }]);
expect(pacDebugFixtureDisclosure(passing, null).checks).toHaveLength(23);
});