fix: resolve missing_disposition recovery loop for blocked issues with active blockers
When an issue is `blocked` with unresolved first-class blockers, it has a valid disposition. But `classifySourceRecoveryRevalidation()` gated the `blocked + unresolvedBlockerCount > 0` check behind `durableSourceChange`, which was only true when status/assignee/blockers/etc. actually changed in the PATCH. Heartbeat comment-only PATCHes had `durableSourceChange = false`, so the function returned `null` (no resolution) even though the issue was correctly blocked. This caused a `missing_disposition` recovery action to stay `active` indefinitely, waking the agent on every scheduler tick. Fix: move the `blocked + unresolvedBlockerCount > 0` check before the `read_projection` early-return gate so it fires on every revalidation regardless of what changed. A blocked issue with active blockers always has a valid disposition. Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
parent
70b1a9109d
commit
02b2fecdf7
|
|
@ -995,6 +995,17 @@ export function issueRoutes(
|
|||
return "Recovery action became stale because the source issue was manually moved from blocked to todo.";
|
||||
}
|
||||
|
||||
// Check blocked+blockers before any trigger-based early returns: a blocked issue with
|
||||
// active first-class blockers always has a valid disposition regardless of what changed.
|
||||
// This prevents recovery-action loops where the issue is correctly blocked but the
|
||||
// missing_disposition action stays active because no "durable change" has occurred.
|
||||
if (issue.status === "blocked") {
|
||||
const readiness = await svc.getDependencyReadiness(issue.id);
|
||||
if (readiness.unresolvedBlockerCount > 0) {
|
||||
return "Recovery action became stale because the source issue now has unresolved first-class blockers.";
|
||||
}
|
||||
}
|
||||
|
||||
if (input.trigger === "read_projection") return null;
|
||||
if (
|
||||
input.trigger === "comment" &&
|
||||
|
|
|
|||
Loading…
Reference in New Issue