diff --git a/src/transition/preflight.ts b/src/transition/preflight.ts index f44a07a..2ce8c9f 100644 --- a/src/transition/preflight.ts +++ b/src/transition/preflight.ts @@ -154,6 +154,13 @@ export function validateStories(stories: Story[], parseWarnings: string[]): Pref return issues; } +// Matches a NO-GO verdict anywhere in the report, but NOT the "GO / NO-GO" +// label itself (e.g. the standard "## GO / NO-GO Decision" heading), where +// NO-GO is merely the second of the two listed options. Without the negative +// lookbehind, every readiness report — including GO-ready ones that carry that +// heading — would be flagged as NO-GO and block the transition. +const NO_GO_VERDICT_PATTERN = /(? { + const content = `# Implementation Readiness Report\n\n## GO / NO-GO Decision\n\n**Decision:** GO - all requirements met.\n`; + + const issues = validateReadiness(content); + + expect(issues).toHaveLength(0); + }); + + it("still flags a NO-GO verdict even when the 'GO / NO-GO' heading is present", () => { + const content = `# Implementation Readiness Report\n\n## GO / NO-GO Decision\n\n**Decision:** NO-GO - missing test coverage.\n`; + + const issues = validateReadiness(content); + + expect(issues[0]!.id).toBe("E1"); + }); + + it("does not flag the compact 'GO/NO-GO' label without spaces", () => { + const issues = validateReadiness("## GO/NO-GO\n\nDecision: GO\n"); + + expect(issues).toHaveLength(0); + }); }); describe("runPreflight", () => {