fix: prevent non-convergent stuck loops on trivial tasks#13
Merged
Conversation
The default-path coding loop (reviewer-only) had no stuck-loop detection, unlike the flagged path which gets it from the synthesizer. When a reviewer repeatedly returned approved=False / blocking=False (e.g. requesting minor polish), the loop burned all 5 iterations + 2 advisor rounds without converging, eventually causing an exit -2 abort. Changes: - Add _detect_stuck_loop() that detects 3+ consecutive non-blocking fix cycles on the default path - When stuck or loop-exhausted with non-blocking reviewer feedback AND code changes present, return COMPLETED_WITH_DEBT instead of FAILED_UNRECOVERABLE — the issue flows through the debt gate rather than triggering replanning/abort - Preserve FAILED_UNRECOVERABLE for genuinely blocking failures and cases where no code was produced Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…gradation 25 tests exercising run_coding_loop end-to-end with scripted call_fn (only AI agent calls are mocked). Covers: - Happy path (approved first/second iteration) - Non-blocking stuck loop → COMPLETED_WITH_DEBT at window boundary - Blocking review → immediate FAILED_UNRECOVERABLE - Stagnation (no files changed) → FAILED_UNRECOVERABLE - Loop exhaustion with non-blocking → COMPLETED_WITH_DEBT - Flagged path (QA + reviewer + synthesizer) scenarios - Coder exception handling - Artifact/checkpoint persistence to disk - File accumulation across iterations - note_fn tag observability Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes #12 — Stall/non-convergence on trivial
repo_pathsmoke tasks that exit with code -2._detect_stuck_loop()for the default path (reviewer-only) which previously had no stuck detection (unlike the flagged path which gets it from the synthesizer)COMPLETED_WITH_DEBTinstead ofFAILED_UNRECOVERABLE— issues flow through the debt gate rather than triggering replanning/abort/stallFAILED_UNRECOVERABLEfor genuinely blocking failures and cases where no code was producedRoot cause
The default-path coding loop had no mechanism to detect repetitive non-convergent fix cycles. When a reviewer repeatedly returned
approved=False/blocking=False(e.g. requesting minor polish on trivial tasks), the loop burned all 5 iterations + 2 advisor rounds without converging, eventually causing an exit -2 abort withcompleted_issues: []and the issue stuck inin_flight_issues.Behavior change
Test plan
_detect_stuck_loop()with various history patternstest_model_config.py)repo_pathbuild and verify it converges🤖 Generated with Claude Code