Skip to content

Fix visual settings refresh#1996

Merged
steipete merged 3 commits into
steipete:mainfrom
Zihao-Qi:codex/fix-visual-settings-refresh
Jul 9, 2026
Merged

Fix visual settings refresh#1996
steipete merged 3 commits into
steipete:mainfrom
Zihao-Qi:codex/fix-visual-settings-refresh

Conversation

@Zihao-Qi

@Zihao-Qi Zihao-Qi commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

Summary

Fixes #1994 by separating visual/display settings changes from background provider refresh settings.

  • Adds a dedicated background-work settings revision so visual-only settings no longer trigger provider quota refreshes.
  • Keeps real background/data-affecting settings wired to refresh behavior.
  • Persists cached widget snapshots only when widget-relevant display settings change, not on unrelated config edits.
  • Adds focused coverage for display-only settings, provider refresh avoidance, and widget snapshot behavior.

Why

Changing visual settings such as usage bar display mode, icon layout, loading pattern, or other menu presentation options should update cached UI only. Previously, those changes were observed by the background refresh path and could trigger provider quota probes, which risks hitting provider rate limits while the user is only adjusting display preferences.

This keeps quota refreshes scoped to settings that actually affect provider data, credentials, background checks, alerts, cost/history processing, or account layout behavior.

Behavior Proof

I avoided live provider probes and real Keychain reads, per the repository guidance against validation that can display credential or Keychain prompts. The proof below uses redacted/no-credential test seams that would record provider refreshes if the settings observer triggered them.

Display-only settings do not refresh providers:

  • UsageStoreCoverageTests.display only settings do not invoke provider refresh while background work is active installs _test_providerRefreshOverride to record every provider refresh request.
  • The test observes backgroundWorkSettingsObservationToken with the same callback shape used by the background settings watcher: on change, call refreshForSettingsChange().
  • It changes only visual/display settings: usageBarsShowUsed, mergeIcons, randomBlinkEnabled, and debugLoadingPattern.
  • After observation delivery, the recorded provider refresh list remains empty.
  • The same test directly calls refreshForSettingsChange() and confirms .codex is recorded, proving the override would catch a provider refresh if one occurred.

Provider-affecting settings still refresh:

  • UsageStoreCoverageTests.background work settings observation ignores display only settings churn first confirms the same display-only setting changes do not fire the background observer.
  • It then changes statusChecksEnabled and observes the background-work token firing.
  • It re-observes and changes multiAccountMenuLayout, then confirms the token fires again.

Cached UI/widget state updates without unrelated config churn:

  • StatusItemIconObservationSignatureTests.display settings persist cached widget snapshot toggles usageBarsShowUsed, waits for widgetSnapshotPersistTask, and confirms the cached widget snapshot records usageBarsShowUsed == true with a Codex entry.
  • StatusItemIconObservationSignatureTests.config only settings do not persist cached widget snapshot mutates zaiAPIToken and confirms no widget snapshot is persisted for that unrelated config-only change.

Validation

  • Manually checked display/settings changes.
  • swift test --filter UsageStoreCoverageTests
  • swift test --filter StatusItemIconObservationSignatureTests
  • swift test --filter UsageStoreWidgetSnapshotTests
  • make check
  • make test

@clawsweeper

clawsweeper Bot commented Jul 8, 2026

Copy link
Copy Markdown

Codex review: needs real behavior proof before merge. Reviewed July 8, 2026, 11:25 PM ET / 03:25 UTC.

Summary
The branch replaces direct background observation of individual visual settings with a background-work settings revision, adds widget snapshot persistence for display-setting changes, adds focused tests, and includes a changelog note.

Reproducibility: yes. Source inspection on current main shows visual settings are observed by UsageStore background work and the on-change path calls refreshForSettingsChange; I avoided live provider validation because AGENTS.md warns against provider and Keychain prompting checks.

Review metrics: 1 noteworthy metric.

  • Diff surface: 8 files changed, +185/-22. The PR spans settings observation, widget snapshot persistence, tests, and release notes, so the refresh-boundary scope matters before merge.

Root-cause cluster
Relationship: fixed_by_candidate
Canonical: #1994
Summary: This PR is the candidate fix for the linked issue about visual/display settings triggering provider quota refreshes.

Members:

Proposal only: this assessment does not dispatch repair, suppress jobs, mutate sibling items, close, or merge anything.

Merge readiness
Overall: 🧂 unranked krab
Proof: 🧂 unranked krab
Patch quality: 🐚 platinum hermit
Result: blocked until real behavior proof is added.

Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch.

Rank-up moves:

  • [P1] Add inspectable redacted proof from a real setup showing display-only settings do not refresh providers and provider-affecting settings still refresh.
  • [P1] Let the in-progress CI jobs finish on the latest head before merge.

Proof guidance:

  • [P1] Needs real behavior proof before merge: Missing: the body lists tests and a manual-check claim but no inspectable redacted terminal output, logs, screenshot, recording, or artifact from a real setup; after adding proof with private data redacted, updating the PR body should trigger re-review, or a maintainer can comment @clawsweeper re-review. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.

Risk before merge

  • [P1] The external PR still lacks inspectable after-fix proof from a real setup, so the real-behavior proof gate remains unmet.
  • [P1] The setter-based refresh split moves responsibility for provider refresh triggers into individual settings setters; a missed data-affecting provider/auth setting could leave state stale until a scheduled or manual refresh.

Maintainer options:

  1. Require proof of the refresh boundary (recommended)
    Merge only after redacted proof and completed checks confirm display-only settings skip provider refresh while data-affecting provider/auth settings still trigger it.
  2. Accept the setter-boundary risk
    A maintainer could accept the current setter audit as sufficient, but that owns the risk of a missed provider-affecting setting.

Next step before merge

  • [P1] The remaining action is contributor-supplied real-behavior proof and normal PR validation, not a narrow code repair ClawSweeper should attempt.

Security
Cleared: Cleared: the diff changes in-app Swift settings observation, widget snapshot persistence, tests, and a changelog note without adding third-party code, CI, dependency, secret, or supply-chain changes.

Review details

Best possible solution:

Land the refresh-boundary split once redacted real-behavior proof and normal validation show visual-only settings repaint cached UI while provider, auth, account, refresh, alert, history, and optional-usage settings still refresh data.

Do we have a high-confidence way to reproduce the issue?

Yes. Source inspection on current main shows visual settings are observed by UsageStore background work and the on-change path calls refreshForSettingsChange; I avoided live provider validation because AGENTS.md warns against provider and Keychain prompting checks.

Is this the best way to solve the issue?

Yes. The revision-counter split is a narrow maintainable fix, and the latest head treats optional usage as data-affecting because it changes ProviderFetchContext.includeOptionalUsage; the remaining blocker is proof, not a code finding.

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning high; reviewed against aa401f1d8b74.

Label changes

Label justifications:

  • P2: This is a normal-priority settings refresh bug with limited blast radius and no evidence of data loss, security bypass, crash loop, or core outage.
  • merge-risk: 🚨 auth-provider: The diff changes which settings trigger provider refresh, so a misclassified provider/auth setting could refresh unnecessarily or leave provider state stale.
  • rating: 🧂 unranked krab: Overall readiness is 🧂 unranked krab; proof is 🧂 unranked krab and patch quality is 🐚 platinum hermit.
  • status: 📣 needs proof: The PR needs real behavior proof before ClawSweeper can clear the contributor ask. Needs real behavior proof before merge: Missing: the body lists tests and a manual-check claim but no inspectable redacted terminal output, logs, screenshot, recording, or artifact from a real setup; after adding proof with private data redacted, updating the PR body should trigger re-review, or a maintainer can comment @clawsweeper re-review. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.
Evidence reviewed

What I checked:

  • Repository policy read: AGENTS.md was read fully; its guidance against live provider probes and Keychain-prompting validation affected this review, so I used source and test-seam inspection instead of running live provider checks. (AGENTS.md:1, aa401f1d8b74)
  • Current-main source reproduction: Current main observes display settings such as usageBarsShowUsed in backgroundWorkSettingsObservationToken, and the on-change path calls refreshForSettingsChange, which is the provider refresh path. (Sources/CodexBar/UsageStore.swift:77, aa401f1d8b74)
  • PR refresh-boundary implementation: At the PR head, backgroundWorkSettingsObservationToken observes backgroundWorkSettingsRevision and configRevision instead of directly reading visual settings and every provider observeSettings hook. (Sources/CodexBar/UsageStore.swift:77, 786b4bc66b4c)
  • Optional usage is data-affecting: The latest head keeps showOptionalCreditsAndExtraUsage on the background-work revision path and documents that it controls ProviderFetchContext.includeOptionalUsage, which is also visible in current ProviderRegistry and token-account fetch context construction. (Sources/CodexBar/SettingsStore+Defaults.swift:489, 786b4bc66b4c)
  • Refresh-boundary tests: The PR adds tests that display-only settings do not fire background observation or provider refresh, while statusChecksEnabled, multiAccountMenuLayout, and showOptionalCreditsAndExtraUsage still fire the background observer. (Tests/CodexBarTests/UsageStoreCoverageTests.swift:626, 786b4bc66b4c)
  • Widget snapshot path: The PR adds a widget display-settings signature and tests that usageBarsShowUsed persists a cached widget snapshot while a config-only token change does not. (Sources/CodexBar/StatusItemController+WidgetSnapshot.swift:2, 786b4bc66b4c)

Likely related people:

  • steipete: Current blame for UsageStore settings observation, SettingsStore defaults, and StatusItemController settings handling points to Peter Steinberger, and Peter also added the latest hardening commits on this PR branch. (role: feature-history owner and recent area contributor; confidence: high; commits: a83a83fa4131, 8106e7d3cc31, 729196a0a072; files: Sources/CodexBar/UsageStore.swift, Sources/CodexBar/SettingsStore+Defaults.swift, Sources/CodexBar/StatusItemController.swift)
  • Floh: History shows a focused change making usageBarsShowUsed participate in smart menu updates, adjacent to the display refresh boundary changed here. (role: adjacent display-refresh contributor; confidence: medium; commits: 0521c53da80e; files: Sources/CodexBar/StatusItemController.swift)
  • Joshua Vial: Recent history includes a menu-open refresh delay fix touching UsageStore and refresh timing near the cache-versus-provider-fetch boundary. (role: recent menu refresh contributor; confidence: medium; commits: 3c2d53de57c1; files: Sources/CodexBar/UsageStore.swift, Sources/CodexBar/UsageStore+Refresh.swift, Sources/CodexBar/StatusItemController+MenuInteractionRefresh.swift)
What the crustacean ranks mean
  • 🦀 challenger crab: rare, exceptional readiness with strong proof, clean implementation, and convincing validation.
  • 🦞 diamond lobster: very strong readiness with only minor maintainer review expected.
  • 🐚 platinum hermit: good normal PR, likely mergeable with ordinary maintainer review.
  • 🦐 gold shrimp: useful signal, but proof or patch confidence is still limited.
  • 🦪 silver shellfish: thin signal; proof, validation, or implementation needs work.
  • 🧂 unranked krab: not merge-ready because proof is missing/unusable or there are serious correctness or safety concerns.
  • 🌊 off-meta tidepool: rating does not apply to this item.

Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics.

How this review workflow works
  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.
Review history (5 earlier review cycles)
  • reviewed 2026-07-08T14:05:23.090Z sha ced57db :: needs real behavior proof before merge. :: none
  • reviewed 2026-07-08T14:11:59.730Z sha ced57db :: needs real behavior proof before merge. :: none
  • reviewed 2026-07-08T14:37:06.049Z sha ced57db :: needs real behavior proof before merge. :: none
  • reviewed 2026-07-08T14:44:14.097Z sha ced57db :: needs real behavior proof before merge. :: [P2] Keep optional usage display out of background refresh
  • reviewed 2026-07-08T16:55:09.330Z sha ced57db :: needs real behavior proof before merge. :: [P2] Keep optional usage display out of background refresh

@Zihao-Qi Zihao-Qi marked this pull request as ready for review July 8, 2026 14:01
@clawsweeper clawsweeper Bot added rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. P2 Normal priority bug or improvement with limited blast radius. merge-risk: 🚨 auth-provider 🚨 Merging this PR could break OAuth, tokens, provider routing, model choice, or credentials. labels Jul 8, 2026
@Zihao-Qi

Zihao-Qi commented Jul 8, 2026

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

@clawsweeper

clawsweeper Bot commented Jul 8, 2026

Copy link
Copy Markdown

🦞🧹
ClawSweeper re-review requested.

I asked ClawSweeper to review this item again.
Action: item re-review queued (workflow sweep.yml, event repository_dispatch).
Result: the existing ClawSweeper review comment will be edited in place when the review finishes.

@steipete steipete merged commit 5c6e6f9 into steipete:main Jul 9, 2026
10 checks passed
@steipete

steipete commented Jul 9, 2026

Copy link
Copy Markdown
Owner

Landed as 5c6e6f9. Thanks @Zihao-Qi!

Maintainer verification:

  • swift test --filter UsageStoreCoverageTests — 27 passed
  • swift test --filter 'StatusItemIconObservationSignatureTests|UsageStoreWidgetSnapshotTests' — 22 passed
  • swift test --filter StatusItemIconObservationSignatureTests — 14 passed after fixture hardening
  • make check — repository checks passed; SwiftFormat clean; SwiftLint reported 0 violations
  • make test — all 49 shards passed
  • Exact-head CI for 786b4bc66b4c79d2d6e941bd5636b4cf222292c0 — lint, Linux builds/tests, four macOS shards, aggregate gate, and GitGuardian all passed: https://github.com/steipete/CodexBar/actions/runs/28991588603
  • Maintainer autoreview — no accepted or actionable findings

Review note: showOptionalCreditsAndExtraUsage intentionally remains refresh-triggering because it controls ProviderFetchContext.includeOptionalUsage; the final patch adds a regression assertion and source comment for that invariant. No live provider or Keychain probe was run, per repository safety policy; deterministic observer/provider-refresh and widget-snapshot seams cover the behavior without account access.

jychp added a commit to jychp/CodexBar that referenced this pull request Jul 9, 2026
Address the remaining P2 review points on steipete#2001:

- Quota hooks no longer depend on notification preferences. Quota-warning and
  session-depletion detection now runs when either notifications OR a matching
  hook rule is enabled, and only the notification post is gated on the
  notification settings. Gating is keyed on hasQuotaHookRule(event:provider:),
  so behavior is byte-identical for users without a configured quota hook.
- Editing hook rules no longer triggers a provider refresh. Hook config writes
  go through a dedicated path that persists and bumps a separate hooksRevision
  for the settings pane, without bumping configRevision (which drives the
  background refresh introduced by steipete#1996).

Bundles the per-refresh quota-warning constants into QuotaWarningTransitionContext
to keep the transition helper within the parameter-count limit.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

merge-risk: 🚨 auth-provider 🚨 Merging this PR could break OAuth, tokens, provider routing, model choice, or credentials. P2 Normal priority bug or improvement with limited blast radius. rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Changing visual/display settings refreshes provider quotas and can hit provider refresh rate limits

2 participants