Skip to content

fix(claude): share the per-entry limits parser between OAuth and Web - #4614

Open
Akagilnc wants to merge 5 commits into
steipete:mainfrom
Akagilnc:fix/4126-shared-limits-parser
Open

Akagilnc wants to merge 5 commits into
steipete:mainfrom
Akagilnc:fix/4126-shared-limits-parser

Conversation

@Akagilnc

@Akagilnc Akagilnc commented Oct 18, 2026 •

Copy link
Copy Markdown

Follow-up to #4126 (comment).

OAuth decoded the whole limits array as one typed value under try?, so one entry with an unexpected field type dropped every model-scoped weekly row. OAuth now uses the Web path's existing per-entry parser, and the OAuth-only limit types are removed.

Tests

ClaudeOAuthTests: a sibling entry with a string percent and a Fable entry with a numeric resets_at. The Fable row stays at 5% with no reset time. Fails on main.

Runtime proof

Live OAuth run, this branch's CLI and 0.77.0 (identity fields omitted). Both print:

{"source":"oauth","primary":{"usedPercent":4,"windowMinutes":300},"secondary":{"usedPercent":59,"windowMinutes":10080},"extraRateWindows":[{"id":"claude-weekly-scoped-fable","title":"Fable only","usedPercent":5,"resetsAt":"2026-10-18T21:00:00Z"}]}

Question

A JSON boolean percent reads as 1% / 0% on both paths, the same as Web on main. Intended, or should it be dropped like a string? (Also asked in #4126 (comment).)

Commands run

bash -c 'source ./Scripts/test_environment.sh && swift test --filter "ClaudeOAuthTests|ClaudeWebUsageExtraWindowTests|ClaudeScopedWeeklyLimitMapperTests|ClaudeCloudCreditsTests"'
✔ Test run with 74 tests in 4 suites passed after 0.029 seconds.

make check
Done linting! Found 0 violations, 0 serious in 3051 files.

🤖 Generated with Claude Code

Akagilnc and others added 3 commits October 18, 2026 19:28
OAuth decoded the whole `limits` array as one typed value, so a single entry
with an unexpected field type dropped every model-scoped weekly row. Parse
the array with the Web path's entry-by-entry parser instead and remove the
OAuth-only limit types.

Co-Authored-By: claude-sonnet-5-5 <noreply@anthropic.com>
The per-entry limits parse re-reads the body with JSONSerialization, which
rejects numbers JSONDecoder accepts (e.g. 1e400) and threw for the whole
response. Fall back to an empty limits list instead, as before.

Fold the cross-path limits tests into ClaudeWebUsageExtraWindowTests using
the per-test OAuth defaults fixture, assert the Web primary percent in the
sibling-shape case, and drop the separate suite.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
@clawsweeper

clawsweeper Bot commented Oct 18, 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.

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 18, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-19T04:07:12.781667Z 4790693 New commits
ℹ️ 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" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@clawsweeper clawsweeper Bot added clawsweeper:intake:bug Preliminary submission classification; full source review pending. clawsweeper:intake:needs-repro Preliminary submission classification; full source review pending. 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. and removed clawsweeper:intake:bug Preliminary submission classification; full source review pending. clawsweeper:intake:needs-repro Preliminary submission classification; full source review pending. labels Oct 18, 2026
@clawsweeper

clawsweeper Bot commented Oct 18, 2026 •

Copy link
Copy Markdown

Codex review: needs real behavior proof before merge.

What this changes

This PR makes Claude OAuth reuse the Web parser so unexpected limit-field types do not discard valid sibling quota rows.

Example: An OAuth response contains a session entry with percent "11" and a Fable weekly entry with percent 5 and numeric resets_at 1791800000.

  • Before: Typed decoding discards the entire limits array, hiding the Fable row.
  • After: The Fable row shows 5% with no reset time.

Review scores

Measure Result What it means
Overall readiness 🦪 silver shellfish (2/6) The patch is focused and source-consistent, with useful regression coverage; runtime evidence covers ordinary operation but leaves the changed recovery behavior unproven.
Proof confidence 🦪 silver shellfish (2/6) Real behavior proof is necessary before merge. See Before merge.
Patch quality 🐚 platinum hermit (4/6) No actionable review findings were identified.

Product

Kind: Bug fix · Worth it: Yes · Fix scope: Complete
User problem: An unexpected field type in one OAuth limit can hide otherwise valid model-specific weekly quota rows.
Reason: The maintainer explicitly approved this narrowly scoped hardening, and the patch removes duplicate parsing without adding settings or cross-source account merging.

Merge readiness

⛔ Blocked before merge - 1 item remains

Keep this PR open: it implements explicitly approved parser hardening with a focused change, and inspection found no actionable code defect.

Priority: P2
Reviewed head: 2ca67674b1dc7898029a4baa3456ad2676721106

Before merge

  • Add real behavior proof - The updated PR body shows this branch’s shipped CLI preserving ordinary OAuth quotas and a 5% Fable row against a live account, matching v0.77.0. It does not exercise the changed malformed-field behavior, and the author confirms that case remains test-only because the CLI endpoint is fixed. The previous changed-path proof request therefore remains unresolved: provide terminal output, redacted logs, or a recording showing malformed sibling fields preserve the scoped row and ordinary quotas through the shipped path; redact IPs, API keys, phone numbers, and non-public endpoints. After adding proof, update the PR body, then request a new review with @clawsweeper re-review. The PR author or someone with repository write access can request it.

Findings

None.

Tests

  • Missing end-to-end proof: The supplied live CLI run does not exercise malformed-entry recovery through the shipped OAuth path.
Agent review details

How this fits together

Claude’s OAuth and Web fetchers turn provider usage responses into shared quota windows consumed by the app and CLI.

flowchart LR
  A[OAuth response] --> B[OAuth usage decoder]
  C[Web response] --> D[Shared entry parser]
  B --> D
  D --> E[Scoped weekly mapper]
  E --> F[Usage snapshot]
  F --> G[App and CLI]
Loading

Technical review

Best possible solution:

Use the existing per-entry parser for both sources while preserving quota mapping, row ordering, and ordinary OAuth usage.

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

The base decoder and supplied fixture establish the array-wide failure deterministically in source; no tests were run during this read-only review, and no malformed live response is documented.

Is this the best way to solve the issue?

Reusing the existing Web parser is the smallest complete fix for the demonstrated field-type failures and follows the maintainer’s explicit direction.

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning medium; reviewed against 6480977b47f6.

Provenance checked

  • OAuth and Web scoped weekly parsing changes intended behavior with a stated reason (21e3beb: Expose the provider’s model-scoped weekly quotas through both usage sources.)
  • Reset-date parsing and snapshot mapping keeps the original intent (12e3cc2: Consolidate equivalent ISO-8601 parsing while preserving caller-specific formatting and fallback policies.)

Testing

Proof path: unit tests only.

Security

None.

Evidence

What I checked:

Likely related people:

  • Ivan Kononov: Raw commit 21e3beb adds Sources/CodexBarCore/Providers/Claude/ClaudeWeb/ClaudeWebExtraRateWindowParser.swift:53 relative to its recorded parents. This identifies author metadata, not feature responsibility or a PR merger. (role: source-line author; confidence: high; commits: 21e3beb37743; files: Sources/CodexBarCore/Providers/Claude/ClaudeWeb/ClaudeWebExtraRateWindowParser.swift)

Review metrics

Metric Value Why it matters
Patch size Production +16/-52; tests +22; changelog +4 The shared-parser change removes duplicate production code and adds one focused regression test.

Labels

Label changes:

  • add rating: 🦪 silver shellfish: Overall readiness is 🦪 silver shellfish; proof is 🦪 silver shellfish and patch quality is 🐚 platinum hermit.
  • remove rating: 🧂 unranked krab: Current PR rating is rating: 🦪 silver shellfish, so this older rating label is no longer current.

Label justifications:

  • P2: Malformed OAuth limit fields can hide scoped quota rows while ordinary usage remains available; no affected live payload has been reported.
  • rating: 🦪 silver shellfish: Overall readiness is 🦪 silver shellfish; proof is 🦪 silver shellfish and patch quality is 🐚 platinum hermit.
  • status: 📣 needs proof: The PR needs real behavior proof before ClawSweeper can clear the contributor ask.

Rating scale

6/6 🦀 challenger crab · 5/6 🦞 diamond lobster · 4/6 🐚 platinum hermit · 3/6 🦐 gold shrimp · 2/6 🦪 silver shellfish · 1/6 🧂 unranked krab. Overall follows the weaker of proof and patch quality; ✨ marks media proof (a screenshot, video, or linked artifact) that directly shows the changed behavior.

Workflow

ClawSweeper edits this one comment on every review. Comment @clawsweeper re-review for a fresh review only. Repair and merge execution lanes are retired.

History

Review history (1 earlier review cycle)
  • reviewed 2026-10-18T13:10:43.375Z sha 2ca6767 :: needs real behavior proof before merge. :: none

Reviewed October 18, 2026, 9:43 AM ET / 13:43 UTC (Revision 2).

@Akagilnc

Copy link
Copy Markdown
Author

Added a "Runtime proof" section to the description: a live OAuth run with this branch's CLI and with the released 0.77.0 gives identical output, including the "Fable only" row. A malformed limits entry can't be fed to the shipped CLI (the endpoint is fixed and there is no fixture option), so that case stays covered by the test, which fails on main.

@clawsweeper re-review

@clawsweeper

clawsweeper Bot commented Oct 18, 2026 •

Copy link
Copy Markdown

🦞👀
Exact review queued.

Re-review progress:

@clawsweeper clawsweeper Bot added clawsweeper:intake:bug Preliminary submission classification; full source review pending. clawsweeper:intake:needs-repro Preliminary submission classification; full source review pending. rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. and removed rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. clawsweeper:intake:bug Preliminary submission classification; full source review pending. clawsweeper:intake:needs-repro Preliminary submission classification; full source review pending. labels Oct 18, 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: 4790693616

ℹ️ 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 on lines +183 to +184
let json = try? JSONSerialization.jsonObject(with: data) as? [String: Any]
usage.limits = json.map(ClaudeWebExtraRateWindowParser.scopedWeeklyLimits)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Parse OAuth limits without a whole-body serialization gate

When an OAuth response includes an otherwise ignored field whose JSON number Foundation cannot materialize (for example a future field on a sibling limit with 1e400), JSONDecoder successfully builds the usage response but this whole-body JSONSerialization re-read returns nil, so usage.limits is left empty. Before this change the typed decoder ignored such unknown fields and retained a valid weekly_scoped sibling, whereas the new path silently removes its model row; decode limits through a lossy Decodable entry wrapper instead of making it contingent on serializing the entire response.

Useful? React with 👍 / 👎.

This branch has not been deployed

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

Labels

P2 Normal priority bug or improvement with limited blast radius. rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants