fix(gsd): recognize "Not provided." default in isVerificationNotApplicable

Strip trailing punctuation before matching and add "provided" to the
alternation so the plan-milestone default value no longer deadlocks
completing-milestone dispatch. Also change plan-milestone verification
defaults from "Not provided." to empty string to prevent recurrence.

Fixes #3634

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Tibsfox 2026-04-06 18:12:06 -07:00
parent b4c6229360
commit c138cca078
3 changed files with 21 additions and 6 deletions

View file

@ -140,9 +140,9 @@ export function setRewriteCount(basePath: string, count: number): void {
* @see https://github.com/gsd-build/gsd-2/issues/2931
*/
export function isVerificationNotApplicable(value: string): boolean {
const v = (value ?? "").toLowerCase().trim();
const v = (value ?? "").toLowerCase().trim().replace(/[.\s]+$/, "");
if (!v || v === "none") return true;
return /^(?:none[\s._-]*(?:required|needed|planned)?|n\/?a|not[\s._-]+(?:applicable|required|needed)|no[\s._-]+operational[\s\S]*)$/i.test(v);
return /^(?:none[\s._-]*(?:required|needed|planned)?|n\/?a|not[\s._-]+(?:applicable|required|needed|provided)|no[\s._-]+operational[\s\S]*)$/i.test(v);
}
// ─── Rules ────────────────────────────────────────────────────────────────

View file

@ -80,3 +80,18 @@ test("isVerificationNotApplicable: 'Verify API response times under load' requir
test("isVerificationNotApplicable: 'Monitor error rates for 24h' requires verification", () => {
assert.equal(isVerificationNotApplicable("Monitor error rates for 24h"), false);
});
// Regression: #3634 — "Not provided." default from plan-milestone
test("isVerificationNotApplicable: 'Not provided.' is not applicable (#3634)", () => {
assert.equal(isVerificationNotApplicable("Not provided."), true);
});
test("isVerificationNotApplicable: 'Not provided' (no period) is not applicable (#3634)", () => {
assert.equal(isVerificationNotApplicable("Not provided"), true);
});
test("isVerificationNotApplicable: trailing period does not defeat match (#3634)", () => {
assert.equal(isVerificationNotApplicable("None required."), true);
assert.equal(isVerificationNotApplicable("N/A."), true);
assert.equal(isVerificationNotApplicable("Not applicable."), true);
});

View file

@ -168,10 +168,10 @@ function validateParams(params: PlanMilestoneParams): PlanMilestoneParams {
successCriteria: params.successCriteria ? validateStringArray(params.successCriteria, "successCriteria") : [],
keyRisks: params.keyRisks ? validateRiskEntries(params.keyRisks) : [],
proofStrategy: params.proofStrategy ? validateProofStrategy(params.proofStrategy) : [],
verificationContract: params.verificationContract ?? "Not provided.",
verificationIntegration: params.verificationIntegration ?? "Not provided.",
verificationOperational: params.verificationOperational ?? "Not provided.",
verificationUat: params.verificationUat ?? "Not provided.",
verificationContract: params.verificationContract ?? "",
verificationIntegration: params.verificationIntegration ?? "",
verificationOperational: params.verificationOperational ?? "",
verificationUat: params.verificationUat ?? "",
definitionOfDone: params.definitionOfDone ? validateStringArray(params.definitionOfDone, "definitionOfDone") : [],
requirementCoverage: params.requirementCoverage ?? "Not provided.",
boundaryMapMarkdown: params.boundaryMapMarkdown ?? "Not provided.",