spec: reconciler token refresh for stale OIDC bug - #470
Conversation
|
🤖 Amber Review — This is a well-reasoned spec that correctly diagnoses the root cause (stale OIDC token embedded in a long-lived Overall: Findings (5)🔴 Critical — Missing call site:
|
Sessions get stuck in Creating when the OIDC token expires during the sandbox readiness polling loop. The SDK client captures a static token at provision time but execAfterReady can block for minutes before calling UpdateStatus. This spec defines the fix: pass the factory instead of a captured client so tokens are refreshed lazily at each API call site. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add missing call sites to Implementation Notes table: sdk.Sessions().Get() at ~line 1054 (exec-retry loop) and ~line 1086 (stop_on_run_finished re-read) - Fix risk levels: completion-phase calls are High, not Medium (longest elapsed time) - Fix incident timeline: token had ~39s remaining at capture, not full 5min TTL - Add "nearly expired at capture" scenario matching actual incident failure mode - Add explicit failSession/ForProject failure scenario with K8s annotation fallback - Add design decision section: why per-call-site patching over client-level token provider Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
24e2c39 to
60d80a7
Compare
Summary
specs/platform/reconciler-token-refresh.spec.md— spec for fixing sessions stuck inCreatingphase due to stale OIDC tokensspecs/index.spec.mdProblem
execAfterReadyreceives a*sdkclient.Clientwith a static bearer token captured at provision time. The sandbox readiness polling loop can block for up to 600s (ndots retries, image pulls, scheduling delays). If the OIDC token expires during this wait,UpdateStatus(phase=Running)fails with HTTP 401 and the session is orphaned inCreatingforever.Observed on 2026-07-31: session
dasfadsfdsahit 3 ndots retries (~26s delay) which pushed the reconciler past the 5-minute token TTL. All subsequent API calls failed with 401.Fix (specified, not yet implemented)
execAfterReadyto acceptprojectIDinstead of*sdkclient.Clientr.factory.ForProject(ctx, projectID)before each API callOIDCTokenProvider.Token()already handles lazy refresh — just needs to be called at the right timeRelated
Test plan
execAfterReady(Running, Failed, Completed)🤖 Generated with Claude Code