Sitelet https://github.com/lidge-jun/opencodex/pull/6745
Skip to content

fix(oauth): bound and classify ChatGPT token refresh failures - #6745

Draft
luvs01 wants to merge 1 commit into
lidge-jun:devfrom
luvs01:fix/chatgpt-refresh-hardening-upstream
Draft

luvs01 wants to merge 1 commit into
lidge-jun:devfrom
luvs01:fix/chatgpt-refresh-hardening-upstream

Conversation

@luvs01

@luvs01 luvs01 commented Oct 8, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

The registered ChatGPT OAuth refresh provider dropped caller cancellation, had no fetch deadline, and could repeatedly retry expired or invalidated refresh grants. It could also interpret availability failures as terminal from the provider's free-text description.

  • Forward refresh cancellation and compose it with a fresh 30-second fetch deadline. Browser token exchange uses the same bound and its login controller's cancellation signal.
  • Carry HTTP status, an allowlisted OAuth code and the shared Codex refresh classifier's terminal verdict in ChatGptTokenError. The generic refresh path marks only the matching credential generation needsReauth; transient failures remain eligible for recovery.
  • Expose only status and the allowlisted code in token errors. Provider descriptions, nested messages and unknown codes do not reach error messages, properties or stacks.
  • Add synthetic coverage for flat and nested grant refusals, availability failures, cancellation, deadlines, recovery, redaction and concurrent credential replacement. Update the OAuth structure contract and account reference.

Prepared on dev at dfea21d2d244b1bdca716857225d32d130f9c7e4. Adapted from source commits f3e3c34a8bb5d7de7bc30625f0b2834425aee142, a905ab36a7ffce2299544549f1db93985263568e and 8657241015b7bb62298ec2769ae88e7ba64ad22f, with browser cancellation and stronger regression coverage added here.

This is independent of #6594's import-cycle refactor. Its ChatGPT file move was applied in a separate compatibility worktree, followed by this change using Git's 3-way application: no conflicts, clean typecheck and 81 passing related tests. That refactor is not included in this branch.

Verification

Tests use Bun 1.4.0, as required by testRunnerBun. Runtime/tooling commands use the installed Bun 1.4.2. Token-endpoint responses are synthetic. No provider credentials, real accounts or paid calls were used. All test commands below were run with an additional --preload pointing to an untracked offline guard: to reproduce it, wrap the original global fetch and reject hosts other than localhost, 127.0.0.1 and ::1. Tests replace fetch with synthetic executors where vendor URLs are exercised.

  • bun run test tests/oauth: 701 pass, 0 fail, 38 files. The same command on pristine base dfea21d2d gives 672 pass, 0 fail.
  • bun test tests/oauth/chatgpt-token-expiry.test.ts tests/oauth/oauth-refresh-generic-lock.test.ts: 39 pass, 0 fail.
  • bun run test:changed tests/oauth tests/codex-integration/codex-account-store-refresh-classification.test.ts tests/codex-integration/codex-main-account-refresh.test.ts tests/lab/core-lab-boundary.test.ts: 698 pass, 0 fail, 35 files, resolved comparison upstream/dev at dfea21d2d.
  • bun test tests/test-layout.test.ts tests/test-layout-tooling.test.ts tests/lab/core-lab-boundary.test.ts tests/codex-integration/codex-account-store-refresh-classification.test.ts tests/codex-integration/codex-main-account-refresh.test.ts tests/ci-workflows/structure-ssot.test.ts tests/ci-workflows/repo-hygiene.test.ts: 142 pass, 0 fail.
  • bun run typecheck, bun run privacy:scan, bun run structure:check, bun scripts/file-size-ratchet.ts, git diff --check: pass.
  • In docs-site, bun install --frozen-lockfile, then ASTRO_TELEMETRY_DISABLED=1 bun run build with XDG_CONFIG_HOME set to a temporary directory: pass, 569 pages and 79,090 internal links checked.
  • Seven additional scratch behavioral probes fail on pristine base and pass on the candidate. They cover registry cancellation, the default deadline, error redaction, nested terminal codes, needsReauth, transient preservation and browser cancellation/deadline.
  • A single in-flight browser-cancellation probe was also run against the exact Devin source head 8657241015b7bb62298ec2769ae88e7ba64ad22f and the frozen candidate: 0 pass / 1 fail on Devin, 1 pass / 0 fail here. Caller abort leaves Devin's fetch signal un-aborted; this candidate aborts it immediately and preserves the exact caller AbortError. The control is bounded by a 100 ms synthetic harness fallback, not provider traffic.

Full repository and platform-matrix tests were not run locally: this is a focused four-file OAuth behavior change plus two required documentation updates, while the repository has over 2,300 test files. Local coverage includes the complete OAuth domain, its shared classifier consumers, import-connected selection and structural/privacy guards. Required upstream CI still needs to run on the submitted head.

A preliminary bare, non-isolated bun test tests/oauth run had the same existing oauth-health.test.ts failure on both base and candidate (Codex reauth action points at the dashboard pool, not ocx login codex, missing entry at line 331). Both complete domain runs pass with the repository's official isolated test wrapper.

Checklist

  • Scope stays focused and avoids unrelated cleanup.
  • Docs or release notes were updated when needed.
  • Security-sensitive changes were reviewed for secrets, auth, and unsafe defaults.

Local auth/security review is complete. Explicit maintainer security review and the maintainer-sponsored gate remain required before merge; no label, workflow or security-setting changes are included.

Forward caller cancellation through the registered refresh provider and
compose it with a fresh 30-second fetch deadline. Apply the same deadline
and login cancellation to browser token exchange. Reuse the closed Codex
refresh classifier for terminal account-state decisions and redact all
provider-controlled descriptions and unknown codes from token errors.

Adapt the refresh hardening from source commits f3e3c34,
a905ab3 and 8657241 onto current dev. Add synthetic end-to-end
coverage for cancellation, deadlines, terminal/transient responses,
credential generation races, recovery and redaction.

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
@coderabbitai

coderabbitai Bot commented Oct 8, 2026

Copy link
Copy Markdown
Contributor

Important

Draft PR not reviewed

Draft PRs are not automatically reviewed by default.

  • Trigger a manual review

To automatically review draft PRs, update your CodeRabbit configuration:

reviews:
  auto_review:
    drafts: true
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions

github-actions Bot commented Oct 8, 2026

Copy link
Copy Markdown
Contributor

✅ Deterministic PR hygiene checks passed.

@github-actions github-actions Bot added the bug Something isn't working label Oct 8, 2026

This branch has not been deployed

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

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant