Skip to content

fix(pacing): keep a pace deficit on displays after the burn cools - #41

Merged
pekth merged 1 commit into
mainfrom
fix/pace-display-raw
Sep 27, 2026
Merged

pekth merged 1 commit into
mainfrom
fix/pace-display-raw

Conversation

@pekth

@pekth pekth commented Sep 27, 2026

Copy link
Copy Markdown
Owner

Problem

The pacing displays lied after a burst cooled. A Codex weekly window at 43% used with 6d 13h left — clearly ahead of pace — rendered as "on pace" with "Paced to last until reset" once the last local session was more than 30 minutes old.

Root cause is a gate that outran its intent. PR #26 added QuotaPace.effective(lastBurn:now:) to stop the false "Codex burning fast. Switch to Grok" nudge: it demotes a pace deficit to on-pace when the provider hasn't burned inside BurnRecency.quietPeriod (30 min). That is right for the present-tense nudge, but the same gate was applied to every display surface too, so the bar, side-notch banner and rows, and the menu-bar chip dropped the deficit (and its ETA) as soon as the burn went quiet. A window shape can hold a deficit for days; the display was silently discarding it.

Solution

Split the two kinds of claim:

  • Window-shape displays now consume QuotaPace.pace(now:) directly — the quota bar, the side-notch banner, its window rows, and the menu-bar ETA chip keep a deficit's projected run-out whatever the last burn recency.
  • Present-tense claims stay gated on BurnRecency via QuotaPace.effective(lastBurn:now:) — the failover nudge, pace alerts, and the meterusage json report. The stale-nudge fix that motivated the gate is unchanged.

The lastBurn plumbing is removed from QuotaSection, SideNotchPanelView.entries, and PopoverRoot's quota card, since only the gated callers need burn evidence now.

Verification

  • swift build clean on macOS arm64, Swift 6.4 (one pre-existing unrelated warning).
  • swift test: 362/362 pass, including the new SideNotchPanelTests.testEntriesKeepWeeklyDeficitWithoutBurnEvidence, which asserts a 43% / 6d13h weekly headline with no local sessions reports isDeficit == true and carries an ETA.
  • Docs updated: docs/KB.md and README.md now describe displays as raw-pace and gating as limited to the nudge / alerts / report.

Model(s): deepseek-v4.1-flash
Harness: OpenCode

…claims

A quota window's shape (usedPercent ahead of the elapsed fraction) can
hold a pace deficit long after the burst that caused it. The burn-recency
gate shipped for the failover nudge was applied to every display too, so
a bar, banner, or menu-bar chip flipped to "on pace" and dropped its ETA
30 minutes after the last local session — a weekly at 43% with 6 days
left read as if nothing were ahead of pace.

Displays now consume QuotaPace.pace(now:) directly: the bar, side-notch
banner and rows, and the menu-bar chip keep a deficit's projected run-out
whatever the last burn recency. The present-tense claims stay gated on
BurnRecency via QuotaPace.effective(lastBurn:now:): the failover nudge,
pace alerts, and the meterusage json report, so the stale-nudge fix that
motivated the gate is unchanged.

Verification: swift build clean and swift test 362/362 on macOS arm64,
Swift 6.4, including the new SideNotchPanelRegressionTests case.
@pekth
pekth merged commit 540bb40 into main Sep 27, 2026
1 check passed
@pekth
pekth deleted the fix/pace-display-raw branch September 27, 2026 14:43
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