From 6b26534610e78675931909db3c53bf578610b33a Mon Sep 17 00:00:00 2001 From: Dotta Date: Fri, 11 Sep 2026 14:58:51 -0500 Subject: [PATCH] Accept concrete clarification requests without question punctuation --- tests/runner-e2e/chat-flow.test.ts | 20 ++++++++++++++++++++ tests/runner-e2e/chat-flow.ts | 11 ++++++++++- 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/tests/runner-e2e/chat-flow.test.ts b/tests/runner-e2e/chat-flow.test.ts index 3270ebd7fb..734cf771f2 100644 --- a/tests/runner-e2e/chat-flow.test.ts +++ b/tests/runner-e2e/chat-flow.test.ts @@ -9,6 +9,7 @@ import { collectChatRunEvidence, readRunningChatLog, readChatOutputDocument, + isChatClarificationReply, isResetRun, type ChatIssue, type ChatRun, @@ -44,6 +45,25 @@ const run: ChatRun = { startedAt: "2026-09-11T10:00:01Z", }; describe("chat acceptance contracts", () => { + it("accepts concrete information requests without requiring question punctuation", () => { + expect(isChatClarificationReply("What is the club name?")).toBe(true); + expect( + isChatClarificationReply( + "Before assigning the welcome-note work, please share:\n\n1. Club name and intended readers.\n2. Format, length, and tone.\n3. Required details, sender, and deadline.", + ), + ).toBe(true); + expect( + isChatClarificationReply("Tell me the intended audience and format."), + ).toBe(true); + expect(isChatClarificationReply("Please share:")).toBe(false); + expect( + isChatClarificationReply("Asked the user clarifying questions about their club."), + ).toBe(false); + expect( + isChatClarificationReply("I created the task and started writing the welcome note."), + ).toBe(false); + }); + it("keeps chat markers literal across rich-text and Markdown boundaries", () => { for (const prefix of ["CHAT", "DRAFT", "OLDCONTEXT"] as const) { expect(chatMarker(prefix, "abc123-1")).toBe(`${prefix}abc1231`); diff --git a/tests/runner-e2e/chat-flow.ts b/tests/runner-e2e/chat-flow.ts index d965e71799..d468c00f2a 100644 --- a/tests/runner-e2e/chat-flow.ts +++ b/tests/runner-e2e/chat-flow.ts @@ -48,6 +48,15 @@ type Comment = { type Plan = { body: string; latestRevisionId: string; updatedAt: string }; type ChatOutputDocument = Plan & { id: string; issueId: string; key: string }; +/** Clarification may request information imperatively rather than end in a question mark. */ +export function isChatClarificationReply(body: string): boolean { + if (body.includes("?")) return true; + const request = body.match( + /\b(?:please\s+(?:share|provide|clarify|confirm)|tell me|let me know)\b([\s\S]*)/i, + ); + return Boolean(request?.[1].replace(/[\s:*-]/g, "")); +} + /** A requested output document may have a descriptive key; a copied plan is not output. */ export async function readChatOutputDocument( api: Pick, @@ -446,7 +455,7 @@ export async function runChatFlow(input: { expect( Boolean(pendingQuestions?.length) || (await comments()).some( - (c) => c.authorAgentId && c.body.includes("?"), + (c) => c.authorAgentId && isChatClarificationReply(c.body), ), ).toBe(true); const clarification = `It is the garden club; use the existing Garden ${nonce} project. Make one assigned task for yourself to write a two-sentence welcome note. Include ${marker} in that note, save it as the output document, and finish that execution task. Please get it started now.`;