fix(release): accept Kova collector-only phases (#104008)

This commit is contained in:
Vincent Koc
2026-07-10 17:31:42 -07:00
committed by GitHub
parent b7d6291bfd
commit f4b3a4841f
2 changed files with 79 additions and 5 deletions
+34 -3
View File
@@ -96,6 +96,23 @@ function validateCommandResult(value, label) {
check(result.status === 0 && result.timedOut === false, `${label} failed`);
}
function validateCollectorOnlyPhase(phase) {
check(
phase.driverKind === "none" && phase.collectionIntent === "post-ready-health",
"commandless phase was not a collector-only phase",
);
const evidence = array(phase.evidence, "collector-only phase evidence");
check(
evidence.length > 0 &&
evidence.every((entry) => typeof entry === "string" && entry.trim().length > 0),
"collector-only phase evidence was invalid",
);
check(
object(phase.metrics, "collector-only phase metrics").schemaVersion === "kova.envMetrics.v1",
"collector-only phase metrics schema was invalid",
);
}
function alreadyAbsent(result, noun) {
check(
Number.isSafeInteger(result.status) && result.status !== 0,
@@ -128,9 +145,23 @@ function validateRecord(recordValue) {
const phases = array(record.phases, "record phases");
check(phases.length > 0, "record had no phases");
for (const phaseValue of phases) {
const results = array(object(phaseValue, "phase").results, "phase results");
check(results.length > 0, "phase had no command results");
results.forEach((result, index) => validateCommandResult(result, `phase result ${index}`));
const phase = object(phaseValue, "phase");
const commands = array(phase.commands, "phase commands");
const results = array(phase.results, "phase results");
check(commands.length === results.length, "phase command/result counts did not match");
if (commands.length === 0) {
validateCollectorOnlyPhase(phase);
continue;
}
results.forEach((resultValue, index) => {
const result = object(resultValue, `phase result ${index}`);
check(
text(result.command, `phase result ${index} command`) ===
text(commands[index], `phase command ${index}`),
`phase command ${index} did not match its result`,
);
validateCommandResult(result, `phase result ${index}`);
});
}
validateCleanup(
record.cleanup,
+45 -2
View File
@@ -206,7 +206,13 @@ function partialReport(): JsonObject {
cpuPercentMax: 80,
peakRssMb: 650,
},
phases: [{ id: "agent-turn", results: [commandResult()] }],
phases: [
{
commands: [commandResult().command],
id: "agent-turn",
results: [commandResult()],
},
],
profiling: normalProfiling(),
scenario: SCENARIO,
state: { id: STATE },
@@ -300,7 +306,13 @@ function profiledResourceReport(): JsonObject {
"agent-process": { maxCpuPercent: 156.2, peakRssMb: 923.7 },
},
},
phases: [{ id: "agent-turn", results: [commandResult()] }],
phases: [
{
commands: [commandResult().command],
id: "agent-turn",
results: [commandResult()],
},
],
profiling: deepProfiling(),
scenario: SCENARIO,
state: { id: STATE },
@@ -417,6 +429,21 @@ describe("scripts/lib/kova-report-gate.mjs", () => {
});
});
it("accepts a declared collector-only phase without commands", () => {
const report = partialReport();
setAt(report, ["records", 0, "phases", 0], {
collectionIntent: "post-ready-health",
commands: [],
driverKind: "none",
evidence: ["startup logs"],
id: "logs",
metrics: { schemaVersion: "kova.envMetrics.v1" },
results: [],
});
expect(evaluateToleratedPartialKovaReport(report)).toEqual({ ok: true });
});
it("accepts an exact deep-profile resource-only rejection", () => {
expect(evaluateToleratedProfiledKovaReport(profiledResourceReport())).toEqual({
ok: true,
@@ -549,6 +576,15 @@ describe("scripts/lib/kova-report-gate.mjs", () => {
"rejects timed-out phase commands",
(report) => setAt(report, ["records", 0, "phases", 0, "results", 0, "timedOut"], true),
],
[
"rejects phase command/result count drift",
(report) => setAt(report, ["records", 0, "phases", 0, "results"], []),
],
[
"rejects phase command/result identity drift",
(report) =>
setAt(report, ["records", 0, "phases", 0, "results", 0, "command"], "different command"),
],
[
"rejects retained record cleanup",
(report) => setAt(report, ["records", 0, "cleanup"], "retained"),
@@ -832,6 +868,13 @@ describe("scripts/lib/kova-report-gate.mjs", () => {
"rejects PARTIAL phase failures",
(report) => setAt(report, ["records", 0, "phases", 0, "results", 0, "status"], 1),
],
[
"rejects unmarked commandless PARTIAL phases",
(report) => {
setAt(report, ["records", 0, "phases", 0, "commands"], []);
setAt(report, ["records", 0, "phases", 0, "results"], []);
},
],
[
"rejects PARTIAL cleanup failures",
(report) => setAt(report, ["records", 0, "cleanup"], "destroy-failed"),