[Fix] Restore header-based /usage (revert b87992f drift)#21
Merged
dtzp555-max merged 1 commit intomainfrom Apr 20, 2026
Merged
Conversation
Replaces fetchUsageFromApi() hallucinated /api/oauth/usage endpoint
with the original header-based approach: POST /v1/messages with
max_tokens=1 and extract anthropic-ratelimit-unified-{5h,7d}-{utilization,reset}
from response headers.
Drift: b87992f (2026-04-11) introduced /api/oauth/usage — an endpoint
that does not exist in Claude Code cli.js. Hallucinated. Within 24h
it started returning 429, which cb6c2a8 attempted to mask with stale
cache + extended TTL (cleaned up in follow-up PR C).
Golden reference: 47e39d7 v3.0.0 (2026-03-24) — correct implementation
using anthropic-ratelimit-unified-* headers.
Claude Code cli.js alignment evidence:
- function vE4 iterates [["five_hour","5h"],["seven_day","7d"]]
- reads headers anthropic-ratelimit-unified-${key}-utilization
and anthropic-ratelimit-unified-${key}-reset
- cli.js path: /home/opc/.npm-global/lib/node_modules/@anthropic-ai/claude-code/cli.js
Preserved modernisations from post-47e39d7 work:
- getOAuthCredentials(): keychain + Linux ~/.claude/.credentials.json
- NEW: CLAUDE_CODE_OAUTH_TOKEN env var fallback (highest precedence)
- OAuth refresh on 401 / pre-emptive on expiry
- NEW: exponential refresh backoff 60s -> 3600s to prevent tight
retry loops (previously burned rate-limit in seconds after 401)
Added ALIGNMENT anchor comment at top of block referencing cli.js vE4
and ALIGNMENT.md, so future refactors can grep before re-drifting.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
dtzp555-max
pushed a commit
that referenced
this pull request
Apr 20, 2026
Removes the stale-cache fallback branches in handleUsage() and handleStatus() originally introduced by cb6c2a8 (2026-04-12). Background: cb6c2a8 was a compensation for b87992f's hallucinated /api/oauth/usage endpoint starting to 429 within 24h of deployment. Since PR B restores the correct header-based endpoint from /v1/messages, this compensation is now dead code masking a problem that no longer exists. Changes: - handleUsage: remove `else if (usageCache.data)` stale fallback - handleStatus: remove `else if (usageCache.data)` stale fallback - USAGE_CACHE_TTL: already reset to 5min in PR B's rewritten block (cb6c2a8 had bumped it to 15min as further compensation) Depends on #21 (PR B: restore header-based /usage). Merge PR B first. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
3 tasks
dtzp555-max
pushed a commit
that referenced
this pull request
Apr 20, 2026
…fore grep Two false positives discovered during PR #20 bootstrap CI: 1. /api/usage is a legitimate OCP dashboard route (per-key quota, added in v3.8, server.mjs:1472). The bare token "api/usage" was too broad. 2. The ANCHOR warning comment in server.mjs (added by PR #21) references /api/oauth/usage as a DO-NOT-USE example, triggering the scanner. Fix: require full host "api.anthropic.com/api/oauth/usage" to ensure only real outbound fetch calls trip the guard, and strip line comments with sed before grep so historical ANCHOR warnings pass. Amendment procedure (ALIGNMENT.md) still governs future blacklist changes. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
dtzp555-max
added a commit
that referenced
this pull request
Apr 20, 2026
…drift) (#20) * docs(constitution): establish OCP alignment constitution + CI guardrails (PR A) Introduces the OCP project constitution to structurally prevent the kind of scope drift that produced commit b87992f on 2026-04-11 (the fabricated "/api/oauth/usage" endpoint, which does not appear in cli.js and broke the dashboard usage bar for nine days). This PR is governance-only. It does not modify server.mjs, package.json, or any runtime code. It is intentionally shipped as one reviewable unit per Iron Rule 11 (governance is one layer). Files added: - ALIGNMENT.md Supreme scope document. Core principle: OCP is a proxy layer for Claude Code, not an extension layer. Five binding Rules: grep cli.js first; no invention; match the implementation; unalignable features are deleted; commits cite cli.js line numbers. Includes the 2026-04-11 drift postmortem, the Unalignable Policy, and an Annual Alignment Audit fixed to 11 April each year. - CLAUDE.md Project session instructions. Flags ALIGNMENT.md as required reading before any code. Codifies three hard requirements for server.mjs changes: cli.js citation, CI blacklist pass, and an independent reviewer per Iron Rule 10. References CC 开发铁律 Rules 10, 11, and 12. - .github/PULL_REQUEST_TEMPLATE.md Mandatory "Claude Code Alignment Evidence" section. Three author checkboxes (cli.js citation, scope justification if cli.js does not perform the op, commit-message citations). Reviewer checklist requires opening cli.js at the cited lines before approval. A PR with this section blank receives request-changes. - .github/workflows/alignment.yml Hard-fail blacklist on server.mjs for tokens "api/oauth/usage" and "api/usage" (scan restricted to server.mjs; ALIGNMENT.md and CLAUDE.md may quote them as historical references). Soft check over all PR commit messages for "Claude Code uses X" / "cli.js uses X" assertions lacking a cli.js:NNNN or cli.js vE4 <fn> citation. Historical reference: b87992f ("fix: use dedicated /api/oauth/usage endpoint for reliable plan data") asserted the endpoint was used by Claude Code CLI. The string does not occur in cli.js. Root cause was LLM hallucination accepted without grep verification. See ALIGNMENT.md -> Historical Lesson for the full record. Merge precondition: this PR must be approved by an independent reviewer (Iron Rule 10). The drafter of this commit may not self-approve. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * docs(alignment): pin first audit to 2026-04-20 (cli.js 2.1.89, SHA-256 a9950ef6) First annual alignment audit pin. Records the cli.js version and content hash that the current ALIGNMENT.md codified implementations mirror. - Claude Code version: 2.1.89 - cli.js SHA-256: a9950ef6407fdc750bddb673852485500387e524a99d42385cb81e7d17128e01 - Audit date: 2026-04-20 - Auditor: Tao Deng Next audit: 2027-04-11 (drift anniversary). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * ci(alignment): narrow blacklist to full host+path + strip comments before grep Two false positives discovered during PR #20 bootstrap CI: 1. /api/usage is a legitimate OCP dashboard route (per-key quota, added in v3.8, server.mjs:1472). The bare token "api/usage" was too broad. 2. The ANCHOR warning comment in server.mjs (added by PR #21) references /api/oauth/usage as a DO-NOT-USE example, triggering the scanner. Fix: require full host "api.anthropic.com/api/oauth/usage" to ensure only real outbound fetch calls trip the guard, and strip line comments with sed before grep so historical ANCHOR warnings pass. Amendment procedure (ALIGNMENT.md) still governs future blacklist changes. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Oracle Public Cloud User <opc@instance-20230820-1333.subnet07301351.vcn07301351.oraclevcn.com> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
dtzp555-max
pushed a commit
that referenced
this pull request
Apr 20, 2026
Removes the stale-cache fallback branches in handleUsage() and handleStatus() originally introduced by cb6c2a8 (2026-04-12). Background: cb6c2a8 was a compensation for b87992f's hallucinated /api/oauth/usage endpoint starting to 429 within 24h of deployment. Since PR B restores the correct header-based endpoint from /v1/messages, this compensation is now dead code masking a problem that no longer exists. Changes: - handleUsage: remove `else if (usageCache.data)` stale fallback - handleStatus: remove `else if (usageCache.data)` stale fallback - USAGE_CACHE_TTL: already reset to 5min in PR B's rewritten block (cb6c2a8 had bumped it to 15min as further compensation) Depends on #21 (PR B: restore header-based /usage). Merge PR B first. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
dtzp555-max
added a commit
that referenced
this pull request
Apr 20, 2026
…int (#23) Removes the stale-cache fallback branches in handleUsage() and handleStatus() originally introduced by cb6c2a8 (2026-04-12). Background: cb6c2a8 was a compensation for b87992f's hallucinated /api/oauth/usage endpoint starting to 429 within 24h of deployment. Since PR B restores the correct header-based endpoint from /v1/messages, this compensation is now dead code masking a problem that no longer exists. Changes: - handleUsage: remove `else if (usageCache.data)` stale fallback - handleStatus: remove `else if (usageCache.data)` stale fallback - USAGE_CACHE_TTL: already reset to 5min in PR B's rewritten block (cb6c2a8 had bumped it to 15min as further compensation) Depends on #21 (PR B: restore header-based /usage). Merge PR B first. Co-authored-by: Oracle Public Cloud User <opc@instance-20230820-1333.subnet07301351.vcn07301351.oraclevcn.com> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
dtzp555-max
pushed a commit
that referenced
this pull request
Apr 20, 2026
…s probe Follow-up to #21. The restored header-based fetchUsageFromApi() copied the golden 47e39d7 implementation verbatim, which used x-api-key auth because v3.0.0 targeted API-key users (sk-ant-api03-*). Current OCP uses OAuth tokens (sk-ant-oat01-*) from Claude Pro/Max subscriptions, so x-api-key with an OAuth token returns 401, breaking /usage. Claude Code cli.js alignment evidence: - For OAuth calls, headers are: Authorization: Bearer <accessToken> anthropic-beta: oauth-2025-04-20 - Constant qJ="oauth-2025-04-20" in cli.js - Multiple call sites confirmed (e.g. /v1/files upload, /v1/sessions) Fix: replace x-api-key with Authorization: Bearer + add anthropic-beta header. Matches the exact headers cli.js sends for every OAuth request. ALIGNMENT.md compliance: change aligns OCP with cli.js; CI blacklist unaffected. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2 tasks
dtzp555-max
added a commit
that referenced
this pull request
Apr 20, 2026
…s probe (#24) Follow-up to #21. The restored header-based fetchUsageFromApi() copied the golden 47e39d7 implementation verbatim, which used x-api-key auth because v3.0.0 targeted API-key users (sk-ant-api03-*). Current OCP uses OAuth tokens (sk-ant-oat01-*) from Claude Pro/Max subscriptions, so x-api-key with an OAuth token returns 401, breaking /usage. Claude Code cli.js alignment evidence: - For OAuth calls, headers are: Authorization: Bearer <accessToken> anthropic-beta: oauth-2025-04-20 - Constant qJ="oauth-2025-04-20" in cli.js - Multiple call sites confirmed (e.g. /v1/files upload, /v1/sessions) Fix: replace x-api-key with Authorization: Bearer + add anthropic-beta header. Matches the exact headers cli.js sends for every OAuth request. ALIGNMENT.md compliance: change aligns OCP with cli.js; CI blacklist unaffected. Co-authored-by: Oracle Public Cloud User <opc@instance-20230820-1333.subnet07301351.vcn07301351.oraclevcn.com> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
dtzp555-max
pushed a commit
that referenced
this pull request
Apr 20, 2026
dtzp555-max
added a commit
that referenced
this pull request
Apr 20, 2026
PR #21 (fd7973a) removed the hallucinated /api/oauth/usage endpoint. PR #24 (01e260c) then fixed the OAuth Bearer header for the restored header-based probe. Co-authored-by: Oracle Public Cloud User <opc@instance-20230820-1333.subnet07301351.vcn07301351.oraclevcn.com> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
dtzp555-max
pushed a commit
that referenced
this pull request
Apr 20, 2026
…oration
Minor version bump covering substantive functional + governance changes
since v3.8.0:
Functional
- Restore header-based /usage probe (reads anthropic-ratelimit-unified-*
response headers; mirrors Claude Code cli.js vE4). Progress bars
work again after 9-day drift. PR #21 (fd7973a) + #24 (01e260c).
- Remove stale-cache compensation for the hallucinated endpoint. PR #23.
- CLAUDE_CODE_OAUTH_TOKEN environment variable fallback for credentials.
- Exponential backoff on OAuth refresh (60s -> 3600s) to prevent tight
retry loops that previously burned rate-limit in seconds.
Governance
- ALIGNMENT.md project constitution (five binding rules, annual audit
pinned to 11 April, Historical Lesson recording b87992f drift).
- CLAUDE.md session instructions requiring cli.js citations for every
server.mjs change.
- .github/PULL_REQUEST_TEMPLATE.md with mandatory alignment evidence.
- .github/workflows/alignment.yml CI guardrail (hard-fail blacklist +
soft-check commit citation).
No API / wire-format breaking changes.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
dtzp555-max
added a commit
that referenced
this pull request
Apr 20, 2026
…oration (#26) Minor version bump covering substantive functional + governance changes since v3.8.0: Functional - Restore header-based /usage probe (reads anthropic-ratelimit-unified-* response headers; mirrors Claude Code cli.js vE4). Progress bars work again after 9-day drift. PR #21 (fd7973a) + #24 (01e260c). - Remove stale-cache compensation for the hallucinated endpoint. PR #23. - CLAUDE_CODE_OAUTH_TOKEN environment variable fallback for credentials. - Exponential backoff on OAuth refresh (60s -> 3600s) to prevent tight retry loops that previously burned rate-limit in seconds. Governance - ALIGNMENT.md project constitution (five binding rules, annual audit pinned to 11 April, Historical Lesson recording b87992f drift). - CLAUDE.md session instructions requiring cli.js citations for every server.mjs change. - .github/PULL_REQUEST_TEMPLATE.md with mandatory alignment evidence. - .github/workflows/alignment.yml CI guardrail (hard-fail blacklist + soft-check commit citation). No API / wire-format breaking changes. Co-authored-by: Oracle Public Cloud User <opc@instance-20230820-1333.subnet07301351.vcn07301351.oraclevcn.com> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
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
Reverts the b87992f drift that switched /usage to a hallucinated /api/oauth/usage endpoint, restoring the original header-based approach from the v3.0.0 golden reference (47e39d7).
Alignment evidence
Drift commit: b87992f (2026-04-11) —
fix: use dedicated /api/oauth/usage endpoint for reliable plan data. The endpoint does not exist in Claude Code cli.js. Hallucinated.Golden commit: 47e39d7 (2026-03-24) v3.0.0 — reads
anthropic-ratelimit-unified-{5h,7d}-{utilization,reset}from/v1/messagesresponse headers.Claude Code cli.js:
vE4iterates[["five_hour","5h"],["seven_day","7d"]]anthropic-ratelimit-unified-${key}-utilizationand-resetheaders{utilization: Number(Y), resets_at: Number($)}used_percentage = utilization * 100/home/opc/.npm-global/lib/node_modules/@anthropic-ai/claude-code/cli.jsWhat changed
fetchUsageFromApi()now POSTs minimal/v1/messages(max_tokens=1, content='.') and extracts 9 rate-limit headersparseUsageResponse()(JSON body parser); replaced with inlineparseRateLimitHeaders(rl)Preserved modernisations
getOAuthCredentials()keychain + Linux~/.claude/.credentials.jsonpathsNew in this PR
CLAUDE_CODE_OAUTH_TOKENenv var fallback (highest precedence) — second bug confirmed in prior sessionFollow-ups
plan.currentSession.utilization,plan.weeklyLimits.allModels.utilization, etc.) — verified compatible.Test plan
node -c server.mjssyntax checkcurl -s localhost:11434/usage | jq .planafter localnode server.mjswith valid creds