feat(cloud): use Codex broker for auth recovery
Summary
Codex authentication recovery now uses the account-scoped refresh broker after confirmation. This Mac remains the single refresh-token holder; only a short-lived access token is delivered to the selected VM. The native device-code prompt is cancellable, bounded, and shows the code in cmux instead of a VM terminal. Claude recovery remains unchanged.
The recovery dialog explains exactly what moves and reminds the user to keep cmux running on this Mac so the broker can renew access. Cancellation, dismissal, logout, and scope changes stop the in-flight prompt without retrying the failed turn. Debug-only fixtures and focused tests cover cancellation, already-cancelled tasks, browser handoff, and successful retry.
Dependencies
The broker and auth-recovery prerequisites have landed. This auth-only follow-up is based on NEXT at 1c1632b0eb6f53b647adf485914d21a67c1cd74f; it preserves the native backend availability check and the account, team, tab, session, and daemon guards from #26148. The wizard switch is separate.
Operational rules
The OpenAI CI/CD auth guidance says:
“Use one auth.json per runner or per serialized workflow stream.”
“Do not share the same file across concurrent jobs or multiple machines.”
The broker follows those rules by keeping refresh state on the user's Mac, serializing refreshes, and delivering only short-lived access to confirmed VMs. It never copies a shared refresh seed into a VM, writes credentials to the repository, or prints them to logs.
Note coverage
This addresses the setup note “Claude failed to authenticate” and the requirement to make “manual transfer claude credentials to VM” explicit and confirmed. Codex recovery now has the same one-click, user-confirmed path while stating that its refresh credential stays on the Mac.
Validation
prepush-gate.py --base 1c1632b0eb6f53b647adf485914d21a67c1cd74f— pass (no new violations; app-size warnings only).- Catalog validation passes; all seven new keys include all 21 locales.
- Focused fleet verification at
cde52914522c43d0644641163b93d19d87c5fa42:CloudCodexDeviceRecoveryTests,CloudCredentialRecoveryTests, andCloudCodexBrokerAdapterTests, cmux-ci step33a791a56a95b31fe3aeda26: PASS (exit 0); app/test package compiled and all three suites passed. - The device prompt has no timer. Its user-answer stream is bounded to one answer; cancellation and scope changes dismiss it, and deferred cleanup finishes the stream.
Native UI evidence
Native cmux app captures at cde52914522c43d0644641163b93d19d87c5fa42, artifact job 2ea571994eaade549d021b8f. The before fixture reproduces the prior disclosure text from 1c1632b0eb6f; it is not an execution of that base build. The after disclosure and device-code prompt use the production native dialog specs. All fixtures are inert; no real credentials or sign-in were used. Capture privacy checks passed.
Before — previous per-VM disclosure (inert reconstruction of existing text)
| Light | Dark |
|---|---|
![]() | ![]() |
After — broker disclosure
| Light | Dark |
|---|---|
![]() | ![]() |
After — native device-code prompt (synthetic DEMO-CODE)
| Light | Dark |
|---|---|
![]() | ![]() |
Review (codex gpt-6-astra xhigh, review-26211): SHIP at cde52914522c43d0644641163b93d19d87c5fa42. No findings.
Agent session: agent session





