10 — Projection and provider semantics
Traces projection-language provenance and records provider semantics that remain unresolved.
Summary
Public evidence supports fixed-window projection language for some providers, but several reset anchors and wire details remain unresolved.
Question and scope
(1) Do the projection phrases "Runs out in", "Projected empty in", "Lasts until reset" actually appear in CodexBar or OpenUsage UIs, per clean-room-allowed materials only (raw README bytes, GitHub release notes, screenshots, homepage prose, third-party reviews)? (2) Which Authorization header form (raw key vs Bearer <key>) do public third-party clients of api.z.ai/api/monitor/usage/quota/limit use, and is there evidence the Bearer form (jackin❯ form, crates/jackin-usage/src/usage/zai.rs:259) succeeds? (3) What public evidence exists of Amp's userDisplayBalanceInfo displayText / amp usage output after the 2026-07-18 Megawatt/Gigawatt subscription launch? (4) From primary docs: is the Codex 5h window rolling-from-first-message or fixed slots, and is the Grok weekly pool a fixed weekly reset — enough to validate a linear-from-window-start projection model?
This chapter informs jackin-desktop.
Method
Verification cutoff: 2026-07-24 Method: web (clean-room: READMEs/releases/screenshots only for CodexBar/OpenUsage), all fetched/verified live 2026-07-24. Raw-byte fetches (curl) used for READMEs, codexbar.app, learn.chatgpt.com pricing, docs.x.ai FAQ, ampcode.com/news — no summarizer mediation except where noted.
Findings
Q1 — Projection phrase provenance ("Runs out in" / "Projected empty in" / "Lasts until reset")
Verdict per phrase — all three originate in CodexBar; none appear in OpenUsage:
- "Runs out in" — CONFIRMED-VISIBLE in CodexBar. The codexbar.app homepage renders a demo popover whose text reads verbatim: "Codex · Updated just now · …@icloud.com · Plus · Session · 60% left · 2% in reserve · Resets in 2h 53m · Lasts until reset · Weekly · 73% left · On pace · Resets in 5d 4h · Runs out in 4d 21h · Limit Reset Credits · Next expires in 28d 2h · 1 reset available" — https://codexbar.app/ (raw curl fetch 2026-07-24; homepage prose = allowed material) (confidence: HIGH)
- "Lasts until reset" — CONFIRMED-VISIBLE in CodexBar, three independent allowed sources:
- codexbar.app homepage demo popover, twice (same fetch as above; second card: "Session · 89% left · 5% in reserve · Resets in 4h 12m · Lasts until reset · Weekly · 98% left · Resets in 6d 23h") — https://codexbar.app/ (confidence: HIGH)
- Release notes v0.36.0 (2026-06-15): "Weekly pace: suppress the “Lasts until reset” label when the projected run-out risk is nonzero (#1561)" — https://github.com/steipete/CodexBar/releases/tag/v0.36.0 (confidence: HIGH)
- Release notes v0.21 (2026-04-18): "OpenCode: enable weekly pace visualization … weekly bars show reserve percentage, expected-usage markers, and "Lasts until reset" details like Codex and Claude (#639)" — https://github.com/steipete/CodexBar/releases/tag/v0.21 (confidence: HIGH)
- Wording variant: the README screenshot (
docs/codexbar.png, raw byte fetch, image inspected) shows a Claude weekly bar captioned "Pace: Behind (-42%) · Lasts to reset" — "Lasts to reset", not "until" — https://raw.githubusercontent.com/steipete/CodexBar/main/docs/codexbar.png (confidence: HIGH that the screenshot shows this; the until/to drift is across versions/surfaces)
- "Projected empty" — CONFIRMED as a CodexBar label; the
"in <duration>"suffix is NOT verbatim in any allowed material. Release notes v0.27.0 (2026-05-18): "Claude: label five-hour session pace as "Projected empty" so it is not confused with the reset countdown (#960)" — https://github.com/steipete/CodexBar/releases/tag/v0.27.0 (confidence: HIGH for the label; LOW for the exact "Projected empty in Xh" rendering — no allowed source shows the full string) - CodexBar README contains none of the three phrases. Byte-level grep of https://raw.githubusercontent.com/steipete/CodexBar/main/README.md (19.9 KB, fetched 2026-07-24) finds zero hits for "Runs out", "Projected", or "Lasts". The homepage and release notes provide the relevant UI evidence instead. (confidence: HIGH)
- OpenUsage: all three phrases NOT FOUND in any allowed material. Byte-level grep of https://raw.githubusercontent.com/robinebers/openusage/main/README.md (9.5 KB): zero hits; the only pace mention is "Dashboard popover. Provider-grouped meters with live reset countdowns and pace indicators." Full release-notes corpus (gh API, all releases, 2 520 lines): zero exact-phrase hits; pace features are alerts, e.g. "Quota pace alerts — 3 triggers, launch-prime, per-app stacking (#786)" and "Show Codex usage percentages as reported while keeping near-empty pacing calm (#905)" — https://github.com/robinebers/openusage/releases (confidence: HIGH)
- OpenUsage's projection idiom is different: "~N% left at reset". The README screenshot (https://raw.githubusercontent.com/robinebers/openusage/main/assets/screenshot.jpg, image inspected) shows bounded quota cards with projected remaining-at-reset values rather than time-to-empty countdowns (confidence: HIGH). Other screenshot surfaces are outside jackin❯ limits-only scope.
- Cross-ref: CodexBar's homepage pace tokens ("2% in reserve", "On pace") match jackin❯
quota_pace_labelvocabulary exactly (crates/jackin-usage/src/usage/format.rs:176-191), and the homepage co-displays "On pace" with "Runs out in 4d 21h" on one line — relevant to the capsule TUI rule that suppresses "Lasts until reset" only when a "Runs out…" detail exists (crates/jackin-capsule/src/tui/components/dialog_widgets/usage.rs:754-764).
Q2 — z.ai quota endpoint Authorization header evidence (raw key vs Bearer)
GitHub code search for "api/monitor/usage/quota/limit" returns 1 396 files; 22 distinct non-banned client implementations were fetched raw (HEAD) and inspected. CodexBar and OpenUsage hits skipped unread (clean-room).
Raw key, no Bearer prefix — 10 clients (several with explicit "Bearer fails/differs" commentary):
- akitaonrails/ai-usagebar (Rust): "Note the auth-header quirk — the API key is passed as
Authorization: <KEY>WITHOUT theBearerprefix. SendingBearer …returns 401." — https://raw.githubusercontent.com/akitaonrails/ai-usagebar/HEAD/src/zai/fetch.rs (lines 1-3, 129) (confidence: HIGH that the client claims this; MED that it holds for all keys — contradicted below) - fabioluciano/tmux-powerkit: header doc
"Auth: Authorization: <ZAI_API_KEY> (raw key; Bearer fallback on 401)"; in-code comment "The Z.ai monitor endpoints accept the raw API key (matching the web console). Some keys require the Bearer form, so retry on a 401." — https://raw.githubusercontent.com/fabioluciano/tmux-powerkit/HEAD/src/plugins/aiquotas/zai.sh (confidence: HIGH) - farion1231/cc-switch:
.header("Authorization", api_key)with a comment stating that Zhipu does not add a Bearer prefix, lines 325 and 1218 — https://raw.githubusercontent.com/farion1231/cc-switch/HEAD/src-tauri/src/services/coding_plan.rs (confidence: HIGH) - can1357/oh-my-pi: "// Authorization header (no Bearer prefix)."
Authorization: token— https://raw.githubusercontent.com/can1357/oh-my-pi/HEAD/packages/ai/src/usage/zai.ts (lines 225-232) (confidence: HIGH) - juggler-ai/juggler (Go): "authenticates with the raw API key in the Authorization header (no "Bearer")" →
RawAuthorization: credential— https://raw.githubusercontent.com/juggler-ai/juggler/HEAD/cmd/juggler/providers/zai/usage.go (line 48) (confidence: HIGH) - onllm-dev/onWatch (Go): "Z.ai uses API key directly without Bearer prefix" — https://raw.githubusercontent.com/onllm-dev/onWatch/HEAD/internal/api/zai_client.go (lines 85-86) (confidence: HIGH)
- Cmochance/codex-app-transfer (Rust): documents
Authorization: <apiKey>with no Bearer prefix, matching the upstream monitor contract — https://raw.githubusercontent.com/Cmochance/codex-app-transfer/HEAD/src-tauri/src/glm_quota.rs (lines 4, 105–106) (confidence: HIGH) - opgginc/opencode-bar:
-H "Authorization: $API_KEY"for quota/limit, model-usage and tool-usage — https://raw.githubusercontent.com/opgginc/opencode-bar/HEAD/scripts/query-zai-coding-plan.sh (confidence: HIGH) - musistudio/claude-code-router (zhipu-cn preset,
open.bigmodel.cnhost): connectorauth: "provider-api-key-raw"— https://raw.githubusercontent.com/musistudio/claude-code-router/HEAD/packages/core/src/providers/presets/zhipu-cn-general/index.ts (confidence: HIGH) - Yeachan-Heo/oh-my-claudecode: quota/limit call sends
'Authorization': authTokenwhereauthToken = process.env.ANTHROPIC_AUTH_TOKEN— raw, no prefix (its other endpoint,coding_plan/remains, uses Bearer) — https://raw.githubusercontent.com/Yeachan-Heo/oh-my-claudecode/HEAD/src/hud/usage-api.ts (lines 710, 737 vs 1152) (confidence: HIGH) - Other raw-key clients: opencode-glm-quota, opencode-mystatus, and the cc-switch issue script (chapter 06).
Bearer <key> — 12 clients ship it as the only form:
- openclaw/openclaw — https://raw.githubusercontent.com/openclaw/openclaw/HEAD/src/infra/provider-usage.fetch.zai.ts (line 74)
- nguyenphutrong/quotio (packaged macOS app; GLM support since 2026-01, issue #77) — https://raw.githubusercontent.com/nguyenphutrong/quotio/HEAD/Quotio/Services/GLMQuotaFetcher.swift (line 136)
- tddworks/ClaudeBar — https://raw.githubusercontent.com/tddworks/ClaudeBar/HEAD/Sources/Infrastructure/Zai/ZaiUsageProbe.swift (line 98)
- junhoyeo/tokscale — https://raw.githubusercontent.com/junhoyeo/tokscale/HEAD/crates/tokscale-cli/src/commands/usage/zai.rs (lines 46, 59)
- tingly-dev/tingly-box —
fetchBearerJSON— https://raw.githubusercontent.com/tingly-dev/tingly-box/HEAD/ai/quota/fetcher/zai.go - tontinton/maki —
ResolvedAuth::bearer(...)used forQUOTA_LIMIT_URL— https://raw.githubusercontent.com/tontinton/maki/HEAD/maki-providers/src/providers/zai/mod.rs (lines 256, 336) - raycast/extensions agent-usage —
normalizeBearerTokenforce-prefixes "Bearer " — https://raw.githubusercontent.com/raycast/extensions/HEAD/extensions/agent-usage/src/agents/http.ts (lines 12-14, 136) - Curbob/LobsterBoard — https://raw.githubusercontent.com/Curbob/LobsterBoard/HEAD/server/ai-providers.cjs (lines 918-919)
- Javis603/token-monitor (line 274), AutoMaker-Org/automaker (line 257), talkcody/talkcody (line 103), openchamber/openchamber (line 43) — same Bearer form at the quota/limit URL.
Does Bearer succeed? Mixed but leaning yes-for-most-keys:
- Direct positive claim: tmux-powerkit's "Some keys require the Bearer form" (above) — i.e. the author observed Bearer being required, not merely tolerated, for some keys (confidence: MED — one author's comment).
- Circumstantial: 12 shipped tools (several packaged apps with real user bases) send Bearer-only; issue-tracker sweeps of quotio and tokscale show no z.ai/GLM auth-failure reports — https://github.com/nguyenphutrong/quotio/issues, https://github.com/junhoyeo/tokscale/issues (confidence: MED — absence of complaints, not proof)
- Direct negative claim: ai-usagebar's "Sending
Bearer …returns 401" (above). Unreconciled; acceptance may vary by key type, host (api.z.ai vs open.bigmodel.cn), or time (confidence: LOW either way as a universal rule). - Net for jackin❯ (
zai.rs:259, Bearer): the header form is not uniformly wrong; only an operator live probe of both forms settles it.
Q3 — Amp amp usage / userDisplayBalanceInfo output after the 2026-07-18 subscription launch
- Launch page verbatim (raw fetch): "Megawatt $20/month … 750 hours of small orbs · $20 included agent usage · Low & medium modes only · Use your ChatGPT sub for GPT-5.6 · Use your 𝕏 Premium+/SuperGrok sub"; "Gigawatt $200/month … 1,000 hours of large orbs · $200 included agent usage · All modes, including high & ultra"; "to use Amp beyond your subscription's included monthly limits, you need to link your ChatGPT subscription or add paid credits"; 2x first-month bonus for subscribing by July 19 — https://ampcode.com/news/subscriptions (confidence: HIGH)
- No public capture of a subscription-account
displayTextexists as of 2026-07-24. Strongest negative evidence: othavi0/omarchy-agent-bar PR #15 (2026-07-21, an actively maintained AmpdisplayTextparser) explicitly states that the real subscription-account usage format is unverified because the author lacked access to one, and adds a raw-lines fallback for unknown formats such asmegawattandgigawattsubscriptions — https://github.com/othavi0/omarchy-agent-bar/pull/15 (confidence: HIGH that this dated source had no publicly known format) - The same PR documents the current free-tier
displayTextshape post-launch: a "Free Tier" percentage line with "resets daily", a "Credits: $N.NN remaining" line with "replenishes automatically" wording; Amp Free resets at midnight UTC daily (rule extracted from the ampcode.com/settings production frontend,nextAmpFreeResetDate = Date.UTC(y, m, d+1), and empirically confirmed 2026-07-20: 90% → 100% at 00:02 UTC); and notesdisplayTextalready changed server-side without a CLI update on 2026-07-11 — https://github.com/othavi0/omarchy-agent-bar/pull/15 (confidence: MED — third-party but dated, specific, and self-verified) - A Megawatt subscriber's tooling notes (commit 2026-07-23) describe the post-launch accounting model seen through
amp threads usage: "Amp credit cost breakdown: 'free' = Amp Free daily credits + Megawatt included usage; 'paid' = individual credits. Megawatt ($20/month) includes $20 of agent usage."; and "When amp threads usage returns 'unavailable', the thread's tokens went through a linked third-party subscription rather than Amp credits" (ChatGPT Plus/Pro, X Premium+/SuperGrok routing) — https://github.com/ZoomC2021/agent-tools/blob/HEAD/scripts/amp-token-usage.py (notes array + lines 65-83; commit 2026-07-23 "subscription-eligibility billing routes") (confidence: MED — subscriber-authored, but describesamp threads usagecost buckets, not theamp usagedisplayText) - Official prose on the replenishment cycle: "You can add paid credits to keep using Amp until your subscription usage replenishes at the end of each monthly period" and "We give at least the subscription cost per month in agent usage" — https://ampcode.com/pricing (WebFetch-mediated, confidence: MED);
amp usageremains the documented check: "Buy credits and check your balance in user settings or workspace settings, or by runningamp usage" — https://ampcode.com/manual (WebFetch-mediated, confidence: MED) - Ecosystem parsers (raycast agent-usage
src/amp/parser.ts, The-Focus-AI/usage-monitorampcode.ts, tokscaleamp.rs) still target only "Free tier $X/$Y remaining" / "Individual credits: $N remaining" lines — zero public parser handles a Megawatt/Gigawatt plan line as of 2026-07-24 (raw HEAD fetches of all three) (confidence: HIGH). Consequence forcrates/jackin-usage/src/usage/amp.rs:345-372: no evidence its labels broke, and no evidence of the new plan-line shape either; chapter 04's operator-authenticated-run recommendation stands, now with the added question of whether "workspace credits" and "included agent usage" get distinct lines.
Q4 — Window boundary semantics: Codex 5h, Grok weekly
Codex (learn.chatgpt.com/docs/pricing — raw markdown fetch of the .md endpoint, 2026-07-24):
- The only statement about the 5h window is the repeated per-plan footnote, verbatim: "*The usage limits for local messages and cloud chats share a five-hour window. Additional weekly limits may apply." — the primary doc is silent on rolling vs fixed anchoring — https://learn.chatgpt.com/docs/pricing.md (confidence: HIGH that this is all it says)
- The word "rolling" appears once, and only for the adjacent Voice allowance: "ChatGPT Voice on desktop uses a separate, plan-dependent allowance measured in rolling five-hour windows." — same URL (confidence: HIGH for the quote; LOW as inference that the Codex message window is also "rolling")
- The client-observable model is linear-from-window-start-compatible: each window is one snapshot
{used_percent, limit_window_seconds, reset_after_seconds, reset_at}with a single discretereset_at(chapter 02), and field logs compute window start asresets_at − 300min— e.g. the user analysis in openai/codex issue #32607: "5h window starting 08:08:34 local (resets_at - 300min)" — https://github.com/openai/codex/issues/32607 (confidence: HIGH for the client-side model: a discrete window with one reset instant, not a continuously-sliding decay — a sliding window could not be represented by onereset_at) - Caveat for the projection model: that same issue (2026-07-12, ChatGPT Plus) reports a fresh window whose first server reading was already
used_percent=79%with no model activity after the reset — either carry-over accounting or a server bug; no maintainer reply — https://github.com/openai/codex/issues/32607 (confidence: LOW, single anecdote; means "usage=0 at window start" is not guaranteed) - help.openai.com articles that would state the anchor return HTTP 403 to non-browser fetches (retried 2026-07-24); third-party blogs contradict each other — extraheadroom.com says blocked "until the window rolls over" with no cited OpenAI source, others claim continuous token aging — leads only, not usable — https://extraheadroom.com/codex-usage-limits (confidence: n/a, discarded)
Grok (docs.x.ai/grok/faq — raw markdown fetch of the .md endpoint, 2026-07-24):
- Fixed weekly reset, verbatim: "The usage pool limit resets every week on a schedule shown in the Usage tab in Settings." and the usage view shows "Your weekly reset date and time." — a single known future reset instant, i.e. fixed weekly windows, not rolling-from-first-message — https://docs.x.ai/grok/faq.md (confidence: HIGH)
- Behavior at limit, verbatim: "When your weekly usage limit is met, paid features will pause until your weekly limit resets." Free-tier Chat/Voice limits are "separate from your weekly usage limit and resets on their own schedule." — same URL (confidence: HIGH)
- Corroborates chapter 05's RPC shape:
config.currentPeriod {type: USAGE_PERIOD_TYPE_WEEKLY, start, end}plushistoryof past periods = consecutive fixed slots; window start is available on the RPC path (periodstart), so linear-from-window-start projection is well-founded for Grok weekly; on the web-scrape path onlyreset_atis available and window start must be inferred asreset_at − 7d(valid under fixed slots) (confidence: HIGH for the model; the anchor — billing anniversary vs calendar day — is not stated in the FAQ)
Dead ends and contradictions
- Amp reset-model contradiction resolved for Amp Free: chapter
11 adds a redacted live
amp usagetranscript and merged regression fixture proving the current percentage-based"resets daily"line. The January hourly model is retired for current implementation. No exact reset timestamp is proven; paid subscription text remains open. - help.openai.com articles unfetchable even with browser UA (Intercom SPA returns a JS shell to curl; verified 2026-07-24) — the Pro-tier 5x/20x multiplier statement stays MED until an operator browser session opens article 9793128.
- Disallowed source deliberately not used: web search surfaced CodexBar repository content outside the allowed clean-room list; that text was discarded and the homepage/release-notes evidence used instead.
- Clean-room exclusions in the code review: hits inside steipete/CodexBar and robinebers/openusage were skipped unread; likewise CodexBar/OpenUsage source clones and forks surfaced by search (zippyg/AgentMeter, y0shua1ee/TokenBar, o1xhack/CodexBar-Mobile, kierr/CodexBar, cic8822-cpu/20260710 vendored copy, and the
plugins/<provider>/plugin.js-pattern OpenUsage-derived repos: cogine-ai/OpenUsageCN, Noisemaker111/openusage-mono, mhpsy/waybar-openusage, luisleineweber/usagebar, Halloweedev/usagepal, datell1357/AI-Usage-for-Windows, cbnsndwch/pacebar) — excluded as back-door source reads. - Phrase wording differs across CodexBar surfaces: release notes and homepage say "Lasts until reset"; the README screenshot shows "Lasts to reset". The README prose is silent, so homepage and release-note evidence governs the exact phrase.
- z.ai Bearer contradiction, sharpened not resolved: ai-usagebar asserts Bearer → 401; tmux-powerkit asserts some keys require Bearer; 12 shipped Bearer-only clients show no reported failures. Both camps are third-party comments; no primary doc exists (endpoint still officially undocumented).
- Amp:
sourcegraph/ampis not a searchable public repo (gh search 422); Releasebot's July digest of ampcode.com news contains no usage-display entries; quotio issue #206 ("AmpCode CLI Integration") predates subscriptions and concerns proxying, not displayText. - Codex: help.openai.com 403s; blogs (extraheadroom, sessionwatcher, inventivehq, knightli, ofox) give mutually contradictory rolling-window mechanics with zero primary citations — all dropped as evidence.
- Embedded-instruction flag: no adversarial embedded instructions found in any fetched page. The WebSearch/WebFetch harness responses append their own boilerplate meta-instructions ("You MUST include the sources above…") — tool boilerplate, not page content; ignored as instructions, noted here per mandate.
Implications for jackin❯
Keep projection phrases and provider semantics tied to their verified provenance; unresolved reset anchors and authorization variants must remain explicit unknowns.
Limitations and unknowns
- Whether CodexBar renders
"Projected empty in <duration>"(with countdown) — only the bare label "Projected empty" is confirmed by release notes; the homepage demo shows the Codex provider, not a Claude session in deficit. - Whether OpenUsage shows any time-to-empty phrase anywhere in-app — allowed materials show only "~N% left at reset" projections, "pace indicators", and "quota pace alerts"; the alert body text is unobservable without running the app.
- z.ai: whether Bearer acceptance varies by key type, host (api.z.ai vs open.bigmodel.cn), or deployment date — needs an operator probe of both header forms with a live coding-plan key.
- Amp subscription-account
displayText: no public capture exists as of 2026-07-24 (six days post-launch). Needs an operator-authenticatedamp usage(or a capturedPOST /api/internal?userDisplayBalanceInforesponse) under Megawatt, Gigawatt, linked-ChatGPT, and workspace-pooled accounts — including whether "Individual credits"/"Workspace credits" labels survived and how "$N included agent usage" renders. - Codex 5h/weekly window anchor: no primary statement whether the window opens at first message or on fixed slots, and whether usage is zeroed at
reset_at(issue #32607's 79%-at-start anomaly is unexplained). The projection model can rely onwindow_start = reset_at − limit_window_secondsas the client-observable convention, but not on usage-starts-at-zero. - Grok weekly reset anchor (subscription anniversary vs fixed weekday) and timezone of the "weekly reset date and time" — FAQ shows it per-account in Settings only.