Skip to content

feat: size rate-limit backoff from CLI-reported reset time - #97

Merged
tdrml merged 1 commit into
mainfrom
feat/rate-limit-reset-parsing
Jun 10, 2026
Merged

feat: size rate-limit backoff from CLI-reported reset time#97
tdrml merged 1 commit into
mainfrom
feat/rate-limit-reset-parsing

Conversation

@tdrml

@tdrml tdrml commented Jun 10, 2026

Copy link
Copy Markdown
Owner

Summary

Follow-up to #95. During the 09:17Z limit window, the breaker's exponential backoff scheduled recovery for 13:19Z even though the CLI output said capacity returned at 12:40pm UTC — 39 minutes wasted (recovered manually). The CLI tells us exactly when to retry; use it.

Changes

  • packages/worker/src/entrypoint.tsparseResetTime() parses resets <h>(:mm)?<am|pm> (UTC) from CLI output and resolves it to the next UTC occurrence (rolls to tomorrow when the time already passed; handles 12am/12pm). runClaude now returns { exitCode, rateLimitResetAt? }, and on a limit hit the entrypoint saves the hint as a rate-limit-reset task output keyed by RUN_ID (best-effort: failures are logged and swallowed).
  • packages/core/src/dynamodb/rate-limit-service.tstripBreaker(now, resetAt?): when a hint is present, valid, in the future, and within 24h, backoffUntil = resetAt + 2 min buffer; otherwise the existing 1h × 2^(n−1) schedule (cap 24h) applies. Failure counting unchanged.
  • packages/lambdas/src/handlers/reconcile.ts — on RATE_LIMIT_EXIT_CODE, reads the hint from task-outputs and passes it to tripBreaker.
  • packages/cdk/src/constructs/compute.ts — task-outputs grant widened from read to read/write so workers can save the hint.

Verification

Full workspace suite: 45 files, 1111 tests pass. New coverage: reset-time parsing (am/pm, hour-only, day rollover, 12am/12pm, malformed), breaker hint usage (hint honored with buffer; past/far-future/unparseable hints fall back to exponential), runClaude return shape.

🤖 Generated with Claude Code

The Claude CLI names the exact time capacity returns ("resets 12:40pm
(UTC)"), but the circuit breaker guessed exponentially (1h x 2^(n-1)),
which last night scheduled a retry 39 minutes after capacity was
already back.

The worker entrypoint now parses the reset time on limit detection and
saves it as a 'rate-limit-reset' task output (best-effort; workers get
write access to the task-outputs table). Reconcile reads the hint and
the breaker waits until reset + 2 min instead of guessing, ignoring
hints that are in the past or more than 24h out. Exponential backoff
remains the fallback when no hint is available.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@tdrml
tdrml merged commit 2a8121a into main Jun 10, 2026
3 checks passed
@tdrml
tdrml deleted the feat/rate-limit-reset-parsing branch July 31, 2026 15:37
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.

1 participant