Skip to content

spec: persistent weekly USD spend status bar (#9965)#10224

Open
lonexreb wants to merge 4 commits intowarpdotdev:masterfrom
lonexreb:spec/9965-spend-status-bar
Open

spec: persistent weekly USD spend status bar (#9965)#10224
lonexreb wants to merge 4 commits intowarpdotdev:masterfrom
lonexreb:spec/9965-spend-status-bar

Conversation

@lonexreb
Copy link
Copy Markdown
Contributor

@lonexreb lonexreb commented May 6, 2026

Spec for #9965. Opt-in (agents.show_weekly_spend_status, default false) status-bar indicator showing rolling 7-day Agent spend. Click opens Settings → Billing. Hidden when billing data is unavailable (avoids misleading $0.00).

Closes (spec-only) #9965.

@cla-bot cla-bot Bot added the cla-signed label May 6, 2026
@github-actions github-actions Bot added the external-contributor Indicates that a PR has been opened by someone outside the Warp team. label May 6, 2026
@oz-for-oss
Copy link
Copy Markdown
Contributor

oz-for-oss Bot commented May 6, 2026

@lonexreb

I'm starting a first review of this spec-only pull request.

I completed the review and no human review was requested for this pull request.

Comment /oz-review on this pull request to retrigger a review (up to 3 times on the same pull request).

Powered by Oz

Copy link
Copy Markdown
Contributor

@oz-for-oss oz-for-oss Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overview

This spec proposes an opt-in status-bar indicator for rolling 7-day Agent spend, with click-through to Billing & Usage and no new telemetry. The direction is clear, but several behavior contracts are underspecified enough that implementations could show the wrong spend window or account context.

Concerns

  • Define which billing scope the indicator represents for users with personal and team/workspace billing contexts.
  • Align the user-facing label with the rolling-7-day requirement instead of using wording that implies a calendar week.
  • Specify the source-of-truth and stale/error behavior needed to satisfy the ≤2s post-turn update requirement.
  • Expand tests to cover the hidden-unavailable state, refresh timing, and tooltip totals.

Verdict

Found: 0 critical, 3 important, 1 suggestions

Request changes

Comment /oz-review on this pull request to retrigger a review (up to 3 times on the same pull request).

Powered by Oz

Comment thread specs/GH9965/SPEC.md
## Goal

Add an opt-in persistent indicator at the bottom-right of the Warp
window showing the user's running 7-day rolling USD spend on Agent
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ [IMPORTANT] Define whose spend is shown (personal, current team/workspace, or aggregate) and what happens when the active billing context changes; otherwise the implementation can surface the wrong budget.

Comment thread specs/GH9965/SPEC.md Outdated
- B1. New setting
`agents.show_weekly_spend_status: bool` (default `false`,
`SyncToCloud::Globally(RespectUserSyncSetting::Yes)`).
- B2. When ON, a status-bar item shows "$XX.XX this week" in the
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ [IMPORTANT] this week conflicts with the rolling-7d requirement and reads as calendar-week spend; choose one wording/window so the label, tooltip, and acceptance criteria cannot diverge.

Comment thread specs/GH9965/SPEC.md Outdated
same status-bar slot used by other agent indicators (verify slot
by grepping the existing status-bar render path).
- B3. The indicator updates on every agent turn finish AND on a
60-second timer (cheap; the spend value comes from the same
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ [IMPORTANT] same billing model that already polls is not precise enough for the ≤2s update contract; identify the model/API, whether the value is server-confirmed or locally estimated after turn finish, and how stale/error states are handled.

Comment thread specs/GH9965/SPEC.md
the existing `setting_changed` event with the boolean value.
- The indicator is read-only — it cannot send the value anywhere.

## Test plan
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 [SUGGESTION] Extend the test plan to cover billing-unavailable hiding, the ≤2s post-turn refresh, and the tooltip's rolling-7d/month totals; those are explicit acceptance criteria but currently untested.

@lonexreb
Copy link
Copy Markdown
Contributor Author

lonexreb commented May 8, 2026

Round-1 fixes for oz-for-oss review: (1) added Billing Scope subsection clarifying personal vs team/workspace selection via workspace selector; (2) renamed UI label from 'Weekly spend' to '7-day spend' (rolling) to match requirements; (3) added Data Source subsection specifying Billing & Usage backend, ≤2s TTL after turn completion, stale-on-error, hide-on-30s-failure; (4) added tests for hidden-unavailable, refresh timing, and tooltip total formatting.

@lonexreb
Copy link
Copy Markdown
Contributor Author

lonexreb commented May 8, 2026

/oz-review

@oz-for-oss
Copy link
Copy Markdown
Contributor

oz-for-oss Bot commented May 8, 2026

@lonexreb

I'm re-reviewing this spec-only pull request in response to a review request.

You can view the conversation on Warp.

I completed the review and no human review was requested for this pull request.

Comment /oz-review on this pull request to retrigger a review (up to 3 times on the same pull request).

Powered by Oz

Copy link
Copy Markdown
Contributor

@oz-for-oss oz-for-oss Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overview

The spec defines an opt-in status-bar indicator for rolling 7-day Agent spend using existing Billing & Usage data.

Concerns

  • The data-source section does not specify what existing Billing & Usage field/query provides rolling 7-day USD totals, so the “no new endpoint” constraint may not be implementable as written.
  • The hide-after-30s failure behavior conflicts with the 60-second refresh cadence unless the spec defines a separate retry/failure timer.
  • The status-bar placement requirement should name the concrete slot/ordering and collision behavior instead of leaving implementers to verify it ad hoc.

Verdict

Found: 0 critical, 2 important, 1 suggestions

Request changes

Comment /oz-review on this pull request to retrigger a review (up to 3 times on the same pull request).

Powered by Oz

Comment thread specs/GH9965/SPEC.md

## Data source

- **Source of truth.** The indicator reads from the same
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ [IMPORTANT] The source of truth is underspecified: the existing Billing & Usage model must provide a rolling 7-day USD total, but the spec only says to reuse the current endpoint. Specify the exact query/field and whether the client computes the 7-day sum or the backend returns it before locking V1 to “no new endpoint.”

Comment thread specs/GH9965/SPEC.md Outdated
key keeps the existing `weekly` token for backwards-compat with
any in-progress drafts; user-facing copy uses "7-day spend".
- B2. When ON, a status-bar item shows "$XX.XX · 7-day spend" in the
same status-bar slot used by other agent indicators (verify slot
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 [SUGGESTION] Replace “verify slot by grepping” with the concrete status-bar slot, ordering, and collision behavior with existing agent indicators so implementation and tests do not depend on ad hoc discovery.

Comment thread specs/GH9965/SPEC.md Outdated
annotation in the tooltip ("Updated Xs ago — couldn't refresh").
The chip itself does not change appearance; only the tooltip
surfaces the staleness so the layout doesn't shift.
- **Hide-on-prolonged-failure.** After 30 seconds of consecutive
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ [IMPORTANT] The 30-second hide rule is not implementable with only the 60-second refresh cadence. Define when the failure clock starts, whether failures trigger a shorter retry timer, and whether a single failed 60-second poll should hide before another retry occurs.

@lonexreb
Copy link
Copy Markdown
Contributor Author

lonexreb commented May 8, 2026

Round-2 fixes: (1) data source — added explicit dependency on usage_rolling_7d_usd field in existing BillingUsage response (additive, no new endpoint); flagged in Open Questions until backend confirms; (2) separated refresh vs failure-retry timers — refresh on 60s cadence + post-turn event; failures use exponential backoff 5/10/20/40/80s cap; ≥30s since success → 'stale' tooltip; ≥5 min consecutive failures → hide segment; reconciled the prior 30s-conflict; (3) status-bar placement now names concrete slot — same right-group as context-remaining indicator, ordering [7d spend][context%][others], with explicit collapse priority on width constraint.

@lonexreb
Copy link
Copy Markdown
Contributor Author

lonexreb commented May 8, 2026

/oz-review

@oz-for-oss
Copy link
Copy Markdown
Contributor

oz-for-oss Bot commented May 8, 2026

@lonexreb

I'm re-reviewing this spec-only pull request in response to a review request.

You can view the conversation on Warp.

I completed the review and no human review was requested for this pull request.

Comment /oz-review on this pull request to retrigger a review (up to 3 times on the same pull request).

Powered by Oz

Copy link
Copy Markdown
Contributor

@oz-for-oss oz-for-oss Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overview

Reviewed the spec-only PR for the opt-in 7-day Agent spend status-bar indicator. The spec covers the major product behavior, data dependency, failure handling, placement, and test plan.

Concerns

  • The multi-context behavior allows the previous billing scope's dollar value to remain visible until the next refresh tick after switching to another workspace/context. The spec should require immediate clearing or an immediate scoped refresh on every scope change so spend from one context is never displayed under another.
  • The tooltip test coverage does not verify all tooltip requirements from B4, specifically the current-month total and the View details → link behavior.

Security

  • Billing spend and workspace scope names are sensitive account data. The stale cross-scope display gap should be fixed before implementation to avoid exposing personal or team spend in the wrong context.

Verdict

Found: 0 critical, 1 important, 1 suggestions

Request changes

Comment /oz-review on this pull request to retrigger a review (up to 3 times on the same pull request).

Powered by Oz

Comment thread specs/GH9965/SPEC.md Outdated
Comment on lines +31 to +34
team/workspace billing accounts), the indicator follows the
workspace selector — the same selector that drives which workspace
the agent runs against. Switching the workspace selector switches
the indicator's scope on the next refresh tick.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ [IMPORTANT] [SECURITY] Do not leave the previous context's spend visible until the next refresh tick after switching workspaces. Require immediate clearing or an immediate scoped refresh on any billing-scope change so personal/team spend is never shown under the wrong active scope.

Comment thread specs/GH9965/SPEC.md Outdated
Comment on lines +257 to +259
- T7. Tooltip totals: tooltip renders the active scope name,
exact USD with 2 decimal places, and the "rolling 7 days"
caption.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 [SUGGESTION] B4 requires the tooltip to show the current-month total and a View details → link, but T7 only asserts the scope, rolling amount, and caption. Add coverage for the monthly total and link navigation so required tooltip behavior is not skipped.

@lonexreb
Copy link
Copy Markdown
Contributor Author

lonexreb commented May 8, 2026

Addressed both concerns from latest oz-for-oss review:

Cross-scope leak (important + security)
Added new 'Cross-scope leak prevention' subsection with 5 mandatory implementation rules:

  1. Synchronous clear — cache invalidation happens before the workspace-selector mutation commits to the UI tree, so no frame ever contains the old value alongside the new scope label.
  2. Scope-keyed cache — cache lookups returning a different-scope value are treated as misses, not displayed.
  3. Immediate scoped refresh — dispatched in the same code path as the synchronous clear, NOT waiting for the 60 s tick.
  4. In-flight fetch cancellation + scope-id verification on response handlers.
  5. Tooltip parity — scope label and dollar value read from the same cache entry.

Added new B6.1 specifying the loading-state placeholder (— · 7-day spend) used between the synchronous clear and the new scope's first successful fetch. Width-equivalent so the right cluster does not reflow. Existing 5-minute hide threshold absorbs prolonged loading.

New tests T9a (synchronous clear, asserted on the same UI commit), T9b (cross-scope cache miss), T9c (late-response discard with fault-injecting fake), and T9d (immediate scoped refresh). T9a is the explicit security-regression guard.

Tooltip B4 coverage (suggestion)
T7 expanded to cover ALL of B4's requirements:

  • (a) active scope name
  • (b) rolling 7-day USD with 2 decimals
  • (c) current-month total (the missing item) — sourced from existing BillingUsage.usage_current_month_usd, no client-side aggregation
  • (d) 'rolling 7 days' caption
  • (e) 'View details →' link (the missing item) — both click and keyboard activation dispatch OpenSettingsPage(BillingAndUsage). Asserted with click-handler unit test plus DOM snapshot verifying all 5 fields.

@lonexreb
Copy link
Copy Markdown
Contributor Author

lonexreb commented May 8, 2026

/oz-review

@oz-for-oss
Copy link
Copy Markdown
Contributor

oz-for-oss Bot commented May 8, 2026

@lonexreb

I'm re-reviewing this spec-only pull request in response to a review request.

You can view the conversation on Warp.

I completed the review and no human review was requested for this pull request.

Comment /oz-review on this pull request to retrigger a review (up to 3 times on the same pull request).

Powered by Oz

Copy link
Copy Markdown
Contributor

@oz-for-oss oz-for-oss Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overview

Reviewed the spec for an opt-in persistent 7-day Agent spend status-bar indicator. The spec covers the main UX, data-source, privacy, refresh, failure, and test-plan areas, and it includes a supplemental security-relevant treatment of cross-scope leakage.

Concerns

  • The scope-change state model is internally contradictory: some sections require immediate hiding during workspace switching/unresolved scope, while B6.1 requires a loading placeholder during scope change.
  • The retry timing test wording should distinguish retry intervals from absolute timestamps.

Security

  • The missing-field warning log should explicitly avoid logging raw billing payloads, dollar amounts, or scope names.

Verdict

Found: 1 critical, 0 important, 2 suggestions

Request changes

Comment /oz-review on this pull request to retrigger a review (up to 3 times on the same pull request).

Powered by Oz

Comment thread specs/GH9965/SPEC.md
successful fetch surfaces a "stale" tooltip annotation but keeps
the chip visible; ≥5 minutes of continuous failure hides the chip
entirely. See "Refresh vs failure-retry timers" below.
- B6.1. **Loading-state rendering during scope change.** Between the
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚨 [CRITICAL] Resolve the state-model contradiction: B6/A3a hide the chip immediately when scope is unresolved or workspace switching, but B6.1 requires rendering a loading placeholder during scope change. Specify one behavior for scope-change loading vs unresolved scope.

Comment thread specs/GH9965/SPEC.md
- T5c. Hidden-after-5min: with the same fault-injecting client, the
chip is hidden by t+5 min 5 s, and reappears within ≤2 s of the
next successful fetch.
- T5d. Backoff schedule: assert retry attempts occur at +5 s, +10 s,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 [SUGGESTION] Clarify whether +5, +10, +20, ... are retry intervals or absolute timestamps since the first failure; as written this can conflict with the exponential-backoff behavior above.

Comment thread specs/GH9965/SPEC.md
full label is rendered.
- T12. Field dependency: a fixture response missing
`usage_rolling_7d_usd` causes the chip to hide (treated as
unavailable) and surfaces a single warn-level log entry — does
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 [SUGGESTION] [SECURITY] Make the warn-level log explicitly redacted: log only that the required field is absent, not raw BillingUsage payloads, dollar amounts, or scope names.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cla-signed external-contributor Indicates that a PR has been opened by someone outside the Warp team.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant