fix(gsd): accept 'passed' as terminal validation verdict (#1429) (#1509)

isValidationTerminal() now normalizes verdict: passed → pass before
comparison. LLM-generated validation files that write "passed" instead
of "pass" are accepted as terminal, preventing milestones from being
treated as incomplete.

Closes #1429

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
TÂCHES 2026-03-19 17:33:15 -06:00 committed by GitHub
parent 4c081fa556
commit 95f585d183
2 changed files with 7 additions and 1 deletions

View file

@ -64,11 +64,12 @@ export function isValidationTerminal(validationContent: string): boolean {
if (!match) return false;
const verdict = match[1].match(/verdict:\s*(\S+)/);
if (!verdict) return false;
const v = verdict[1] === 'passed' ? 'pass' : verdict[1];
// 'pass' and 'needs-attention' are always terminal.
// 'needs-remediation' is treated as terminal to prevent infinite loops
// when no remediation slices exist in the roadmap (#832). The validation
// report is preserved on disk for manual review.
return verdict[1] === 'pass' || verdict[1] === 'needs-attention' || verdict[1] === 'needs-remediation';
return v === 'pass' || v === 'needs-attention' || v === 'needs-remediation';
}
// ─── State Derivation ──────────────────────────────────────────────────────

View file

@ -104,6 +104,11 @@ test("isValidationTerminal returns true for verdict: needs-remediation (#832)",
assert.equal(isValidationTerminal(content), true);
});
test("isValidationTerminal returns true for verdict: passed (#1429)", () => {
const content = "---\nverdict: passed\nremediation_round: 0\n---\n\n# Validation";
assert.equal(isValidationTerminal(content), true);
});
test("isValidationTerminal returns false for missing frontmatter", () => {
const content = "# Validation\nNo frontmatter here.";
assert.equal(isValidationTerminal(content), false);