Skip to content

Require a current burn before claiming burning fast - #26

Merged
pekth merged 1 commit into
mainfrom
fix/pace-burn-recency
Sep 18, 2026
Merged

pekth merged 1 commit into
mainfrom
fix/pace-burn-recency

Conversation

@pekth

@pekth pekth commented Sep 18, 2026

Copy link
Copy Markdown
Owner

The problem

The popover kept nudging "Codex burning fast. Switch to Grok, OpenCode Go for headroom." while the same card read 0 / no sessions today. The claim is a window-shape artifact: deficit = usedPercent − elapsedPercent assumes usage spreads evenly across the window, so one burst early in a long window (e.g. Codex's weekly) holds the deficit until reset — days after the burn stopped. The nudge is level-triggered, so it reappeared on every popover open. The same stale-deficit flaw fed pace notifications, the menu-bar ETA chip, the notch banner and pills, and the meterusage json report.

The fix

"burning fast" is present tense, so it now requires burn evidence. A BurnRecency helper derives each provider's last observable burn from local sessions (30-minute quiet period), and QuotaPace.effective(lastBurn:now:) demotes a burn-quiet deficit to on-pace. Every deficit surface consumes the effective pace:

  • Popover nudge: actively burning keeps "burning fast"; a headline window at 80%+ without a current burn reads "near its limit"; a stale deficit below that no longer nags. Actively burning outranks near-limit, and hot providers are still excluded from switch suggestions.
  • Pace notifications (paceSoftWarning/paceCliff) fire only on a current burn; 80%/95% threshold alerts stay state-based.
  • meterusage json gates pacing the same way and now scans local activity sources for burn evidence.
  • Menu-bar ETA chip, notch banner/pills/strip entries, and quota-card pills all render the demoted pace — a quiet window shows the reset countdown in the calm tint instead of a burn alarm.

Providers without a local session store have no burn evidence: they lose pace alerts but keep threshold alerts (documented in docs/KB.md).

Verification

swift build clean and swift test 316/316 passed (0 failures) on macOS arm64, Swift 6.4 — including the new BurnRecencyTests regression suite (the exact reported case: weekly window 85% used, one-day-old burn → on-pace everywhere and a silent nudge).

Model(s): GLM (glm-5.3-flash)
Harness: opencode

A quota window's shape (usedPercent ahead of the elapsed fraction) can
outlive the burst that caused it — one early weekly burst held the pace
deficit for days, so the popover nudged "Codex burning fast. Switch to
Grok, OpenCode Go for headroom." while the same card read "no sessions
today".

"burning fast" is a present-tense claim, so every deficit surface now
consumes QuotaPace.effective(lastBurn:now:), which demotes a burn-quiet
deficit to on-pace (BurnRecency, 30-minute quiet period). The popover
nudge splits into two honest claims: actively burning keeps the old
wording, a headline window at 80%+ without a current burn reads "near
its limit", and a stale deficit below that no longer nags at all.
Pace notifications and the machine report (meterusage json, which now
also scans local activity for burn evidence) gate the same way; the
80%/95% threshold alerts stay state-based.

Verification: swift build clean and swift test 316/316 (incl. the new
BurnRecencyTests regression suite) on macOS arm64, Swift 6.4.
@pekth
pekth merged commit 3e221a1 into main Sep 18, 2026
@pekth
pekth deleted the fix/pace-burn-recency branch September 18, 2026 20:46
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