fix(ci): evaluate duplicate proof sections

This commit is contained in:
Shadow
2026-05-26 11:15:06 -05:00
parent ead847f606
commit 7671068daf
2 changed files with 80 additions and 27 deletions

View File

@@ -143,22 +143,34 @@ export async function isMaintainerTeamMember({
return body?.state === "active";
}
function extractMarkdownSection(headingRegex, body = "") {
function extractMarkdownSections(headingRegex, body = "") {
// Normalize CRLF → LF so regexes and section slicing see GitHub web-editor PR
// bodies the same way as locally-authored Markdown.
const normalizedBody = normalizeLineEndings(body);
const match = headingRegex.exec(normalizedBody);
if (!match) {
return "";
const sections = [];
const matcher = new RegExp(
headingRegex.source,
headingRegex.flags.includes("g") ? headingRegex.flags : `${headingRegex.flags}g`,
);
for (const match of normalizedBody.matchAll(matcher)) {
const sectionStart = match.index + match[0].length;
const rest = normalizedBody.slice(sectionStart);
const nextHeading = rest.match(/\n#{1,6}\s+\S/);
sections.push((nextHeading ? rest.slice(0, nextHeading.index) : rest).trim());
}
const sectionStart = match.index + match[0].length;
const rest = normalizedBody.slice(sectionStart);
const nextHeading = rest.match(/\n#{1,6}\s+\S/);
return (nextHeading ? rest.slice(0, nextHeading.index) : rest).trim();
return sections;
}
function extractMarkdownSection(headingRegex, body = "") {
return extractMarkdownSections(headingRegex, body)[0] ?? "";
}
export function extractRealBehaviorProofSections(body = "") {
return extractMarkdownSections(/^#{2,6}\s+real behavior proof\b[^\n]*$/im, body);
}
export function extractRealBehaviorProofSection(body = "") {
return extractMarkdownSection(/^#{2,6}\s+real behavior proof\b[^\n]*$/im, body);
return extractRealBehaviorProofSections(body)[0] ?? "";
}
function extractOutOfScopeFollowUpsSection(body = "") {
@@ -298,24 +310,7 @@ export function evaluateClawSweeperExactHeadProof({ pullRequest, comments = [] }
return result("insufficient", "No exact-head ClawSweeper proof verdict was found.");
}
export function evaluateRealBehaviorProof({ pullRequest, labels } = {}) {
const currentLabels = labels ?? pullRequest?.labels ?? [];
if (hasProofOverride(currentLabels)) {
return result("override", `Maintainer override label ${PROOF_OVERRIDE_LABEL} is present.`);
}
if (!isExternalPullRequest(pullRequest)) {
return result("skipped", "Maintainer, collaborator, or bot PRs do not require this gate.");
}
const body = pullRequest?.body ?? "";
const section = extractRealBehaviorProofSection(body);
if (!section) {
return result(
"missing",
"External PRs must include a Real behavior proof section with after-fix evidence from a real setup.",
);
}
function evaluateRealBehaviorProofSection(section, body) {
const fields = Object.fromEntries(
requiredProofFields.map((field) => [field.key, extractFieldValue(section, field)]),
);
@@ -378,6 +373,28 @@ export function evaluateRealBehaviorProof({ pullRequest, labels } = {}) {
return result("passed", "External PR includes after-fix real behavior proof.", { fields });
}
export function evaluateRealBehaviorProof({ pullRequest, labels } = {}) {
const currentLabels = labels ?? pullRequest?.labels ?? [];
if (hasProofOverride(currentLabels)) {
return result("override", `Maintainer override label ${PROOF_OVERRIDE_LABEL} is present.`);
}
if (!isExternalPullRequest(pullRequest)) {
return result("skipped", "Maintainer, collaborator, or bot PRs do not require this gate.");
}
const body = pullRequest?.body ?? "";
const sections = extractRealBehaviorProofSections(body);
if (sections.length === 0) {
return result(
"missing",
"External PRs must include a Real behavior proof section with after-fix evidence from a real setup.",
);
}
const latestSection = sections.at(-1) ?? "";
return evaluateRealBehaviorProofSection(latestSection, body);
}
export function labelsForRealBehaviorProof(evaluation) {
if (evaluation.status === "passed") {
return [PROOF_SUPPLIED_LABEL];