Skip to content

Opt-in expiry runway for Codex reset credits (addresses #1758)#1907

Closed
cleanerzkp wants to merge 1 commit into
steipete:mainfrom
cleanerzkp:codex-expiry-runway
Closed

Opt-in expiry runway for Codex reset credits (addresses #1758)#1907
cleanerzkp wants to merge 1 commit into
steipete:mainfrom
cleanerzkp:codex-expiry-runway

Conversation

@cleanerzkp

Copy link
Copy Markdown
Contributor

Summary

An opt-in "expiry runway" view for the Codex reset-credits menu row: a horizontal timeline with one dot per credit, so all expiries are visible at a glance instead of clipped behind +N in the compact list. Addresses #1758 (show all reset-credit expirations, not only the soonest).

Default is unchanged — this ships behind a new CreditExpiryDisplayStyle picker (Display settings) defaulting to .list, so nobody's current row changes unless they opt in. Happy to flip the default or drop the setting entirely — see the open question below.

Why

The 0.39.x compact list (#1902) reads well at 2–3 credits but at 4+ it clips (7d 7h · 13d 5h · 22d 4h · +2) and asks you to place four countdowns on a mental timeline. The runway makes position carry the timing: a far-right cluster reads "nothing expires for weeks" pre-attentively, and the nearest dot turns red under 48h. Hovering any dot reveals its exact countdown + absolute date (mirroring the ZaiHourlyUsageChartMenuView hover), so the runway is a strict superset of the list — no information is lost, and the row's .help() tooltip + accessibility label are untouched.

Design notes (kept native)

  • Data-derived horizon (max(expiresAt − grantedAt) across the inventory) — no hardcoded window; credits with no expiry stay counted/in the tooltip but off the track.
  • Theming via MenuHighlightStyle (progressTrack / progressTint / error), mirroring UsageProgressBar, so the runway stays legible on the highlighted (blue) row rather than clashing with raw .accentColor/.red.
  • Reset-time style is respected for free (the nearest label reuses compactExpiryText); hover shows both forms.
  • Reduce Motion: hover scale/fade gate on accessibilityReduceMotion (per QuotaWarningAlertOverlayController).
  • Height fingerprint: the runway is a distinct fixed-height row, so CodexResetCreditsPresentation.heightFingerprint gets a runway discriminator (the honest cost of gating — two heights).

Open question for you

Straight replacement, or keep the gate (this PR)? Replacement is defensible since hover makes the runway a superset of the list and it drops the second height/settings surface; the gate keeps your fresh default untouched. I went with opt-in to be conservative on a surface you just built — flipping the default or removing the picker is a one-line change, your call.

Not in scope (declared): single-point resets (session/weekly/monthly, CodexCreditLimitSnapshot.resetsAt) stay as text — one timestamp needs no axis. A natural future adopter is OpenAI API credit grants (per-grant expiresAt exists but the snapshot currently collapses to nextGrantExpiry, so it'd need fetcher plumbing first) — happy to follow up if this direction lands.

Commands run

  • swift build — green
  • swift test --filter CodexResetCreditRunwayTests --filter CodexResetCreditsMenuCardTests --filter MenuCardHeightFingerprintTests — green
  • make check — SwiftFormat + SwiftLint + locale gate green

Tests

CodexResetCreditRunwayTests covers marker placement over the data-derived horizon, the nearest-credit flag, <48h urgency, no-expiry exclusion, empty→list fallback, the horizon label, and that make(…) only builds runway data for .runway.

Render the reset-credit inventory as a horizontal timeline — one dot per
credit, positioned by remaining time over the longest credit lifetime —
behind a new CreditExpiryDisplayStyle picker that defaults to the existing
compact list. Addresses steipete#1758 (show all reset-credit expirations, not only
the soonest).

- Colors resolve through MenuHighlightStyle so the runway stays legible on
  the highlighted row; hover reveals each credit's exact countdown +
  absolute date, mirroring the Z.ai chart; hover animation gates on
  accessibilityReduceMotion.
- Data-derived horizon (max expiresAt - grantedAt); no-expiry credits stay
  counted and in the tooltip but off the track.
- Distinct height fingerprint for the runway row.
- Extract loadQuotaWarningMarkersVisible to keep loadDefaultsState within
  the function-length limit.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@clawsweeper

clawsweeper Bot commented Jul 5, 2026

Copy link
Copy Markdown

Codex review: needs real behavior proof before merge. Reviewed July 4, 2026, 9:35 PM ET / 01:35 UTC.

Summary
The branch adds an opt-in timeline-style Codex reset-credit expiry display, a persisted display picker, localized picker strings, height-fingerprint handling, and focused runway tests.

Reproducibility: not applicable. as a feature PR rather than a bug report. Source inspection confirms current main already has compact expiry text and full help text, while this PR proposes a new opt-in timeline view for the remaining at-a-glance concern.

Review metrics: 2 noteworthy metrics.

  • Changed surface: 17 files, +426/-23. The PR spans SwiftUI rendering, settings persistence, localization, and tests, so it needs UI and settings review rather than parser-only review.
  • Locale coverage: 4 updated, 19 fallback-only. The new visible picker labels are added for English and the strict locales, while other app locales fall back to English until translated.

Merge readiness
Overall: 🧂 unranked krab
Proof: 🧂 unranked krab
Patch quality: 🐚 platinum hermit
Result: blocked until real behavior proof is added.

Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch.

Rank-up moves:

  • [P1] Add a redacted screenshot or short recording of the built app showing the Display picker and timeline row in the Codex menu.
  • State whether the preferred product direction is still opt-in, replacement, or maintainer’s choice after review.
  • If the macOS shard remains failed, update with the failure cause or a rerun result after logs are available.

Proof guidance:

  • [P1] Needs real behavior proof before merge: No after-fix screenshot, recording, terminal output, logs, or linked artifact is present; add redacted built-app UI proof before merge. 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.

Mantis proof suggestion
A visible menu/settings change is best verified with before/after built-app UI proof. A maintainer can ask Mantis to capture proof by posting this exact PR comment:

@openclaw-mantis visual task: verify the Codex reset-credit expiry style picker and timeline row in the built CodexBar app.

Risk before merge

  • [P1] The new timeline row is visual SwiftUI behavior, but the PR currently provides no built-app screenshot or recording proving the picker, row height, hover label, and highlighted-row colors work in the real menu.
  • [P1] The author explicitly asks whether this should be an opt-in setting or a replacement, so the added persistent configuration surface needs maintainer product direction before merge.
  • [P1] Hosted GitHub status was not clean at inspection time: one macOS shard was failing and logs were not yet available while other checks were still pending.

Maintainer options:

  1. Decide the mitigation before merge
    Choose the intended product shape for reset-credit expiry visibility, then land the narrow UI after redacted built-app proof and clean required checks, keeping the current compact list as the default unless maintainers decide otherwise.
  2. Pause or close
    Do not merge this PR until maintainers decide whether the risk is worth taking.

Next step before merge

  • [P1] Human review is needed because the remaining blockers are product direction, contributor UI proof, and hosted check status rather than a narrow automated code repair.

Security
Cleared: No concrete security or supply-chain concern was found; the diff is limited to UI, settings defaults, localization, and tests.

Review details

Best possible solution:

Choose the intended product shape for reset-credit expiry visibility, then land the narrow UI after redacted built-app proof and clean required checks, keeping the current compact list as the default unless maintainers decide otherwise.

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

Not applicable as a feature PR rather than a bug report. Source inspection confirms current main already has compact expiry text and full help text, while this PR proposes a new opt-in timeline view for the remaining at-a-glance concern.

Is this the best way to solve the issue?

Unclear until maintainers choose the product shape. The implementation is narrow and default-compatible, but the new setting versus replacement decision and missing real UI proof should be resolved before merge.

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning high; reviewed against 17347d847b15.

Label changes

Label changes:

  • add P3: This is a low-risk optional UI enhancement for reset-credit expiry visibility, not an urgent runtime regression.
  • add rating: 🧂 unranked krab: Overall readiness is 🧂 unranked krab; proof is 🧂 unranked krab and patch quality is 🐚 platinum hermit.
  • add status: 📣 needs proof: The PR needs real behavior proof before ClawSweeper can clear the contributor ask. Needs real behavior proof before merge: No after-fix screenshot, recording, terminal output, logs, or linked artifact is present; add redacted built-app UI proof before merge. 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.

Label justifications:

  • P3: This is a low-risk optional UI enhancement for reset-credit expiry visibility, not an urgent runtime regression.
  • rating: 🧂 unranked krab: Overall readiness is 🧂 unranked krab; proof is 🧂 unranked krab and patch quality is 🐚 platinum hermit.
  • status: 📣 needs proof: The PR needs real behavior proof before ClawSweeper can clear the contributor ask. Needs real behavior proof before merge: No after-fix screenshot, recording, terminal output, logs, or linked artifact is present; add redacted built-app UI proof before merge. 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.
Evidence reviewed

Acceptance criteria:

  • [P1] swift build.
  • [P1] swift test --filter CodexResetCreditRunwayTests --filter CodexResetCreditsMenuCardTests --filter MenuCardHeightFingerprintTests.
  • [P1] make check.

What I checked:

Likely related people:

  • steipete: Authored the merged compact reset-credit expiry PR and prior maintainer discussion around splitting all-expiration inventory from broader reset-credit behavior. (role: recent reset-credit display owner; confidence: high; commits: c5cf41c94411, e437044c32ba; files: Sources/CodexBar/MenuCardView+CodexResetCredits.swift, Sources/CodexBar/MenuCardHeightFingerprint.swift, Tests/CodexBarTests/CodexResetCreditsMenuCardTests.swift)
  • rogdex24: Authored the merged PR that introduced Codex rate-limit reset credits, menu-card display, CLI output, and focused reset-credit tests. (role: introduced behavior; confidence: high; commits: a3ea16743560; files: Sources/CodexBar/MenuCardView+CodexResetCredits.swift, Sources/CodexBarCore/CreditsModels.swift, Sources/CodexBarCore/Providers/Codex/CodexOAuth/CodexOAuthUsageFetcher.swift)
  • Zihao-Qi: Recently merged the settings window layout changes touching the Display pane that this PR now extends with a new picker. (role: recent settings-area contributor; confidence: medium; commits: 17347d847b15; files: Sources/CodexBar/PreferencesDisplayPane.swift, Sources/CodexBar/PreferencesView.swift, Tests/CodexBarTests/SettingsWindowAppearanceTests.swift)
What the crustacean ranks mean
  • 🦀 challenger crab: rare, exceptional readiness with strong proof, clean implementation, and convincing validation.
  • 🦞 diamond lobster: very strong readiness with only minor maintainer review expected.
  • 🐚 platinum hermit: good normal PR, likely mergeable with ordinary maintainer review.
  • 🦐 gold shrimp: useful signal, but proof or patch confidence is still limited.
  • 🦪 silver shellfish: thin signal; proof, validation, or implementation needs work.
  • 🧂 unranked krab: not merge-ready because proof is missing/unusable or there are serious correctness or safety concerns.
  • 🌊 off-meta tidepool: rating does not apply to this item.

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.

How this review workflow works
  • 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.

@clawsweeper clawsweeper Bot added 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. P3 Low-risk cleanup, docs, polish, ergonomics, or speculative feature. labels Jul 5, 2026
@steipete

steipete commented Jul 5, 2026

Copy link
Copy Markdown
Owner

Thanks for the thoughtful implementation and especially the attention to highlight styling, accessibility, and focused tests.

I am closing this as superseded by #1902 (c5cf41c94411bd783aaf0ebf16320eb65eaf63f6). That landed the product direction we want: one compact expiry summary in the menu, with the complete sorted inventory retained in tooltip and accessibility text. The optional runway would add a 17-file persistent Display setting for a low-frequency row immediately after we simplified Settings, so the extra configuration and rendering surface is not justified here.

The current CI failures are not the reason for closing; the core issue is product/scope fit. Thank you for exploring the alternative so thoroughly.

@steipete steipete closed this Jul 5, 2026
@cleanerzkp

Copy link
Copy Markdown
Contributor Author

Status update on the two failing macOS shards from the first run (both now understood):

  • swift-test-macos (1, 4) — real bug on my side: the new credit_expiry_style_* picker strings were added to English + the strict locales (ar/fa/th) but not the fully-maintained catalogs, so LocalizationLanguageCatalogTests (Galician/Turkish/Ukrainian/Korean exact-key-match) failed. Fixed in 57dd27c0 — the keys are now in all 23 catalogs with translations; LocalizationLanguageCatalogTests (22/22) and make check (23 locales) pass locally.
  • swift-test-macos (3, 4) — CI infra flake, not the code: the job failed at 40s in swift test list with fatal: cannot change to .../org.swift.swiftpm/repositories/...: No such file or directory for swift-crypto/sparkle/swift-log/etc. — a corrupted SwiftPM cache on that runner. A fresh run should clear it.

Also folded in a small /simplify pass (route the runway horizon/hover labels through the existing compactExpiryText).

On your review questions: product direction is opt-in by default (picker defaults to the current list; the runway changes nothing unless selected) — happy to make it replacement or drop the gate, your call. The new run needs a maintainer approval to start; @clawsweeper re-review once it's green. Built-app light/dark screenshots to follow.

@cleanerzkp

Copy link
Copy Markdown
Contributor Author
CleanShot 2026-07-05 at 11 05 46@2x [*]

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

Labels

P3 Low-risk cleanup, docs, polish, ergonomics, or speculative feature. 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.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants