fix: resume owner after failed reviewer feedback (#208)

This commit is contained in:
Eyejoker
2026-06-03 01:37:22 +08:00
committed by GitHub
parent b4197875fa
commit 63a4515241
4 changed files with 51 additions and 3 deletions

View File

@@ -135,6 +135,16 @@ describe('paired completion signals', () => {
visibleVerdict: 'done', visibleVerdict: 'done',
}), }),
).toEqual({ kind: 'request_owner_finalize' }); ).toEqual({ kind: 'request_owner_finalize' });
expect(
resolveReviewerFailureSignal({
visibleVerdict: 'step_done',
}),
).toEqual({ kind: 'request_owner_changes' });
expect(
resolveReviewerFailureSignal({
visibleVerdict: 'done_with_concerns',
}),
).toEqual({ kind: 'request_owner_changes' });
expect( expect(
resolveReviewerFailureSignal({ resolveReviewerFailureSignal({
visibleVerdict: 'needs_context', visibleVerdict: 'needs_context',

View File

@@ -98,13 +98,15 @@ export function resolveReviewerFailureSignal(args: {
case 'task_done': case 'task_done':
case 'done': case 'done':
return { kind: 'request_owner_finalize' }; return { kind: 'request_owner_finalize' };
case 'step_done':
case 'done_with_concerns':
return { kind: 'request_owner_changes' };
case 'blocked': case 'blocked':
case 'needs_context': case 'needs_context':
return { return {
kind: 'complete', kind: 'complete',
completionReason: 'escalated', completionReason: 'escalated',
}; };
case 'done_with_concerns':
case 'continue': case 'continue':
default: default:
return { kind: 'preserve_review_ready' }; return { kind: 'preserve_review_ready' };

View File

@@ -52,7 +52,8 @@ export function handleFailedReviewerExecution(args: {
}); });
if ( if (
signal.kind === 'request_owner_finalize' || signal.kind === 'request_owner_finalize' ||
signal.kind === 'complete' signal.kind === 'complete' ||
signal.kind === 'request_owner_changes'
) { ) {
const ownerWs = const ownerWs =
signal.kind === 'request_owner_finalize' signal.kind === 'request_owner_finalize'
@@ -68,7 +69,9 @@ export function handleFailedReviewerExecution(args: {
nextStatus: nextStatus:
signal.kind === 'request_owner_finalize' signal.kind === 'request_owner_finalize'
? 'merge_ready' ? 'merge_ready'
: 'completed', : signal.kind === 'request_owner_changes'
? 'active'
: 'completed',
expectedUpdatedAt: task.updated_at, expectedUpdatedAt: task.updated_at,
updatedAt: now, updatedAt: now,
patch: { patch: {

View File

@@ -1445,3 +1445,36 @@ describe('paired execution context', () => {
}); });
}); });
}); });
describe('paired execution context reviewer failures', () => {
beforeEach(() => {
vi.resetAllMocks();
});
it('moves failed reviewer STEP_DONE output back to active for owner follow-up', () => {
const task = buildPairedTask({
status: 'in_review',
updated_at: '2026-03-28T00:05:00.000Z',
});
vi.mocked(db.getPairedTaskById).mockReturnValue(task);
completePairedExecutionContext({
taskId: task.id,
role: 'reviewer',
status: 'failed',
runId: 'run-failed-reviewer-step-done',
summary: 'STEP_DONE\n오너 수정이 더 필요합니다.',
});
expect(db.updatePairedTask).toHaveBeenCalledWith(
task.id,
expect.objectContaining({
status: 'active',
}),
);
expect(db.releasePairedTaskExecutionLease).toHaveBeenCalledWith({
taskId: task.id,
runId: 'run-failed-reviewer-step-done',
});
});
});