import { createHash } from "node:crypto"; import { cpSync, existsSync, lstatSync, mkdirSync, mkdtempSync, readFileSync, realpathSync, renameSync, rmSync, statSync, symlinkSync, writeFileSync } from "node:fs"; import { tmpdir } from "node:os"; import { dirname, isAbsolute, relative, resolve, sep } from "node:path"; import { spawnSync } from "node:child_process"; import { rootPath } from "./config"; import { AGENTRUN_CONFIG_PATH, resolveAgentRunLaneTarget } from "./agentrun-lanes"; import { renderAgentRunPipelineManifest } from "./agentrun-manifests"; import { hwlabRuntimeLaneSpecForNode, isHwlabRuntimeLane, type HwlabRuntimeLaneSpec } from "./hwlab-node-lanes"; import { nodeRuntimeGitopsRoot } from "./hwlab-node/cleanup"; import { nodeRuntimeFeatureConfigSchemaStage, nodeRuntimePipelinePostprocessScript } from "./hwlab-node/render"; import { nodeRuntimeRenderOverlay } from "./hwlab-node/web-probe"; import { hwlabRuntimePipelineProvenance } from "./hwlab-node/pipeline-provenance"; import { applyNodeRuntimeDeployYamlOverlay } from "./hwlab-node/deploy-overlay"; import type { RenderedCliResult } from "./output"; import { renderedCliResult } from "./agentrun/render"; import { stableJsonSha256, stableJsonValue } from "./stable-json"; import { pipelineProvenanceAnnotations, pipelineProvenanceFromManifest, withPipelineProvenanceAnnotations } from "./pipeline-provenance"; import { renderSub2RankDesiredPipeline, sub2RankOwningSourceRemote } from "./platform-infra-sub2rank-pipeline"; import { renderSelfMediaDesiredPipeline, selfMediaSourceWorktreeRemote } from "./selfmedia-delivery-renderer"; import { renderPikaoaTestDesiredPipeline, pikaoaReleaseSourceWorktreeRemote, pikaoaTestSourceWorktreeRemote } from "./pikaoa-test-delivery-renderer"; export type PacSourceArtifactMode = "embedded-pipeline-spec" | "remote-pipeline-annotation"; export type PacSourceArtifactRenderer = "agentrun-control-plane" | "hwlab-runtime-lane" | "sub2rank-platform-service" | "selfmedia-runtime" | "pikaoa-test-runtime" | "pikaoa-release-runtime"; export type PacSourceArtifactAction = "plan" | "check" | "write" | "status" | "verify-runtime"; export type PacSourceArtifactRuntimeAlignment = "not-requested" | "aligned" | "drifted" | "missing" | "unavailable"; export interface PacSourceArtifactTaskRunTemplateSpec { readonly hostNetwork: boolean; readonly dnsPolicy: "ClusterFirst" | "ClusterFirstWithHostNet" | "Default" | "None"; readonly fsGroup: number; } export interface PacSourceArtifactSpec { readonly mode: PacSourceArtifactMode; readonly renderer: PacSourceArtifactRenderer; readonly configRef: string; readonly pipelineRunPath: string; readonly pipelinePath: string | null; readonly maxKeepRuns: number; readonly taskRunTemplate: PacSourceArtifactTaskRunTemplateSpec; } export interface PacSourceArtifactBinding { readonly target: { readonly id: string }; readonly consumer: { readonly id: string; readonly node: string; readonly lane: string; readonly namespace: string; readonly pipeline: string; readonly pipelineRunPrefix: string; readonly argoNamespace: string; readonly argoApplication: string; readonly argoBootstrap: { readonly project: string; readonly repoUrl: string; readonly targetRevision: string; readonly path: string; readonly destinationNamespace: string; readonly automated: boolean; } | null; readonly deliveryProvenance?: { readonly markerAnnotation: string; readonly markerValue: string; readonly executionServiceAccountName: string; } | null; readonly sourceArtifact: PacSourceArtifactSpec; }; readonly repository: { readonly id: string; readonly url: string; readonly cloneUrl: string; readonly owner: string; readonly repo: string; readonly params: Readonly>; }; } export interface PacSourceArtifactOptions { readonly action: PacSourceArtifactAction; readonly targetId: string; readonly consumerId: string; readonly sourceWorktree: string; readonly sourceCommit: string | null; readonly confirm: boolean; readonly json: boolean; readonly full: boolean; } export interface PacSourceArtifactRuntimeObservation { readonly live: PacSourceArtifactRuntimeItem; readonly embedded: PacSourceArtifactRuntimeItem; } export interface PacSourceArtifactRuntimeItem { readonly status: "aligned" | "drifted" | "missing" | "unavailable"; readonly name: string | null; readonly canonicalSha256: string | null; readonly firstDrift: PacSourceArtifactDrift | null; readonly provenanceAligned: boolean; readonly configRef: string | null; readonly effectiveConfigSha256: string | null; readonly sourceCommit: string | null; readonly reason: string | null; readonly candidateCount: number; } export interface PacSourceArtifactDrift { readonly path: string; readonly expected: string; readonly actual: string; } export type PacSourceArtifactRuntimeObserver = (input: { readonly binding: PacSourceArtifactBinding; readonly desiredSpec: Record; readonly desiredWrapper: Record | null; readonly provenance: PacSourceArtifactProvenance; readonly sourceCommit: string | null; }) => Promise; interface PacSourceArtifactProvenance { readonly configRef: string; readonly effectiveConfigSha256: string; readonly renderer: PacSourceArtifactRenderer; readonly mode: PacSourceArtifactMode; } interface DesiredArtifact { readonly pipeline: Record; readonly pipelineRun: Record; readonly provenance: PacSourceArtifactProvenance; readonly desiredSpec: Record; readonly files: readonly { readonly path: string; readonly content: string }[]; } interface SourceInspection { readonly status: "aligned" | "drifted" | "missing"; readonly aligned: boolean; readonly pipelineCanonicalSha256: string | null; readonly pipelineRunCanonicalSha256: string | null; readonly firstDrift: PacSourceArtifactDrift | null; readonly provenanceAligned: boolean; } export interface SourceWorktreeState { readonly head: string; readonly clean: boolean; readonly matchesSourceCommit: boolean | null; } export class PacSourceArtifactError extends Error { readonly code: string; readonly safeDetails: Readonly>; constructor(code: string, safeDetails: Readonly> = {}) { super(code); this.name = "PacSourceArtifactError"; this.code = code; this.safeDetails = safeDetails; } } export interface PacSourceArtifactSafeError { readonly code: string; readonly evidence: string; readonly details: Readonly>; } export function pacSourceArtifactSafeError(error: unknown): PacSourceArtifactSafeError { const message = error instanceof Error ? error.message : String(error); const allowedDetailKeys = new Set([ "expectedUrlFingerprint", "observedUrlFingerprint", "head", "requestedSourceCommit", ]); const details = error instanceof PacSourceArtifactError ? Object.fromEntries(Object.entries(error.safeDetails).map(([key, value]) => [key, allowedDetailKeys.has(key) ? value : pacValueEvidence(value)])) : {}; return { code: error instanceof PacSourceArtifactError ? error.code : "source-artifact-operation-failed", evidence: pacValueEvidence(message), details, }; } const knownDriftPathKeys = new Set([ "accessModes", "annotations", "apiVersion", "args", "command", "computeResources", "default", "description", "dnsPolicy", "env", "envFrom", "executionMode", "finally", "fsGroup", "generateName", "hostNetwork", "image", "kind", "labels", "length", "metadata", "mode", "mountPath", "name", "namespace", "onError", "operator", "optional", "params", "pipeline", "pipelineRef", "pipelineSpec", "podTemplate", "readinessProbe", "readOnly", "requests", "resources", "results", "retries", "runAfter", "script", "secret", "secretName", "securityContext", "serviceAccountName", "sidecars", "spec", "steps", "storage", "subPath", "taskRunTemplate", "taskSpec", "tasks", "timeout", "timeouts", "type", "value", "values", "volumeClaimTemplate", "volumeMounts", "volumes", "when", "workspaces", "workingDir", "wrapper", ]); export function parsePacSourceArtifactOptions(args: readonly string[]): PacSourceArtifactOptions { const action = args[0]; if (!isSourceArtifactAction(action)) { throw new Error("source-artifact requires one of plan, check, write, status, verify-runtime"); } let targetId: string | null = null; let consumerId: string | null = null; let sourceWorktree: string | null = null; let sourceCommit: string | null = null; let confirm = false; let json = false; let full = false; for (let index = 1; index < args.length; index += 1) { const arg = args[index]; if (arg === "--confirm") { confirm = true; continue; } if (arg === "--json") { json = true; continue; } if (arg === "--full") { full = true; continue; } if (arg === "--target" || arg === "--consumer" || arg === "--source-worktree" || arg === "--source-commit") { const value = args[index + 1]; if (value === undefined || value.startsWith("--")) throw new Error(`${arg} requires a value`); if (arg === "--target") targetId = value; else if (arg === "--consumer") consumerId = value; else if (arg === "--source-worktree") sourceWorktree = value; else sourceCommit = value.toLowerCase(); index += 1; continue; } throw new Error(`unsupported source-artifact option: ${arg}`); } if (targetId === null) throw new Error("source-artifact requires explicit --target"); if (consumerId === null) throw new Error("source-artifact requires explicit --consumer"); if (sourceWorktree === null) throw new Error("source-artifact requires explicit --source-worktree"); if (!isAbsolute(sourceWorktree)) throw new Error("--source-worktree must be an absolute path"); if (sourceCommit !== null && !/^[0-9a-f]{40}$/u.test(sourceCommit)) throw new Error("--source-commit must be a full 40-character git SHA"); if (sourceCommit !== null && action !== "status" && action !== "verify-runtime") throw new Error("--source-commit is accepted only by source-artifact status or verify-runtime"); if (action === "verify-runtime" && sourceCommit === null) throw new PacSourceArtifactError("source-commit-required"); if (action === "write" && !confirm) throw new Error("source-artifact write requires --confirm"); if (action !== "write" && confirm) throw new Error("--confirm is accepted only by source-artifact write"); return { action, targetId, consumerId, sourceWorktree, sourceCommit, confirm, json, full }; } export async function runPacSourceArtifact( binding: PacSourceArtifactBinding, options: PacSourceArtifactOptions, observeRuntime?: PacSourceArtifactRuntimeObserver, ): Promise> { if (binding.target.id.toLowerCase() !== options.targetId.toLowerCase()) { throw new Error(`source-artifact target ${options.targetId} does not match resolved target ${binding.target.id}`); } if (binding.consumer.id.toLowerCase() !== options.consumerId.toLowerCase()) { throw new Error(`source-artifact consumer ${options.consumerId} does not match resolved consumer ${binding.consumer.id}`); } const sourceWorktree = validateSourceWorktree(options.sourceWorktree, binding); const sourceHead = git(sourceWorktree, ["rev-parse", "HEAD"]).toLowerCase(); const sourceWorktreeState: SourceWorktreeState = { head: sourceHead, clean: git(sourceWorktree, ["status", "--porcelain=v1", "--untracked-files=all"]).length === 0, matchesSourceCommit: options.sourceCommit === null ? null : sourceHead === options.sourceCommit, }; assertPacSourceArtifactVerifyWorktree(options.action, options.sourceCommit, sourceWorktreeState); const desired = renderDesiredArtifact(binding, sourceWorktree); let source = inspectSourceArtifact(sourceWorktree, binding, desired); const written: string[] = []; if (options.action === "write") { written.push(...writeArtifactFilesAtomically(sourceWorktree, desired.files)); source = inspectSourceArtifact(sourceWorktree, binding, desired); } const needsRuntime = options.action === "status" || options.action === "verify-runtime"; const runtime = needsRuntime ? observeRuntime === undefined ? unavailableRuntimeObservation() : await observeRuntime({ binding, desiredSpec: desired.desiredSpec, desiredWrapper: options.sourceCommit === null ? null : desiredRuntimePipelineRunWrapper(binding, desired.pipelineRun, options.sourceCommit), provenance: desired.provenance, sourceCommit: options.sourceCommit, }) : null; const sourceOk = source.aligned && source.provenanceAligned; const runtimeAlignment = sourceArtifactRuntimeAlignment(runtime, sourceWorktreeState, options.sourceCommit, binding.consumer.sourceArtifact.mode); const runtimeOk = runtimeAlignment === "aligned"; const ok = options.action === "check" ? sourceOk : options.action === "verify-runtime" ? sourceOk && runtimeOk : options.action === "write" ? sourceOk : true; const desiredSpecSha256 = canonicalSha256(desired.desiredSpec); return { ok, action: `platform-infra-pipelines-as-code-source-artifact-${options.action}`, mutation: options.action === "write" && written.length > 0, target: binding.target.id, consumer: binding.consumer.id, node: binding.consumer.node, lane: binding.consumer.lane, mode: binding.consumer.sourceArtifact.mode, renderer: binding.consumer.sourceArtifact.renderer, sourceWorktree, files: { pipelineRun: binding.consumer.sourceArtifact.pipelineRunPath, pipeline: binding.consumer.sourceArtifact.pipelinePath, written, }, provenance: desired.provenance, desired: { canonicalSha256: desiredSpecSha256, pipeline: binding.consumer.pipeline, namespace: binding.consumer.namespace, }, source, sourceWorktreeState, runtime, runtimeTarget: { sourceCommit: options.sourceCommit }, runtimeAlignment, boundary: { desiredAuthority: "owning YAML plus domain renderer", liveExportAllowed: false, sourceWorktreeExplicit: true, canonicalAdmissionDefaultsRemoved: [ "PipelineRun.spec.timeouts.pipeline=", "workspaces[].volumeClaimTemplate.metadata={}", "workspaces[].volumeClaimTemplate.status={}", "tasks[].taskSpec.metadata={}", "tasks[].taskSpec.spec=null", "tasks[].taskSpec.params[].type=string", "tasks[].taskSpec.results[].type=string", "tasks[].taskSpec.steps[].computeResources={}", "tasks[].taskSpec.sidecars[].computeResources={}", ], valuesPrinted: false, }, next: sourceArtifactNext(binding, options, sourceOk, sourceWorktreeState, runtime, runtimeAlignment), }; } export function assertPacSourceArtifactVerifyWorktree( action: PacSourceArtifactAction, sourceCommit: string | null, worktree: SourceWorktreeState, ): void { if (action !== "verify-runtime") return; if (sourceCommit === null) throw new PacSourceArtifactError("source-commit-required"); if (!worktree.clean) throw new PacSourceArtifactError("source-worktree-not-clean", { head: worktree.head }); if (worktree.matchesSourceCommit !== true) { throw new PacSourceArtifactError("source-worktree-commit-mismatch", { head: worktree.head, requestedSourceCommit: sourceCommit, }); } } export function sourceArtifactRuntimeAlignment( runtime: PacSourceArtifactRuntimeObservation | null, worktree: SourceWorktreeState, sourceCommit: string | null, mode: PacSourceArtifactMode = "remote-pipeline-annotation", ): PacSourceArtifactRuntimeAlignment { if (runtime === null) return "not-requested"; if (sourceCommit !== null && (!worktree.clean || worktree.matchesSourceCommit !== true)) return "unavailable"; const required = mode === "embedded-pipeline-spec" ? [runtime.embedded] : [runtime.live, runtime.embedded]; if (required.some((item) => item.status === "unavailable")) return "unavailable"; if (required.some((item) => item.status === "missing")) return "missing"; if (required.some((item) => item.status === "drifted" || !item.provenanceAligned)) return "drifted"; return "aligned"; } function sourceArtifactNext( binding: PacSourceArtifactBinding, options: PacSourceArtifactOptions, sourceOk: boolean, worktree: SourceWorktreeState, runtime: PacSourceArtifactRuntimeObservation | null, runtimeAlignment: PacSourceArtifactRuntimeAlignment, ): string { if (!sourceOk) { return options.action === "write" ? "Generated files remain inconsistent; inspect the safe firstDrift evidence and do not publish." : `Run source-artifact write --confirm for ${binding.consumer.id}, then rerun check.`; } if (runtime === null) return `After the consumer PR rolls out, use a clean exact-commit worktree and run verify-runtime for ${binding.consumer.id} with --source-commit .`; if (!worktree.clean || (options.sourceCommit !== null && worktree.matchesSourceCommit !== true)) { return "Create a clean worktree at the exact GitHub merge commit, then rerun status or verify-runtime with that full source commit."; } if (binding.consumer.sourceArtifact.mode === "remote-pipeline-annotation" && runtime.live.status === "unavailable") return "Repair the owning control-plane runtime observer or RBAC, then rerun status before verification."; if (binding.consumer.sourceArtifact.mode === "remote-pipeline-annotation" && runtime.live.status === "missing") return "Apply the owning YAML control plane, confirm the live Pipeline exists, then rerun verify-runtime."; if (binding.consumer.sourceArtifact.mode === "remote-pipeline-annotation" && (runtime.live.status === "drifted" || !runtime.live.provenanceAligned)) return "Apply the owning YAML control plane so the live Pipeline spec and provenance align, then rerun verify-runtime."; if (runtime.embedded.status === "unavailable") return "Inspect the exact-commit PaC PipelineRun identity and observer access, then rerun verify-runtime."; if (runtime.embedded.status === "missing") return "Wait for or repair the exact-commit PaC PipelineRun; do not validate a prefix-selected run."; if (runtime.embedded.status === "drifted" || !runtime.embedded.provenanceAligned) return "Regenerate and merge the consumer source artifact, then verify the new exact-commit PipelineRun."; return runtimeAlignment === "aligned" ? binding.consumer.sourceArtifact.mode === "embedded-pipeline-spec" ? "Exact source, embedded PipelineRun, and provenance are aligned; continue consumer closeout." : "Exact source, live Pipeline, embedded PipelineRun, and provenance are aligned; continue consumer closeout." : "Resolve the reported runtime layer and rerun verify-runtime."; } export function renderPacSourceArtifactResult(result: Record): RenderedCliResult { const files = record(result.files); const desired = record(result.desired); const source = record(result.source); const sourceWorktreeState = record(result.sourceWorktreeState); const runtime = result.runtime === null ? null : record(result.runtime); const live = runtime === null ? null : record(runtime.live); const embedded = runtime === null ? null : record(runtime.embedded); const firstDrift = source.firstDrift === null ? null : record(source.firstDrift); const liveDrift = live?.firstDrift === null ? null : record(live?.firstDrift); const embeddedDrift = embedded?.firstDrift === null ? null : record(embedded?.firstDrift); const warnings = Array.isArray(result.warnings) ? result.warnings.map(record) : []; const lines = [ "PAC SOURCE ARTIFACT", `target=${text(result.target)} consumer=${text(result.consumer)} node=${text(result.node)} lane=${text(result.lane)}`, `mode=${text(result.mode)} renderer=${text(result.renderer)} mutation=${text(result.mutation)}`, `pipelineRun=${text(files.pipelineRun)} pipeline=${text(files.pipeline ?? "-")}`, `desired=${shortSha(desired.canonicalSha256)} source=${shortSha(source.pipelineCanonicalSha256)} aligned=${text(source.aligned)} provenance=${text(source.provenanceAligned)}`, `sourceWorktree=head:${shortSha(sourceWorktreeState.head)} clean:${text(sourceWorktreeState.clean)} commitMatch:${text(sourceWorktreeState.matchesSourceCommit)}`, `sourceDrift=${formatDrift(firstDrift)}`, `runtime=${text(result.runtimeAlignment)} commit=${text(embedded?.sourceCommit ?? record(result.runtimeTarget).sourceCommit)} candidates=${text(embedded?.candidateCount)}`, `live=status:${text(live?.status)} name:${text(live?.name)} hash:${shortSha(live?.canonicalSha256)} provenance:${text(live?.provenanceAligned)} drift:${formatDrift(liveDrift)}`, `embedded=status:${text(embedded?.status)} name:${text(embedded?.name)} hash:${shortSha(embedded?.canonicalSha256)} provenance:${text(embedded?.provenanceAligned)} drift:${formatDrift(embeddedDrift)}`, `runtimeReason=live:${text(live?.reason)} embedded:${text(embedded?.reason)}`, `written=${Array.isArray(files.written) && files.written.length > 0 ? files.written.join(",") : "-"}`, ...warnings.map((warning) => `warning=object:${text(record(warning.object).kind)}:${text(record(warning.object).id)} blocking:${text(warning.blocking)} code:${text(warning.code)} config:${text(warning.configPath)}`), ]; if (typeof result.next === "string") lines.push(`next=${result.next}`); return renderedCliResult(result.ok !== false, String(result.action), `${lines.join("\n")}\n`); } export function canonicalizePacPipelineSpec(value: unknown, path: readonly (string | number)[] = []): unknown { if (Array.isArray(value)) return value.map((item, index) => canonicalizePacPipelineSpec(item, [...path, index])); const duration = canonicalTektonPipelineTimeout(path, value); if (duration !== null) return duration; if (!isRecord(value)) return value; const output: Record = {}; for (const key of Object.keys(value).sort()) { const child = value[key]; const childPath = [...path, key]; if (isProvenTektonAdmissionDefault(childPath, child)) continue; output[key] = canonicalizePacPipelineSpec(child, childPath); } return output; } function canonicalTektonPipelineTimeout(path: readonly (string | number)[], value: unknown): string | null { if (path.join(".") !== "spec.timeouts.pipeline" || typeof value !== "string") return null; const matchSign = /^([+-]?)(.*)$/u.exec(value); if (matchSign === null) return null; const source = matchSign[2] ?? ""; const units: Readonly> = { h: 3_600_000_000_000n, m: 60_000_000_000n, s: 1_000_000_000n, ms: 1_000_000n, us: 1_000n, "µs": 1_000n, "μs": 1_000n, ns: 1n, }; const segment = /([0-9]+)(ns|us|µs|μs|ms|s|m|h)/uy; let offset = 0; let nanoseconds = 0n; let count = 0; while (offset < source.length) { segment.lastIndex = offset; const matched = segment.exec(source); if (matched === null) return null; nanoseconds += BigInt(matched[1] ?? "0") * (units[matched[2] ?? ""] ?? 0n); offset = segment.lastIndex; count += 1; } if (count === 0) return null; if (matchSign[1] === "-") nanoseconds = -nanoseconds; return `tekton-duration-ns:${nanoseconds}`; } export function canonicalSha256(value: unknown): string { return `sha256:${createHash("sha256").update(JSON.stringify(canonicalizePacPipelineSpec(value))).digest("hex")}`; } export function firstPacSourceArtifactDrift(expected: unknown, actual: unknown, path = "$"): PacSourceArtifactDrift | null { const left = canonicalizePacPipelineSpec(expected); const right = canonicalizePacPipelineSpec(actual); return firstCanonicalDrift(left, right, path); } function renderDesiredArtifact(binding: PacSourceArtifactBinding, sourceWorktree: string): DesiredArtifact { const sourceArtifact = binding.consumer.sourceArtifact; const rendered = sourceArtifact.renderer === "agentrun-control-plane" ? renderAgentRunDesiredPipeline(binding) : sourceArtifact.renderer === "hwlab-runtime-lane" ? renderHwlabDesiredPipeline(binding, sourceWorktree) : sourceArtifact.renderer === "sub2rank-platform-service" ? renderSub2RankDesiredPipeline(binding) : sourceArtifact.renderer === "selfmedia-runtime" ? renderSelfMediaPipeline(binding, sourceWorktree) : renderPikaoaTestPipeline(binding, sourceWorktree); const pipeline = sourceArtifact.renderer === "hwlab-runtime-lane" ? rendered.pipeline : withPipelineProvenanceAnnotations(rendered.pipeline, rendered.provenance); if (!provenanceEquals(pacSourceArtifactProvenanceFromManifest(pipeline), rendered.provenance)) { throw new Error(`${sourceArtifact.renderer} did not render the declared Pipeline provenance contract`); } const desiredSpec = requiredRecord(pipeline.spec, "rendered Pipeline.spec"); assertPipelineIdentity(pipeline, binding); const pipelineRun = sourceArtifact.mode === "embedded-pipeline-spec" ? embeddedPipelineRun(binding, desiredSpec, rendered.provenance) : remotePipelineRun(binding, pipeline, rendered.provenance); const files = sourceArtifact.mode === "embedded-pipeline-spec" ? [{ path: sourceArtifact.pipelineRunPath, content: pacSourceArtifactYaml(pipelineRun) }] : [ { path: requiredString(sourceArtifact.pipelinePath, "sourceArtifact.pipelinePath"), content: pacSourceArtifactYaml(pipeline) }, { path: sourceArtifact.pipelineRunPath, content: pacSourceArtifactYaml(pipelineRun) }, ]; return { pipeline, pipelineRun, provenance: rendered.provenance, desiredSpec, files }; } function renderAgentRunDesiredPipeline(binding: PacSourceArtifactBinding): { pipeline: Record; provenance: PacSourceArtifactProvenance } { const { spec } = resolveAgentRunLaneTarget({ node: binding.consumer.node, lane: binding.consumer.lane }); const expectedConfigRef = `${AGENTRUN_CONFIG_PATH}#controlPlane.lanes.${spec.lane}`; assertConfigRef(binding.consumer.sourceArtifact.configRef, expectedConfigRef); assertBindingIdentity(binding, { node: spec.nodeId, lane: spec.lane, namespace: spec.ci.namespace, pipeline: spec.ci.pipeline, pipelineRunPrefix: spec.ci.pipelineRunPrefix, serviceAccount: spec.ci.serviceAccountName, sourceBranch: spec.source.branch, gitopsBranch: spec.gitops.branch, }); return { pipeline: renderAgentRunPipelineManifest(spec), provenance: { configRef: expectedConfigRef, effectiveConfigSha256: stableJsonSha256(spec), renderer: "agentrun-control-plane", mode: binding.consumer.sourceArtifact.mode, }, }; } function renderHwlabDesiredPipeline(binding: PacSourceArtifactBinding, sourceWorktree: string): { pipeline: Record; provenance: PacSourceArtifactProvenance } { if (!isHwlabRuntimeLane(binding.consumer.lane)) throw new Error(`HWLAB source artifact lane ${binding.consumer.lane} is not declared`); const spec = hwlabRuntimeLaneSpecForNode(binding.consumer.lane, binding.consumer.node); const provenance = hwlabRuntimePipelineProvenance(spec); if (binding.consumer.sourceArtifact.renderer !== provenance.renderer || binding.consumer.sourceArtifact.mode !== provenance.mode) { throw new Error(`sourceArtifact renderer/mode must match ${provenance.configRef}.pipelineProvenance`); } assertConfigRef(binding.consumer.sourceArtifact.configRef, provenance.configRef); assertBindingIdentity(binding, { node: spec.nodeId, lane: spec.lane, namespace: "hwlab-ci", pipeline: spec.pipeline, pipelineRunPrefix: spec.pipelineRunPrefix, serviceAccount: spec.serviceAccountName, sourceBranch: spec.sourceBranch, gitopsBranch: spec.gitopsBranch, }); const pipeline = renderHwlabPipelineFromOwningYaml(spec, sourceWorktree); return { pipeline, provenance, }; } function renderSelfMediaPipeline(binding: PacSourceArtifactBinding, sourceWorktree: string): { pipeline: Record; provenance: PacSourceArtifactProvenance } { const rendered = renderSelfMediaDesiredPipeline(binding, sourceWorktree); return { pipeline: rendered.pipeline, provenance: { configRef: rendered.configRef, effectiveConfigSha256: rendered.effectiveConfigSha256, renderer: "selfmedia-runtime", mode: "embedded-pipeline-spec", }, }; } function renderPikaoaTestPipeline(binding: PacSourceArtifactBinding, sourceWorktree: string): { pipeline: Record; provenance: PacSourceArtifactProvenance } { const rendered = renderPikaoaTestDesiredPipeline(binding, sourceWorktree); return { pipeline: rendered.pipeline, provenance: { configRef: rendered.configRef, effectiveConfigSha256: rendered.effectiveConfigSha256, renderer: binding.consumer.sourceArtifact.renderer, mode: "embedded-pipeline-spec", }, }; } function renderHwlabPipelineFromOwningYaml(spec: HwlabRuntimeLaneSpec, sourceWorktree: string): Record { const temporaryRoot = mkdtempSync(resolve(tmpdir(), "unidesk-pac-source-artifact-")); const temporarySource = resolve(temporaryRoot, "source"); const output = resolve(temporaryRoot, "rendered"); const sourceCommit = git(sourceWorktree, ["rev-parse", "HEAD"]); try { copySourceWorktreeForRender(sourceWorktree, temporarySource); const overlayRecord = nodeRuntimeRenderOverlay(spec); const deployPath = resolve(temporarySource, "deploy", "deploy.yaml"); const deploy = parseYamlRecord(readFileSync(deployPath, "utf8"), deployPath); writeFileSync(deployPath, `${Bun.YAML.stringify(applyNodeRuntimeDeployYamlOverlay(deploy, overlayRecord)).trim()}\n`); const renderArgs = [ "scripts/run-bun.mjs", "scripts/gitops-render.mjs", "--lane", spec.lane, "--node", spec.nodeId, "--gitops-root", nodeRuntimeGitopsRoot(spec), "--catalog-path", spec.catalogPath, "--image-tag-mode", "full", "--source-revision", sourceCommit, "--source-repo", spec.gitUrl, "--source-branch", spec.sourceBranch, "--gitops-branch", spec.gitopsBranch, "--git-read-url", spec.gitReadUrl, "--git-write-url", spec.gitWriteUrl, "--registry-prefix", spec.registryPrefix, "--runtime-endpoint", spec.publicApiUrl, "--web-endpoint", spec.publicWebUrl, "--out", output, ]; runChecked("node", renderArgs, temporarySource, 120_000, "HWLAB owning YAML renderer"); const overlay = Buffer.from(JSON.stringify(overlayRecord), "utf8").toString("base64"); const postprocess = [ "set -eu", `render_dir=${shellQuote(output)}`, `overlay_b64=${shellQuote(overlay)}`, ...nodeRuntimePipelinePostprocessScript(nodeRuntimeFeatureConfigSchemaStage(spec)), ].join("\n"); runChecked("sh", [], temporarySource, 120_000, "HWLAB UniDesk domain postprocess/verify renderer", postprocess); const path = resolve(output, spec.tektonDir, "pipeline.yaml"); if (!existsSync(path)) throw new Error(`HWLAB domain renderer did not produce ${path}`); return parseYamlRecord(readFileSync(path, "utf8"), path); } finally { rmSync(temporaryRoot, { recursive: true, force: true }); } } function copySourceWorktreeForRender(sourceWorktree: string, destination: string): void { const excluded = new Set([".git", ".worktree", ".state", "node_modules", "coverage", "tmp", ".tmp"]); cpSync(sourceWorktree, destination, { recursive: true, filter: (source) => { const rel = relative(sourceWorktree, source); if (rel === "") return true; return !excluded.has(rel.split(sep)[0] ?? ""); }, }); const nodeModules = resolve(sourceWorktree, "node_modules"); if (existsSync(nodeModules)) symlinkSync(nodeModules, resolve(destination, "node_modules"), "dir"); } function embeddedPipelineRun(binding: PacSourceArtifactBinding, desiredSpec: Record, provenance: PacSourceArtifactProvenance): Record { const workspaces = pipelineRunWorkspaces(binding, desiredSpec); return { apiVersion: "tekton.dev/v1", kind: "PipelineRun", metadata: { name: `${binding.consumer.pipelineRunPrefix}-{{ revision }}`, namespace: binding.consumer.namespace, annotations: pipelineRunAnnotations(binding, provenance), labels: pipelineRunLabels( binding, provenance.renderer === "sub2rank-platform-service" ? "sub2rank" : provenance.renderer === "selfmedia-runtime" ? "selfmedia" : provenance.renderer === "pikaoa-test-runtime" ? "pikaoa" : "agentrun", ), }, spec: { ...(binding.repository.params.pipeline_timeout === undefined ? {} : { timeouts: { pipeline: binding.repository.params.pipeline_timeout } }), pipelineSpec: desiredSpec, taskRunTemplate: taskRunTemplate(binding), params: pipelineRunParams(binding, desiredSpec), ...optionalPipelineRunWorkspaces(workspaces), }, }; } function remotePipelineRun(binding: PacSourceArtifactBinding, pipeline: Record, provenance: PacSourceArtifactProvenance): Record { const desiredSpec = requiredRecord(pipeline.spec, "rendered Pipeline.spec"); const workspaces = pipelineRunWorkspaces(binding, desiredSpec); const pipelinePath = requiredString(binding.consumer.sourceArtifact.pipelinePath, "sourceArtifact.pipelinePath"); const annotations = { ...pipelineRunAnnotations(binding, provenance), "pipelinesascode.tekton.dev/pipeline": pipelinePath, }; if (provenance.renderer === "hwlab-runtime-lane") { if (!isHwlabRuntimeLane(binding.consumer.lane)) throw new Error(`HWLAB source artifact lane ${binding.consumer.lane} is not declared`); const spec = hwlabRuntimeLaneSpecForNode(binding.consumer.lane, binding.consumer.node); Object.assign(annotations, { "hwlab.pikastech.local/ci-contract": "tekton-native-primitive-tasks", "hwlab.pikastech.local/download-profile": spec.downloadProfileId, "hwlab.pikastech.local/gitops-branch": spec.gitopsBranch, "hwlab.pikastech.local/network-profile": spec.networkProfileId, "hwlab.pikastech.local/node": spec.nodeId, "hwlab.pikastech.local/policy": "native-per-service-taskrun-image-publish", "hwlab.pikastech.local/runtime-path": spec.runtimePath, "hwlab.pikastech.local/source-branch": spec.sourceBranch, "hwlab.pikastech.local/source-config": binding.consumer.sourceArtifact.pipelineRunPath, }); } return { apiVersion: "tekton.dev/v1", kind: "PipelineRun", metadata: { generateName: `${binding.consumer.pipelineRunPrefix}-`, namespace: binding.consumer.namespace, annotations, labels: pipelineRunLabels(binding, "hwlab"), }, spec: { timeouts: { pipeline: binding.repository.params.pipeline_timeout }, taskRunTemplate: taskRunTemplate(binding), pipelineRef: { name: binding.consumer.pipeline }, ...optionalPipelineRunWorkspaces(workspaces), params: pipelineRunParams(binding, desiredSpec), }, }; } export function optionalPipelineRunWorkspaces(workspaces: readonly Record[]): Record { return workspaces.length === 0 ? {} : { workspaces }; } function pipelineRunAnnotations(binding: PacSourceArtifactBinding, provenance: PacSourceArtifactProvenance): Record { const branch = requiredParam(binding, "source_branch"); return { "pipelinesascode.tekton.dev/on-event": "[push]", "pipelinesascode.tekton.dev/on-target-branch": `[${branch}]`, "pipelinesascode.tekton.dev/on-cel-expression": `event == 'push' && target_branch == '${branch}' && node == '${binding.consumer.node}'`, "pipelinesascode.tekton.dev/max-keep-runs": String(binding.consumer.sourceArtifact.maxKeepRuns), ...(binding.consumer.deliveryProvenance == null ? {} : { [binding.consumer.deliveryProvenance.markerAnnotation]: binding.consumer.deliveryProvenance.markerValue, }), ...pipelineProvenanceAnnotations(provenance), }; } export function pipelineRunLabels(binding: PacSourceArtifactBinding, partOf: "agentrun" | "hwlab" | "sub2rank" | "selfmedia" | "pikaoa"): Record { if (partOf === "agentrun") { return { "app.kubernetes.io/part-of": "agentrun", "agentrun.pikastech.local/lane": "v0.2", "agentrun.pikastech.local/node": binding.consumer.node, "agentrun.pikastech.local/source-commit": "{{ revision }}", "agentrun.pikastech.local/trigger": "pipelines-as-code", }; } if (partOf === "selfmedia") { return { "app.kubernetes.io/name": `${binding.consumer.id}-pac`, "app.kubernetes.io/part-of": "selfmedia-factory", "unidesk.ai/source-commit": "{{ revision }}", "selfmedia.pikapython.com/source-commit": "{{ revision }}", "selfmedia.pikapython.com/trigger": "pipelines-as-code", }; } if (partOf === "pikaoa") { return { "app.kubernetes.io/name": `${binding.consumer.id}-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", }; } if (partOf === "sub2rank") { return { "app.kubernetes.io/name": "sub2rank", "app.kubernetes.io/part-of": "platform-infra", "unidesk.ai/node": binding.consumer.node, "unidesk.ai/source-commit": "{{ revision }}", "unidesk.ai/trigger": "pipelines-as-code", }; } return { "app.kubernetes.io/name": `${binding.consumer.id}-pac`, "app.kubernetes.io/part-of": "hwlab", "unidesk.ai/source-commit": "{{ revision }}", "hwlab.pikastech.local/gitops-target": binding.consumer.lane, "hwlab.pikastech.local/source-commit": "{{ revision }}", "hwlab.pikastech.local/trigger": "pipelines-as-code", }; } function taskRunTemplate(binding: PacSourceArtifactBinding): Record { const declared = binding.consumer.sourceArtifact.taskRunTemplate; return { serviceAccountName: binding.consumer.deliveryProvenance?.executionServiceAccountName ?? `{{ service_account }}`, podTemplate: { hostNetwork: declared.hostNetwork, dnsPolicy: declared.dnsPolicy, securityContext: { fsGroup: declared.fsGroup }, }, }; } function desiredRuntimePipelineRunWrapper( binding: PacSourceArtifactBinding, pipelineRun: Record, sourceCommit: string, ): Record { const sourceSpec = structuredClone(requiredRecord(pipelineRun.spec, "generated PipelineRun.spec")); delete sourceSpec.pipelineSpec; delete sourceSpec.pipelineRef; return { mode: binding.consumer.sourceArtifact.mode, executionMode: "pipeline-spec", spec: resolvePacRuntimeTemplates(sourceSpec, binding, sourceCommit), }; } function resolvePacRuntimeTemplates(value: unknown, binding: PacSourceArtifactBinding, sourceCommit: string): unknown { if (Array.isArray(value)) return value.map((item) => resolvePacRuntimeTemplates(item, binding, sourceCommit)); if (isRecord(value)) { return Object.fromEntries(Object.entries(value).map(([key, item]) => [key, resolvePacRuntimeTemplates(item, binding, sourceCommit)])); } if (typeof value !== "string") return value; const templateValues: Readonly> = { ...binding.repository.params, revision: sourceCommit, repo_url: binding.repository.url, }; const resolved = value.replace(/\{\{\s*([A-Za-z0-9_]+)\s*\}\}/gu, (_match, key: string) => { const replacement = templateValues[key]; if (replacement === undefined) throw new PacSourceArtifactError("source-artifact-runtime-template-unresolved", { template: pacValueEvidence(key) }); return replacement; }); if (/\{\{|\}\}/u.test(resolved)) throw new PacSourceArtifactError("source-artifact-runtime-template-invalid"); return resolved; } function pipelineRunParams(binding: PacSourceArtifactBinding, desiredSpec: Record): Record[] { const params = arrayRecords(desiredSpec.params, "Pipeline.spec.params"); return params.map((param) => { const name = requiredString(param.name, "Pipeline.spec.params[].name"); if (name === "revision" || name === "source-commit") return { name, value: "{{ revision }}" }; if (name === "source-stage-ref") return { name, value: "{{ source_snapshot_prefix }}/{{ revision }}" }; if (name === "git-url") return { name, value: "{{ repo_url }}" }; const repositoryParam = name.replaceAll("-", "_"); if ((binding.consumer.sourceArtifact.renderer === "selfmedia-runtime" || binding.consumer.sourceArtifact.renderer === "pikaoa-test-runtime" || binding.consumer.sourceArtifact.renderer === "pikaoa-release-runtime") && Object.prototype.hasOwnProperty.call(param, "default")) { return { name, value: param.default }; } if (Object.prototype.hasOwnProperty.call(binding.repository.params, repositoryParam)) { return { name, value: `{{ ${repositoryParam} }}` }; } if (Object.prototype.hasOwnProperty.call(param, "default")) return { name, value: param.default }; throw new Error(`Pipeline param ${name} has no default or PaC repository parameter`); }); } export function pipelineRunWorkspaces(binding: PacSourceArtifactBinding, desiredSpec: Record): Record[] { if (desiredSpec.workspaces === undefined) return []; return arrayRecords(desiredSpec.workspaces, "Pipeline.spec.workspaces").map((workspace) => { const name = requiredString(workspace.name, "Pipeline.spec.workspaces[].name"); if (name === "source" || (name === "workspace" && (binding.consumer.sourceArtifact.renderer === "pikaoa-test-runtime" || binding.consumer.sourceArtifact.renderer === "pikaoa-release-runtime"))) { return { name, volumeClaimTemplate: { spec: { accessModes: ["ReadWriteOnce"], resources: { requests: { storage: requiredParam(binding, "workspace_pvc_size") } }, }, }, }; } if (name === "git-ssh") return { name, secret: { secretName: requiredParam(binding, "git_ssh_secret") } }; throw new Error(`unsupported Pipeline workspace ${name}; declare a renderer mapping before generating the source artifact`); }); } function inspectSourceArtifact(sourceWorktree: string, binding: PacSourceArtifactBinding, desired: DesiredArtifact): SourceInspection { const sourceArtifact = binding.consumer.sourceArtifact; const pipelineRunPath = safeArtifactPath(sourceWorktree, sourceArtifact.pipelineRunPath); const pipelinePath = sourceArtifact.pipelinePath === null ? null : safeArtifactPath(sourceWorktree, sourceArtifact.pipelinePath); if (!existsSync(pipelineRunPath) || (pipelinePath !== null && !existsSync(pipelinePath))) { return { status: "missing", aligned: false, pipelineCanonicalSha256: null, pipelineRunCanonicalSha256: null, firstDrift: drift("$", { artifact: "generated" }, undefined), provenanceAligned: false }; } const actualPipelineRun = parseYamlRecord(readFileSync(pipelineRunPath, "utf8"), sourceArtifact.pipelineRunPath); const actualPipeline = sourceArtifact.mode === "remote-pipeline-annotation" ? parseYamlRecord(readFileSync(requiredString(pipelinePath, "pipelinePath"), "utf8"), requiredString(sourceArtifact.pipelinePath, "pipelinePath")) : { apiVersion: "tekton.dev/v1", kind: "Pipeline", metadata: desired.pipeline.metadata, spec: requiredRecord(requiredRecord(actualPipelineRun.spec, "PipelineRun.spec").pipelineSpec, "PipelineRun.spec.pipelineSpec"), }; const pipelineDrift = firstPacSourceArtifactDrift(desired.pipeline, actualPipeline); const pipelineRunDrift = firstPacSourceArtifactDrift(desired.pipelineRun, actualPipelineRun); const actualProvenance = sourceArtifact.mode === "remote-pipeline-annotation" ? pacSourceArtifactProvenanceFromManifest(actualPipeline) : pacSourceArtifactProvenanceFromManifest(actualPipelineRun); const wrapperProvenance = pacSourceArtifactProvenanceFromManifest(actualPipelineRun); const provenanceAligned = provenanceEquals(actualProvenance, desired.provenance) && provenanceEquals(wrapperProvenance, desired.provenance); const aligned = pipelineDrift === null && pipelineRunDrift === null && provenanceAligned; return { status: aligned ? "aligned" : "drifted", aligned, pipelineCanonicalSha256: canonicalSha256(requiredRecord(actualPipeline.spec, "source Pipeline.spec")), pipelineRunCanonicalSha256: canonicalSha256(actualPipelineRun), firstDrift: pipelineDrift ?? pipelineRunDrift ?? (provenanceAligned ? null : drift("$.metadata.annotations.provenance", desired.provenance, actualProvenance)), provenanceAligned, }; } function validateSourceWorktree(input: string, binding: PacSourceArtifactBinding): string { if (!existsSync(input) || !statSync(input).isDirectory()) throw new Error(`source worktree does not exist or is not a directory: ${input}`); const worktree = realpathSync(input); const top = realpathSync(git(worktree, ["rev-parse", "--show-toplevel"])); if (top !== worktree) throw new Error(`--source-worktree must be the git worktree root; resolved ${top}`); const remote = git(worktree, ["remote", "get-url", "origin"]); const expectedRemote = owningSourceRemote(binding); const expectedIdentity = remoteRepositoryIdentity(expectedRemote); const observedIdentity = remoteRepositoryIdentity(remote); if (expectedIdentity === null || observedIdentity === null || expectedIdentity.host !== observedIdentity.host || expectedIdentity.ownerRepo !== observedIdentity.ownerRepo) { throw new PacSourceArtifactError("source-worktree-origin-mismatch", { expectedUrlFingerprint: fingerprint(expectedRemote), observedUrlFingerprint: fingerprint(remote), }); } safeArtifactPath(worktree, binding.consumer.sourceArtifact.pipelineRunPath); if (binding.consumer.sourceArtifact.pipelinePath !== null) safeArtifactPath(worktree, binding.consumer.sourceArtifact.pipelinePath); return worktree; } function owningSourceRemote(binding: PacSourceArtifactBinding): string { if (binding.consumer.sourceArtifact.renderer === "agentrun-control-plane") { return resolveAgentRunLaneTarget({ node: binding.consumer.node, lane: binding.consumer.lane }).spec.source.worktreeRemote; } if (binding.consumer.sourceArtifact.renderer === "sub2rank-platform-service") return sub2RankOwningSourceRemote(); if (binding.consumer.sourceArtifact.renderer === "selfmedia-runtime") return selfMediaSourceWorktreeRemote(binding.consumer.node); if (binding.consumer.sourceArtifact.renderer === "pikaoa-test-runtime") return pikaoaTestSourceWorktreeRemote(binding.consumer.node); if (binding.consumer.sourceArtifact.renderer === "pikaoa-release-runtime") return pikaoaReleaseSourceWorktreeRemote(binding.consumer.node); if (!isHwlabRuntimeLane(binding.consumer.lane)) throw new PacSourceArtifactError("owning-source-lane-unresolved"); return hwlabRuntimeLaneSpecForNode(binding.consumer.lane, binding.consumer.node).gitUrl; } function remoteRepositoryIdentity(remote: string): { readonly host: string; readonly ownerRepo: string } | null { const trimmed = remote.trim(); const scp = /^[^/@\s]+@([^:\s]+):(.+)$/u.exec(trimmed); let host = scp?.[1] ?? ""; let path = scp?.[2] ?? ""; if (host.length === 0 || path.length === 0) { try { const parsed = new URL(trimmed); if (parsed.username.length > 0 || parsed.password.length > 0 || parsed.search.length > 0 || parsed.hash.length > 0) return null; host = parsed.hostname; path = parsed.pathname; } catch { return null; } } const segments = path.replace(/^\/+|\/+$/gu, "").split("/").filter(Boolean); if (segments.length !== 2) return null; const owner = segments[0]?.toLowerCase(); const repo = segments[1]?.replace(/\.git$/iu, "").toLowerCase(); if (!host || !owner || !repo || !/^[a-z0-9_.-]+$/u.test(owner) || !/^[a-z0-9_.-]+$/u.test(repo)) return null; return { host: host.toLowerCase(), ownerRepo: `${owner}/${repo}` }; } function writeArtifactFilesAtomically(sourceWorktree: string, files: readonly { readonly path: string; readonly content: string }[]): string[] { const pending = files.map((file) => ({ ...file, output: safeArtifactPath(sourceWorktree, file.path) })) .filter((file) => !existsSync(file.output) || readFileSync(file.output, "utf8") !== file.content); if (pending.length === 0) return []; for (const file of pending) { mkdirSync(dirname(file.output), { recursive: true }); safeArtifactPath(sourceWorktree, file.path); } const token = `${process.pid}-${Date.now()}`; const staged = pending.map((file, index) => ({ ...file, temporary: `${file.output}.unidesk-${token}-${index}.tmp` })); try { for (const file of staged) writeFileSync(file.temporary, file.content, { flag: "wx" }); for (const file of staged) renameSync(file.temporary, file.output); } finally { for (const file of staged) rmSync(file.temporary, { force: true }); } return pending.map((file) => file.path); } function safeArtifactPath(worktree: string, relativePath: string): string { if (relativePath.length === 0 || isAbsolute(relativePath) || relativePath.split(/[\\/]/u).includes("..")) { throw new Error(`source artifact path must be a non-empty worktree-relative path without ..: ${relativePath}`); } const root = realpathSync(worktree); const candidate = resolve(root, relativePath); if (candidate !== root && !candidate.startsWith(`${root}${sep}`)) throw new Error(`source artifact path escapes worktree: ${relativePath}`); let current = root; for (const segment of relativePath.split(/[\\/]/u).filter(Boolean)) { current = resolve(current, segment); if (!existsSync(current)) continue; if (lstatSync(current).isSymbolicLink()) throw new Error(`source artifact path crosses symlink: ${relativePath}`); const resolved = realpathSync(current); if (resolved !== root && !resolved.startsWith(`${root}${sep}`)) throw new Error(`source artifact path resolves outside worktree: ${relativePath}`); } return candidate; } function assertConfigRef(actual: string, expected: string): void { if (actual !== expected) throw new Error(`sourceArtifact.configRef must equal resolved owning selector ${expected}; observed ${actual}`); const [file, selector] = actual.split("#", 2); if (file === undefined || selector === undefined || selector.length === 0) throw new Error(`invalid sourceArtifact.configRef: ${actual}`); const parsed = Bun.YAML.parse(readFileSync(rootPath(...file.split("/")), "utf8")) as unknown; let value = parsed; for (const segment of selector.split(".")) { if (!isRecord(value) || !Object.prototype.hasOwnProperty.call(value, segment)) throw new Error(`sourceArtifact.configRef selector does not exist: ${actual}`); value = value[segment]; } if (!isRecord(value)) throw new Error(`sourceArtifact.configRef must resolve to an owning YAML object: ${actual}`); } function assertBindingIdentity(binding: PacSourceArtifactBinding, expected: { node: string; lane: string; namespace: string; pipeline: string; pipelineRunPrefix: string; serviceAccount: string; sourceBranch: string; gitopsBranch: string; }): void { const observed = { node: binding.consumer.node, lane: binding.consumer.lane, namespace: binding.consumer.namespace, pipeline: binding.consumer.pipeline, pipelineRunPrefix: binding.consumer.pipelineRunPrefix, serviceAccount: requiredParam(binding, "service_account"), sourceBranch: requiredParam(binding, "source_branch"), gitopsBranch: requiredParam(binding, "gitops_branch"), }; for (const key of Object.keys(expected) as Array) { if (observed[key] !== expected[key]) throw new Error(`PaC ${binding.consumer.id} ${key}=${observed[key]} does not match owning renderer ${expected[key]}`); } if (requiredParam(binding, "pipeline_name") !== expected.pipeline) throw new Error(`PaC ${binding.consumer.id} repository pipeline_name does not match ${expected.pipeline}`); if (requiredParam(binding, "pipeline_run_prefix") !== expected.pipelineRunPrefix) throw new Error(`PaC ${binding.consumer.id} repository pipeline_run_prefix does not match ${expected.pipelineRunPrefix}`); if (requiredParam(binding, "node") !== expected.node) throw new Error(`PaC ${binding.consumer.id} repository node does not match ${expected.node}`); } function assertPipelineIdentity(pipeline: Record, binding: PacSourceArtifactBinding): void { if (pipeline.apiVersion !== "tekton.dev/v1" || pipeline.kind !== "Pipeline") throw new Error("domain renderer must return tekton.dev/v1 Pipeline"); const metadata = requiredRecord(pipeline.metadata, "rendered Pipeline.metadata"); if (metadata.name !== binding.consumer.pipeline) throw new Error(`rendered Pipeline name ${String(metadata.name)} does not match consumer ${binding.consumer.pipeline}`); if (metadata.namespace !== binding.consumer.namespace) throw new Error(`rendered Pipeline namespace ${String(metadata.namespace)} does not match consumer ${binding.consumer.namespace}`); } export function pacSourceArtifactProvenanceFromManifest(manifest: Record): PacSourceArtifactProvenance | null { const provenance = pipelineProvenanceFromManifest(manifest); if (provenance === null) return null; if (provenance.renderer !== "agentrun-control-plane" && provenance.renderer !== "hwlab-runtime-lane" && provenance.renderer !== "sub2rank-platform-service" && provenance.renderer !== "selfmedia-runtime" && provenance.renderer !== "pikaoa-test-runtime" && provenance.renderer !== "pikaoa-release-runtime") return null; if (provenance.mode !== "embedded-pipeline-spec" && provenance.mode !== "remote-pipeline-annotation") return null; return provenance as PacSourceArtifactProvenance; } function provenanceEquals(actual: PacSourceArtifactProvenance | null, expected: PacSourceArtifactProvenance): boolean { return actual !== null && actual.configRef === expected.configRef && actual.effectiveConfigSha256 === expected.effectiveConfigSha256 && actual.renderer === expected.renderer && actual.mode === expected.mode; } function firstCanonicalDrift(expected: unknown, actual: unknown, path: string): PacSourceArtifactDrift | null { if (Object.is(expected, actual)) return null; if (Array.isArray(expected) || Array.isArray(actual)) { if (!Array.isArray(expected) || !Array.isArray(actual)) return drift(path, expected, actual); if (expected.length !== actual.length) return drift(`${path}.length`, expected.length, actual.length); for (let index = 0; index < expected.length; index += 1) { const child = firstCanonicalDrift(expected[index], actual[index], `${path}[${index}]`); if (child !== null) return child; } return null; } if (isRecord(expected) || isRecord(actual)) { if (!isRecord(expected) || !isRecord(actual)) return drift(path, expected, actual); const keys = [...new Set([...Object.keys(expected), ...Object.keys(actual)])].sort(); for (const key of keys) { const expectedOwnsKey = Object.prototype.hasOwnProperty.call(expected, key); const actualOwnsKey = Object.prototype.hasOwnProperty.call(actual, key); const childPath = knownDriftPathKeys.has(key) ? `${path}.${key}` : `${path}.[key:${pacValueEvidence(key)}]`; if (!expectedOwnsKey || !actualOwnsKey) return drift(childPath, expected[key], actual[key]); const child = firstCanonicalDrift(expected[key], actual[key], childPath); if (child !== null) return child; } return null; } return drift(path, expected, actual); } function isProvenTektonAdmissionDefault(path: readonly (string | number)[], value: unknown): boolean { const normalized = path.map((segment) => typeof segment === "number" ? "*" : segment).join("."); const emptyRecord = isRecord(value) && Object.keys(value).length === 0; if ([ "spec.workspaces.*.volumeClaimTemplate.metadata", "spec.workspaces.*.volumeClaimTemplate.status", ].includes(normalized)) return emptyRecord; const atTaskSpec = (suffix: string): boolean => [ `tasks.*.taskSpec.${suffix}`, `spec.tasks.*.taskSpec.${suffix}`, `spec.pipelineSpec.tasks.*.taskSpec.${suffix}`, ].includes(normalized); if (atTaskSpec("metadata")) return emptyRecord; if (atTaskSpec("spec")) return value === null; if (atTaskSpec("params.*.type")) return value === "string"; if (atTaskSpec("results.*.type")) return value === "string"; if (atTaskSpec("steps.*.computeResources")) return emptyRecord; if (atTaskSpec("sidecars.*.computeResources")) return emptyRecord; return false; } function drift(path: string, expected: unknown, actual: unknown): PacSourceArtifactDrift { return { path, expected: pacValueEvidence(expected), actual: pacValueEvidence(actual) }; } export function pacValueEvidence(value: unknown): string { const type = value === null ? "null" : Array.isArray(value) ? "array" : typeof value; const stable = stableJsonValue(value); const serialized = JSON.stringify(stable) ?? String(stable); const length = typeof value === "string" ? Buffer.byteLength(value, "utf8") : Array.isArray(value) ? value.length : isRecord(value) ? Object.keys(value).length : Buffer.byteLength(serialized, "utf8"); return `type=${type},length=${length},sha256=${fingerprint(serialized).replace(/^sha256:/u, "")}`; } function fingerprint(value: string): string { return `sha256:${createHash("sha256").update(value).digest("hex")}`; } function formatDrift(value: Record | null): string { return value === null ? "-" : `${text(value.path)} expected:${text(value.expected)} actual:${text(value.actual)}`; } function unavailableRuntimeObservation(): PacSourceArtifactRuntimeObservation { const item: PacSourceArtifactRuntimeItem = { status: "unavailable", name: null, canonicalSha256: null, firstDrift: null, provenanceAligned: false, configRef: null, effectiveConfigSha256: null, sourceCommit: null, reason: "runtime-observer-not-configured", candidateCount: 0 }; return { live: item, embedded: item }; } function parseYamlRecord(text: string, label: string): Record { const parsed = Bun.YAML.parse(text) as unknown; if (!isRecord(parsed)) throw new Error(`${label} must contain one YAML object`); return parsed; } export function pacSourceArtifactYaml(value: Record): string { const lines = Bun.YAML.stringify(value, null, 2).split("\n"); let blockScalarHeaderIndent: number | null = null; const normalized = lines.map((line) => { const content = line.trim(); const indent = line.length - line.trimStart().length; if (blockScalarHeaderIndent !== null) { if (content.length === 0 || indent > blockScalarHeaderIndent) return line; blockScalarHeaderIndent = null; } const structuralLine = line.replace(/:[\t ]+$/u, ":"); if (/(?:^|:[\t ]+|-[\t ]+)[|>](?:[1-9][+-]?|[+-][1-9]?|[+-])?[\t ]*(?:#.*)?$/u.test(structuralLine)) { blockScalarHeaderIndent = indent; } return structuralLine; }).join("\n"); const withSingleEofNewline = `${normalized.replace(/\n+$/u, "")}\n`; const roundTrip = parseYamlRecord(withSingleEofNewline, "serialized source artifact"); const roundTripDrift = firstCanonicalDrift(value, roundTrip, "$"); if (roundTripDrift !== null) { throw new PacSourceArtifactError("source-artifact-yaml-round-trip-failed", { driftPath: roundTripDrift.path, expectedEvidence: roundTripDrift.expected, actualEvidence: roundTripDrift.actual, }); } return withSingleEofNewline; } function requiredParam(binding: PacSourceArtifactBinding, key: string): string { return requiredString(binding.repository.params[key], `PaC repository ${binding.repository.id} params.${key}`); } function requiredString(value: unknown, label: string): string { if (typeof value !== "string" || value.length === 0) throw new Error(`${label} must be a non-empty string`); return value; } function requiredRecord(value: unknown, label: string): Record { if (!isRecord(value)) throw new Error(`${label} must be an object`); return value; } function arrayRecords(value: unknown, label: string): Record[] { if (!Array.isArray(value) || value.some((item) => !isRecord(item))) throw new Error(`${label} must be an array of objects`); return value as Record[]; } function isRecord(value: unknown): value is Record { return typeof value === "object" && value !== null && !Array.isArray(value); } function record(value: unknown): Record { return isRecord(value) ? value : {}; } function isSourceArtifactAction(value: string | undefined): value is PacSourceArtifactAction { return value === "plan" || value === "check" || value === "write" || value === "status" || value === "verify-runtime"; } function git(worktree: string, args: readonly string[]): string { const result = spawnSync("git", ["-C", worktree, ...args], { encoding: "utf8", timeout: 15_000, maxBuffer: 1024 * 1024 }); if (result.status !== 0) throw new Error(`git ${args.join(" ")} failed for ${worktree}: ${(result.stderr || result.stdout).trim().slice(0, 1000)}`); return result.stdout.trim(); } function runChecked(command: string, args: readonly string[], cwd: string, timeout: number, label: string, input?: string): void { const result = spawnSync(command, [...args], { cwd, encoding: "utf8", timeout, maxBuffer: 32 * 1024 * 1024, input }); if (result.status !== 0) { const output = [result.stderr, result.stdout].find((value) => typeof value === "string" && value.trim().length > 0)?.trim(); const reason = output ?? result.error?.message ?? `exit=${String(result.status)} signal=${String(result.signal)}`; throw new Error(`${label} failed: ${reason.slice(-4000)}`); } } function shellQuote(value: string): string { return `'${value.replaceAll("'", `'"'"'`)}'`; } function text(value: unknown): string { if (value === null || value === undefined || value === "") return "-"; return String(value); } function shortSha(value: unknown): string { return typeof value === "string" && value.length > 0 ? value.replace(/^sha256:/u, "").slice(0, 12) : "-"; }