Provider accounts P10: arb usage --by account / --account, arb quota --account, JSON + LiveView surfaces - #2000
Merged
Conversation
…--account, JSON + LiveView surfaces (bd-icwk2k) Usage.summarize(by: :provider_account) and its provider_account_id filter now read usage_events.provider_account_id directly instead of the pre-P9 workspace-join approximation, so probe/pre-flight rows (no workspace_id, but always an account) are included — closing the exact under-reporting bias bd-adyhvn measured. Quota.provider_spend/1 gets the same fix. arb usage and arb quota gain --account (CLI + REST), and the usage/quota web surfaces and workspace detail page expose the account dimension. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…-accounts-p10-arb-usage-by
- Quota.decorate_view/2's headline cost_usd now reads Quota.provider_spend/1 (account_id, direct usage_events.provider_account_id read) instead of summing the per-workspace breakdown, which excluded probe/preflight rows (workspace_id: nil) and reintroduced the bd-adyhvn under-reporting bias. provider_spend/1 now has a real caller. - Usage.summarize/1 accepts `--by account` / `by=account` as an alias for `provider_account` (docs/provider-account-design.md §8's spelling), alongside the existing `campaign` -> `epic` alias. - Updated moduledocs (Usage, UsageController, arb usage CLI help) and the provider_spend_test.exs claim that was false before this fix. - Tests: controller test asserting the account total includes a workspace-less preflight row; CLI test asserting the printed total isn't recomputed from the breakdown; CLI/controller tests for --by account / by=account; fixed quota_test.exs fixtures that predated P9's provider_account_id column. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
ryanrborn
deleted the
feature/1856-provider-accounts-p10-arb-usage-by
branch
September 23, 2026 13:45
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Provider accounts P10 (
docs/provider-account-design.md§8):arb usage --by account/--account,arb quota --account, and the account dimension on the JSON + LiveView surfaces.The real fix here is underneath the new flags. P7 had already added
Usage.summarize(by: :provider_account)and a:provider_account_idfilter, but sinceusage_eventshad no account column yet, both worked by joining throughworkspace_id— an approximation that silently dropped probe/pre-flight rows, which carry noworkspace_idbut always an account (they're issued as a credential). That's exactly the under-reporting bias bd-adyhvn measured.Quota.provider_spend/1had the same gap, since it summedworkspace_spend/1per workspace.Now that P9 has landed
usage_events.provider_account_id(a real column, backfilled and written on every insert), both are rewired to read/filter that column directly — so probe/pre-flight spend is included, and a chunk of now-dead approximation code (account_index/1,provider_codes/1,default_provider_codes/2,exact_account_groups/3) comes out with it.On top of that:
arb usage --by provider_account/--account <id|provider:slug|slug>(mirrors--workspace), same onarb usage events.arb quota --account <ref>goes straight to an account (no workspace lookup), reusing the account-total + per-workspace-breakdown machinery P5/P6 already built.GET /api/usageandGET /api/usage/eventsgainaccount;GET /api/quotagains?account=./usageLiveView gains a "By account" tab (account slug, not raw id).Test plan
Arbiter.Usage.ProviderAccountRollupTest— probe/pre-flight rows (noworkspace_id) are included inby: :provider_accountand theprovider_account_idfilter, across-account isolation,(none)sentinel.Arbiter.Quota.ProviderSpendTest—provider_spend/1includes probe rows, cross-account isolation,nilaccount spends nothing.Arbiter.Quota.AccountWideHoldTestfixtures to stampprovider_account_idthe way the realArbiter.Workerwrite path does (they previously relied on the read-time workspace-join fallback this PR removes); added a probe-row case.Arbiter.Workflows.DispatchQueueTest's overage-alert test, which had the same gap (seed_usage/2wrote noprovider_account_id, soOverage.windowed_spend/2— which already read the account column via P7 — silently stopped seeing the seeded spend once the filter became exact).ArbiterWeb.Api.UsageControllerTest/QuotaControllerTest— new?account=/by=provider_accountcoverage, including unknown/ambiguous account refs (400/404/422).ArbiterCli.Cmd.UsageTest/QuotaTest—--accountforwarded as a query param,--accounttakes priority over--workspaceforarb quota.ArbiterWeb.UsageLiveTest— "By account" tab renders bars with the account slug.ArbiterWeb.WorkspaceLiveTest— provider account label shown/not-shown on the agent pool.apps/arbiter(7262 tests),apps/arbiter_web(1687 tests),apps/arbiter_cli(883 tests) — all green.mix precommit(compile --warnings-as-errors, format, test) clean.References
bd-icwk2k. Depends on P9 (bd-al9qqe) and P5 (bd-3yokey), both already merged. Part of bd-7df8nh / #1593.
Closes #1856