fix(recovery): terminate exhausted recovery assessments with one actionable notice #251
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "fix/exhausted-recovery-attention"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Fixes the silent exhaustion path diagnosed in
development-evidence/validator-agent-stall/PR165-APOLOGY-STALL-TRACE.md(installed/base95cf3a4).Bug:
assessRetainedTaskhandled retry exhaustion in two places (entry withrecoveryRetry.attempts >= 3, and the third technical/invalid evaluation) viareconcileUnassessedTaskonly. The task becameblockedwith a host placeholdernext, but notermination, norecoveryAttentionIdand no operator notice.controlTaskBudgetrequirestermination === "recovery_assessment_failed", so the supported reset rejected it ("Task is not host budget-blocked"). Live tasks$iwrda06z…/$T48P6I6…show exactly this signature.Fix (reuse only): both exhaustion paths now call the existing
recoveryAttention(s, task, "exhausted")after the existing placeholder reconciliation. Persisted under the existing barrier:termination, dedup idtask-recovery-exhausted:…, one outbox notice naming the supported reset. That terminal notice is delivered even with default-offrecoveryDiagnostics(same class as task-budget escalation; documented indocs/gateway-progress.md). Other technical diagnostics stay opt-in.Not changed: no new retry machine, no admission/queue entry, no worker execution/replay, no cross-task linking, no deadline extension; stop/pause/expiry/semantic-blocked tasks untouched (
assessRetainedTaskonly acts onactive). Legacy tasks already persisted as silentblockedare deliberately not inferred terminal or migrated (test asserts reset still rejects them); see PR result evidence for the documented limitation.Tests: red on base (9 failures incl. both branches), green with fix. New: technical + invalid exhaustion across JSON StateStore reloads → one termination, one notice delivered once, no fourth assessment, no worker turn/queue, reset commits idempotently and keeps deadline; holds/legacy unchanged. Updated tests that encoded the silent block. Full serial 1422/1422, typecheck, build. Independent exact-diff
plugin_review: passed, 0 findings (fingerprint75810489…).Both retained-assessment exhaustion paths (exhausted retry on entry and the third invalid/technical evaluation) silently parked the task as blocked without recovery_assessment_failed, attention id or operator notice. The supported budget reset therefore rejected it ("not host budget-blocked"). Reuse the existing recoveryAttention("exhausted"): persist the terminal reason and the dedup id under the same barrier, and deliver its single notice even with default-off recovery diagnostics, like task-budget escalation. No new retry machine, no work admission, no replay. Legacy tasks already persisted as silent blocked are not inferred terminal or migrated.