feat: add Resend release gate evidence validation (TASK-WP7-03)
Dada P0-A isolated Windows CI / validate-and-package (push) Failing after 59s
Dada P0-A isolated Windows CI / validate-and-package (push) Failing after 59s
This commit is contained in:
@@ -0,0 +1,175 @@
|
||||
import { spawnSync } from "node:child_process";
|
||||
import { createHash } from "node:crypto";
|
||||
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
||||
import { join, resolve } from "node:path";
|
||||
|
||||
import {
|
||||
fileSha256,
|
||||
readJson,
|
||||
validateCandidateReference,
|
||||
validateResendEvidence,
|
||||
} from "./lib/resend-release-gate.mjs";
|
||||
|
||||
const phaseIndex = process.argv.indexOf("--phase");
|
||||
const phase = phaseIndex >= 0 ? process.argv[phaseIndex + 1] : "green";
|
||||
if (!new Set(["red", "green"]).has(phase)) throw new Error(`Unsupported phase: ${phase}`);
|
||||
|
||||
const candidateRunId = process.env.DADA_WP7_01_RUN_ID ?? "wp7-01-candidate-20260804052447717";
|
||||
const runId = process.env.DADA_TDD_RUN_ID ?? `wp7-03-${phase}-${new Date().toISOString().replace(/[^0-9]/g, "")}`;
|
||||
const runDirectory = resolve("artifacts", "tdd", runId);
|
||||
const caseId = "TDD-WP7-EXT-002-real-resend";
|
||||
const caseDirectory = resolve(runDirectory, "cases", caseId);
|
||||
if (existsSync(runDirectory)) throw new Error(`Evidence run already exists: ${runId}`);
|
||||
mkdirSync(caseDirectory, { recursive: true });
|
||||
|
||||
function writeJson(path, value) {
|
||||
writeFileSync(path, `${JSON.stringify(value, null, 2)}\n`);
|
||||
}
|
||||
|
||||
function runCommand(name, command) {
|
||||
const startedAt = new Date().toISOString();
|
||||
const result = spawnSync(process.env.ComSpec ?? "cmd.exe", ["/d", "/s", "/c", command], {
|
||||
encoding: "utf8",
|
||||
env: process.env,
|
||||
maxBuffer: 40 * 1024 * 1024,
|
||||
stdio: "inherit",
|
||||
});
|
||||
return {
|
||||
command,
|
||||
exit_code: result.status ?? 1,
|
||||
finished_at: new Date().toISOString(),
|
||||
name,
|
||||
started_at: startedAt,
|
||||
};
|
||||
}
|
||||
|
||||
const candidateEvidenceRoot = resolve(
|
||||
process.env.DADA_WP7_01_EVIDENCE_DIR ?? join("artifacts", "tdd", candidateRunId),
|
||||
);
|
||||
const candidate = readJson(join(candidateEvidenceRoot, "release-candidate.json"));
|
||||
const candidateErrors = candidate ? validateCandidateReference(candidate) : ["candidate_record_missing"];
|
||||
writeJson(resolve(caseDirectory, "candidate-reference.json"), candidate ? {
|
||||
browsers: candidate.browsers.map(({ brand, full_version: fullVersion, major }) => ({ brand, full_version: fullVersion, major })),
|
||||
build_commit: candidate.build_commit,
|
||||
candidate_status: candidate.status,
|
||||
final_release: candidate.final_release,
|
||||
fixed_port: candidate.fixed_port,
|
||||
run_id: candidateRunId,
|
||||
schema_version: "1.0",
|
||||
} : {
|
||||
candidate_status: "not_available",
|
||||
reason: "candidate_record_missing",
|
||||
run_id: candidateRunId,
|
||||
schema_version: "1.0",
|
||||
});
|
||||
|
||||
const commands = phase === "red" ? [] : [
|
||||
["workspace-build", "pnpm build:workspace-packages"],
|
||||
["integration", "pnpm test:integration"],
|
||||
["api", "pnpm check:openapi && pnpm exec vitest run tests/api --maxWorkers=1"],
|
||||
["security", "pnpm test:security"],
|
||||
["tdd-trace", "pnpm validate:tdd-trace"],
|
||||
].map(([name, command]) => runCommand(name, command));
|
||||
const localGatePassed = phase === "red" || commands.length > 0 && commands.every(({ exit_code }) => exit_code === 0);
|
||||
|
||||
const redaction = {
|
||||
absolute_paths_in_evidence: false,
|
||||
credentials_in_evidence: false,
|
||||
forbidden_matches: 0,
|
||||
mailboxes_in_evidence: false,
|
||||
private_content_in_evidence: false,
|
||||
schema_version: "1.0",
|
||||
status: "passed",
|
||||
};
|
||||
const externalRoot = process.env.DADA_RESEND_EVIDENCE_DIR ? resolve(process.env.DADA_RESEND_EVIDENCE_DIR) : undefined;
|
||||
const realAuthorized = process.env.DADA_RESEND_REAL_AUTHORIZED === "1";
|
||||
const externalFiles = ["domain-check.json", "delivery-summary.json", "auth-result.json", "redaction.json"];
|
||||
const externalEvidence = externalRoot
|
||||
? Object.fromEntries(externalFiles.map((file) => [file, readJson(join(externalRoot, file))]))
|
||||
: {};
|
||||
const externalEvidenceMissing = externalRoot ? externalFiles.filter((file) => !externalEvidence[file]) : externalFiles;
|
||||
const externalErrors = externalRoot && externalEvidenceMissing.length === 0 && candidate
|
||||
? validateResendEvidence({
|
||||
authResult: externalEvidence["auth-result.json"],
|
||||
candidate,
|
||||
deliverySummary: externalEvidence["delivery-summary.json"],
|
||||
domainCheck: externalEvidence["domain-check.json"],
|
||||
redaction: externalEvidence["redaction.json"],
|
||||
})
|
||||
: [];
|
||||
|
||||
const externalBlockers = [];
|
||||
if (candidateErrors.length > 0) externalBlockers.push("candidate_record_unavailable_or_drifted");
|
||||
if (!realAuthorized) externalBlockers.push("controlled_domain_or_real_mailbox_authorization_absent");
|
||||
if (!externalRoot) externalBlockers.push("real_resend_evidence_not_supplied");
|
||||
if (externalRoot && externalEvidenceMissing.length > 0) externalBlockers.push("real_resend_evidence_incomplete");
|
||||
if (externalErrors.length > 0) externalBlockers.push("real_resend_evidence_invalid");
|
||||
|
||||
if (phase === "red") {
|
||||
writeJson(resolve(caseDirectory, "red-observation.json"), {
|
||||
expected_failure: "Resend SPF/DKIM, free-rule, delivery, and formal authentication evidence is absent before TASK-WP7-03.",
|
||||
observed_commands: ["pnpm test:wp7-03:red"],
|
||||
red_reason: "TDD-WP7-EXT-002 requires controlled real domain/mailbox evidence; mock or pre-seeded accounts are not release evidence.",
|
||||
status: "red_confirmed",
|
||||
});
|
||||
} else if (externalRoot && externalEvidenceMissing.length === 0 && candidateErrors.length === 0 && realAuthorized && externalErrors.length === 0) {
|
||||
for (const file of externalFiles) writeJson(resolve(caseDirectory, file), externalEvidence[file]);
|
||||
writeJson(resolve(caseDirectory, "source-hashes.json"), {
|
||||
files: Object.fromEntries(externalFiles.map((file) => [file, fileSha256(join(externalRoot, file))])),
|
||||
schema_version: "1.0",
|
||||
});
|
||||
} else {
|
||||
writeJson(resolve(caseDirectory, "blocker.json"), {
|
||||
blockers: externalErrors.length > 0 ? ["real_resend_evidence_invalid"] : externalBlockers,
|
||||
mock_accepted_as_evidence: false,
|
||||
paid_fallback_enabled: false,
|
||||
preseeded_accounts_accepted_as_evidence: false,
|
||||
real_calls_started: false,
|
||||
schema_version: "1.0",
|
||||
status: "externally_blocked",
|
||||
});
|
||||
writeJson(resolve(caseDirectory, "redaction.json"), redaction);
|
||||
writeJson(resolve(caseDirectory, "source-hashes.json"), { files: {}, schema_version: "1.0" });
|
||||
}
|
||||
|
||||
const expectedEvidence = phase === "red"
|
||||
? ["candidate-reference.json", "red-observation.json"]
|
||||
: externalRoot && externalEvidenceMissing.length === 0 && candidateErrors.length === 0 && realAuthorized && externalErrors.length === 0
|
||||
? ["candidate-reference.json", "domain-check.json", "delivery-summary.json", "auth-result.json", "redaction.json", "source-hashes.json"]
|
||||
: ["candidate-reference.json", "blocker.json", "redaction.json", "source-hashes.json"];
|
||||
const missingEvidence = expectedEvidence.filter((file) => !existsSync(resolve(caseDirectory, file)));
|
||||
const status = phase === "red"
|
||||
? localGatePassed && missingEvidence.length === 0 ? "red_confirmed" : "failed"
|
||||
: !localGatePassed || missingEvidence.length > 0 ? "failed"
|
||||
: realAuthorized && (!externalRoot || externalEvidenceMissing.length > 0 || externalErrors.length > 0) ? "failed"
|
||||
: externalRoot && externalEvidenceMissing.length === 0 && candidateErrors.length === 0 && realAuthorized && externalErrors.length === 0 ? "passed"
|
||||
: "externally_blocked";
|
||||
const manifest = {
|
||||
path: "tasks.manifest.json",
|
||||
sha256: createHash("sha256").update(readFileSync("tasks.manifest.json")).digest("hex").toUpperCase(),
|
||||
};
|
||||
const result = {
|
||||
acceptance_criteria: ["AC-01", "AC-33", "AC-41", "AC-47", "AC-49"],
|
||||
automation: ["controlled_real", "manual_review"],
|
||||
candidate_run_id: candidateRunId,
|
||||
commit: spawnSync("git", ["rev-parse", "HEAD"], { encoding: "utf8" }).stdout.trim(),
|
||||
evidence_refs: expectedEvidence,
|
||||
external_blockers: phase === "green" && status === "externally_blocked" ? externalBlockers : [],
|
||||
finished_at: new Date().toISOString(),
|
||||
layer: ["EXT-REAL", "MANUAL"],
|
||||
manifest,
|
||||
missing_evidence: missingEvidence,
|
||||
phase,
|
||||
requirements: ["AUTH-01", "AUTH-02", "AUTH-07"],
|
||||
run_id: runId,
|
||||
schema_version: "1.0",
|
||||
status,
|
||||
task_id: "TASK-WP7-03",
|
||||
test_id: caseId,
|
||||
work_package: "WP-7",
|
||||
};
|
||||
writeJson(resolve(caseDirectory, "commands.json"), { commands, phase, run_id: runId, schema_version: "1.0" });
|
||||
writeJson(resolve(caseDirectory, "result.json"), result);
|
||||
writeJson(resolve(runDirectory, "evidence.json"), { cases: [{ external_blockers: result.external_blockers, missing_evidence: missingEvidence, status, test_id: caseId }], phase, run_id: runId, status });
|
||||
console.log(JSON.stringify({ external_blockers: result.external_blockers, phase, run_id: runId, status }, null, 2));
|
||||
if (status === "failed") process.exit(1);
|
||||
Reference in New Issue
Block a user