fix(opencode): show Zen balance for Go accounts without subscription usage#1498
fix(opencode): show Zen balance for Go accounts without subscription usage#1498kiranmagic7 wants to merge 8 commits into
Conversation
|
Codex review: needs real behavior proof before merge. Reviewed June 15, 2026, 4:29 AM ET / 08:29 UTC. Summary Reproducibility: no. high-confidence live reproduction is available yet. Source inspection shows current main fails before Zen balance fallback and the PR has stubbed regressions, but the real Zen-only dashboard payload proof is still absent. Review metrics: 2 noteworthy metrics.
Merge readiness Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch. Rank-up moves:
Proof guidance:
Mantis proof suggestion Risk before merge
Maintainer options:
Next step before merge
Security Review findings
Review detailsBest possible solution: Keep the current balance-only direction, repair the cancellation race, collect redacted live Zen-only account proof, and remove or intentionally retain the temporary test-artifact workflow before merge. Do we have a high-confidence way to reproduce the issue? No high-confidence live reproduction is available yet. Source inspection shows current main fails before Zen balance fallback and the PR has stubbed regressions, but the real Zen-only dashboard payload proof is still absent. Is this the best way to solve the issue? No for the current head: reusing the existing Zen balance fetch and rendering a balance-only snapshot is the right narrow direction, but the cancellation race and missing live proof need to be resolved before merge. Full review comments:
Overall correctness: patch is incorrect AGENTS.md: found and applied where relevant. Codex review notes: model internal, reasoning high; reviewed against 87b1195969a7. Label changesLabel changes:
Label justifications:
Evidence reviewedAcceptance criteria:
What I checked:
Likely related people:
What the crustacean ranks mean
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
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 22854fa03e
ℹ️ 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".
| else { | ||
| throw error | ||
| } | ||
| let zenBalance = try await self.completedOptionalZenBalance(from: zenBalanceTask) |
There was a problem hiding this comment.
Wait for required Zen balance before rethrowing parse failure
When the Go page has no subscription usage fields, this balance fetch is no longer optional: it is the only way a Zen-only account can succeed. However completedOptionalZenBalance only waits for optionalZenBalanceJoinGrace (250 ms) before cancelling the task, so a normal network response from /workspace/<id> that arrives after that grace period but within the request timeout still causes parseFailed and the account remains broken. In this fallback path, await the balance task to its timeout instead of using the optional/non-blocking helper.
Useful? React with 👍 / 👎.
22854fa to
59e5fca
Compare
|
Addressed the required-fallback review finding: the Zen balance task is now awaited to its normal timeout only when subscription usage is missing, while normal subscription enrichment keeps the 250 ms grace. Added a 400 ms regression and synchronized concurrent request recording; focused tests, @clawsweeper re-review |
|
🦞🧹 I asked ClawSweeper to review this item again. Re-review progress:
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 59e5fca0a5
ℹ️ 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".
| guard case let .parseFailed(message) = error, | ||
| message.contains("Missing usage fields"), | ||
| let zenBalanceTask | ||
| else { | ||
| throw error | ||
| } | ||
| let zenBalance = try await zenBalanceTask.value |
There was a problem hiding this comment.
Reuse the Zen fallback for final parse failures
When the /go response contains enough legacy text to pass fetchUsagePage's precheck (for example a rollingUsage usagePercent) but is still missing the weekly/reset fields required by parseSubscription below, the parseFailed is thrown after this catch block. In that case the already-started /workspace/<id> balance task is canceled by the defer, so an account with no complete subscription windows can still fail even if the Zen balance request succeeded; the same balance-only fallback needs to cover the final parseSubscription failure path too.
Useful? React with 👍 / 👎.
59e5fca to
49524f8
Compare
|
Addressed the latest review finding at @clawsweeper re-review |
|
🦞🧹 I asked ClawSweeper to review this item again. Re-review progress:
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 49524f803f
ℹ️ 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".
| guard case let .parseFailed(message) = error, | ||
| message.contains("Missing usage fields"), | ||
| let task, | ||
| let zenBalance = try await task.value |
There was a problem hiding this comment.
Propagate cancellation while awaiting required Zen balance
When /go has no usage fields and the balance request is still pending, canceling the provider refresh while this fallback is awaiting task.value does not cancel the unstructured zenBalanceTask; the defer only runs after this await returns. In that Zen-only fallback path, the canceled refresh can stay stuck until the balance request finishes or hits the full web timeout, so this await needs cancellation handling that cancels the balance task promptly.
Useful? React with 👍 / 👎.
|
Fixed the remaining cancellation defect at The required Zen-only fallback now cancels its unstructured balance task immediately when the parent provider refresh is canceled, instead of waiting for the balance request timeout. Added a direct regression test that verifies both prompt parent cancellation and cancellation of the underlying balance task. Validation:
The code path is repaired. The existing redacted live Zen-only account proof request remains the merge blocker. @clawsweeper re-review |
|
🦞🧹 I asked ClawSweeper to review this item again. Re-review progress:
|
|
Pushed What changed:
Validation:
@clawsweeper re-review |
|
🦞🧹 I asked ClawSweeper to review this item again. Re-review progress:
|
ad01a74 to
bba5fda
Compare
|
Rebased and repaired exact head The optional Zen enrichment race no longer uses a structured task group that waits for a cancellation-ignoring request when leaving scope. It now returns after the 250 ms grace, cancels the source request, and leaves the required Zen-only fallback path free to wait for the caller's full timeout. This preserves concurrent subscription/balance fetching instead of adding serial latency to every successful refresh. Validation on the rebased exact head:
No live provider/account probe was run. The existing redacted Zen-only account proof request remains the merge gate; this update is intended to make CI and code review green without weakening that requirement. @codex review @clawsweeper re-review |
|
🦞🧹 I asked ClawSweeper to review this item again. Re-review progress:
|
|
Codex Review: Didn't find any major issues. Already looking forward to the next diff. Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
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". |
bba5fda to
26cb5ef
Compare
|
Maintainer rebase onto Rebase testing found and fixed two additional defects before push: optional Zen enrichment could occupy a serial transport before required subscription usage, and non-eligible API errors could start stray balance work. Required usage now starts first with overlapping bounded enrichment; workspace fallback coverage is deterministic.
Merge remains blocked on redacted live proof from a Zen-only account. @codex review |
|
🦞🧹 I asked ClawSweeper to review this item again. Re-review progress:
|
|
Codex Review: Didn't find any major issues. Nice work! Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
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". |
26cb5ef to
86b5fb5
Compare
|
Maintainer rebase and review completed against current Reviewed exact head: Local proof:
This remains proof-gated: do not merge until a redacted Zen-only OpenCode account refresh demonstrates the balance-only state. @codex review |
|
🦞🧹 I asked ClawSweeper to review this item again. Re-review progress:
|
|
Codex Review: Didn't find any major issues. Can't wait for the next one! Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
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". |
|
Exact-head CI is green on Maintainer validation already completed:
Still proof-gated: do not merge until a redacted Zen-only account refresh confirms balance display when no Go subscription usage is present. |
I'd love to help test this behavior as my account has Zen balance without a Go subscription, but I don't have Xcode installed on my Mac to build the plugin from source. Since the macOS CI packaging pipeline is now green, could you please provide a pre-built testing binary (.dmg) or artifact link here? If a pre-built binary becomes available for download, I'll install it and provide a live screenshot confirmation for the Zen-only account state. |
|
Thanks for offering to test this. I checked the exact-head CI run for I will leave the proof gate open for a maintainer-provided build or maintainer/live-account validation. The latest source, tests, and CI are green; the remaining blocker is only the redacted Zen-only account refresh proof. |
86b5fb5 to
63df956
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 63df956e33
ℹ️ 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".
| throw error | ||
| } | ||
| let zenBalance = try await withTaskCancellationHandler { | ||
| try await task.value |
There was a problem hiding this comment.
Race required Zen fallback against cancellation
In a Zen-only fallback where the /workspace/<id> request is backed by a transport that does not stop on Task.cancel(), the cancellation handler only cancels the source task while this await task.value keeps the refresh suspended until that task returns or hits the full web timeout. Fresh evidence: the new fallback still awaits task.value directly here, so cancellation needs to race the required balance task rather than rely on the source observing cancellation.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 9fda9f0258
ℹ️ 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".
| guard case let .parseFailed(message) = error, | ||
| message.contains("Missing usage fields"), | ||
| let task |
There was a problem hiding this comment.
Fetch required Zen balance even when optional usage is off
When a user disables “Show optional credits and extra usage”, OpenCodeGoUsageFetchStrategy passes includeZenBalance: false, so zenBalanceTask is nil here. For a Zen-only account whose /go page has no subscription fields, this new fallback still rethrows Missing usage fields instead of producing the balance-only snapshot, because the only balance request was skipped as optional. The required fallback should start or perform the Zen balance fetch independently of optional enrichment, while subscription accounts can still suppress optional display.
Useful? React with 👍 / 👎.
Summary
Fixes #1476
Tests
swift test --filter OpenCodeGoUsageFetcherErrorTests --skip-update(16 tests passed)make check(SwiftFormat clean, SwiftLint 0 violations, packaging/release-path checks passed)git diff --checkProof and risk