fix(server): usage counts every configured provider instance - #8470
fix(server): usage counts every configured provider instance#8470DonovanMontoya wants to merge 9 commits into
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (6)
Included review availability: Your plan provides up to 10 included reviews per hour; 9 remain after this review. 📝 WalkthroughWalkthroughThe usage scan now resolves transcript homes from all configured provider instances. It supports custom Claude and Codex homes, preserves Grok resolution, deduplicates paths, and changes usage merging to claim overlapping provider sources by environment. ChangesUsage discovery and merge
Estimated code review effort: 4 (Complex) | ~45 minutes Merge Risk: ⚪ Minimal · up to The PR expands usage totals to include configured provider instances and deduplicates shared homes; no actionable merge-blocking risk remains beyond normal checks and review. Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
Full details: Description checkExplanation The description explains the problem, implementation, scope, tests, screenshots, and issue reference. It does not use the template headings or include the checklist, but it provides the required information in equivalent sections. Full details: Linked Issues checkExplanation The changes satisfy issue Full details: Out of Scope Changes checkExplanation The Claude support, shared home resolver, Grok refactor, merge changes, tests, and documentation directly support the broader provider-instance usage-scanning objective. No unrelated product-area changes are evident. Full details: Docstring CoverageExplanation Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 4 functions across 5 files. (1 skipped: 1 unsupported.) ✨ Finishing Touches🧪 Generate unit tests (beta)
Warning Your free Security trial is over. An organization admin can activate Security or dismiss this notice. Comment |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 0f40cc244f
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
ApprovabilityVerdict: Not approved Macroscope's review found this PR not approvable — This change materially alters production usage and estimated-cost accounting across provider instances and environments, including source ownership and compatibility handling for older summaries. Its cross-cutting runtime and contract effects warrant human review. You can add or adjust custom eligibility rules. Learn more. |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Want fixes drafted automatically? Bugbot Autofix can create code changes for findings. A team admin can enable Autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 2e02d6c. Configure here.
|
Thanks for picking this up — this is the most complete take on the scanning half that I've seen. Would you consider also attributing each bucket to the home it came from, so the Usage page renders one series per instance rather than pooling everything into a single "Claude" line? That's what #6920 is asking for: with several accounts configured (work vs. personal), a single combined total doesn't answer the question people actually have, which is what each account is spending against its own limit. #5738 is a worked example of that half — Understood if you'd rather keep this PR to the scan fix and leave the split for a follow-up — in that case it would help a lot if |
|
Hi @Jardo-51 Thanks for laying this out and for pointing to the existing #5806 → #5738 split. I agree that separate, labelled usage per instance is the more useful end state for people with work and personal accounts, but I think I like keeping #8470 focused on the scanning/correctness half so it can land without expanding into contract and client changes. I considered retaining an instance ID/display name on each resolved home now, but multiple instances and Codex shadow overlays can resolve to the same transcript directory. So I think keeping individual attribution as a follow-up gives this fix a better chance of merging. I did adopt the effective-environment behavior documented in #5806: Usage now inherits server-level That leaves #6920 as a clean follow-up based on the attribution work in #5738, rather than partially introducing those semantics here. |
|
Cant wait for this to be merged. Thank you for your effort! |
|
Note 🤖 GPT-6 Astra (preview) responding on behalf of Theo This note is part of an automated cleanup pass. Carryover from #5806 at 0ed33dde6e: canonicalize transcript directories with |
|
Addressed the carryover in 62ef044:
Added coverage for symlink aliases plus a missing home, source-indexed aggregation, the two-environment subset case, and the three-environment intersecting case from the review. Focused tests pass (43), affected server/contracts/shared/web/mobile typechecks pass, and focused lint passes. |
The usage scan resolved one transcript directory per provider from the legacy single-instance settings, so Claude and Codex instances configured through providerInstances (separate accounts with their own config directories) reported zero usage. Enumerate instance homes with the same settings merge the runtime registry uses, honor CLAUDE_CONFIG_DIR for homeless instances, and dedupe instances that share a directory.
Environment-provided homes (CLAUDE_CONFIG_DIR, CODEX_HOME) reach the spawned CLI verbatim, so usage no longer tilde-expands them and only honors absolute values; relative ones depend on each workspace's cwd and have no single scan directory. Codex instances isolated purely through an instance-level CODEX_HOME are now scanned too, matching the runtime's config-over-environment precedence.
With a shadow overlay the runtime overrides CODEX_HOME and the shadow's sessions symlink back to the shared home, so an instance-level CODEX_HOME must only decide the scan directory when the layout yields no effective home.
…ment With multiple homes per provider, an environment's buckets aggregate every home it scans, but the cross-environment merge claimed ownership per directory. An environment owning only part of another's home set still contributed its full per-provider aggregate, double counting the shared directories. Claims are now the environment's whole fingerprint set for a provider, with larger sets winning so a superset environment keeps its unique homes.
Usage scans ignored server-level CODEX_HOME and CLAUDE_CONFIG_DIR even though provider processes inherit them. Resolve usage homes from the same effective environment while preserving configured-path precedence.\n\nEnvironment precedence informed by pingdotgg#5806.
Canonicalize resolved transcript directories before local deduplication while retaining unresolved paths as missing sources. Associate each usage bucket with its source so cross-environment merging drops only duplicate directories and keeps every unique home's usage.
Limit the multi-instance history claim to Claude Code and Codex, and document that Grok Build reads the server's single Grok home.
cc8777d to
8ec5450
Compare
Bugbot is paused — on-demand spend limit reachedBugbot uses usage-based billing for this team and has hit its on-demand spend limit. A team admin can raise the spend limit in the Cursor dashboard, or wait for the next billing cycle to continue. |

Problem
The Usage page resolves one transcript directory per provider from the legacy single-instance settings (
settings.providers.claudeAgent/settings.providers.codex). Anyone running multiple instances of a provider throughproviderInstances— e.g. separate Claude accounts isolated in their own config directories — silently gets zero usage from every instance except the default one.Fixes #5805.
Fix
A new
usageProviderHomesmodule enumerates transcript homes from the same settings merge the runtime registry uses (deriveProviderInstanceConfigMap), so the scan sees exactly the set of instances that can run agents:homePathwins; otherwise aCLAUDE_CONFIG_DIRconfigured on the instance's environment; otherwise the default home. The server's own ambient environment is deliberately not consulted, so what usage scans is determined by settings alone.sessionsdirectory via the existingresolveCodexHomeLayout.Each directory reports as its own fingerprinted entry in
sources, which the existing cross-environment merge inusageMergealready dedupes per directory — no contract or client changes needed. Grok'sGROK_HOMEresolution moved into the new module unchanged.Covered by focused tests (multiple instances via
homePathand via instance env var, same-home collapsing, bad-config skipping, ambient-env isolation, legacy settings), plus the existing usage suite.docs/user/usage.mdnow mentions multi-instance coverage.Before / after
Same machine, two configured Claude instances (
~/.claude+ a second account in~/.claude-max), 30-day window.Before — only the default
~/.claudeis scanned (74 sessions, $485.18):After — both instance homes are scanned (88 sessions, $722.05):
Relation to existing PRs
#5806, #6312, #6596, #6603, and #7419 target the same bug. This version differs by deriving the instance set from
deriveProviderInstanceConfigMaprather than re-implementing instance enumeration, so usage can never disagree with the registry about which instances exist; it also handles env-var-isolated instances and same-home dedupe while keeping the diff to the usage module plus docs (no contract, wire, or client changes). Happy to close this one if the maintainers prefer any of the earlier takes.Authored with Claude (Fable 5) running in Claude Code.
Note
Medium Risk
Raises usage contract merge floor to v6 (older servers show partial coverage) and changes multi-environment dedupe semantics; incorrect home resolution could still miss or double-count transcripts.
Overview
Usage scanning now walks every Claude and Codex home from
providerInstances(via newresolveUsageProviderHomes), not only legacysettings.providers. InstancehomePath, absoluteCLAUDE_CONFIG_DIR/CODEX_HOME, Codex shadow layouts, and same-home collapsing match runtime behavior; transcript dirs are canonicalized withrealPathso symlinked aliases scan once while missing paths still show as separatemissingsources.Aggregation and merge tie each bucket to a
sourceIndexinto the summary’ssourcesarray. Cross-environmentmergeUsagedrops duplicate transcript directories per source, not per provider, so overlapping environments keep unique homes instead of losing an entire provider’s totals.Contract v6 adds
sourceIndexonUsageBucket(decode default0);USAGE_MERGE_COMPATIBLE_SINCEis 6, so v5 summaries are treated as stale during merge. User docs note multi-instance Claude/Codex coverage.Reviewed by Cursor Bugbot for commit cc8777d. Bugbot is set up for automated code reviews on this repo. Configure here.
Note
Count usage from every configured provider instance in
UsageServiceresolveUsageProviderHomesto enumerate all configured Claude and Codex instance homes, applying the same home and environment precedence rules as provider execution, skipping invalid instances, and de-duplicating pathsUsageAggregator.addso records from different transcript directories stay in separate buckets even when day, hour, provider, and model matchownedContributionwith source-index ownership so merging drops only duplicate directories while preserving unique directories of the same providerUSAGE_CONTRACT_VERSIONfrom 5 to 6 and raisesUSAGE_MERGE_COMPATIBLE_SINCEfrom 4 to 6; older bucket data decodes with a default source index of zeroUsageBucketshape or merge-compatible range will need updatingMacroscope summarized 3c8d99d.
Summary by CodeRabbit
New Features
Bug Fixes
Documentation