From f054e80661d7d80d87396486d18946f5d6cedc80 Mon Sep 17 00:00:00 2001 From: toki Date: Sun, 2 Aug 2026 05:16:09 +0900 Subject: [PATCH] =?UTF-8?q?fix(agent-ops):=20selfcheck=20=EC=9E=AC?= =?UTF-8?q?=EC=8B=9C=EB=8F=84=20=EC=A7=80=EC=8B=9C=EB=A5=BC=20=EB=8B=A8?= =?UTF-8?q?=EC=88=9C=ED=99=94=ED=95=9C=EB=8B=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../orchestrate-agent-task-loop/SKILL.md | 4 ++-- .../scripts/dispatch.py | 14 +++++--------- .../tests/test_dispatch.py | 19 +++++++++++++------ 3 files changed, 20 insertions(+), 17 deletions(-) diff --git a/agent-ops/skills/project/orchestrate-agent-task-loop/SKILL.md b/agent-ops/skills/project/orchestrate-agent-task-loop/SKILL.md index 8d95fefe..c6f2b755 100644 --- a/agent-ops/skills/project/orchestrate-agent-task-loop/SKILL.md +++ b/agent-ops/skills/project/orchestrate-agent-task-loop/SKILL.md @@ -99,12 +99,12 @@ Keep control prompts in English, insert absolute paths only, and do not expand t - A dispatcher child runs only while `IOP_AGENT_TASK_EXECUTION_ID` is present. - Prefix every worker and review prompt with: `You are a child agent already launched by the dispatcher, not the orchestration caller. Execute only the assigned role directly. Do not start, monitor, or wait for orchestration through dispatch.py or orchestrate-agent-task-loop. You may run dispatch.py --validate-plan only when required by plan or code-review finalization because that mode validates one candidate PLAN without starting or monitoring orchestration.` -- Keep local self-check prompts short. Start them with: `Think in English. Final in Korean.` +- Keep local self-check prompts short. Start fresh self-check and recovery prompts with: `Think in English. Final in Korean.` The same-session unchecked-item retry uses the exact terse prompt below. - Cloud worker: `Read {PLAN_PATH} and complete the task. Keep artifact content in English. Final in Korean.` - Pi worker: `Think in English. Keep artifact content in English. Final in Korean. Read {PLAN_PATH} and complete the task.` - Pi self-check full pass: `Think in English. Final in Korean. Read {PLAN_PATH}; review all work once, fix omissions, and update {CODE_REVIEW_PATH}. Keep files in English.` -- Pi self-check unchecked-item retry: `Think in English. Final in Korean. Read {PLAN_PATH}; complete every unchecked implementation item and update {CODE_REVIEW_PATH}. Keep files in English.` +- Pi self-check unchecked-item retry: `The code review file is incomplete! Complete it now!` - Official review: `Read {CODE_REVIEW_PATH} and start the review. Keep artifact content in English. Final in Korean.` - Review-exit recovery: `Continue the review for {TASK_PATH}. Keep artifact content in English. Final in Korean.` - Context escalation: `Continue from {LOCATOR_PATH}. Check the saved context and current workspace. Keep artifact content in English. Final in Korean.` diff --git a/agent-ops/skills/project/orchestrate-agent-task-loop/scripts/dispatch.py b/agent-ops/skills/project/orchestrate-agent-task-loop/scripts/dispatch.py index 6c4e371f..9d991e1d 100644 --- a/agent-ops/skills/project/orchestrate-agent-task-loop/scripts/dispatch.py +++ b/agent-ops/skills/project/orchestrate-agent-task-loop/scripts/dispatch.py @@ -4369,15 +4369,11 @@ def selfcheck_prompt(task: Task, *, unchecked_items: bool = False) -> str: if task.review is None: raise RuntimeError("selfcheck CODE_REVIEW 파일이 없다") if unchecked_items: - body = ( - f"Read {task.plan.resolve()}; complete every unchecked implementation " - f"item and update {task.review.resolve()}. Keep files in English." - ) - else: - body = ( - f"Read {task.plan.resolve()}; review all work once, fix omissions, " - f"and update {task.review.resolve()}. Keep files in English." - ) + return "The code review file is incomplete! Complete it now!" + body = ( + f"Read {task.plan.resolve()}; review all work once, fix omissions, " + f"and update {task.review.resolve()}. Keep files in English." + ) return f"{SELF_CHECK_PROMPT_PREFIX} {body}" diff --git a/agent-ops/skills/project/orchestrate-agent-task-loop/tests/test_dispatch.py b/agent-ops/skills/project/orchestrate-agent-task-loop/tests/test_dispatch.py index 3ae70a8c..d2b1832d 100644 --- a/agent-ops/skills/project/orchestrate-agent-task-loop/tests/test_dispatch.py +++ b/agent-ops/skills/project/orchestrate-agent-task-loop/tests/test_dispatch.py @@ -3628,11 +3628,10 @@ class ReviewControlTest(unittest.TestCase): ) self.assertEqual( unchecked_retry, - f"{dispatch.SELF_CHECK_PROMPT_PREFIX} Read " - f"{task.plan.resolve()}; complete every unchecked implementation " - f"item and update {task.review.resolve()}. Keep files in English.", + "The code review file is incomplete! Complete it now!", ) - self.assertIn(str(task.plan.resolve()), unchecked_retry) + self.assertNotIn(str(task.plan.resolve()), unchecked_retry) + self.assertNotIn(str(task.review.resolve()), unchecked_retry) self.assertNotIn("dispatcher child", selfcheck.lower()) self.assertEqual( dispatch.continuation_prompt( @@ -12122,13 +12121,21 @@ class ArtifactLanguageContractTest(unittest.TestCase): } concise_selfcheck_prompts = { "selfcheck", - "selfcheck_unchecked", "pi_selfcheck_continuation", - "pi_selfcheck_unchecked_continuation", "pi_selfcheck_native_continuation", } + terse_unchecked_prompts = { + "selfcheck_unchecked", + "pi_selfcheck_unchecked_continuation", + } for name, prompt in prompts.items(): with self.subTest(prompt=name): + if name in terse_unchecked_prompts: + self.assertEqual( + prompt, + "The code review file is incomplete! Complete it now!", + ) + continue self.assertTrue( prompt.startswith( dispatch.SELF_CHECK_PROMPT_PREFIX