Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 13 additions & 2 deletions scripts/pre-open-gate.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,9 @@ export function evaluate(plan, evidence = null) {
}
}

const incompleteReasons = (plan?.uncertainty || [])
.filter((item) => item?.blocksCompletion !== false)
.map((item) => `review_scope:${String(item?.code || "unknown")}`);
const complete = implementationDiffPresent && plan.complete && bugScope.complete && securityScope.complete;
const finalBlockers = implementationDiffPresent
? blockers
Expand All @@ -119,14 +122,15 @@ export function evaluate(plan, evidence = null) {
probeEvidenceErrors: probes.errors,
blockers: finalBlockers,
clearedByEvidence,
incompleteReasons,
decision,
complete,
implementationDiffPresent,
evidenceApplied: Boolean(evidence),
};
}

function report({ repo, baseRef, headRef, baseRefOid, headRefOid, diffIdentity, fileCount, bugScope, securityScope, requiredProbes, probeEvidenceErrors, blockers, clearedByEvidence, decision, complete, implementationDiffPresent, evidenceApplied }) {
function report({ repo, baseRef, headRef, baseRefOid, headRefOid, diffIdentity, fileCount, bugScope, securityScope, requiredProbes, probeEvidenceErrors, blockers, clearedByEvidence, incompleteReasons, decision, complete, implementationDiffPresent, evidenceApplied }) {
return {
schemaVersion: 1,
kind: "github-delivery/pre-open-gate",
Expand All @@ -148,6 +152,7 @@ function report({ repo, baseRef, headRef, baseRefOid, headRefOid, diffIdentity,
probeEvidenceErrors,
blockers,
clearedByEvidence,
incompleteReasons: Array.isArray(incompleteReasons) ? incompleteReasons : [],
instructions: [
"workflow:implementation_missing: this pre-open gate requires a non-empty candidate implementation diff; implement first, then rerun the gate before publication.",
"decision=blocked: complete every remaining required bug lens, security surface, and deterministic probe on this branch diff (with --evidence-file), fix Confirmed High/Critical findings, then rerun before opening the PR.",
Expand Down Expand Up @@ -225,12 +230,17 @@ export function compactPreOpenGateReport(result) {
};
}

const incompleteReasons = sortedUnique(result?.incompleteReasons || []);
const nextAction =
result?.decision === "ready"
? "proceed_to_publication"
: result?.decision === "blocked"
? "complete_evidence"
: "restore_branch_evidence";
: incompleteReasons.includes("review_scope:patch_missing")
? "inspect_missing_patch_evidence"
: incompleteReasons.some((reason) => reason.startsWith("review_scope:probe_registry_invalid"))
? "repair_probe_registry"
: "resolve_incomplete_review_scope";

return {
schemaVersion: 1,
Expand All @@ -248,6 +258,7 @@ export function compactPreOpenGateReport(result) {
implementationDiffPresent: result?.implementationDiffPresent,
evidenceApplied: result?.evidenceApplied,
blockerCount: blockers.length,
incompleteReasons,
remaining,
evidenceRequirements: {
schemaVersion: PRE_OPEN_EVIDENCE_SCHEMA_VERSION,
Expand Down
13 changes: 13 additions & 0 deletions tests/unit/pre-open-gate-compact.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,19 @@ test("pre-open output carries generator version and implementation digests", ()
assert.deepEqual(compactPreOpenGateReport(report).generator, generator);
});

test("unknown compact report names the incomplete review-scope cause", () => {
const report = blockedReport();
report.decision = "unknown";
report.complete = false;
report.blockers = [];
report.incompleteReasons = ["review_scope:patch_missing"];

const compact = compactPreOpenGateReport(report);
assert.equal(compact.decision, "unknown");
assert.deepEqual(compact.incompleteReasons, ["review_scope:patch_missing"]);
assert.equal(compact.nextAction, "inspect_missing_patch_evidence");
});

test("ready compact report has one unambiguous publication disposition", () => {
const report = blockedReport();
report.decision = "ready";
Expand Down
Loading