fix: respect owner verdict during finalize turn

When the reviewer approves (merge_ready) and the owner finalizes,
the system previously only checked for code changes. If the owner
raised concerns (DONE_WITH_CONCERNS, BLOCKED, NEEDS_CONTEXT) during
finalize — e.g. push failed due to detached HEAD — the system
ignored it and auto-completed the task.

Now the owner's verdict is checked first. If the owner raises
concerns, the task goes back to active and re-triggers the reviewer
so the issue can be addressed collaboratively.
This commit is contained in:
Eyejoker
2026-03-30 01:37:30 +09:00
parent ab2680ba11
commit aa6477cf2b

View File

@@ -348,32 +348,52 @@ export function completePairedExecutionContext(args: {
if (role === 'owner') {
const now = new Date().toISOString();
// merge_ready → reviewer already approved. Check if owner made
// additional changes that need re-review.
// merge_ready → reviewer already approved. Check owner verdict and
// whether owner made additional changes that need re-review.
if (task.status === 'merge_ready') {
const workspace = getPairedWorkspace(task.id, 'owner');
const hasNewChanges = workspace?.workspace_dir
? hasCodeChangesSinceRef(workspace.workspace_dir, task.source_ref)
: null;
if (hasNewChanges === false) {
// No code changes since reviewer approved → finalize complete
updatePairedTask(taskId, { status: 'completed', updated_at: now });
// Owner can raise concerns even during finalize (e.g. push failed,
// detached HEAD, discovered issue). Respect the owner's verdict.
const ownerVerdict = classifyReviewerVerdict(args.summary);
if (
ownerVerdict === 'done_with_concerns' ||
ownerVerdict === 'blocked' ||
ownerVerdict === 'needs_context'
) {
updatePairedTask(taskId, { status: 'active', updated_at: now });
logger.info(
{ taskId, summary: args.summary?.slice(0, 100) },
'Owner finalized after reviewer approval — task completed',
{
taskId,
ownerVerdict,
summary: args.summary?.slice(0, 100),
},
'Owner raised concerns during finalize — task set back to active',
);
// Fall through to auto-trigger reviewer for the new concern
} else {
const workspace = getPairedWorkspace(task.id, 'owner');
const hasNewChanges = workspace?.workspace_dir
? hasCodeChangesSinceRef(workspace.workspace_dir, task.source_ref)
: null;
if (hasNewChanges === false) {
// No code changes since reviewer approved → finalize complete
updatePairedTask(taskId, { status: 'completed', updated_at: now });
logger.info(
{ taskId, summary: args.summary?.slice(0, 100) },
'Owner finalized after reviewer approval — task completed',
);
return;
}
// Owner made changes after approval → needs re-review
logger.info(
{
taskId,
sourceRef: task.source_ref,
hasNewChanges,
},
'Owner made changes after reviewer approval — re-triggering review',
);
return;
}
// Owner made changes after approval → needs re-review
logger.info(
{
taskId,
sourceRef: task.source_ref,
hasNewChanges,
},
'Owner made changes after reviewer approval — re-triggering review',
);
}
// Normal turn → auto-trigger reviewer (if within round trip limit)