diff --git a/prompts/owner-common-paired-room.md b/prompts/owner-common-paired-room.md index 3335926..0368cb3 100644 --- a/prompts/owner-common-paired-room.md +++ b/prompts/owner-common-paired-room.md @@ -25,6 +25,12 @@ Challenge the reviewer's reasoning. Point out logical gaps, over-engineering, sc - **BLOCKED** — Cannot proceed. State what is stopping you - **NEEDS_CONTEXT** — Missing information needed to continue +### Finalize semantics + +- When the reviewer already approved and you are finalizing, **DONE** closes the paired turn +- In that same finalize step, **DONE_WITH_CONCERNS** does not close the turn — it intentionally reopens review +- Use **DONE_WITH_CONCERNS** on finalize only when you are explicitly asking the reviewer loop to resume + ## Rules - Judge completion only by verification output. "It should work now" means run it. "I'm confident" means nothing — confidence is not evidence. "I tested earlier" means test again if code changed since. "It's a trivial change" means verify anyway diff --git a/src/message-runtime-prompts.ts b/src/message-runtime-prompts.ts index 9745a8a..bcd8978 100644 --- a/src/message-runtime-prompts.ts +++ b/src/message-runtime-prompts.ts @@ -140,5 +140,7 @@ export function buildFinalizePendingPrompt(args: { ? `\n\nReviewer's final assessment:\n${lastReviewerOutput.output_text.slice(0, 2000)}` : ''; - return `The reviewer approved your work (DONE). Finalize and report the result.${reviewerSummary}`; + return `The reviewer approved your work (DONE). Finalize and report the result. +If you intend to close this paired turn now, your first line must be DONE. +If your first line is DONE_WITH_CONCERNS, the system will reopen review instead of finishing.${reviewerSummary}`; } diff --git a/src/message-runtime.test.ts b/src/message-runtime.test.ts index 30a8d47..28d5ee8 100644 --- a/src/message-runtime.test.ts +++ b/src/message-runtime.test.ts @@ -1414,7 +1414,9 @@ describe('createMessageRuntime', () => { vi.mocked(agentRunner.runAgentProcess).mockImplementation( async (_group, input, _onProcess, onOutput) => { expect(input.prompt).toBe( - `The reviewer approved your work (DONE). Finalize and report the result.\n\nReviewer's final assessment:\n${truncatedReviewerOutput}`, + `The reviewer approved your work (DONE). Finalize and report the result. +If you intend to close this paired turn now, your first line must be DONE. +If your first line is DONE_WITH_CONCERNS, the system will reopen review instead of finishing.\n\nReviewer's final assessment:\n${truncatedReviewerOutput}`, ); expect(input.prompt).not.toContain(longReviewerOutput); expect(input.prompt).not.toContain('이전 reviewer 요약'); @@ -1518,7 +1520,7 @@ describe('createMessageRuntime', () => { vi.mocked(agentRunner.runAgentProcess).mockImplementation( async (_group, input, _onProcess, onOutput) => { expect(input.prompt).toBe( - "The reviewer approved your work (DONE). Finalize and report the result.\n\nReviewer's final assessment:\n리뷰 승인 요약", + "The reviewer approved your work (DONE). Finalize and report the result.\nIf you intend to close this paired turn now, your first line must be DONE.\nIf your first line is DONE_WITH_CONCERNS, the system will reopen review instead of finishing.\n\nReviewer's final assessment:\n리뷰 승인 요약", ); expect(input.prompt).not.toContain('DONE\n승인합니다.'); await onOutput?.({ @@ -2027,7 +2029,7 @@ describe('createMessageRuntime', () => { vi.mocked(agentRunner.runAgentProcess).mockImplementation( async (_group, input, _onProcess, onOutput) => { expect(input.prompt).toBe( - "The reviewer approved your work (DONE). Finalize and report the result.\n\nReviewer's final assessment:\n리뷰 승인 요약", + "The reviewer approved your work (DONE). Finalize and report the result.\nIf you intend to close this paired turn now, your first line must be DONE.\nIf your first line is DONE_WITH_CONCERNS, the system will reopen review instead of finishing.\n\nReviewer's final assessment:\n리뷰 승인 요약", ); await onOutput?.({ status: 'success',