fix: a valid token no longer waits behind a proactive refresh

Merged
AN
10h ago
+713-25

A request whose own token was valid could wait behind another row's refresh for the same account, because any in-flight refresh for that account and credential epoch made admission join it, with no overall bound.

Joining is now keyed on why the refresh is running, recorded when the job starts:

  • Refresh after a 401 on this token: the request waits for it, since re-sending a rejected token only earns another 401, and never receives a token another joiner saw rejected. One overall join deadline (2 s, Core's existing short join budget) replaces stacked lock waits; on expiry it fails retryably with the existing fixed reset error while the refresh continues.
  • Proactive refresh, or a different credential version: a request with a proven unexpired token that has no recorded rejection is admitted at once through the lock-free path.

Refresh locks, single-use refresh-token protection, attempt caps, backoff and persistence are unchanged.

Red-first regressions on OpenCode 1, OpenCode 2 and Pi (proactive refresh doesn't delay a valid token, a 401 refresh never re-serves the rejected token, the deadline refuses retryably). Mutation rows refresh-join-checks-cause and refresh-join-has-overall-deadline CAUGHT.


Summary by cubic

Fixes a bug where a request carrying a valid token could wait behind a proactive refresh for the same account, because any in-flight refresh made it join with no overall bound.

Joining is now keyed on why the refresh is running:

  • A refresh caused by a 401 on the request's own token: the request waits, capped by a single 2-second overall deadline instead of stacked lock waits. On expiry it fails retryably with the existing fixed reset error while the refresh continues. A validation-retry refusal is also skipped for that token so it can be replaced.
  • A proactive refresh, or a refresh for a different credential version: a request with a proven, unexpired token that has no recorded rejection is admitted immediately through the lock-free path.

A token rejected by any caller in the shared job is never served again. Refresh locks, single-use refresh-token protection, attempt caps, backoff, and persistence are unchanged. Serving exclusions such as refresh backoff, permanent errors, and account policy are still checked before joining.