Skip to content

feat(claude): share bounded subscription dates across app and CLI - #4324

Merged
steipete merged 6 commits into
steipete:mainfrom
emanuelst:claude-subscription-dates
Oct 8, 2026
Merged

steipete merged 6 commits into
steipete:mainfrom
emanuelst:claude-subscription-dates

Conversation

@emanuelst

@emanuelst emanuelst commented Oct 7, 2026 •

Copy link
Copy Markdown
Contributor

Claude now supplies authenticated subscription renewal or paid-access expiration dates to the existing menu and Settings rows and to codexbar usage --json.

The maintainer pass keeps @emanuelst's billing schema, date-precision support, and ownership checks, while replacing the separate app-only publication worker with the normal provider result path. This also fixes missing CLI output and enrichment for accepted environment OAuth credentials. The original contributor commits remain in the branch.

Billing uses an existing manual or cached cookie. OAuth additionally verifies the account and organization with the exact token accepted for quota, before and after billing; browser ownership is also checked before and after billing, bypassing response caches. Billing has a two-second total budget after quota succeeds. Failures, cancellation of the optional request, unavailable permissions, and unrecognized metadata preserve quota; caller cancellation remains terminal. No billing task writes into an already published snapshot.

Scheduled endings take precedence over renewal. Missing dates render nothing, calendar-only values retain their original day, and JSON exports include the existing subscription fields plus an ...IsDateOnly: true flag when appropriate. Older JSON defaults to timestamp precision. The feature adds 242 net production lines against the lane base, down from 420 in the original contribution.

Verification

All Swift tests use source Scripts/test_environment.sh to scrub inherited secrets and suppress real Keychain access.

  • Red on the original contributor implementation: swift test --build-system native --jobs 4 -Xswiftc -gnone --filter ClaudeSubscriptionCLITests failed one test with four missing date/JSON assertions. A separate focused run confirmed the accepted environment-credential cache gap.
  • Green: swift test --build-system native --jobs 4 -Xswiftc -gnone --filter 'ClaudeSubscription|ClaudeWebFetchDeadlineTests|ClaudeOAuthFetchStrategyAvailabilityTests|ClaudeCredentialOwnershipBoundaryTests|ClaudeActiveAccountIdentityInvalidationTests|WidgetTokenOwnerTests|ProviderArchitectureGatekeeperTests|ProviderSettingsDescriptorTests|UsageSnapshot|OpenAISubscriptionEnrichmentTests|MiniMaxMenuCardBillingTests|MenuCardNeuralWattTests|MenuCardKiloPassTests' — 291 tests in 27 suites passed.
  • Independent Codex autoreview: no actionable P0–P2 findings.
  • source Scripts/test_environment.sh && make check under Bash — passed with zero violations across 2,849 Swift files.
  • CODEXBAR_TEST_SUITE_TIMEOUT=900 ./Scripts/test.sh --swift-command /tmp/codexbar-pr-4324/swift-native --direct-workers 4 — all 144 groups passed (1,596 selections): 143 first-pass successes, one recovered group after a fresh-process retry, zero timeouts. The wrapper forwards test/build to Swift with --build-system native --jobs 4 -Xswiftc -gnone. The longer group limit was needed on the shared host; the initial 180-second run stopped at existing cost-history timeouts. The final run recovered one existing background-pricing test failure.
  • CI for this exact head is attached at https://github.com/steipete/CodexBar/actions/runs/37708640474 and remained queued at the final fresh check (2026-10-08 01:29 UTC), after the lane's 12 status checks. Local verification is complete; merge should wait for CI to complete.
  • Current main was merged to resolve a changelog-only conflict; the final head is b0fdb969b88c8b43e2143a3b75258b3f27bfc45a.

The fixtures establish behavior for the reported subscription_details schema. They do not establish billing endpoint availability for every Pro/Max/Team/Enterprise plan or organization role. The contributor reported live renewal proof; this maintainer pass uses synthetic fixtures. Live cancellation and Team/Enterprise billing availability remain unverified. No real account or running app was used for the tests or renders.

Synthetic production-card proof

Before, with no billing metadata:

Synthetic Claude card without a billing date

After, with a renewal date:

Synthetic Claude card with a renewal date

After, with paid-access expiration:

Synthetic Claude card with a paid-access expiration date

Refs #1119, #1266, #2503.

@clawsweeper

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

@clawsweeper clawsweeper Bot added P2 Normal priority bug or improvement with limited blast radius. proof: sufficient Contributor real behavior proof is sufficient. proof: 📸 screenshot Contributor real behavior proof includes screenshot evidence. rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. labels Oct 7, 2026
@clawsweeper

clawsweeper Bot commented Oct 7, 2026 •

Copy link
Copy Markdown

Codex review: needs real behavior proof before merge. Reviewed October 7, 2026, 9:37 PM ET / October 8, 2026, 01:37 UTC (Revision 6).

ClawSweeper review

What this changes

Adds authenticated Claude subscription renewal and expiration dates to shared app and CLI results while preserving calendar-date precision and successful quota when billing is unavailable.

Example: The user refreshes Claude usage with an available subscription renewal date.

  • Before: Claude quota appears without a subscription renewal row or renewal date in CLI JSON.
  • After: The card shows “Renews: Nov 5, 2026” and JSON includes subscriptionRenewsAt plus subscriptionRenewsAtIsDateOnly: true.

Review scores

Measure Result What it means
Overall readiness 🦐 gold shrimp (3/6) Useful and coherent implementation with supporting compatibility coverage, but current real behavior proof is incomplete.
Proof confidence 🦐 gold shrimp (3/6) Needs stronger real behavior proof before merge: The changed Web/OAuth provider owners are exercised with injected HTTP and quota fixtures, and inspected screenshots show synthetic production-card rendering. Neither demonstrates the replacement authenticated billing path through the shipped app or CLI. Optional precision flags preserve older JSON decoding and snapshot replacement, so no data migration is required. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.
Patch quality 🐚 platinum hermit (4/6) No actionable review findings were identified.

Product

Kind: Feature · Worth it: Yes
User problem: Claude users can see quota reset timing but cannot see when paid access renews or expires.
Reason: Trustworthy billing dates answer a distinct user question using existing presentation. The recorded owner direction and owner-authored shared-provider revision support this bounded capability.

Merge readiness

⛔ Blocked before merge - 2 items remain

This PR needs real behavior proof before merge. The useful, owner-directed implementation has no actionable code findings, but the current authenticated billing path remains demonstrated only with synthetic fixtures and renders.

Priority: P2
Reviewed head: b0fdb969b88c8b43e2143a3b75258b3f27bfc45a

Before merge

  • Add real behavior proof - Needs stronger real behavior proof before merge: The changed Web/OAuth provider owners are exercised with injected HTTP and quota fixtures, and inspected screenshots show synthetic production-card rendering. Neither demonstrates the replacement authenticated billing path through the shipped app or CLI. Optional precision flags preserve older JSON decoding and snapshot replacement, so no data migration is required. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.
  • Complete next step (P2) - Provide a screenshot, terminal transcript, or redacted runtime logs from the current implementation showing authenticated Claude subscription dates alongside successful quota. Redact credentials, account identifiers, private endpoints, and other personal information. Updating the PR body triggers a fresh review; otherwise a maintainer can comment @clawsweeper re-review.

Findings

None.

Tests

  • Missing end-to-end proof: No current-implementation shipped app or CLI run shows authenticated billing dates alongside intact quota. Reported red/green tests compare the replacement with the original contributor implementation, not the pinned main-to-head change; tests were not executed during this read-only review.
Agent review details

How this fits together

CodexBar’s Claude provider retrieves account usage and returns a shared snapshot consumed by the menu, Settings preview, and CLI. This change adds optional billing dates to that snapshot after checking that the existing cookie session belongs to the quota account.

flowchart TD
 A[Accepted Claude quota] --> B[Existing session cookie]
 B --> C[Verify account and organization]
 C --> D[Fetch optional billing dates]
 D --> E[Recheck ownership]
 E --> F[Shared usage snapshot]
 D -->|Unavailable or timeout| F
 F --> G[Menu and Settings]
 F --> H[CLI JSON]
Loading

Technical review

Best possible solution:

Retain the shared, bounded provider enrichment and substantiate it with redacted authenticated app or CLI output from the current implementation.

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

Not applicable to a new capability; current-main source confirms Claude does not populate these billing dates, while synthetic fixtures demonstrate the proposed mapping.

Is this the best way to solve the issue?

Yes. Reusing the existing provider result and subscription rows avoids competing publication paths, although real authenticated execution remains unproven.

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning medium; reviewed against 844b0e19bbbb.

Provenance checked

  • Sources/CodexBar/MenuCardView+ModelHelpers.swift subscription presentation keeps the original intent (Fix MiniMax token plan usage display #1266: Established provider-neutral subscription fields and separate subscription presentation, confirmed by the repository owner’s linked issue discussion.)
  • Sources/CodexBarCore/UsageFetcher.swift subscription serialization and replacement keeps the original intent (867ac58: Carry optional provider-neutral subscription dates without conflating them with quota resets.)
  • Sources/CodexBarCore/Providers/Claude/ClaudeUsageFetcher.swift OAuth enrichment and provider strategy keeps the original intent (Show Claude prepaid balance #2443: Keep optional web enrichment bounded, cancellable, and account-matched without losing successful usage.)
  • Sources/CodexBarCore/Providers/Claude/ClaudeVerifiedAccountOwner.swift and snapshot identity preservation keeps the original intent (Add verified per-account usage widgets #3585: Bind account usage to verified principal and organization identities so another account’s quota cannot be inherited.)
  • Sources/CodexBarCore/Providers/Claude/ClaudeUsageSnapshot+WebExtras.swift snapshot preservation keeps the original intent (b2319cd: Preserve OAuth ownership through optional web enrichment.)

Testing

Proof path: in-process harness. Added test files: 3.

Security

None.

Evidence

What I checked:

  • Pinned introduction and current-main necessity: Read the introduced main-to-head diff and current-main Web strategy. Main returns quota without this Claude billing enrichment; the related merged MiniMax and Codex work supplies reusable presentation rather than this provider implementation. (Sources/CodexBarCore/Providers/Claude/ClaudeProviderDescriptor.swift:875, b0fdb969b88c)
  • Bounded ownership-checked billing: The production fetcher uses a two-second bounded join, checks cookie account membership before billing, rechecks it afterward, and additionally checks the accepted OAuth token’s account and organization. Unavailable metadata leaves accepted quota intact. (Sources/CodexBarCore/Providers/Claude/ClaudeWeb/ClaudeSubscriptionMetadata.swift:95, b0fdb969b88c)
  • Prepared screenshots inspected: Inspected proof-image-1.png, proof-image-2.png, and proof-image-3.png from the prepared manifest. They show synthetic production cards with no billing row, “Renews: Nov 5, 2026,” and “Plan expires: Nov 5, 2026.” They do not exercise authenticated billing or the shipped CLI. (b0fdb969b88c)
  • Current proof scope and review continuity: The complete current PR body explicitly says no real account or running app was used. The authority-proof document describes injected HTTP and quota fixtures. The previous review covered this same head with no findings and requested current-implementation app or CLI proof; that request remains unmet. (docs/claude-subscription-authority-proof.md:32, b0fdb969b88c)
  • Serialization compatibility: New precision flags default to false when absent, are emitted only when true, and survive snapshot replacement. Added coverage checks legacy JSON and the date-precision round trip; existing timestamp fields retain their format. (Sources/CodexBarCore/UsageFetcher.swift:378, b0fdb969b88c)
  • Established subscription direction: The repository owner’s discussion on Show paid-plan expiration / subscription renewal date separately from usage reset timing #1119 explicitly supports additional providers populating trustworthy subscription dates in the existing shared fields. The owner’s current branch commit replaces the separate app worker with the shared provider path. (5349f629a0c8)

Likely related people:

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

Review metrics

Metric Value Why it matters
Production and test growth Production +264/-22 (net +242); tests +336 across 3 files Production growth is justified by isolated billing parsing, ownership checks, bounded enrichment, and backward-compatible date precision.

Labels

Label changes:

  • add proof: 📸 screenshot: Contributor real behavior proof includes screenshot evidence.

Label justifications:

  • P2: Optional subscription-date visibility is a bounded improvement that preserves existing quota workflows.
  • rating: 🦐 gold shrimp: Overall readiness is 🦐 gold shrimp; proof is 🦐 gold shrimp and patch quality is 🐚 platinum hermit.
  • status: 📣 needs proof: The PR needs real behavior proof before ClawSweeper can clear the contributor ask. Needs stronger real behavior proof before merge: The changed Web/OAuth provider owners are exercised with injected HTTP and quota fixtures, and inspected screenshots show synthetic production-card rendering. Neither demonstrates the replacement authenticated billing path through the shipped app or CLI. Optional precision flags preserve older JSON decoding and snapshot replacement, so no data migration is required. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.
  • proof: 📸 screenshot: Contributor real behavior proof includes screenshot evidence.

Rank-up moves

Optional improvements that raise the rating; they are not merge blockers.

  • Add redacted current-implementation app or CLI output showing authenticated subscription dates alongside intact quota.

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 need explicit maintainer commands such as @clawsweeper autofix or @clawsweeper automerge.

History

Review history (5 earlier review cycles)
  • reviewed 2026-10-07T13:01:30.064Z sha 8d85eb5 :: needs changes before merge. :: [P2] Obtain an OAuth owner independently of account widgets | [P2] Use the selected manual cookie for billing enrichment
  • reviewed 2026-10-07T13:30:39.092Z sha ffd11f0 :: needs real behavior proof before merge. :: none
  • reviewed 2026-10-07T14:12:56.643Z sha 66d66f2 :: needs maintainer review before merge. :: none
  • reviewed 2026-10-08T00:23:29.819Z sha 5349f62 :: needs real behavior proof before merge. :: none
  • reviewed 2026-10-08T00:44:57.376Z sha b0fdb96 :: needs real behavior proof before merge. :: none

@clawsweeper clawsweeper Bot added merge-risk: 🚨 security-boundary 🚨 Merging this PR could weaken sandboxing, authorization, credentials, or sensitive data. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. and removed proof: sufficient Contributor real behavior proof is sufficient. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. labels Oct 7, 2026
@clawsweeper clawsweeper Bot added 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. and removed status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. proof: 📸 screenshot Contributor real behavior proof includes screenshot evidence. rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. merge-risk: 🚨 security-boundary 🚨 Merging this PR could weaken sandboxing, authorization, credentials, or sensitive data. labels Oct 7, 2026
Reuse the shared subscription fields and menu rows with calendar-date precision.
Resolve optional billing through the accepted provider fetch, preserving quota
on timeout or unavailable metadata and checking OAuth and cookie ownership.
Remove the separate app publication worker and its memory-cache credential path.

Add synthetic strategy, serialization, ownership and presentation coverage, and
document billing availability limits. Refs steipete#4324.

Co-authored-by: emanuelst <9994339+emanuelst@users.noreply.github.com>
@clawsweeper clawsweeper Bot added proof: 📸 screenshot Contributor real behavior proof includes screenshot evidence. rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. and removed proof: sufficient Contributor real behavior proof is sufficient. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. labels Oct 8, 2026
@steipete steipete changed the title Show Claude plan renewal and expiration dates feat(claude): share bounded subscription dates across app and CLI Oct 8, 2026
@clawsweeper clawsweeper Bot added proof: 📸 screenshot Contributor real behavior proof includes screenshot evidence. and removed proof: 📸 screenshot Contributor real behavior proof includes screenshot evidence. labels Oct 8, 2026
@steipete
steipete merged commit fba66c0 into steipete:main Oct 8, 2026
9 checks passed
@steipete

steipete commented Oct 8, 2026

Copy link
Copy Markdown
Owner

Thanks @emanuelst! Merged in fba66c0 with the maintainer follow-ups: the CLI now fetches the plan dates too, and environment OAuth credentials go through the memory cache the enrichment requires. Plan renewal and expiration dates show in the menu, settings and CLI/JSON output when the account responses carry them. Ships in the next release.

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. proof: 📸 screenshot Contributor real behavior proof includes screenshot evidence. rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. 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