fix(paired): bound arbiter interventions to stop infinite arbiter loop
The owner↔reviewer↔arbiter loop could repeat forever: when the arbiter ruled PROCEED/REVISE/RESET it reset round_trip_count to 0, and nothing tracked how many times the arbiter had already intervened. A re-deadlock re-invoked the arbiter without bound. Add a persistent arbiter_intervention_count (new column + migration 020) that survives the round-trip reset, and a configurable cap ARBITER_MAX_INTERVENTIONS (default 1). Once the arbiter has intervened that many times and the loop still deadlocks, requestArbiterOrEscalate escalates straight to the user instead of re-invoking the arbiter. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -78,9 +78,19 @@ export function handleArbiterCompletion(args: {
|
||||
const { task, taskId, summary } = args;
|
||||
const now = new Date().toISOString();
|
||||
const arbiterVerdict = classifyArbiterVerdict(summary);
|
||||
// Persist a running count of arbiter interventions so the loop can be bounded.
|
||||
// This must NOT be reset by the round_trip_count reset below — otherwise the
|
||||
// owner↔reviewer loop could re-trigger the arbiter without limit.
|
||||
const nextArbiterInterventionCount =
|
||||
(task.arbiter_intervention_count ?? 0) + 1;
|
||||
|
||||
logger.info(
|
||||
{ taskId, arbiterVerdict, summary: summary?.slice(0, 200) },
|
||||
{
|
||||
taskId,
|
||||
arbiterVerdict,
|
||||
arbiterInterventionCount: nextArbiterInterventionCount,
|
||||
summary: summary?.slice(0, 200),
|
||||
},
|
||||
'Arbiter verdict rendered',
|
||||
);
|
||||
|
||||
@@ -98,6 +108,7 @@ export function handleArbiterCompletion(args: {
|
||||
owner_step_done_streak: 0,
|
||||
finalize_step_done_count: 0,
|
||||
empty_step_done_streak: 0,
|
||||
arbiter_intervention_count: nextArbiterInterventionCount,
|
||||
arbiter_verdict: arbiterVerdict,
|
||||
arbiter_requested_at: null,
|
||||
},
|
||||
@@ -121,12 +132,17 @@ export function handleArbiterCompletion(args: {
|
||||
owner_step_done_streak: 0,
|
||||
finalize_step_done_count: 0,
|
||||
empty_step_done_streak: 0,
|
||||
arbiter_intervention_count: nextArbiterInterventionCount,
|
||||
arbiter_verdict: arbiterVerdict,
|
||||
arbiter_requested_at: null,
|
||||
},
|
||||
});
|
||||
logger.info(
|
||||
{ taskId, arbiterVerdict },
|
||||
{
|
||||
taskId,
|
||||
arbiterVerdict,
|
||||
arbiterInterventionCount: nextArbiterInterventionCount,
|
||||
},
|
||||
'Arbiter requested owner changes — resuming owner flow',
|
||||
);
|
||||
return;
|
||||
|
||||
Reference in New Issue
Block a user