feat(cicd): add bounded pipeline evidence

This commit is contained in:
Codex
2026-07-04 02:40:43 +00:00
parent bc681eddf8
commit 3886bbbb2c
13 changed files with 264 additions and 1 deletions
+63
View File
@@ -0,0 +1,63 @@
// SPEC: PJ2026-01060703 CI/CD branch follower bounded evidence helpers.
// Responsibility: compact pipeline/runtime-ready and refresh evidence for status/drill-down output.
export function compactRefreshEvidence(value: Record<string, unknown> | null): Record<string, unknown> | null {
if (value === null) return null;
const summary = asOptionalRecord(value.summary);
if (summary === null) return null;
return {
jobName: stringOrNull(value.jobName) ?? stringOrNull(summary.jobName),
namespace: stringOrNull(value.namespace) ?? stringOrNull(summary.namespace),
status: stringOrNull(summary.status),
pipeline: stringOrNull(summary.pipeline),
sourceCommit: stringOrNull(summary.sourceCommit),
sourceStageRef: stringOrNull(summary.sourceStageRef),
elapsedMs: numberOrNull(summary.elapsedMs),
sourceAuthority: stringOrNull(summary.sourceAuthority),
statusAuthority: stringOrNull(summary.statusAuthority),
parsedDownstreamCliOutput: false,
};
}
export function followerEvidenceSummary(input: {
observedSha: string | null;
livePayload: Record<string, unknown> | null;
storedCommand: Record<string, unknown> | null;
}): Record<string, unknown> | null {
const livePayload = input.livePayload;
const storedPayload = asOptionalRecord(input.storedCommand?.payload);
const payload = livePayload ?? storedPayload;
if (payload === null) return null;
const tekton = asOptionalRecord(payload.tekton);
const pipeline = asOptionalRecord(payload.pipeline);
const refresh = asOptionalRecord(payload.refreshEvidence);
if (tekton === null && pipeline === null && refresh === null) return null;
const pipelineRefName = stringOrNull(tekton?.pipelineRefName);
const pipelineName = stringOrNull(asOptionalRecord(pipeline?.metadata)?.name);
const refreshPipeline = stringOrNull(refresh?.pipeline);
const refreshSourceCommit = stringOrNull(refresh?.sourceCommit);
return {
pipelineRunRefName: pipelineRefName,
pipeline,
refresh: refresh === null
? null
: {
...refresh,
pipelineRefMatches: pipelineRefName === null || refreshPipeline === null ? null : pipelineRefName === refreshPipeline,
pipelineSpecMatches: pipelineName === null || refreshPipeline === null ? null : pipelineName === refreshPipeline,
sourceCommitMatches: input.observedSha === null || refreshSourceCommit === null ? null : input.observedSha === refreshSourceCommit,
},
};
}
function asOptionalRecord(value: unknown): Record<string, unknown> | null {
return typeof value === "object" && value !== null && !Array.isArray(value) ? value as Record<string, unknown> : null;
}
function stringOrNull(value: unknown): string | null {
return typeof value === "string" && value.length > 0 ? value : null;
}
function numberOrNull(value: unknown): number | null {
return typeof value === "number" && Number.isFinite(value) ? value : null;
}