Skip to content

fix(SUB-003): stop ping-pong between exhausted subscriptions (#444)#445

Merged
vybe merged 1 commit into
mainfrom
feature/444-sub003-stop-ping-pong
Apr 21, 2026
Merged

fix(SUB-003): stop ping-pong between exhausted subscriptions (#444)#445
vybe merged 1 commit into
mainfrom
feature/444-sub003-stop-ping-pong

Conversation

@vybe

@vybe vybe commented Apr 21, 2026

Copy link
Copy Markdown
Contributor

Summary

  • _perform_auto_switch() deleted rate-limit events for the old subscription on every switch, erasing the signal is_subscription_rate_limited() reads. The drained sub then looked viable on the next cycle, causing agents to ping-pong between two exhausted subscriptions (observed: 8+ switches over 90 min across 4 agents).
  • Fix is the issue's minimum-viable patch: drop the clear_rate_limit_events call. Events age out naturally via the existing 2h detection window + 24h cleanup job.
  • Adds 4 db-layer unit regression tests covering post-switch persistence, dual-exhausted no-alternative, full two-switch ping-pong block, and healthy-path sanity.

Scope intentionally narrow — does not tackle the "proper fix" (parsing reset time from 429 body, rate_limited_until column, exhaustion notification). That belongs in a follow-up.

Changes

  • src/backend/services/subscription_auto_switch.py — delete clear_rate_limit_events call, add comment explaining why
  • tests/unit/test_subscription_auto_switch_pingpong.py — new, 4 tests
  • docs/memory/feature-flows/subscription-auto-switch.md — edge case Fix: Add missing Docker labels to system agent container #1 rewritten

Test Plan

  • New tests pass: pytest tests/unit/test_subscription_auto_switch_pingpong.py -v
  • Regression manually verified: tests fail against pre-fix code (confirmed the old buggy clear path makes sub-A look viable)
  • Neighboring unit suites still green: pytest tests/unit/test_subscription_bola.py tests/unit/test_backlog.py
  • Staging: enable auto_switch_subscriptions, exhaust two subs, confirm no switches occur after the first one (replaces the old 8+/90min loop)

Closes #444

Generated with Claude Code

The auto-switch service was deleting rate-limit events from the old
subscription immediately after each switch, which erased the signal that
`is_subscription_rate_limited()` uses to filter candidates. The just-drained
subscription then looked viable again on the next cycle, causing agents to
ping-pong between two exhausted subscriptions (observed: 8+ switches over
90 minutes across 4 agents).

Fix keeps the events in place so the 2h detection window stays truthful;
events age out naturally via the existing cleanup job. Adds unit regression
tests that reproduce the ping-pong against the db layer directly.

Closes #444

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bug(SUB-003): auto-switch ping-pongs between rate-limited subscriptions due to clear_rate_limit_events destroying detection signal

1 participant