diff --git a/BEDIENUNGSANLEITUNG.md b/BEDIENUNGSANLEITUNG.md index 6484690..f4c3433 100644 --- a/BEDIENUNGSANLEITUNG.md +++ b/BEDIENUNGSANLEITUNG.md @@ -860,6 +860,13 @@ Die Checkboxen werden automatisch abgehakt: ## 12. Fehlermeldungen und Lösungen +### "Urteil unklar: … Judge-Urteil nicht erkennbar" + +**Ursache:** In der Judge-Antwort steht keine Zeile „Urteil: PASS | PASS WITH CONCERNS | FAIL“. Markdown dazwischen +wird erkannt (`## Urteil: **PASS**`, `**Urteil:** FAIL`); fehlt das Wort ganz, gilt die Runde als nicht bestanden. + +**Lösung:** Antwort im Chat lesen, dann `/judge` erneut oder `/fix` mit der Kritik. + ### "Modell-Datei nicht gefunden" ``` diff --git a/pi-coding-extension.ts b/pi-coding-extension.ts index 12b24cb..0ac81a4 100644 --- a/pi-coding-extension.ts +++ b/pi-coding-extension.ts @@ -664,10 +664,17 @@ function normalizeForComparison(s: string): string { } function parseVerdict(text: string): string { - const m = text.match(/Urteil:\s*(PASS WITH CONCERNS|PASS|FAIL)/i); + // Markdown zwischen „Urteil“ und dem Wort ist erlaubt: „## Urteil: **PASS**“, „**Urteil:** FAIL“. + const m = text.match(/Urteil[\s*_`:]*(PASS WITH CONCERNS|PASS|FAIL)/i); return m ? m[1].toUpperCase() : "UNREADABLE"; } +// SHIP-Urteil der Freigabe-Runde; Markdown wie bei parseVerdict erlaubt. "" wenn nicht erkennbar. +function parseShipVerdict(text: string): string { + const m = text.match(/Urteil[\s*_`:]*(NO-SHIP|SHIP)/i); + return m ? m[1].toUpperCase() : ""; +} + // Extrahiert den Blocker-Abschnitt für die Loop-Erkennung. // Erkennt Bullet-Listen (- / – / *), Bold (**Blocker**) und Headings (## Blocker). function parseBlockers(text: string): string { @@ -1226,7 +1233,7 @@ export default function (pi: ExtensionAPI) { currentActivity = "Judge: finale Freigabe…"; await sendAndWait(pi, ctx, shipitPrompt(args || "")); const shipText = getLastAssistantText(ctx); - const shipVerdict = shipText.match(/Urteil:\s*(SHIP|NO-SHIP)/i)?.[1]?.toUpperCase() ?? ""; + const shipVerdict = parseShipVerdict(shipText); if (shipVerdict === "SHIP") { await autoCommitIfDirty(pi, ctx); notifyShipSuccess(ctx); diff --git a/tests/pure-logic.test.mjs b/tests/pure-logic.test.mjs index de86901..dd6270e 100644 --- a/tests/pure-logic.test.mjs +++ b/tests/pure-logic.test.mjs @@ -10,6 +10,7 @@ const parseBlockers = extractFn("parseBlockers"); const normalizeForComparison = extractFn("normalizeForComparison"); const licenceMd = extractFn("licenceMd"); const loopKey = extractFn("loopKey"); +const parseShipVerdict = extractFn("parseShipVerdict"); test("parseVerdict: klares PASS", () => { assert.equal(parseVerdict("Review fertig.\nUrteil: PASS\nKeine Blocker."), "PASS"); @@ -102,3 +103,17 @@ test("loopKey: weder Blocker noch Major → ganzer Text", () => { assert.equal(loopKey("Urteil: FAIL\nirgendwas"), "Urteil: FAIL\nirgendwas"); assert.equal(loopKey("## Blocker\nNone\n## Major\n-"), "## Blocker\nNone\n## Major\n-"); }); + +test("parseVerdict: Urteil in Markdown-Fett (Strata-Judge 15.10.)", () => { + assert.equal(parseVerdict("## Urteil: **PASS WITH CONCERNS**\n### Blocker"), "PASS WITH CONCERNS"); + assert.equal(parseVerdict("**Urteil:** FAIL"), "FAIL"); + assert.equal(parseVerdict("## Urteil: **PASS**"), "PASS"); + assert.equal(parseVerdict("Urteil: `PASS`"), "PASS"); +}); + +test("parseShipVerdict: SHIP, NO-SHIP, Markdown, unklar", () => { + assert.equal(parseShipVerdict("Urteil: SHIP"), "SHIP"); + assert.equal(parseShipVerdict("## Urteil: **NO-SHIP**"), "NO-SHIP"); + assert.equal(parseShipVerdict("**Urteil:** ship"), "SHIP"); + assert.equal(parseShipVerdict("kein Urteil"), ""); +});