Skip to content

fix: keep recently used providers' tabs and limits across calendar resets - #402

Merged
chattymin merged 5 commits into
chattymin:mainfrom
Borisserz:fix/limits-carrier-recent-use
Oct 5, 2026
Merged

chattymin merged 5 commits into
chattymin:mainfrom
Borisserz:fix/limits-carrier-recent-use

Conversation

@Borisserz

Copy link
Copy Markdown
Contributor

Stacked on #377. This branch contains #377's two commits plus one commit of its own (fix: keep recently used providers' tabs and limits across calendar resets). Please review only that last commit. Once #377 merges, the diff shrinks to it. The PR targets main so CI runs, because ci.yml only triggers on PRs to main.

Summary

Closes the part of #336 that #377 doesn't cover.

#377 keeps an idle provider's snapshot when its week, month, or daily series has positive tokens. That fixes most idle days. However, those are calendar totals and they reset at their boundaries. A provider last used on Friday has week = 0 on Monday, and after the 1st it also has month = 0. The run in #336 shows exactly that (claude_code: week=0, lastUsage 3.02 days ago). In that case the snapshot still disappears. The popover reaches official limits only through a snapshot (selectedProviderHasLimits keys off selectedSnapshot), so the limits section disappears too, even though limits refreshed / codex limits refreshed succeed in the same refresh.

Changes, following the approach proposed in #336:

  • ProviderEnrichment.lastUsage is the newest entry with total > 0. It is filled once, in the shared ProviderEnrichment.local(entries:now:), so every local provider gets it. Zero-token <synthetic> records don't count, so a provider that was only ever installed still gets no tab (fix: 미사용 프로바이더 탭 회귀 — 캐리어 스냅샷을 활성 블록에 한정 #56 boundary).
  • ProviderSnapshot.lastUsage mirrors it. It carries over through phase 1, like week/month do, and is refreshed in phase 2 under periodsOK.
  • fix(home): retain historical usage on idle days #377's hasDisplayableUsage also accepts lastUsage within LocalUsageReader.recentUseWindow (7 days, the weekly quota window).
  • enrichmentScanStart also covers now - 7d, so the mtime filter can't clip the window near the start of a month.
  • Snapshots are sorted by provider registration order after phase 2. Carriers are appended in task-completion order, and now that they're more common the tabs would otherwise reshuffle on every refresh.

Unchanged: today's total (carriers keep today: nil), burn tier, and menuLimitLine's todayTotalTokens > 0 gate for the compact menu bar.

Refs #336, follow-up to #377. Thanks to @newbieFirewood for the root-cause analysis and suggested shape in #336.

Type of change

  • Bug fix
  • New feature
  • Refactor / cleanup
  • Documentation
  • Other:

UI changes

Before After
Used Codex/Claude Code on Friday, opened the popover on Monday (week total reset to 0, or after the 1st when month also reset): no provider tab and no Official limits section The tab and its Official limits section stay for 7 days after the last real use. Today's count and the menu bar text don't change
Tab order could change between refreshes as carrier snapshots finished in different orders Tabs always follow provider registration order

Checklist

  • swift build and swift test pass locally. Full suite: 1392 tests and 1 failure, SessionKeySettingsRenderingTests.testSessionKeyEntryOpensInsideViewportAndPreservesDifficultyControls. It fails the same way on fix(home): retain historical usage on idle days #377's head without this commit, passes when run alone, and passes in fix(home): retain historical usage on idle days #377's CI, so it depends on the local environment. It doesn't involve this change: the test's UsageStore has providers: [].
  • PR title and description are written in English
  • UI changes are described above (before/after — images optional)
  • No copyrighted assets, secrets, or private tooling references are committed (see CONTRIBUTING)
  • Tests were added or updated for this change

Test plan

  • testCarrierForProviderUsedWithinRecentWindowAcrossCalendarBoundaries: the trigger branch (week = month = 0, series all zero, last use 3 days ago). The snapshot stays across two refreshes (phase-1 carry-over included), today = 0, burn idle.
  • testNoCarrierForProviderIdleBeyondRecentWindow: last use more than 7 days ago stays hidden.
  • testSnapshotOrderFollowsProviderRegistrationOrder: a phase-2 carrier registered first sorts before a phase-1 provider.
  • testEnrichmentLastUsageIgnoresZeroTokenEntries: a newer zero-token record doesn't move lastUsage, and synthetic-only input gives nil.
  • testEnrichmentScanStartCoversAllWindows is extended for the 7-day window. The mid-month equality assertion still holds.
  • Fault injection: removing the lastUsage predicate, the sort, or the total > 0 filter makes the matching test fail. The beyond-window negative test still passes, as expected.
  • Recorded the defect class in docs/reference/defect-log.md.

chattymin and others added 5 commits September 29, 2026 11:49
…sets

Official limits are an account property, but the popover reaches them
only through a provider snapshot. Week and month totals reset at their
calendar boundaries, so a provider used last Friday has week = month = 0
on Monday (or after the 1st) and lost its tab and its limits section
while the limits were being fetched fine (chattymin#336).

Track the newest positive-token entry (lastUsage) in the shared
ProviderEnrichment.local and keep the snapshot while it is within the
7-day weekly quota window. Zero-token synthetic records do not count.
Extend enrichmentScanStart to cover the window and keep snapshots in
provider registration order, since carriers arrive in task-completion
order.
# Conflicts:
#	Sources/PokeTokenBar/Core/UsageStore.swift
#	docs/reference/defect-log.md
@chattymin
chattymin merged commit 11eebe6 into chattymin:main Oct 5, 2026
2 checks passed
donky-ey pushed a commit to donky-ey/PokeDexBar that referenced this pull request Oct 14, 2026
donky-ey pushed a commit to donky-ey/PokeDexBar that referenced this pull request Oct 14, 2026
- keep provider tabs in registration order when carriers append (upstream chattymin#402's dropped hunk)
- gate the menu-bar cost line on today's data so a carrier cannot add a $0.00 line
- saturate Bucket sums at the parse cap so thousands of clamped corrupt entries cannot trap
donky-ey pushed a commit to donky-ey/PokeDexBar that referenced this pull request Oct 15, 2026
Snapshots now exist whenever there is displayable usage (today, active
block, week/month totals, month series, or recent 7-day use), not only
when today has tokens. A successful empty enrichment sweep removes
obsolete carriers; failed reads keep history. The popover keeps period
totals and recap entry visible on quiet days, and hides the grouped
today figure under 1,000 tokens.

Fork note: hasDisplayableUsage absorbs the SP1 lastUsage 7-day carrier
(chattymin#336/chattymin#402) so installed-but-unused providers still stay hidden (chattymin#56).
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.

2 participants