Skip to content

fix(claude): prefer limits[] session over stale five_hour after 5h rollover - #334

Merged
Finesssee merged 2 commits into
mainfrom
fix/issue-279-claude-session-transient-100
Aug 16, 2026
Merged

fix(claude): prefer limits[] session over stale five_hour after 5h rollover#334
Finesssee merged 2 commits into
mainfrom
fix/issue-279-claude-session-transient-100

Conversation

@Finesssee

Copy link
Copy Markdown
Collaborator

Summary

Fixes #279.

After a session (5h) window resets, the legacy five_hour.utilization field can transiently report 1.0 (normalized to 100%) for the new window, even though claude.ai shows only 5%. This is the same bug class as #210, which was fixed for the weekly/all-models lane in 0.48.0 by preferring the limits[] weekly_all entry over legacy seven_day.utilization.

This PR applies the identical pattern to the session (5h) lane, in both the OAuth and web API paths.

Root cause

Right after a window rollover, Anthropic leaves the legacy five_hour.utilization field stale (reporting 1.0100%) while the limits[] array already carries the fresh value as an entry with kind == "session", group == "session". The legacy field was read directly, so the stale 100% won transiently until the legacy field caught up.

Fix

  • scoped_weekly.rs: add session_window(limits) — reads the 5h session window from the limits[] array (kind == "session", group == "session"), mirroring weekly_all_window.
  • web_api.rs: the primary lane now prefers session_window(&usage.limits) over legacy five_hour, falling back to the legacy field, then the informational 5h placeholder.
  • oauth/mod.rs: the primary lane now prefers session_window(&response.limits) over legacy five_hour, falling back to the legacy field, then 0%.

Provider-specific logic stays inside rust/src/providers/claude/ (no cross-provider branching). No secrets/tokens are logged.

Backwards compatible

When no limits[] session entry is present (older API shape), the legacy five_hour field is still the source of truth — verified by a dedicated fallback test in each path.

Test plan

  • cargo test --manifest-path rust/Cargo.toml — 1220 passed, 0 failed
  • cargo clippy --manifest-path rust/Cargo.toml --all-targets -- -D warnings — clean
  • cargo fmt --all -- --check — clean
  • New unit tests reproduce the transient-100% scenario and assert the limits[] value (5%) wins over the stale legacy field (100%):
    • scoped_weekly::tests::session_window_prefers_limits_percent_over_stale_five_hour
    • scoped_weekly::tests::session_window_ignores_mismatched_group_and_null_percent
    • web_api::tests::issue_279_session_limits_win_over_stale_five_hour_after_rollover
    • web_api::tests::session_falls_back_to_legacy_five_hour_without_limits_entry
    • oauth::tests::issue_279_session_limits_win_over_stale_five_hour_after_rollover
    • oauth::tests::session_falls_back_to_legacy_five_hour_without_limits_entry

No UI/tray/float-bar behavior changed; no CUA proof needed (backend parser fix only).

Fixes #279.

…llover

After a session window resets, the legacy five_hour.utilization field can
transiently report 1.0 (normalized to 100%) for the new 5h window while
claude.ai shows only 5% — same bug class as #210, which was fixed for the
weekly lane in 0.48.0 by preferring limits[] weekly_all over seven_day.

Apply the same pattern to the session (5h) lane: prefer the limits[] entry
(kind=="session", group=="session") over legacy five_hour.utilization in
both the OAuth and web API paths. When the limits[] session entry is absent,
fall back to the legacy field (backwards compatible), then to the
informational placeholder (web) / 0% (oauth).

Fixes #279.
…reference chain

The web_api issue-279 tests duplicated the limits[]-over-legacy
preference chain inline instead of calling the production code,
risking silent drift if the chain changes. Extract the chain into
build_rate_windows so both production and tests share one canonical
implementation. Net -9 lines.
@Finesssee
Finesssee merged commit 3387ec0 into main Aug 16, 2026
1 check passed
@Finesssee
Finesssee deleted the fix/issue-279-claude-session-transient-100 branch August 16, 2026 11:47
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.

Claude session (5h) window transiently reads 100% via OAuth while claude.ai shows 5% - v0.48.0, same symptom class as #210

1 participant