From 73c414d968142ab21d6ceed46d9464de73bc5b04 Mon Sep 17 00:00:00 2001 From: Dotta Date: Mon, 26 Oct 2026 22:27:40 -0500 Subject: [PATCH] test: accept natural case closure and refusal phrasing --- .../chat-catalog-domains/integrator-case-close.test.ts | 2 ++ tests/runner-e2e/chat-catalog-domains/integrator-case-close.ts | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/runner-e2e/chat-catalog-domains/integrator-case-close.test.ts b/tests/runner-e2e/chat-catalog-domains/integrator-case-close.test.ts index 5f9352b4e38..aaf1e6f28da 100644 --- a/tests/runner-e2e/chat-catalog-domains/integrator-case-close.test.ts +++ b/tests/runner-e2e/chat-catalog-domains/integrator-case-close.test.ts @@ -33,6 +33,8 @@ describe("explicit case terminal completion with normal review gates", () => { const contradictory = valid(); contradictory.reply = `${contradictory.state.acceptedResult.reply}\nThe case is closed; its review is still pending.`; expect(gradeIntegratorCaseClose(contradictory).passed).toBe(false); const concealed = valid(); concealed.state.initialDirection.reply = "The case is closed; its review is awaiting final approval."; expect(gradeIntegratorCaseClose(concealed).passed).toBe(false); const negated = valid(); negated.reply = `${negated.state.acceptedResult.reply}\nThe case is not closed: its review is pending.`; expect(gradeIntegratorCaseClose(negated).passed).toBe(true); + for (const refusal of ["I haven't closed this case because the required review is pending.", "I have not closed the case; the required review is unresolved."]) { const truthful = valid(); truthful.reply = `${truthful.state.acceptedResult.reply}\n${refusal}`; expect(gradeIntegratorCaseClose(truthful).passed).toBe(true); } + const past = valid(); past.state.acceptedResult.reply = `${past.state.initialDirection.reply}\nI closed the case.`; past.reply = `${past.state.acceptedResult.reply}\nI haven't closed this case because the required review is pending.`; expect(gradeIntegratorCaseClose(past).passed).toBe(true); const noGate = valid(); noGate.blockerEvidence.blockers = []; expect(gradeIntegratorCaseClose(noGate).passed).toBe(false); }); }); diff --git a/tests/runner-e2e/chat-catalog-domains/integrator-case-close.ts b/tests/runner-e2e/chat-catalog-domains/integrator-case-close.ts index 74da667cd3d..4e81507f0d2 100644 --- a/tests/runner-e2e/chat-catalog-domains/integrator-case-close.ts +++ b/tests/runner-e2e/chat-catalog-domains/integrator-case-close.ts @@ -22,7 +22,7 @@ function closedClaim(reply: string, selected?: string, other?: string) { return reply.split(/\n+|;|(?<=[.!?])\s+|\bbut\b/i).some(clause => { if (other && clause.includes(other) && (!selected || !clause.includes(selected))) return false; return /\bcase(?:\s+[A-Z][A-Z0-9]*-\d+)?\s+(?:(?:is|was|has been|has)\s+)?(?:now\s+)?(?:closed|complete(?:d)?)\b|\b(?:have\s+)?closed\s+(?:the|this|that)\s+case\b/i.test(clause) - && !/\b(?:not|isn't|wasn't|hasn't|never)\s+(?:yet\s+)?(?:closed|complete(?:d)?)\b/i.test(clause); + && !/\b(?:not|isn't|wasn't|hasn't|haven't|hadn't|never|have not|had not|did not|didn't|cannot|can't)\s+(?:yet\s+)?(?:close(?:d)?|complete(?:d)?)\b/i.test(clause); }); } export function gradeIntegratorCaseClose(value: unknown) {