fix(gate): reject invalid exclusion expiry dates (#199)

Signed-off-by: Rudy Celekli <[email protected]>
This commit is contained in:
Rudy Mizrahi Celekli authored and GitHub committed 2026-09-30 21:37:26 -07:00
1 parent e1139e2276
commit 0ab94672de
2 files changed
+24 -1

No files matched your search

+9 -1
View File
@@ -21,6 +21,12 @@ export const CUT_CEILING_ISO = "2026-09-30";
// Date-only lexicographic compare: for YYYY-MM-DD, string order IS chronological order.
const day = (d) => String(d).slice(0, 10);
function isCalendarDate(value) {
if (typeof value !== "string" || !/^\d{4}-\d{2}-\d{2}$/.test(value)) return false;
const parsed = new Date(`${value}T00:00:00.000Z`);
return !Number.isNaN(parsed.getTime()) && parsed.toISOString().slice(0, 10) === value;
}
/**
* Rail 3 + Rail 4 static validation: every resident MUST carry the full schema, and its expiry MUST
* NOT outlive the cut ceiling. Returns { valid, errors } — an invalid ledger is a loud gate failure,
@@ -36,7 +42,9 @@ export function validateLedger(ledger = [], { cutCeiling = CUT_CEILING_ISO } = {
errors.push(`${tag}: missing required field "${field}"`);
}
}
if (entry && entry.expiry && day(entry.expiry) > day(cutCeiling)) {
if (!isCalendarDate(entry?.expiry)) {
errors.push(`${tag}: expiry must be a valid YYYY-MM-DD calendar date`);
} else if (day(entry.expiry) > day(cutCeiling)) {
errors.push(`${tag}: expiry ${day(entry.expiry)} exceeds the 0.5.2 cut ceiling ${day(cutCeiling)}`);
}
});
+15
View File
@@ -96,3 +96,18 @@ test("EMPTY SEED — zero residents + any failure → FAIL (the gate is strict b
const r = resolveGateWithLedger({ failures: ["anything"], ledger: [], now: "2025-08-10", cutCeiling: CEIL });
assert.equal(r.gate, "fail");
});
// Invalid exclusion data must never turn a failing suite into a passing gate.
test("rail 3 — expiry must be a calendar date, not a coerced or truncated value", () => {
for (const expiry of [false, 0, true, 123, {}, [], "invalid", "2025-00-10", "2025-02-29", "2025-04-31", "2025-08-20junk", "2025-08-20T00:00:00Z"]) {
const r = resolveGateWithLedger({ failures: ["flaky-suite"], ledger: [ok({ expiry })], now: "2025-08-10", cutCeiling: CEIL });
assert.equal(r.gate, "fail", `invalid expiry ${JSON.stringify(expiry)} must refuse`);
assert.equal(r.validity.valid, false);
assert.ok(r.validity.errors.some((e) => e.includes("expiry")));
}
});
test("rail 3 — leap days validate only in leap years", () => {
assert.equal(validateLedger([ok({ expiry: "2024-02-29" })], { cutCeiling: CEIL }).valid, true);
assert.equal(validateLedger([ok({ expiry: "2025-02-29" })], { cutCeiling: CEIL }).valid, false);
});