Skip to content

[Bug]: Grok coupon redemption can release the client hold on post-open lock or read failures #6897

Closed

Description

@lidge-jun

Client or integration

OpenCodex dashboard

Area

Authentication and account pool

Summary

The irreversible-redemption contract that #6870 introduces is that a caller is never told it may open a replacement operation while the same operation might still be spending. A few remaining paths in Grok reset-coupon redemption still break it. #6870 (merged as d49df2f) made dev strictly safer than before, and the merge debate recorded these items as follow-ups:

  • B1: when the claim mark hits SQLite contention, the request returns 500 attempt_mark_failed ("no redemption was attempted").
  • B2: when a late refusal cannot take the mutation lock, the request returns 503 ledger_unavailable.
  • B3: when the remaining-resets read fails after the operation opens, the request returns 502 fetch_resets_failed without re-reading the operation state.

In each of these, the GUI (useGrokResetCoupons) releases its hold, and the CLI does not print --operation-id. A same-operation winner may still be dispatching.

  • N1 (exists on dev too): the GUI hold lives in controller state, so unmounting and remounting the provider panel drops it.
  • H1 (hardening): the ledger validator accepts an attempted record that carries a code, and replays it as definitive.
  • H2 (hardening): with duplicate grpc-status trailers, the last one wins, so a conflicting pair can settle as redeemed.

Expected: once an operation has opened, every non-definitive error returns the uncertain contract (attempt_in_progress / operation_state_changed with operationId). Paths that can re-read the operation do so first, and replay a terminal winner when there is one. GUI/CLI treat these codes as uncertain. The hold survives navigation. The ledger refuses an attempted+code record, and conflicting trailers stay unresolved.

Reproduction

All reproduction is with mocked upstreams; never reproduce against a live account.

  1. Open operation X from request A. While A is inspecting, let a second same-operation request claim X and dispatch.
  2. Hold BEGIN IMMEDIATE on the config mutation database from another connection while A reaches its claim (B1) or its late refusal with an empty list (B2), or make A's remaining-resets read fail (B3).
  3. Observe a definitive error code on A, the hold cleared in the GUI, and a second confirmation admitted under a new operation id.

Regressions should assert the uncertain code, the operationId, zero dispatches by the losing request, and no admission of a replacement. They should also cover the GUI hold and CLI --operation-id for each code.

Version

dev d49df2f

Operating system

All (macOS, Linux, Windows)

Provider and model

xAI / Grok (reset coupons)

Checks

  • I searched existing issues and documentation.
  • I removed secrets, tokens, account details, request credentials, and personal data.

Activity

  1. lidge-jun commented on Oct 10, 2026

    @lidge-jun
    OwnerAuthor

    Fixed on dev by #6916 (squash 433764e9d8). The server, CLI and dashboard now keep the caller on the same operation until the ledger proves its outcome. This covers contended claim marks, late-refusal records, post-open list-read failures, the GUI hold across panel remounts, ledger records that are attempted but carry a code, conflicting duplicate grpc-status trailers, and unrecognized settled codes. Each path has a fail-first regression, verified with mocked upstreams only.

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    account-poolOAuth, credentials, Codex pool, quota, failover, plansbugSomething isn't working

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions