Skip to content

fix(reauth): preserve polling through cancellation HTTP races - #4945

Merged
lidge-jun merged 1 commit into
devfrom
codex/lane-g-2590-reauth-polling
Sep 18, 2026
Merged

lidge-jun merged 1 commit into
devfrom
codex/lane-g-2590-reauth-polling

Conversation

@lidge-jun

@lidge-jun lidge-jun commented Sep 17, 2026

Copy link
Copy Markdown
Owner

Summary

The 2.59.0 merged-tree audit found a race between reauthentication status polling and cancellation ownership. A non-2xx status read stopped the poll loop while a failed DELETE preserved the active device card, so a later successful login was never observed.

Keep the existing polling cadence while cancellation still owns that same flow. Successful terminal responses release ownership and notify completion once. The regression matrix covers pending and committing phases in both response orders, then observes successful completion without another login POST.

Verification

  • Local verification was NOT RUN because this audit lane forbids local tests, suites, typecheck, builds, installs and proxy execution. Hosted CI is the executable verification.
  • Static source/diff review, independent Sol review, and git diff --check completed. All existing cancellation and HTTP-status assertions remain.
  • Regression: gui/tests/main-device-reauth-ownership.test.tsx adds four deterministic cases using the existing controlled request/timer harness.
  • Based on audited dev a0f611d; final merge-result CI belongs to the release host after integration.
  • Exact head fd2f1cd passed Linux 1/4–4/4, gates, macOS 1/2 and smoke checks in run 35278602938. macOS 2/2 job 105395565508 stopped after an unrelated full-picker ordering test, then remained silent for 17m33s before the job limit. The aggregate is failure, and this PR remains draft under the exact-head readiness rule. The release host owns the separate macOS hang investigation; this result has not been rerun or described as capacity loss.

Existing reauthentication card presentation

Presentation reference from #4594, using a synthetic device code. This patch changes polling lifetime behind that card; the image is not a new runtime-verification claim.

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. Same-flow guards, non-2xx rejection and terminal completion ownership remain enforced.

@coderabbitai

coderabbitai Bot commented Sep 17, 2026

Copy link
Copy Markdown
Contributor

Warning

Review limit reached

Next included review available in 28 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used all 10 included reviews currently available.

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Learn how review limits work.

Review configuration:

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Advanced

Run ID: 628771b5-4e09-4d07-b9b3-7a47db0487a3

📥 Commits

Reviewing files that changed from the base of the PR and between a0f611d and fd2f1cd.

📒 Files selected for processing (5)
  • gui/src/components/use-main-device-reauth.ts
  • gui/tests/main-device-reauth-ownership.test.tsx
  • structure/design-methodology.md
  • structure/gui-and-management-api.md
  • structure/overview.md

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 added the bug Something isn't working label Sep 17, 2026
@github-actions

Copy link
Copy Markdown
Contributor

Deterministic PR hygiene checks passed.

@lidge-jun

Copy link
Copy Markdown
Owner Author

리뷰 · 우선순위 73 / 80

이 PR은 메인 계정 기기 재인증(reauth) 카드에서 취소(DELETE)와 상태 폴링(GET)이 동시에 실패/비-2xx로 겹칠 때 폴링이 멈춰 버려, 나중에 성공한 로그인을 못 보는 레이스를 고칩니다. 바로 앞 팁에 들어온 #4594가 “취소 소유권을 유지하고 retryable DELETE 실패 시 카드를 살린다”까지 했고, 이번 패치는 그 연장선에서 같은 flow를 취소 중일 때는 non-2xx GET이어도 폴링 주기를 유지해 이후 terminal(succeeded 등)을 관측하게 합니다.

변경 핵심은 gui/src/components/use-main-device-reauth.ts의 poll 루프입니다. 예전에는 !res.ok이면 곧바로 return해서 루프가 끝났습니다. 이제는 cancellationRequestedFlowRef가 이 flow면 실패 UI만 갱신하고 return하지 않아 다음 sleep 후 GET이 이어집니다. 취소 소유권이 없는 일반 경로의 non-2xx는 이전처럼 폴링을 멈춥니다. main-device-reauth-ownership.test.tsx에 pending/committing × poll-first/cancel-first 네 케이스를 추가해, 양쪽 503 이후에도 succeeded를 보고 completed=1·POST는 1회만임을 고정했습니다. structure 문서 세 곳도 계약을 맞춰 고쳤습니다.

라인 use-main-device-reauth.ts !res.ok + cancellationRequested - 의도는 명확합니다. 다만 cancellationRequested인데 DELETE가 아직 안 나갔거나, 취소 클릭 직후 아주 짧은 창에서만 GET non-2xx가 오면 “취소 소유권” 플래그와 실제 DELETE 진행이 어긋날 수 있는지 확인이 필요합니다. 플래그 set 시점과 DELETE 시작 순서가 테스트 하네스와 실사용에서 동일한지 한 줄 더 적어 두면 좋습니다.

라인 use-main-device-reauth.ts else 분기 succeeded/cancelled/failed - 들여쓰기 재배치로 로직은 이전과 같아야 합니다. diff상 terminal에서 flowRef=null + onCompleted는 succeeded에만 유지된 것으로 보입니다. #4594에서 문서화한 “successful DELETE + terminal failed DTO” 경로와 이번 “keep polling under cancel ownership”이 서로 덮어쓰지 않는지, cancelFailed 배지가 terminal까지 남는지도 기존 테스트가 여전히 통과하는지 CI에서 한 번 더 보면 됩니다.

라인 main-device-reauth-ownership.test.tsx raced polling HTTP error and cancellation - 좋은 회귀입니다. 다만 실제 버그는 “GET non-2xx가 폴링을 영구 중지”였고, 테스트는 양쪽 503 후 한 번의 추가 GET으로 succeeded를 줍니다. sleepers/wake 타이밍에 의존하므로 플레이키하면 고정 타이머나 명시적 poll 카운트 assert를 보강하세요.

메인테이너의 판단이 필요한 지점

  • audit lane이라 로컬 테스트 금지가 맞는지, 그래도 GUI 소유권 스위트만은 CI 필수인지
  • #4594와 연속 랜딩 시 merge-train으로 묶을지, 단독 머지할지
  • draft 상태: 문서·테스트까지 갖췄으면 ready로 올려도 되는지

너의 추천
CI(특히 gui ownership 테스트) 그린 확인 후 draft 해제하고 단독 랜딩해도 됩니다. #4594 불변식을 깨지 않는 좁은 후속이라 우선순위 높습니다. types/config 분할과 무관. leftover 원본 PR 패턴도 아닙니다.

이 댓글은 grok-bot이 작성했습니다

@lidge-jun

Copy link
Copy Markdown
Owner Author

Merging on the macOS exception now recorded in #4956, with the Windows evidence this change needed.

At its exact head all nine Windows shards are green in the dispatched lane=all run, along with the full Linux suite, gates, and the cross-platform smokes. The outstanding macOS legs are the long-standing defect in #4956, which was shown this evening to affect Windows as well and which has now been traced to spawned Bun child processes that are assigned a PID, write nothing to either stream, and never exit. A dedicated lane owns that investigation.

Holding this fix for that defect would delay a correctness fix for a problem it does not share and cannot influence. The release candidate remains held on #4956; this merge is not a promotion and makes no claim about macOS at this SHA.

@lidge-jun
lidge-jun marked this pull request as ready for review September 18, 2026 00:00
@lidge-jun
lidge-jun requested a review from Ingwannu as a code owner September 18, 2026 00:00
@lidge-jun
lidge-jun merged commit d13b059 into dev Sep 18, 2026
87 of 93 checks passed
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 18, 2026

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review Completed 2026-09-18T00:02:45.045054Z fd2f1cd Draft marked ready
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@lidge-jun
lidge-jun deleted the codex/lane-g-2590-reauth-polling branch September 18, 2026 00:00

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: fd2f1cd03d

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

flowRef.current = null;
setState({ phase: "failed", code: failureCode(dto.code) });
return;
if (!cancellationRequested) return;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Release ownership when status says unknown_flow

When cancellation has been requested, this now continues polling after every non-2xx response, including the status endpoint's definitive 404 unknown_flow. If the DELETE response is lost and the server's terminal receipt expires while the browser is suspended or disconnected, each later GET returns unknown_flow, but the hook keeps the stale pending card and issues another GET every two seconds indefinitely instead of allowing re-login. Handle unknown_flow here like the DELETE path by releasing the expired flow, while continuing only for genuinely retryable failures.

AGENTS.md reference: gui/AGENTS.md:L9-L10

Useful? React with 👍 / 👎.

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