fix(paired): break reviewer step_done ⇄ owner task_done infinite loop
The reviewer step_done verdict mapped to request_owner_changes unconditionally, bypassing the deadlock guard that every sibling verdict respects. When the owner kept replying task_done and the reviewer kept replying step_done, the room oscillated forever, spamming duplicate reviewer messages into the channel. Apply the same `roundTripCount >= deadlockThreshold` guard used by the done_with_concerns/continue/default branch so step_done oscillation escalates to the arbiter (or completes via escalation when no arbiter) instead of looping. Reuses existing round_trip_count and deadlockThreshold; no migration needed. Co-Authored-By: Claude Opus 4 <noreply@anthropic.com>
This commit is contained in:
@@ -166,6 +166,26 @@ describe('paired execution context shared verdict helpers', () => {
|
||||
).toEqual({ kind: 'request_arbiter' });
|
||||
});
|
||||
|
||||
it('routes reviewer step_done to arbiter once round trips hit the deadlock threshold', () => {
|
||||
// Below threshold: keep iterating with the owner.
|
||||
expect(
|
||||
resolveReviewerCompletionSignal({
|
||||
visibleVerdict: 'step_done',
|
||||
roundTripCount: 1,
|
||||
deadlockThreshold: 2,
|
||||
}),
|
||||
).toEqual({ kind: 'request_owner_changes' });
|
||||
// At/above threshold: break the owner⇄reviewer step_done oscillation by
|
||||
// escalating to the arbiter instead of looping forever.
|
||||
expect(
|
||||
resolveReviewerCompletionSignal({
|
||||
visibleVerdict: 'step_done',
|
||||
roundTripCount: 2,
|
||||
deadlockThreshold: 2,
|
||||
}),
|
||||
).toEqual({ kind: 'request_arbiter' });
|
||||
});
|
||||
|
||||
it('maps reviewer failure verdicts to explicit failure signals', () => {
|
||||
expect(
|
||||
resolveReviewerFailureSignal({
|
||||
|
||||
@@ -112,6 +112,9 @@ export function resolveReviewerCompletionSignal(args: {
|
||||
case 'done':
|
||||
return { kind: 'request_owner_finalize' };
|
||||
case 'step_done':
|
||||
if (roundTripCount >= deadlockThreshold) {
|
||||
return { kind: 'request_arbiter' };
|
||||
}
|
||||
return { kind: 'request_owner_changes' };
|
||||
case 'blocked':
|
||||
case 'needs_context':
|
||||
|
||||
Reference in New Issue
Block a user