Skip to content

Conversation

@dtsong
Copy link
Owner

@dtsong dtsong commented Jan 24, 2026

Closes #34

Summary

  • Cascading fallback: Full → Reduced (Haiku) → Gates-only → Minimal
  • Pipeline always produces output, never fails silently
  • Clear user communication about degradation level

Changes

  • New: src/pr_review_agent/execution/degradation.py - DegradationLevel enum + DegradedReviewPipeline
  • New: tests/test_degradation.py - 14 tests covering all scenarios
  • Modified: src/pr_review_agent/main.py - Uses degradation pipeline instead of raw retry
  • Modified: src/pr_review_agent/output/github_comment.py - Added format_degraded_review()
  • Modified: tests/test_main.py - Updated mocks for new pipeline

Test Plan

  • All 312 tests pass (95.85% coverage)
  • Linting clean
  • Each degradation level tested individually
  • Gate results preserved when degrading
  • Error messages propagated correctly
  • Never raises exceptions (always returns a result)

🤖 Generated with Claude Code

Implements cascading fallback strategy:
  Full → Reduced (Haiku) → Gates-only → Minimal

Always produces output, never fails silently.

- DegradationLevel enum with 4 levels
- DegradedReviewPipeline wraps LLM calls with fallback
- format_degraded_review for GitHub comment output
- Updated main.py to use degradation pipeline
- Updated existing tests to use new pipeline mocking

Implements #34

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@dtsong dtsong added resiliency Fault tolerance and graceful degradation backlog Backlog items for future implementation labels Jan 24, 2026
dtsong and others added 2 commits January 24, 2026 11:36
- Restore retry/backoff logic within each degradation level using
  retry_with_adaptation (was dropped entirely in initial impl)
- Use config.llm.simple_model for reduced fallback instead of
  hardcoded invalid "haiku" string
- Reuse single LLMReviewer instance across levels
- Remove unreachable MINIMAL level (gate_results can't fail)
- Move format_degraded_review import to top-level in main.py
- Remove dead FULL/REDUCED branches from format_degraded_review
  (main.py already routes those through format_as_markdown)
- Display accumulated errors in degraded comment output

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Degradation pipeline already uses retry_handler internally, so our
branch's higher-level abstraction supersedes main's direct usage.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@dtsong dtsong merged commit 8c3eca1 into main Jan 24, 2026
1 check passed
@dtsong dtsong deleted the feat/34-graceful-degradation branch January 24, 2026 19:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backlog Backlog items for future implementation resiliency Fault tolerance and graceful degradation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Graceful degradation on LLM failure

2 participants