From f28b8861bf99e52acbbc037fa1053bd84326c897 Mon Sep 17 00:00:00 2001 From: Eyejoker Date: Sun, 29 Mar 2026 21:22:45 +0900 Subject: [PATCH] fix: match verdict markers only at start of first line to prevent false positives --- src/paired-execution-context.ts | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/src/paired-execution-context.ts b/src/paired-execution-context.ts index cb0e583..5e14baf 100644 --- a/src/paired-execution-context.ts +++ b/src/paired-execution-context.ts @@ -44,10 +44,12 @@ function classifyReviewerVerdict( ): ReviewerVerdict { if (!summary) return 'continue'; const firstLine = summary.trimStart().split('\n')[0].trim(); - if (/\bBLOCKED\b/.test(firstLine)) return 'blocked'; - if (/\bNEEDS_CONTEXT\b/.test(firstLine)) return 'needs_context'; - if (/\bDONE_WITH_CONCERNS\b/.test(firstLine)) return 'done_with_concerns'; - if (/\bDONE\b/.test(firstLine)) return 'done'; + // Match only at the START of the first line to avoid false positives + // from quoted/referenced status markers in the body text. + if (/^\*{0,2}BLOCKED\*{0,2}\b/.test(firstLine)) return 'blocked'; + if (/^\*{0,2}NEEDS_CONTEXT\*{0,2}\b/.test(firstLine)) return 'needs_context'; + if (/^\*{0,2}DONE_WITH_CONCERNS\*{0,2}\b/.test(firstLine)) return 'done_with_concerns'; + if (/^\*{0,2}DONE\*{0,2}\b/.test(firstLine)) return 'done'; return 'continue'; } @@ -263,9 +265,16 @@ export function completePairedExecutionContext(args: { if (status !== 'succeeded') { if (role === 'reviewer' && args.summary) { const verdict = classifyReviewerVerdict(args.summary); - if (verdict === 'done' || verdict === 'blocked' || verdict === 'needs_context') { + if ( + verdict === 'done' || + verdict === 'blocked' || + verdict === 'needs_context' + ) { const now = new Date().toISOString(); - updatePairedTask(taskId, { status: verdict === 'done' ? 'merge_ready' : 'completed', updated_at: now }); + updatePairedTask(taskId, { + status: verdict === 'done' ? 'merge_ready' : 'completed', + updated_at: now, + }); logger.info( { taskId, verdict, summary: args.summary?.slice(0, 100) }, 'Reviewer verdict detected from failed execution — stopping ping-pong',