test: validate WP5 task lineage for WP4-07 gate
Dada P0-A isolated Windows CI / validate-and-package (push) Failing after 3m23s
Dada P0-A isolated Windows CI / validate-and-package (push) Failing after 3m23s
This commit is contained in:
@@ -4,9 +4,10 @@ import { existsSync, readFileSync } from "node:fs";
|
||||
|
||||
import { WP4_07_RED_RESOURCE_VERSION, WP4_07_SOURCE_HASHES, assertWp407Fixture } from "../../tests/visual-performance/wp4-07-fixture.mjs";
|
||||
|
||||
export const WP4_07_REQUIRED_WP5_BRANCHES = Object.freeze(
|
||||
Array.from({ length: 7 }, (_, index) => `codex/wp5-0${index + 1}`),
|
||||
export const WP4_07_REQUIRED_WP5_TASKS = Object.freeze(
|
||||
Array.from({ length: 7 }, (_, index) => `TASK-WP5-0${index + 1}`),
|
||||
);
|
||||
export const WP4_07_FINAL_WP5_BRANCH = "codex/wp5-07";
|
||||
|
||||
export function validateWp407FrozenInputs() {
|
||||
const mismatches = [];
|
||||
@@ -26,6 +27,28 @@ export function validateWp407FrozenInputs() {
|
||||
return assertWp407Fixture();
|
||||
}
|
||||
|
||||
export function inspectWp5TaskLineage(heads, commits) {
|
||||
const candidate_branch = [...WP4_07_REQUIRED_WP5_TASKS]
|
||||
.reverse()
|
||||
.map((taskId) => taskId.replace("TASK-WP5-", "codex/wp5-"))
|
||||
.find((branch) => /^[0-9a-f]{40}$/.test(heads[branch] ?? "")) ?? null;
|
||||
const task_shas = Object.fromEntries(WP4_07_REQUIRED_WP5_TASKS.flatMap((taskId) => {
|
||||
const commit = commits.find((entry) => entry.subject.includes(taskId));
|
||||
return commit && /^[0-9a-f]{40}$/.test(commit.sha) ? [[taskId, commit.sha]] : [];
|
||||
}));
|
||||
const missing_tasks = WP4_07_REQUIRED_WP5_TASKS.filter((taskId) => !task_shas[taskId]);
|
||||
return {
|
||||
candidate_baseline_branch: candidate_branch,
|
||||
candidate_baseline_sha: candidate_branch ? heads[candidate_branch] : null,
|
||||
complete: candidate_branch === WP4_07_FINAL_WP5_BRANCH && missing_tasks.length === 0,
|
||||
final_branch_sha: heads[WP4_07_FINAL_WP5_BRANCH] ?? null,
|
||||
missing_tasks,
|
||||
required_final_branch: WP4_07_FINAL_WP5_BRANCH,
|
||||
required_tasks: WP4_07_REQUIRED_WP5_TASKS,
|
||||
task_shas,
|
||||
};
|
||||
}
|
||||
|
||||
export function readWp5RemoteGate() {
|
||||
const result = spawnSync("git", ["ls-remote", "--heads", "origin", "codex/wp5-*"], { encoding: "utf8", timeout: 30_000 });
|
||||
if ((result.status ?? 1) !== 0) {
|
||||
@@ -37,12 +60,32 @@ export function readWp5RemoteGate() {
|
||||
const [sha, reference] = line.split(/\s+/);
|
||||
return [reference.replace("refs/heads/", ""), sha];
|
||||
}));
|
||||
const missing_branches = WP4_07_REQUIRED_WP5_BRANCHES.filter((branch) => !/^[0-9a-f]{40}$/.test(heads[branch] ?? ""));
|
||||
const candidateBranch = [...WP4_07_REQUIRED_WP5_TASKS]
|
||||
.reverse()
|
||||
.map((taskId) => taskId.replace("TASK-WP5-", "codex/wp5-"))
|
||||
.find((branch) => /^[0-9a-f]{40}$/.test(heads[branch] ?? ""));
|
||||
let commits = [];
|
||||
if (candidateBranch) {
|
||||
const fetch = spawnSync("git", ["fetch", "--quiet", "--no-tags", "origin", `refs/heads/${candidateBranch}`], { encoding: "utf8", timeout: 60_000 });
|
||||
if ((fetch.status ?? 1) !== 0) {
|
||||
const error = new Error("WP4_07_GITEA_BASELINE_FETCH_FAILED");
|
||||
error.details = { branch: candidateBranch, exit_code: fetch.status ?? 1 };
|
||||
throw error;
|
||||
}
|
||||
const log = spawnSync("git", ["log", "--format=%H%x09%s", heads[candidateBranch]], { encoding: "utf8", timeout: 30_000 });
|
||||
if ((log.status ?? 1) !== 0) {
|
||||
const error = new Error("WP4_07_GITEA_BASELINE_HISTORY_UNREADABLE");
|
||||
error.details = { branch: candidateBranch, exit_code: log.status ?? 1 };
|
||||
throw error;
|
||||
}
|
||||
commits = log.stdout.trim().split(/\r?\n/).filter(Boolean).map((line) => {
|
||||
const separator = line.indexOf("\t");
|
||||
return { sha: line.slice(0, separator), subject: line.slice(separator + 1) };
|
||||
});
|
||||
}
|
||||
return {
|
||||
complete: missing_branches.length === 0,
|
||||
heads,
|
||||
missing_branches,
|
||||
required_branches: WP4_07_REQUIRED_WP5_BRANCHES,
|
||||
...inspectWp5TaskLineage(heads, commits),
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -26,8 +26,12 @@ try {
|
||||
code: "WP4_07_WP5_GATE_INCOMPLETE",
|
||||
fixture_sha256: fixture.fixture_sha256,
|
||||
layer,
|
||||
missing_remote_branches: gate.missing_branches,
|
||||
candidate_baseline_branch: gate.candidate_baseline_branch,
|
||||
candidate_baseline_sha: gate.candidate_baseline_sha,
|
||||
missing_remote_tasks: gate.missing_tasks,
|
||||
observed_remote_heads: gate.heads,
|
||||
observed_task_shas: gate.task_shas,
|
||||
required_final_branch: gate.required_final_branch,
|
||||
status: "red",
|
||||
}, null, 2));
|
||||
process.exit(1);
|
||||
|
||||
@@ -68,7 +68,7 @@ function runDirect(name, executable, args, expected) {
|
||||
|
||||
const commands = phase === "red"
|
||||
? [
|
||||
run("fixture-contract", "node --test tests/visual-performance/wp4-07-fixture.test.mjs", "zero"),
|
||||
run("fixture-contract", "node --test tests/visual-performance/wp4-07-fixture.test.mjs tests/visual-performance/wp4-07-gate.test.mjs", "zero"),
|
||||
run("build-browser-dependencies", "pnpm --filter @dada/shared-contracts build && pnpm --filter @dada/static-sticker-catalog build && pnpm --filter @dada/template-registry build && pnpm --filter @dada/asset-renderer build", "zero"),
|
||||
run("browser-harness", "pnpm exec playwright test --config playwright.wp4-07.config.ts", "zero"),
|
||||
runDirect("visual-diff", process.execPath, ["scripts/compare-wp4-07-screenshots.mjs", "--evidence", visualDirectory, "--phase", "red"], "zero"),
|
||||
@@ -110,8 +110,11 @@ const observation = {
|
||||
eligible_for_green: false,
|
||||
expected_failure: "Final WP-5 task SHAs, immutable release inputs, real fonts, and the final renderer are unavailable, so Chrome/Edge visual and performance results cannot become Green.",
|
||||
fixture_sha256: fixture.fixture_sha256,
|
||||
missing_remote_branches: remoteGate.missing_branches,
|
||||
candidate_baseline_branch: remoteGate.candidate_baseline_branch,
|
||||
candidate_baseline_sha: remoteGate.candidate_baseline_sha,
|
||||
missing_remote_tasks: remoteGate.missing_tasks,
|
||||
observed_remote_heads: remoteGate.heads,
|
||||
observed_task_shas: remoteGate.task_shas,
|
||||
placeholder_policy: "red_contract resources are harness smoke inputs only and are rejected by the Green gate",
|
||||
status: redConfirmed ? "red_confirmed" : "failed",
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user