Repository navigation
Description
Scope and current conclusion
This is a Linux transport-support request, not a quota regression and not a proven transport fix. OAuth quota remains usable; optional Claude subscription dates are absent on the tested VPS. A valid manual session does not guarantee that CodexBar's web requests will be accepted.
The earlier report's curl_cffi comparison was too easy to read as a recommendation. Additional controls below show that no alternative transport has been established as a reliable replacement. I am not asking to merge a new dependency or bypass a challenge based on one successful request.
Reproduction environment
- Official Linux x86_64 v0.84.0 complete release bundle, not a custom build.
- Executable SHA-256:
c1723f529badf182e0d87328aa2f9204f9c635c94948308a868ccf8fa5e6b180. - Linux x86_64; comparison client Python 3.12.3 / curl_cffi 0.17.0.
- An explicitly approved
claudemanualsessionKey, private config mode 0600. The cookie is separate from Claude Platform/Console credentials. - Same VPS/network and credential during each comparison. No proxy, IP change, automated challenge solver or continuously running browser.
Native read-only commands:
codexbar usage --provider claude --source oauth --json
codexbar usage --provider claude --source web --jsonDo not post their unredacted output: it can contain account/usage data. The observed projection at 2026-11-09 10:08 UTC was:
{
"oauth": {
"source": "oauth",
"quotaPresent": true,
"subscriptionRenewsAtPresent": false,
"subscriptionExpiresAtPresent": false
},
"web": {
"exit": 1,
"source": "web",
"errorKind": "provider",
"recognizedCloudflareChallenge": true
}
}The explicit Web failure is CodexBar's recognized Cloudflare error, not an expired-session diagnosis. That initial comparison alone did not locate the optional OAuth failure. The native observation below now does.
Native failure located — supplementary check at 10:44–10:45 UTC
I ran the same official CLI executable twice in a separate one-shot process, with a small metadata-only libcurl observer loaded for that process. This is an instrumented observation of the official binary, not a custom CodexBar build, injected test response or alternative HTTP transport. The observer delegates the original calls unchanged and records only allowlisted route labels, status, timing and a boolean cf-mitigated: challenge marker. It never logs request headers, credentials, account/organization IDs or response bodies, and does not alter TLS, requests, timeouts or retry behavior.
Both executions returned exit 0, valid OAuth quota and absent subscription dates. The decisive second trace at 2026-11-09 10:45:48 UTC was:
| Native request class | HTTP status | Duration | Cloudflare challenge marker |
|---|---|---|---|
| OAuth usage | 200 | 0.319 s | no |
| OAuth profile, ordinary identity read | 200 | 0.317 s | no |
| OAuth profile, optional billing owner check | 200 | 0.201 s | no |
Claude web /api/account |
403 | 0.049 s | yes |
/subscription_details |
not reached | — | — |
The earlier trace at 10:44:39 also recorded successful usage/profile reads and /api/account 403 (0.040 s); it did not yet collect the challenge marker. The second trace therefore adds marker confirmation, not two independent marker observations. The configuration and Claude credential-file hashes were unchanged across both runs; hashes and private values are not published. The observer was not installed in the service or scheduled collection, and its temporary server copy was removed afterward.
This identifies the first failing native optional step: account verification receives a challenge, so fetchVerified returns unavailable before subscription parsing. It is not evidence of a billing-date parser failure or an expired OAuth token. Instrumentation can have timing effects; these traces establish the observed request/status sequence, not universal network behavior or a reliable replacement transport. The complete observer source and reproduction instructions are attached separately.
Controlled comparison and counterevidence
For each row below, read-only GETs to all three paths had the same indicated outcome:
https://claude.ai/api/accounthttps://claude.ai/api/organizationshttps://claude.ai/api/organizations/{verified-org}/subscription_details
Application headers explicitly supplied: the same Cookie: sessionKey=..., Accept: application/json, User-Agent: CodexBar/0.84.0. Redirects were disabled, TLS verification remained enabled, timeout was six seconds. trust_env=False prevented proxy inheritance. The impersonate setting can change TLS/HTTP behavior; its default headers are a separate variable.
| curl_cffi profile | default_headers |
account / organizations / subscription_details |
|---|---|---|
| None | default (True) |
403 / 403 / 403, cf-mitigated: challenge, HTML |
chrome |
default (True) |
200 / 200 / 200, JSON |
| None | False |
200 / 200 / 200, JSON |
chrome |
False |
403 / 403 / 403, cf-mitigated: challenge, HTML |
These are sequential observations on one network, not a stable acceptance guarantee or an isolated proof that TLS alone is responsible. Changing header/profile combinations reverses the result. This is precisely why the successful external client must not be treated as an accepted CodexBar implementation.
Reproduce the matrix only on an authorized account with existing credentials, keeping secrets in memory:
# cookie and verified_org come from the operator's existing authorized session.
# Never print them or put them in command-line arguments.
from curl_cffi import requests
headers = {"Cookie": cookie, "Accept": "application/json", "User-Agent": "CodexBar/0.84.0"}
paths = ["/api/account", "/api/organizations",
"/api/organizations/" + verified_org + "/subscription_details"]
for default_headers in (True, False):
for profile in (None, "chrome"):
with requests.Session(impersonate=profile, trust_env=False) as session:
for path in paths:
r = session.get("https://claude.ai" + path, headers=headers,
default_headers=default_headers,
timeout=6, allow_redirects=False)
# Print a route label, not the URL containing the private org ID.
label = "subscription_details" if path.endswith("subscription_details") else path.rsplit("/", 1)[-1]
print(profile, default_headers, label, r.status_code,
r.headers.get("cf-mitigated"), r.headers.get("content-type"))The comparison is diagnostic only, not a proposed runtime dependency or a request to retry until a challenge is evaded.
Credential and data validity, independently checked
Before and after the successful billing read, the web account UUID and its organization membership matched the profile returned for the OAuth credential supplying quota. Both profile checks and both web account checks returned 200; a header containing only sessionKey was sufficient for the successful comparison. No alternate organization or Console cookie was substituted.
The successful billing response had status: "active", timestamp-string next_charge_at, calendar-string next_charge_date, and null plan_ending_at / plan_ending_before. Its renewal matched the provider billing UI. Actual dates, account identifiers, credentials and monetary values are intentionally not published. This confirms that a renewal exists; it does not prove a new native transport or all plan variants.
Source and prior maintainer boundary
Source reviewed at 7447bc77c2497323d9c41e40164ce705533493c8:
ClaudeWebHTTPTransport.currentusesProviderHTTPClient.sharedoutside test overrides.ClaudeSubscriptionMetadataFetcherhas a two-second optional budget, owner rechecks and fail-soft publication.ClaudeSubscriptionCLITestsalready cover ordinary HTTP failure, unavailable metadata, ownership changes, Off and timeout. They do not establish network acceptance of a new transport.- Support Claude web usage on Linux with manual cookies #4241 deliberately enabled the existing Linux manual-cookie path without promising challenge bypass. Claude: Cloudflare 403 challenge surfaces as "Sign in to claude.ai (or refresh Claude cookies)", with no fallback to the working OAuth usage endpoint #3367 fixed challenge classification. Neither promised that manual cookies make every Linux network portable. Claude Platform: guided CLI login and reauthentication on headless Linux #4845 concerns a different Console-login path.
Explicit decision requested, before any implementation PR
Is an opt-in, supported Linux billing transport investigation in scope, or should this capability remain outside the supported transport boundary? The safest current implementation remains unchanged until that decision. This is a product/dependency decision, not an unresolved assertion that cookies are stale.
If investigation is accepted, acceptance must require a candidate exercised inside CodexBar on the affected network, repeated bounded success without challenge automation, no new discovery/credential mutation, TLS verification, owner isolation, cancellation and the existing total billing deadline. The external matrix alone does not satisfy that gate.
If it is declined, a documentation clarification should explicitly name the split: successful OAuth quota + valid manual cookie can still yield no subscription dates on challenged networks. That documents the limit; it does not implement native billing for this VPS.
In either case, add a specific optional-billing fixture for OAuth profile 200 followed by /api/account 403 with cf-mitigated: challenge and HTML: retain quota, omit dates and assert zero calls to subscription details or post-fetch ownership checks. Existing generic billing-403 tests do not prove this exact path. Keep Off/mismatched-owner/malformed-date/timeout cases fail-soft. A later code PR must run the focused ClaudeSubscription suites and make check. No custom CodexBar build or upstream Swift tests were run for this report; the official release was used with and without the explicitly described per-process observer.
Prepared with AI assistance; claims above distinguish live observations, source inspection and proposed acceptance tests. No private credentials or account-specific billing data are attached.
Activity
clawsweeper commentedon Nov 9, 2026
Codex review: this still needs some work.
Summary
Keep this issue open for a transport-support decision: current source explains the reported missing dates, but preserves quota as designed and establishes no reliable replacement transport.
Reproducibility: Current source establishes that an initial account 403 omits dates while preserving OAuth quota, consistent with the reporter's disclosed release observations; this review ran no live probe or tests.
Maintainer decision needed
Next step
Decide whether to investigate Linux billing transport or document the limit, and add an account-challenge fixture that retains quota and prevents downstream billing reads.
Review details
Best possible solution:
Record the supported Linux billing boundary, preserve quota-first behavior, and admit another transport only after bounded native validation.
Do we have a high-confidence way to reproduce the issue?
Current source establishes that an initial account 403 omits dates while preserving OAuth quota, consistent with the reporter's disclosed release observations; this review ran no live probe or tests.
Is this the best way to solve the issue?
Decision-first scoping is appropriate because the comparison client proves no reliable replacement, while an account-challenge fixture can protect the existing contract independently.
AGENTS.md: found and applied where relevant.
Remaining risk / open question:
Codex review notes: model internal, reasoning medium; reviewed against 7447bc77c249.
Label changes
Label changes:
No label changes.
Label justifications:
P2: Optional subscription dates are unavailable on the reported Linux network while OAuth quota remains usable; no blocked first run or regression is established.impact:auth-provider: The request concerns authenticated Claude web transport used for provider metadata enrichment.Evidence reviewed
What I checked:
AGENTS.md:1, 7447bc77c249)Sources/CodexBarCore/Providers/Claude/ClaudeWeb/ClaudeSubscriptionMetadata.swift:137, 7447bc77c249)Sources/CodexBarCore/Providers/Claude/ClaudeUsageFetcher.swift:875, 7447bc77c249)Tests/CodexBarTests/ClaudeSubscriptionCLITests.swift:55, 7447bc77c249)docs/claude.md:349, 7447bc77c249)How this review workflow works
@clawsweeper re-reviewcomments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.@clawsweeper re-reviewor@clawsweeper re-runon an open PR or issue to request a fresh review only.@clawsweeper reviewto request a fresh review only.@clawsweeper explainto ask for more context, or@clawsweeper stopto stop active automation.Reviewed November 12, 2026, 11:26 AM ET / 16:26 UTC.
[-]Claude Linux CLI: valid web session cannot enrich subscription dates on a challenged transport[/-][+]Claude Linux: challenged web transport leaves optional subscription dates unavailable[/+]mySebbe commentedon Nov 9, 2026
Reworked the report against the review, including counterevidence rather than presenting the external client as a fix. The controlled profile/header matrix reverses success when default headers are disabled, so no reliable replacement transport is claimed. Native OAuth quota, explicit Web challenge, same-owner checks, the two-second optional boundary, and the existing maintainer support decision are separated. The report now asks only for a supported transport-investigation decision; no dependency or implementation PR is proposed without it.
Please assess the corrected evidence and scope. A maintainer decision remains a real gate, not something a favorable issue rating should override.
@clawsweeper re-review
clawsweeper commentedon Nov 9, 2026
🦞👀
Exact review queued.
Re-review progress:
48 remaining items
steipete commentedon Nov 14, 2026
Thanks @mySebbe for the careful follow-up and for separating the native trace from the external-client comparison. The account-check challenge explains the missing dates: OAuth quota succeeds, but optional billing stops at the web account verification step. A valid manual cookie cannot guarantee that the server accepts that request.
We're retaining the existing transport boundary and closing the proposed alternative-transport investigation. PR #5081 adds the exact profile-success/account-challenge fixture and documents that quota can remain available while subscription dates are absent; it does not fix transport acceptance on your VPS. Reconsidering transport support would require a bounded candidate demonstrated inside CodexBar on the affected network, preserving TLS verification, account ownership, cancellation and the billing deadline. The external matrix does not establish that candidate.