Skip to content

Report Grok usage with recorded and estimated spend - #3135

Open
olddonkey wants to merge 35 commits into
steipete:mainfrom
olddonkey:feat/grok-real-token-usage
Open

Report Grok usage with recorded and estimated spend#3135
olddonkey wants to merge 35 commits into
steipete:mainfrom
olddonkey:feat/grok-real-token-usage

Conversation

@olddonkey

@olddonkey olddonkey commented Aug 22, 2026

Copy link
Copy Markdown
Contributor

Problem and resulting behavior

Grok's local fallback reads ending context occupancy from signals.json, which is not completed-turn usage, and publishes no local cost. This PR reads completed turns from bounded native CLI logs and carries recorded-versus-estimated cost through the menu and Usage & Spend.

  • Read both session/update and _x.ai/session/update records in updates.jsonl, with daily, model, and request breakdowns.
  • Prefer a positive outer usage.costUsdTicks / 1e10 as the authoritative turn total. Count it once. Show nested model dollars only when all nested ticks exist and reconcile to that total; otherwise retain model tokens with unknown model dollars. Missing recorded cost falls back to disclosed public xAI list prices.
  • Keep useful remote data during billing failures while rescanning local sessions. Consumers select the newer publication for the current configuration and preserve account override isolation.
  • Retain cost provenance after menu and dashboard window/day filtering. Populated surfaces disclose Grok CLI-recorded spend, list price where unrecorded · not a bill.
  • Refresh the xAI models.dev catalog for Grok-only installs and keep its pricing fingerprint independent from native Codex pricing.

OpenCodex integration

With the existing Include OpenCodex usage logs switch enabled (off by default), Usage & Spend also includes reported physical Grok OAuth attempts. The producer contract originally proposed in OpenCodex #3642 has now landed in dev through the attributed carry #3762, merged as f00f2bcaea251ebe7ad4de9e38337b4be0ccee47. It writes attempts[].credentialSource from the resolved upstream transport. Compatibility is verified against the pinned producer commit in the evidence below; availability in a released OpenCodex version is not claimed.

Only provider: "xai", credentialSource: "grok-oauth" attempts with an upstream send and reported token usage qualify. API-key traffic, historic rows, locally answered requests, unknown sources, and estimated/unreported token counts stay excluded. Current configuration and top-level credential metadata cannot retroactively classify usage.

Combo requests contribute each qualifying attempt's own token counts, never the parent aggregate. Duplicate request IDs are resolved before grouping; duplicate attempt ordinals are rejected. SQLite cache schema 3 retains attempt metadata and rebuilds older derived caches from the log. OpenCodex dollars use list prices and remain estimates, including when combined with native CLI-recorded spend. Missing token classes and unknown prices retain tokens without inventing a dollar value. The Grok menu continues to use native CLI logs.

Producer-to-dashboard evidence and review fixes

The committed evidence report and raw ledger fixture contain output from OpenCodex's unmodified production handlers and durable usage writer at 146ed679c9633e5d68726217fcadc8e0b107339b. Two localhost HTTP requests exercised OAuth 401 replay through Responses and native Chat API-key dispatch. Upstream responses and credentials used isolated fixtures; this is production-path capture evidence, not live vendor authentication or billing evidence. The capture helper rejects unexpected external fetches and is reproducible against that pinned checkout.

CodexBar imports the exact captured bytes through the production disk loader, with no injected entries or loader closure, and reopens the persisted cache:

producer_capture_sha256=ef6d8758b40910f6e5993d5b5a105a2ad2834c6c1bd0565ab87b61cf091c4978
producer_log_rows=2 total_reported_tokens=10 grok_oauth_tokens=5
producer_import_dashboard_tokens=5 cache_reopen_bytes=0
producer_api_key_only_subscription_rows=0

Standalone reports retain explicit xAI custom-price estimates from either the caller overlay or the application overlay, including known zero. Raw xAI records without an explicit price remain token-only, and the subscription fan-out still excludes API-key and historic records. opencode and opencode-free retain their existing catalog and custom prices.

Application overlays first match the original model name before the provider-qualified catalog name. Bare keys retain precedence when both keys exist; incomplete rates stay unknown, cached-input accounting is preserved, and caller-supplied custom pricing still takes precedence over the application overlay. New regressions cover these cases through the application-overlay parameter and the standalone disk/cache loader. Coverage includes known-zero overrides, incomplete rates, cache accounting, and both snapshot and application overlays.

Both async native Grok scan entry points propagate the executor's cancellation callback through discovery, JSONL reads, and aggregation. An in-flight regression cancels after parsing begins, observes CancellationError, and confirms the next queued scan runs within one second. Cancelled partial parses are uncacheable and cannot establish complete history. The final serial proof stopped at 4,874/40,000 decoded records and released the queue after 0.001864583 seconds. The evidence report also retains the initial measurement.

Bounds and compatibility

Native scans run on the dedicated executor with limits of 64 MiB / 20,000 turns per file, 1 MiB per record, 256 sessions / 256 MiB / 100,000 turns per scan, and 4,096 discovery entries. The process cache retains at most 64 files or 50,000 turns. Cancellation and truncated history cannot publish complete coverage.

Merged main 31131374b2c547914243f54303b2c5f5f09d77e9, retaining the new Claude account-warning preservation, MiMo malformed-row handling, and earlier Poe elapsed-week fix. The architecture-test line records match the merged source while retaining this PR's Grok bridge and reference fingerprints. All upstream and Grok release notes are retained under 0.56.8 Unreleased. The previously integrated Linux cache replacement fixes, stacked-chart rendering, provider/widget changes, and release metadata remain intact. Regenerated the native parser hash from the resulting source: 1a4afd74939160fd. The released main hash 9547dc9d7b7675f6 and previous PR hash 0bd6588c70196700 are compatible predecessors because the catalog persistence change does not alter native parsed rows or checkpoints; existing predecessors are preserved. Parameterized SQLite adoption tests exercise both newly retained hashes without rebuilding. Release notes are under 0.56.8 — Unreleased, with published sections unchanged.

Validation

Head: 6f4a7d1058de2180f1f293824074cbbcd15ec5cc.

  • Current-head make check passed: zero SwiftLint violations in 2,138 files.
  • Current-head architecture, Claude credential-warning, Grok fallback, and dashboard freshness checks passed: 46 tests in four suites.
  • Earlier supplemental cache adoption, OpenCodex integration/pricing, architecture, and stacked-chart tests at c3919a224: 136 tests in five suites passed (4.392 seconds).
  • Current-head make test passed: 1,032 selections, 86/86 groups successful on the first attempt, zero failures, retries, or timeouts (629.6 seconds execution; 633.9 seconds total).
  • Earlier supplemental native Grok scanner, projection, pricing, provenance, dashboard, architecture, OpenCodex integration, custom-price/cache compatibility, stacked charts, executor cancellation, and opt-in local proof at c3919a224 passed: 206 tests in 14 suites (5.747 seconds), using --no-parallel as the repository test harness does.
  • git diff --check passed. All nine GitHub CI checks passed on 6f4a7d105, including both macOS shards, all three Linux builds, lint, and the aggregate gate.

The supplemental proof and local-corpus measurements below were captured at c3919a224, before the latest main sync. The Grok accounting and OpenCodex import source is unchanged by that sync. The supplemental proof uses the repository’s serial execution mode because these suites share scanner-cache counters; the required full suite passed again on the current head after the latest upstream integration.

The September 6 local-corpus proof retained vendorMetered for populated windows: 7 days = 95,891,889 tokens / $12.57875572; 30 days = 98,631,812 tokens / $12.94957366. The empty 1-day window retained unknown. Controlled JSONL fixtures also proved recorded-only and estimate-only windows after narrowing mixed source history.

CODEXBAR_LIVE_GROK_CATALOG_PROOF=1 CODEXBAR_SUPPRESS_TEST_KEYCHAIN_ACCESS=1 CODEXBAR_ALLOW_TEST_KEYCHAIN_ACCESS=0 CODEXBAR_TEST_CODEX_FILE_ISOLATION=1 swift test --skip-build --no-parallel --filter 'GrokWindowProvenanceProofTests|GrokXAISpendCatalogTests|GrokTokenSnapshotProjectionTests|GrokCostUsagePricingTests|GrokLocalSessionScannerTests|ProviderArchitectureGatekeeperTests|CostProvenanceTests|SpendDashboardGrokFreshnessTests|GrokOpenCodexUsageTests|CostUsageScanExecutorTests|OpenCodexUsagePricingTests|CostUsageStoreTests|SpendStackedBarChartTests'

The OpenCodex regressions cover mixed OAuth/API-key/provider attempts, historical and malformed records, duplicate suppression, cache reopen/incremental append/schema upgrade, missing-price behavior, recorded-plus-estimated date filtering, and the dashboard's opt-in switch. Existing native regressions cover bounded parsing, outer/nested cost reconciliation, local fallback freshness, account isolation, and menu/dashboard provenance.

All ordinary tests suppress Keychain access and isolate provider files. The optional native proof reads local Grok logs and the cached pricing catalog without authentication, browser-cookie import, or live provider requests. Presentation evidence uses production menu/dashboard models; no app-bundle screenshot is claimed.

Maintainer decision

Please revisit the 2026-08-21 Grok cost ruling before merge. It preferred public-card pricing based partly on my incorrect 1e9 divisor; #3345 established 1e10, and the corrected measurement explains the difference. This branch uses recorded spend with public-card fallback.

Whether existing Grok users should receive this disclosed dollar surface by default remains an owner decision. The accounting corrections and source labeling do not override that decision. Maintainer approval is still required.

@clawsweeper

clawsweeper Bot commented Aug 22, 2026

Copy link
Copy Markdown

🦞👀
ClawSweeper picked this up.

Pull request received. I will update this pull request when review starts.

ClawSweeper review complete

ClawSweeper finished reviewing this revision. The review result is being finalized.

View the workflow run.

olddonkey added a commit to olddonkey/CodexBar that referenced this pull request Aug 22, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 09cf7edb0f

ℹ️ 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".

Comment thread Sources/CodexBar/UsageStore+Refresh.swift Outdated
Comment thread Sources/CodexBarCore/Providers/Grok/GrokLocalSessionScanner.swift
@clawsweeper clawsweeper Bot added merge-risk: 🚨 compatibility 🚨 Merging this PR could break existing users, config, migrations, defaults, or upgrades. P2 Normal priority bug or improvement with limited blast radius. rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. labels Aug 22, 2026
@clawsweeper

clawsweeper Bot commented Aug 22, 2026

Copy link
Copy Markdown

Codex review: blocked before merge. Reviewed September 6, 2026, 5:57 PM ET / 21:57 UTC.

ClawSweeper review

What this changes

The PR counts completed Grok CLI turns, reports recorded spend with labeled price estimates, and imports qualifying OpenCodex OAuth usage into Usage & Spend.

Merge readiness

Blocked before merge - 3 items remain

This remains useful work: current main and v0.56.7 still count context occupancy and publish no native Grok spend. Earlier pricing findings are resolved, and no new actionable defect was found; product acceptance remains unresolved.

Priority: P2
Reviewed head: 6f4a7d1058de2180f1f293824074cbbcd15ec5cc
Owner decision: Required. See Decision needed.

Review scores

Measure Result What it means
Overall readiness 🐚 platinum hermit (4/6) A well-supported implementation with resolved prior findings; the remaining owner decision does not reduce its technical quality rating.
Proof confidence 🦞 diamond lobster (5/6) Sufficient (terminal): Recorded real local-log runs exercise the Grok scanner and menu/dashboard projections, while pinned production-writer output exercises the OpenCodex disk importer and cache with OAuth inclusion and API-key exclusion. Relevant source is unchanged since those captures; this proves accounting behavior, not live vendor billing or a released producer version.
Patch quality 🐚 platinum hermit (4/6) No actionable review findings were identified.

Verification

Check Result Evidence
Real behavior Verified Sufficient (terminal): Recorded real local-log runs exercise the Grok scanner and menu/dashboard projections, while pinned production-writer output exercises the OpenCodex disk importer and cache with OAuth inclusion and API-key exclusion. Relevant source is unchanged since those captures; this proves accounting behavior, not live vendor billing or a released producer version.
Evidence reviewed 10 items Current main still needs the accounting correction: The main scanner reads signals.json, sums totalTokensBeforeCompaction and contextTokensUsed, and explicitly publishes nil session and window costs.
Latest release has the same old behavior: The v0.56.7 scanner still uses occupancy fields and nil dollars; the release tag resolves to d8f4cec.
Prior pricing findings resolved: The aggregator checks the application overlay against the original model before qualifying the catalog lookup and preserves explicit xAI custom prices before the token-only fallback. Regression coverage includes bare-key precedence, zero prices, incomplete rates, cached inputs, and standalone disk/cache loading.
Findings None None.
Security None None.

How this fits together

CodexBar turns local usage logs into token and spending summaries for its menu and Usage & Spend dashboard. This change updates Grok accounting and the optional OpenCodex log importer while keeping remote subscription quotas separate.

flowchart TD
  A[Grok CLI session logs] --> B[Bounded completed-turn scanner]
  C[Recorded spend and public prices] --> B
  B --> D[Windowed usage summaries]
  E[Optional OpenCodex logs] --> F[Reported OAuth attempt filter]
  F --> G[Usage and Spend dashboard]
  D --> G
  D --> H[Grok menu]
Loading

Decision needed

Question Recommendation
Should existing Grok cost-tracking users receive recorded-first dollar figures with disclosed list-price fallback? Approve the disclosed dollar display: Accept recorded-first costs for existing cost-tracking users and explicitly reconsider the earlier requested-changes review.

Why: The corrected divisor and runtime evidence support the accounting, but they cannot supersede the earlier owner ruling or establish acceptance of the new display semantics.

Before merge

  • Resolve merge risk (P2) - Existing Grok users with cost tracking enabled would receive dollar figures on upgrade; acceptance of recorded-first spend with disclosed list-price fallback is still an owner decision.
  • Complete next step (P2) - Have steipete decide whether existing cost-tracking users should receive the disclosed dollar display and reconsider the earlier requested-changes review.
  • Resolve maintainer decision - Resolve the maintainer decision shown above before merge.
Agent review details

Security

None.

Review metrics

Metric Value Why it matters
Production and test growth Production +1,699/-196 (net +1,503); tests +3,103/-146 (net +2,957) The stated scope justifies growth for bounded parsing, cost provenance, publication freshness, and producer/cache compatibility coverage.

Merge-risk options

Maintainer options:

  1. Accept the disclosed upgrade behavior (recommended)
    The owner can approve dollar display for existing cost-tracking users based on the corrected accounting and explicit non-bill disclosure.
  2. Preserve token-only presentation
    If automatic dollar display is unwanted, retain token accounting and make dollar visibility an explicit user choice.

Technical review

Best possible solution:

Keep bounded completed-turn accounting and source-specific disclosures, with dollar visibility governed by an explicit owner-approved upgrade policy.

Do we have a high-confidence way to reproduce the issue?

Yes: current main directly sums context-occupancy fields, and independent corpus evidence shows the resulting undercount. This read-only review did not execute a reproduction.

Is this the best way to solve the issue?

Yes for the accounting: completed-turn logs, recorded-first pricing, and request-time OpenCodex provenance provide a coherent correction. Default dollar visibility remains a separate product choice.

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning medium; reviewed against 31131374b2c5.

Labels

Label justifications:

  • P2: This corrects Grok usage accounting and adds a bounded spending display without evidence of an urgent core outage.
  • merge-risk: 🚨 compatibility: Upgrading existing cost-tracking users changes Grok from token-only presentation to dollar figures without a newly selected preference.
  • rating: 🐚 platinum hermit: Overall readiness is 🐚 platinum hermit; proof is 🦞 diamond lobster and patch quality is 🐚 platinum hermit.
  • status: 👀 ready for maintainer look: ClawSweeper has no concrete contributor-facing blocker left for this PR. Sufficient (terminal): Recorded real local-log runs exercise the Grok scanner and menu/dashboard projections, while pinned production-writer output exercises the OpenCodex disk importer and cache with OAuth inclusion and API-key exclusion. Relevant source is unchanged since those captures; this proves accounting behavior, not live vendor billing or a released producer version.
  • proof: sufficient: Contributor real behavior proof is sufficient. Recorded real local-log runs exercise the Grok scanner and menu/dashboard projections, while pinned production-writer output exercises the OpenCodex disk importer and cache with OAuth inclusion and API-key exclusion. Relevant source is unchanged since those captures; this proves accounting behavior, not live vendor billing or a released producer version.

Evidence

What I checked:

  • Current main still needs the accounting correction: The main scanner reads signals.json, sums totalTokensBeforeCompaction and contextTokensUsed, and explicitly publishes nil session and window costs. (Sources/CodexBarCore/Providers/Grok/GrokLocalSessionScanner.swift:127, 31131374b2c5)
  • Latest release has the same old behavior: The v0.56.7 scanner still uses occupancy fields and nil dollars; the release tag resolves to d8f4cec. (Sources/CodexBarCore/Providers/Grok/GrokLocalSessionScanner.swift:53, d8f4cec19b82)
  • Prior pricing findings resolved: The aggregator checks the application overlay against the original model before qualifying the catalog lookup and preserves explicit xAI custom prices before the token-only fallback. Regression coverage includes bare-key precedence, zero prices, incomplete rates, cached inputs, and standalone disk/cache loading. (Sources/CodexBarCore/Vendored/OpenCodexUsage/OpenCodexUsageAggregator.swift:376, 6f4a7d1058de)
  • Producer contract and recorded import proof: The evidence report explicitly depends on lidge-jun/opencodex's request-time attempts[].credentialSource contract. Its capture is pinned to producer commit 146ed679c9633e5d68726217fcadc8e0b107339b and ledger SHA-256 ef6d8758b40910f6e5993d5b5a105a2ad2834c6c1bd0565ab87b61cf091c4978. Recorded localhost production-path output feeds CodexBar's actual disk loader and dashboard: five OAuth tokens, zero API-key subscription rows, and zero log bytes on cache reopen. The report distinguishes fixture upstream responses from live vendor authentication and does not claim released producer availability. (docs/evidence/grok-opencodex-producer-2026-09-05.md:3, 6f4a7d1058de)
  • Native proof remains relevant to this head: The captured PR body reports real local-corpus results at c3919a2: 95,891,889 tokens and $12.57875572 over seven days, with recorded-cost provenance. The inspected accounting, importer, and projection source has no changes between that proof revision and the reviewed head. (Tests/CodexBarTests/GrokWindowProvenanceProofTests.swift:79, 6f4a7d1058de)
  • Cache compatibility has focused coverage: The OpenCodex schema advances to version 3 and rebuilds its derived cache from the retained log. Tests cover initial loading, cache reopen, incremental append, and version-2 rejection/rebuild; native Codex predecessor adoption also has explicit regression coverage. (Tests/CodexBarTests/GrokOpenCodexUsageTests.swift:76, 6f4a7d1058de)

Likely related people:

  • steipete: Suggested for follow-up; no historical authorship or introduction is verified. (role: unverified routing candidate; confidence: low)
  • olddonkey: Suggested for follow-up; no historical authorship or introduction is verified. (role: unverified routing candidate; confidence: low)

Rating scale

Score Internal tier Crab rank Meaning
6/6 S 🦀 challenger crab Exceptional readiness
5/6 A 🦞 diamond lobster Very strong readiness
4/6 B 🐚 platinum hermit Good normal PR; ordinary maintainer review
3/6 C 🦐 gold shrimp Useful, but confidence is limited
2/6 D 🦪 silver shellfish Proof or implementation needs work
1/6 F 🧂 unranked krab Not merge-ready
N/A NA 🌊 off-meta tidepool Rating does not apply

Overall follows the weaker of proof and patch quality.
Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics.

Workflow

  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.

History

Review history (50 earlier review cycles; latest 8 shown)
  • reviewed 2026-09-05T09:34:56.028Z sha 231714c :: blocked before merge. :: [P1] Preserve bare-model custom prices before qualifying catalog lookups | [P1] Preserve explicit xAI prices in standalone OpenCodex reports
  • reviewed 2026-09-05T11:09:11.628Z sha 81f1e2e :: blocked before merge. :: none
  • reviewed 2026-09-05T11:16:10.479Z sha 81f1e2e :: blocked before merge. :: none
  • reviewed 2026-09-06T18:27:11.837Z sha c3919a2 :: blocked before merge. :: none
  • reviewed 2026-09-06T18:36:11.840Z sha c3919a2 :: blocked before merge. :: none
  • reviewed 2026-09-06T20:30:06.415Z sha 0874450 :: blocked before merge. :: none
  • reviewed 2026-09-06T21:21:40.103Z sha 6f4a7d1 :: blocked before merge. :: none
  • reviewed 2026-09-06T21:33:40.105Z sha 6f4a7d1 :: blocked before merge. :: none

@olddonkey
olddonkey force-pushed the feat/grok-real-token-usage branch from 08360b5 to e3cd3b9 Compare August 22, 2026 06:21
@olddonkey olddonkey changed the title Report real Grok token usage and list-price cost from CLI session logs Report real Grok token usage and list-price cost, from the CLI logs and OpenCodex alike Aug 22, 2026
@clawsweeper clawsweeper Bot added merge-risk: 🚨 auth-provider 🚨 Merging this PR could break OAuth, tokens, provider routing, model choice, or credentials. rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. and removed rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. labels Aug 22, 2026
@olddonkey

Copy link
Copy Markdown
Contributor Author

Both automated findings are addressed, plus the review's other checklist items. The inline comments were left against 09cf7edb0, which no longer exists — the branch has since been rebased onto 27c7f334e and the head is now 03e5a25dc, so I'm summarising here rather than replying in a stale diff.

P1 — Preserve the Grok fallback on repeated probe failures

Fixed in 923193ec0, Sources/CodexBar/UsageStore+Refresh.swift. The guard had been hoisted into the if provider == .grok, publication == nil condition, so a Grok failure with a publication fell through to the generic else if tokenCostRequiresProviderSnapshot { clearTokenSnapshot } branch. Grok now owns its branch outright and can never reach the clear:

if provider == .grok {
    if self.tokenSnapshotPublicationForCurrentProviderConfig(for: provider) == nil {
        Task { @MainActor [weak self] in
            await self?.scanAndPublishGrokLocalTokenSnapshot(...)
        }
    }
} else if Self.tokenCostRequiresProviderSnapshot(provider) {
    self.clearTokenSnapshot(for: provider)
}

Regression coverage is in missing remote snapshot scans and publishes local tokens then clears empty data. Per the review's request it now drives two consecutive failing refreshes (03e5a25dc) rather than one — which matters here, because the first failure is what publishes through the fallback scan and only the second arrives with a publication in place, i.e. the failure that used to wipe the row. Both iterations assert the row still reads 77 tokens and that no redundant rescan ran.

P2 — Refresh pricing before scanning Grok sessions

Correct, and thank you — this was a genuine gap and not one the local tests would have surfaced. refreshPricingIfAllowed is gated to Codex and Claude, and Grok never reaches it at all because its snapshot comes from the provider probe rather than CostUsageFetcher.loadTokenSnapshot. On a machine with Codex or Claude also enabled the shared cache is already populated, so the failure is invisible there; enable only Grok and the catalog never appears and the Cost row shows tokens with no money, permanently.

Fixed in 744677e68. The Grok scan paths now request ModelsDevPricingPipeline.refreshIfNeeded through a summarizeRequestingPricingRefresh wrapper, called from all four scan sites (GrokStatusProbe, both branches in GrokProviderDescriptor, and UsageStore.scanAndPublishGrokLocalTokenSnapshot). It is detached rather than awaited, matching how the Codex and Claude paths already treat it — pricing availability must not delay or fail a local scan — and it is safe to call repeatedly, since it returns immediately unless the cache is stale and serialises through its own coordinator. summarize itself stays synchronous and side-effect free.

Note the inline comment still points at GrokLocalSessionScanner.swift:662; that line is the unchanged pricing lookup, and the fix is upstream of it in the new wrapper, so the anchor looks live even though it is addressed.

Coverage: absent models dev cache requests a background refresh, stale models dev cache requests a background refresh, and fresh models dev cache skips the background refresh. All three assert whether a refresh was requested through an injected transport — no test touches the network.

Real-session evidence

CODEXBAR_LIVE_GROK_CATALOG_PROOF=1 swift test --filter GrokXAISpendCatalogTests, against real local Grok CLI sessions, through the shipped code path:

catalog_source=grok
today_tokens=5043749
last_30_days_tokens=52696354
today_cost_usd=3.3471699999999993
window_cost_usd=49.353424
cost_provenance=listPriceEstimate
history_days=365
priced_days=4
token_days=4
daily_buckets=4
available_sources=grok

The same corpus on main reports 653K tokens and no cost. history_days=365 shows the requested window is honoured (it was pinned to 30). priced_days == token_days shows no day was silently left unpriced. The gated proof was extended in e3cd3b9ce to print cost, provenance and priced-day coverage, since tokens alone cannot evidence the half of this change that is about money.

Those figures were cross-checked against an independent reimplementation of the pricing formula over the same logs; the two agree to the cent.

Merge risk / branch state

Rebased onto current main (27c7f334e); the branch reports clean. Full suite on the head: 77/77 groups, 922 selections, 0 failures. swiftformat --lint and swiftlint --strict clean. Upstream CI green on the previous head including all three Linux builds.

One thing deliberately left undone: no CHANGELOG.md entry. 0.54.1 was finalized and there is no open Unreleased section, so I did not invent a version heading — happy to add one wherever you prefer.

@clawsweeper clawsweeper Bot added rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. and removed rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. labels Aug 22, 2026
@olddonkey

olddonkey commented Aug 22, 2026

Copy link
Copy Markdown
Contributor Author

Both new findings addressed at 44d79a95a.

P1 — Do not map every xAI log record to the Grok subscription

Agreed, and taken as specified rather than argued down. Routing on the prefix alone is right for the case that motivated this — traffic authenticated with the user's Grok account, which is what makes it consume SuperGrok quota — but it silently folds an API-key user's pay-as-you-go xAI spend into the subscription row. CodexBar already models the developer platform as its own xai provider precisely to keep those apart, so the old behaviour crossed a boundary the app deliberately maintains.

The usage log carries no per-record credential evidence; I checked every field emitted for xai rows (requestId, timestamp, provider, model, requestedModel, resolvedModel, usage, usageStatus, status, routeDecision, …) and there is nothing about auth, account or key. The signal that does exist is ~/.opencodex/config.json, which records authMode per provider.

So attribution now requires positive OAuth evidence:

  • xai routes to .subscription(.grok) only when its configured authMode is OAuth. Anything else returns .tokenOnly — the spend is real, it just belongs to no tracked subscription — rather than .unknown, which would read as "unrecognised provider".
  • Fail closed. A missing or malformed config, a providers block without xai, or an entry without authMode all count as no evidence and keep the records off the Grok row.
  • OpenCodexRouteDispatcher stays a pure function. The set of OAuth-backed provider ids is threaded in from the caller (OpenCodexUsageFanOutSpendDashboardSource), so the routing site never touches the filesystem and every existing caller and test that does not care about auth keeps working.
  • The gate applies only to xai. openai, kimi-coding, deepseek and opencode-go are untouched — changing them would be an unreviewed behaviour change for other providers — and a test pins that they ignore xAI auth state entirely.

Coverage: xai OAuth config routes to Grok, xai non OAuth config stays token only (parameterised over several non-OAuth values), xai routing fails closed without readable complete OAuth config, non xai subscription routes ignore xai auth state, plus fan-out cases proving the same entries land on the Grok row under an OAuth config and are absent under an API-key one. No test reads the developer's real ~/.opencodex; the home directory is injected.

docs/grok.md no longer claims this path cannot distinguish OAuth from API-key traffic, because it now can.

P2 — Republish the Grok snapshot after a missing catalog refreshes

I looked at this closely and am deliberately not adding a republish path. Reasoning, so you can overrule it if you disagree:

The refresh is fire-and-forget, so the scan that requests it returns whatever the cache currently holds — that part is accurate. But the parse cache stores parsed turns, not prices, so aggregation and pricing re-run on every summarize. The next Grok scan therefore prices against the refreshed catalog with no extra machinery, bounding the unpriced window to a single refresh cycle. That is the same behaviour Codex and Claude already have: refreshPricingIfAllowed dispatches into Task.detached and their current scan does not wait for it either.

The alternative — plumbing a completion signal back across the actor boundary into the @MainActor publication path — buys one refresh cycle of latency on first run, at the cost of a new cross-actor completion path in code that publishes user-visible spend. That trade looked disproportionate, and inconsistent with how the two established providers behave. I have recorded the reasoning as a comment at the call site rather than leaving it implicit, so the next reader does not have to re-derive it.

Happy to build it if you would rather have it.

Evidence

The attribution itself only becomes visible in the app: SpendDashboardSource.mergingOpenCodexInputs is what merges the fan-out into provider rows, and the CLI's cost command reports OpenCodex as its own source rather than routing it, so terminal output cannot show this path. The figures below are read off the freshly packaged build running against real local data, on a machine whose ~/.opencodex/config.json has "xai": { "authMode": "oauth" }; screenshots of both panes follow.

The two halves stay distinguishable in the UI, which makes the attribution legible rather than something you have to take on trust: the CLI goes through the responses API so its SKU is grok-4.6-build, while OpenCodex's records resolve to the bare grok-4.6 / grok-4.5 / grok-4.3. Both sit under the Grok provider.

model row source shown
grok-4.6-build Grok CLI session logs $50.52 · 54M
grok-4.6 OpenCodex $161.21 · 182M
grok-4.5 OpenCodex $4.54 · 5.5M
grok-4.3 OpenCodex $0.50 · 201K

Independently recomputing the same corpus agrees to the cent on both halves: 54,121,501 tokens / $50.52 for the CLI logs, and $166.25 across 1,520 OpenCodex xai records. The CLI half is reproducible by anyone on their own machine through the gated proof test (CODEXBAR_LIVE_GROK_CATALOG_PROOF=1), whose output is in the PR body.

The negative direction — API-key traffic staying off the Grok row — is covered by tests rather than a screenshot, since demonstrating it live would mean rewriting the machine's OpenCodex config.

State

Full suite on 44d79a95a: 77/77 groups, 922 selections, 0 failures. swiftformat --lint and swiftlint --strict clean. Rebased on 27c7f334e.

image image

@clawsweeper clawsweeper Bot added proof: 📸 screenshot Contributor real behavior proof includes screenshot evidence. proof: sufficient Contributor real behavior proof is sufficient. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. and removed status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. labels Aug 22, 2026
@olddonkey olddonkey changed the title Report real Grok token usage and list-price cost, from the CLI logs and OpenCodex alike Report real Grok token usage and list-price cost from CLI logs Aug 23, 2026
@olddonkey

Copy link
Copy Markdown
Contributor Author

Addressed both current findings in 211e1977d and resolved the two review threads.

  • P1 / historical xAI attribution: removed current-config-based xAI → Grok routing. usage.jsonl has no request-time credential provenance, so xAI records now remain token-only until the producer can persist that evidence. Removed the config reader/plumbing and added dispatcher/fan-out regressions.
  • P2 / first pricing publication: when no models.dev artifact exists, the first Grok scan now awaits the initial best-effort refresh attempt before summarizing. A successful refresh prices the first returned snapshot; stale catalogs still price immediately and refresh in the background. Added a regression that writes the catalog during refresh and asserts the first summary is priced.
  • Updated the PR title/body and docs/grok.md so they no longer claim OpenCodex xAI traffic is merged into the Grok subscription row.

Validation on the exact pushed head:

  • focused Grok/OpenCodex suites: 32 tests passed
  • make check: passed
  • make test: 922 selections, 77/77 groups, 0 failed groups, 0 retries
  • branch is based on current main (27c7f334e) and the merge-tree is clean

@clawsweeper re-review

@clawsweeper

clawsweeper Bot commented Aug 23, 2026

Copy link
Copy Markdown

🦞🧹
ClawSweeper re-review requested.

I asked ClawSweeper to review this item again.
Action: item re-review queued (workflow sweep.yml, event exact_review_queue).
Result: when the review finishes, ClawSweeper will create the durable review comment if needed or update the existing comment in place.

@clawsweeper clawsweeper Bot added merge-risk: 🚨 availability 🚨 Merging this PR could cause crashes, hangs, restart loops, stalls, or process outages. and removed merge-risk: 🚨 compatibility 🚨 Merging this PR could break existing users, config, migrations, defaults, or upgrades. proof: sufficient Contributor real behavior proof is sufficient. proof: 📸 screenshot Contributor real behavior proof includes screenshot evidence. labels Aug 23, 2026
Rebase onto current main and reconcile the surfaces it moved:

- Route the Grok local summary through the injectable `localSummary`/`cliVersion`
  seams steipete#3237 introduced, keeping the 365-day lookback and the models.dev
  pricing refresh in the injected defaults rather than at the call sites.
- Regenerate the Codex parser hash and record main's `21f10143afe00c55` as a
  compatible predecessor; the Grok-only parser additions leave persisted Codex
  rows unchanged. Drop the stale branch-internal predecessor entry.
- Re-anchor the provider-architecture gatekeeper suppressions and allowlists to
  the line numbers main's Spend dashboard and usage store now sit at.
- Anchor the unstubbed Grok publish test to the real clock instead of a fixed
  calendar day, which had drifted outside its own seven-day window.
- Move the xAI pricing-fingerprint test next to the other Grok pricing tests so
  `CostUsagePricingTests.swift` stays byte-identical to main and inside the
  file- and type-length limits.
0.56.0 shipped without this change, so the entry belongs in the open
`0.56.1 — Unreleased` section rather than the released one.
- Queue the refreshable Grok summary through `CostUsageScanExecutor`. It called the
  synchronous corpus scanner inline, so the probe and descriptor callers ran a
  potentially multi-minute scan on the cooperative pool the executor exists to protect.
  A cancelled scan now reports unestablished coverage rather than an authoritative zero.
- Derive the Grok lookback cutoff from the local start of day minus `historyDays - 1`
  so the scan window matches the inclusive local-day window `narrowed(toHistoryDays:)`
  renders, instead of collecting a partial extra day consumers discard.

Each fix carries a regression that was confirmed to fail without it.
- Regenerate `CodexParserHash.value` to `69eee1ccce7ed69c`.
- Record main's `50a2507f4c10d080` in `CostUsageStore.compatiblePredecessorParserHashes`
  and in its exact-set assertion.
steipete#3345 measured `costUsdTicks` on an independent 934-turn corpus and established
its divisor as 1e10. My own 2026-08-21 backtest had concluded 1e9, because that
quotient came out to exactly 1.7x the public card on a 25-turn sample drawn
entirely from an xAI promotional window. Re-running that arithmetic on this
branch's corpus reproduces both readings to four decimals, so the divisor was
wrong rather than the measurement.

The consequence is not a rounding artifact. The six turns behind this branch's
gated proof publish $2.181282 reconstructed from the public card; the spend the
CLI recorded for the same turns is $0.370818. steipete#3345 reports 6.66x across a whole
promotional period.

Read `costUsdTicks` when a record has it, since it already carries the price tier
and any promotional rate, and fall back to the public card only where it does not.
Fallback entries are counted as estimated rather than priced, and the window
publishes `.vendorMetered`, `.listPriceEstimate`, or `.mixed` accordingly, so the
dashboard and menu name the source instead of asserting one.

A record that omits the field or reports 0 has no recorded spend; steipete#3345 measured
that at 2 of 934 turns. The fixtures no longer inject a sentinel tick value by
default, so the existing suites keep exercising the fallback path.

Note for the maintainer: the 2026-08-21 owner ruling chose the public card over
`costUsdTicks` for Grok, and my incorrect divisor was part of the evidence behind
it. That ruling should be revisited on these numbers rather than treated as
overridden by this commit.
ClawSweeper found two window-projection defects that the 365-day Grok snapshot
newly exposes, since a maximum-window snapshot is now narrowed per consumer.

`grokLocalTokenSnapshot` recomputed tokens and requests from the retained days
but copied the published cost total, so a 30-day menu view could render the
365-day dollar amount beside a 30-day token count. It now sums the retained
rows.

Both that projection and `CostUsageTokenSnapshot.narrowed(toHistoryDays:)`
carried the snapshot-wide provenance into the derived window, so a window that
excluded every recorded row still claimed recorded spend — newly reachable now
that a Grok window can be mixed. The Grok projection derives the disclosure from
the coverage counts of the days it kept, because its scanner counts a recorded
turn as priced and a card fallback as estimated. The generic narrowing applies
the existing `CostProvenance.forWindow` rule instead, which stops a costless
window from claiming a provenance without guessing what the surviving rows of
another provider mean.

Each fix carries a regression confirmed to fail without it.
@olddonkey

Copy link
Copy Markdown
Contributor Author

Rebased onto current main 4d27bb113e5e4899b1d481a1c989adc03c63bcdf and pushed 9aba5e0d62b0168c611e14515a9b22e16442a6db.

The existing opt-in OpenCodex import now accepts only reported physical Grok OAuth attempts with request-time provenance from OpenCodex #3642. It excludes API-key/historic/unknown records, avoids combo-parent and duplicate counting, preserves provenance through the derived cache, and keeps OpenCodex list-price estimates distinct from native CLI-recorded spend. The menu remains backed by native CLI logs.

Validation on this head:

  • make check: zero violations in 2,131 files.
  • make test: 1,024 selections; 86/86 groups passed first try; zero failures, retries, or timeouts.
  • Focused OpenCodex and architecture tests: 102 passed.
  • Native and OpenCodex provenance tests plus the local-corpus proof: 112 passed in ten suites. The redacted real-log result retains vendor-metered provenance for the populated 7- and 30-day windows; controlled mixed-source fixtures retain the correct source after date filtering.

The PR description contains the exact commands and evidence. The default Grok dollar surface remains an owner/product decision before merge.

@clawsweeper re-review

@clawsweeper

clawsweeper Bot commented Sep 5, 2026

Copy link
Copy Markdown

🦞🧹
ClawSweeper re-review requested.

I asked ClawSweeper to review this item again.
Action: item re-review queued (workflow sweep.yml, event exact_review_queue).
Result: when the review finishes, ClawSweeper will create the durable review comment if needed or update the existing comment in place.

@olddonkey

Copy link
Copy Markdown
Contributor Author

Addressed both custom-pricing findings on 81f1e2e0917425992c356e4a0413d390f6020a8a.

  • Resolve the application overlay against the original model before provider-qualified catalog lookup. Bare-key precedence, explicit zero prices, missing-rate behavior, and cached-input accounting are preserved. Caller-provided custom pricing retains its previous precedence.
  • Preserve explicit xAI custom estimates in the standalone disk/cache report through both override paths. Unconfigured raw xAI rows stay token-only. The physical-attempt fan-out still rejects API-key and historic records for the Grok subscription.

The new regression suite reproduced both findings before the repair. Validation on the final tree: make check passed with zero violations in 2,132 files; make test passed all 1,025 selections / 86 groups on the first pass, with zero failures, retries, or timeouts; the serial Grok/provenance/custom-pricing/producer-import proof passed 124 tests in 12 suites. The production-ledger import still reports five OAuth tokens and zero API-key subscription rows, with a zero-byte cache reopen. Actual native-log totals and recorded-cost provenance remain unchanged.

The PR body now contains the final-head validation and the explicit standalone-price contract. The Grok dollar-display decision remains with the maintainer. Please review this final description and head.

@clawsweeper re-review

@clawsweeper

clawsweeper Bot commented Sep 5, 2026

Copy link
Copy Markdown

🦞🧹
ClawSweeper re-review requested.

I asked ClawSweeper to review this item again.
Action: item re-review queued (workflow sweep.yml, event exact_review_queue).
Result: when the review finishes, ClawSweeper will create the durable review comment if needed or update the existing comment in place.

@olddonkey

Copy link
Copy Markdown
Contributor Author

Synced #3135 with main 0be7714904c311b6349a250407ad88f0ba73c524 in final head c3919a224eeb50298728921290efa784ba987b21.

The generated parser-hash conflict is resolved by regeneration from the merged source (1a4afd74939160fd). Main's atomic catalog replacement does not change native parsed rows or checkpoints, so the released-main hash 9547dc9d7b7675f6 and prior-PR hash 0bd6588c70196700 are retained as compatible predecessors. The actual SQLite adoption tests verify that both preserve stored state without rebuilding. Existing predecessors remain intact.

Main's Linux cache fixes, stacked-chart rendering, provider/widget changes, and release metadata are preserved. The two Grok changelog entries now live under 0.56.8 Unreleased; published release sections match main. The evidence report also records that the producer contract landed through the attributed OpenCodex #3762 carry; its original captured bytes remain pinned and are not represented as a new capture of that carry.

Validation on this final head:

  • make check: zero violations in 2,137 files.
  • make test: 1,031 selections, 86/86 groups passed on the first attempt; zero failures, retries, or timeouts.
  • Focused cache adoption, OpenCodex, architecture, and chart tests: 136 passed.
  • Serial native Grok/producer import/pricing/cache adoption proof: 206 tests in 14 suites passed. Native recorded-cost totals remain unchanged; the producer fixture still contributes five OAuth tokens, excludes API-key subscription rows, and reopens its cache without reading log bytes.

The PR description now contains the final source, commands, and evidence. The default Grok dollar display remains an owner decision. Please review the final head and description.

@clawsweeper re-review

@clawsweeper

clawsweeper Bot commented Sep 6, 2026

Copy link
Copy Markdown

🦞🧹
ClawSweeper re-review requested.

I asked ClawSweeper to review this item again.
Action: item re-review queued (workflow sweep.yml, event exact_review_queue).
Result: when the review finishes, ClawSweeper will create the durable review comment if needed or update the existing comment in place.

@olddonkey

Copy link
Copy Markdown
Contributor Author

Updated to 08744509f9691781b67ee47b242cb57df065012f on current main 7353c717502de72ed10dd1507a3f91d5e9ccb716. The only merge conflict was in CHANGELOG.md; both Grok entries and the new upstream Poe fix are retained.

Current-head validation: make check passed with zero SwiftLint violations; make test passed all 1,031 selections in 86 groups on the first attempt, with zero failures, retries, or timeouts. Grok accounting and OpenCodex import source is unchanged. The PR body distinguishes the current full-suite validation from the earlier supplemental proof.

The default Grok dollar display remains an owner decision, and the prior maintainer change-request review still needs reconsideration.

@clawsweeper re-review

@clawsweeper

clawsweeper Bot commented Sep 6, 2026

Copy link
Copy Markdown

🦞🧹
ClawSweeper re-review requested.

I asked ClawSweeper to review this item again.
Action: item re-review queued (workflow sweep.yml, event exact_review_queue).
Result: when the review finishes, ClawSweeper will create the durable review comment if needed or update the existing comment in place.

@olddonkey

Copy link
Copy Markdown
Contributor Author

@steipete The latest ClawSweeper review of 08744509f reports no actionable findings, and local make check plus all 1,031 test selections passed. Could you confirm whether recorded-first Grok costs with disclosed list-price fallback should be shown to existing users who already enabled cost tracking, and revisit the earlier changes-requested review? The current PR body records the accounting evidence and leaves this display policy decision with you. Cross-platform CI is still running.

@olddonkey

Copy link
Copy Markdown
Contributor Author

Updated to 6f4a7d1058de2180f1f293824074cbbcd15ec5cc after main advanced to 31131374b. The latest integration preserves the upstream Claude warning-state and MiMo fixes. The sole conflict was the architecture gate's source locations and Grok bridge record; the merged gate retains the existing Grok reference fingerprints and correct source lines.

make check passed with zero violations in 2,138 files; 46 focused architecture/Claude/Grok/dashboard tests passed. The required full suite and new CI run are in progress. The previous head passed the full local suite, all nine CI checks, and an exact-head review with no actionable findings. The Grok display-policy decision still belongs to the owner.

@clawsweeper re-review

@clawsweeper

clawsweeper Bot commented Sep 6, 2026

Copy link
Copy Markdown

🦞🧹
ClawSweeper re-review requested.

I asked ClawSweeper to review this item again.
Action: item re-review queued (workflow sweep.yml, event exact_review_queue).
Result: when the review finishes, ClawSweeper will create the durable review comment if needed or update the existing comment in place.

@olddonkey

Copy link
Copy Markdown
Contributor Author

Final validation for 6f4a7d1058de2180f1f293824074cbbcd15ec5cc:

  • All nine GitHub CI checks passed: https://github.com/steipete/CodexBar/actions/runs/34060587552
  • Local make check passed with zero violations in 2,138 files.
  • Local make test passed all 1,032 selections in 86 groups on the first attempt, with no failures, retries, or timeouts.
  • The 46 focused architecture, Claude credential-warning, Grok fallback, and dashboard checks passed.
  • ClawSweeper reviewed this exact head and reports no actionable findings; there are no unresolved inline review threads.

The PR body is updated with the current source and validation. The default Grok dollar-display policy and the earlier maintainer changes-requested review still require the owner's decision.

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

Labels

merge-risk: 🚨 compatibility 🚨 Merging this PR could break existing users, config, migrations, defaults, or upgrades. P2 Normal priority bug or improvement with limited blast radius. proof: sufficient Contributor real behavior proof is sufficient. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants