chore: import upstream snapshot with attribution
This commit is contained in:
@@ -0,0 +1,55 @@
|
||||
---
|
||||
summary: "Refresh cadence, background updates, and error handling."
|
||||
read_when:
|
||||
- Changing refresh cadence, background tasks, or refresh triggers
|
||||
- Investigating refresh timing or stale data behavior
|
||||
---
|
||||
|
||||
# Refresh loop
|
||||
|
||||
## Cadence
|
||||
- `RefreshFrequency`: Manual, 1m, 2m, 5m (default), 15m, 30m, Adaptive.
|
||||
- Stored in `UserDefaults` via `SettingsStore`. The default stays 5m for new and existing users; nothing
|
||||
auto-migrates an existing fixed selection to Adaptive.
|
||||
|
||||
## Behavior
|
||||
- Background refresh runs off-main and updates `UsageStore` (usage + credits + optional web scrape).
|
||||
- Manual “Refresh now” always available in the menu.
|
||||
- Stale/error states dim the icon and surface status in-menu.
|
||||
- Optional provider-storage scans run only when “Show provider storage usage” is enabled. They are scheduled in the
|
||||
background, coalesced/throttled during automatic refreshes, and forced by manual refresh without blocking the usage
|
||||
refresh path.
|
||||
|
||||
## Adaptive mode
|
||||
- `AdaptiveRefreshPolicy` (`Sources/CodexBar/AdaptiveRefreshPolicy.swift`) is a pure function of an `Input`
|
||||
(current time, last menu-open time, Low Power Mode, thermal state) that returns the next delay and a
|
||||
stable `Reason`. It reads no clock and no `ProcessInfo` state itself — `UsageStore.startTimer()` gathers
|
||||
those impure signals immediately before each tick.
|
||||
- Policy table, first match wins:
|
||||
|
||||
| Condition | Delay | Reason |
|
||||
|---|---:|---|
|
||||
| Low Power Mode enabled, or thermal state `.serious`/`.critical` | 30 min | `constrained` |
|
||||
| Menu opened within the last 5 min (including future/clock-adjusted timestamps) | 2 min | `recentInteraction` |
|
||||
| Menu opened 5 min–1 h ago | 5 min | `warm` |
|
||||
| Menu opened 1–4 h ago | 15 min | `idle` |
|
||||
| No recorded menu open, or opened 4+ h ago | 30 min | `longIdle` |
|
||||
|
||||
- Every decision falls in the 2–30 min range by construction. Deliberately excludes quota, latency, error,
|
||||
account, and time-of-day signals.
|
||||
- `UsageStore` tracks `lastMenuOpenAt` in memory only (never persisted; resets on launch). `noteMenuOpened(at:)`
|
||||
is called from `StatusItemController.menuWillOpen(_:)`. A menu open can bring a pending adaptive tick
|
||||
forward to the recent-interaction cadence, but never postpones an earlier tick or refreshes synchronously.
|
||||
- Each adaptive tick recomputes the delay after the previous refresh completes, sleeps, then calls the same
|
||||
`UsageStore.refresh()` used by fixed-interval mode, so the existing `isRefreshing` coalescing guard still
|
||||
applies — only one provider-batch refresh runs at a time regardless of cadence mode.
|
||||
- Selected delay and reason are logged (e.g. `reason=warm delay=300s` in the `adaptive-refresh` category) through
|
||||
the existing local logger; never provider identity, account, email, workspace, path, credentials, or response data.
|
||||
- Interval-derived heuristics (reset-boundary refresh, OpenAI web staleness, persistent-CLI-session idle windows)
|
||||
read `UsageStore.normalRefreshIntervalForHeuristics()`, which resolves adaptive mode to the current decision's
|
||||
delay — they stay active in adaptive mode rather than degrading to manual, whose interval is nil.
|
||||
|
||||
## Optional future
|
||||
- Auto-seed a log if none exists via `codex exec --skip-git-repo-check --json "ping"` (currently not executed).
|
||||
|
||||
See also: `docs/status.md`, `docs/ui.md`.
|
||||
Reference in New Issue
Block a user