2b13f610e195b6ea1553495808733a3a77eaa4cb
Recovery was dying on a stale failure cap, not on anything recovery itself did. detectRepeatedToolFailure (stage_loop_break, #78) counted same-signature ToolExecutionFailedEvents cumulatively across the whole stage. A stage routed to recovery, retried by the ladder, and routed again would re-trip the SAME pre-recovery count on its very first post-recovery round — recovery would burn a full expensive turn and still fail on retryExhausted=true from stale evidence. Fix: window the fold to events after the most recent FailureTicketOpenedEvent naming the stage (mirrors the existing BuildPrerequisiteBootstrapAttemptedEvent windowing pattern already used by repeatedBuildCriticalReferenceBlock). A stage returning from a genuine repair attempt now starts the count clean; it must accumulate stageFailureLoopLimit (default 6) NEW failures post-recovery before re-tripping. This does not weaken RECOVERY_ROUTE_BUDGET/INTENT_ROUTE_BUDGET: those are charged directly off FailureTicketOpenedEvent by the reducer (OrchestrationState.recoveryRoutes/recoveryFailureFingerprints), independent of this fold, and are deliberately left untouched by TransitionExecutedEvent already. A full ladder round-trip therefore stays bounded at RECOVERY_ROUTE_BUDGET(2) + INTENT_ROUTE_BUDGET(2) route-in/route-out cycles, each itself requiring a fresh stageFailureLoopLimit(6) failures to re-trip. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HgDL1v3GuQ9RZnYR6fDT95
fix: workflow inference chain — surface llama-server errors, user-turn-last, bundle-relative prompts
Description
No description provided
Languages
Kotlin
89.1%
Go
10.6%
Python
0.2%
CSS
0.1%