Repository navigation
codex-restart quits the desktop shell where upstream restarts only the app-server, discarding unsaved client state #4761
Description
Client or integration
Codex App
Area
Service lifecycle
Summary
ocx system codex-restart quits and relaunches the whole Codex desktop shell. Upstream's own restart operation does not: codex app-server daemon restart stops and starts only the app-server process it manages, refuses to act when the responding app-server is not daemon-managed, and waits for the replacement to pass a readiness probe. Upstream treats a server restart as something clients survive — SIGTERM means "graceful restart drain", the acceptor stops once running turns reach zero, and connected clients reconnect.
Because we terminate the desktop shell instead, everything that lived only in the client is discarded: an unsaved model-picker selection, an in-progress composer draft, and any approval prompt waiting for the user. The desktop restart path finds root Codex shell processes, asks them to quit, force-stops survivors, and relaunches the app; it never starts or readiness-probes an app-server itself and relies on the relaunched desktop to create replacements.
This is not a regression and not a defect in the current implementation. That code is careful: it revalidates process start times before signalling, refuses uncertain app-server identities, and is gated behind an explicit --yes. The scope is not gratuitous either — model_catalog_json is startup-only upstream, so a catalog change genuinely cannot be picked up by a running desktop without restarting it, and config/batchWrite.reloadUserConfig reapplies only reloadable settings and is documented as neither a process restart nor a catalog reload.
The debt is that the only tool offered for "pick up the new catalog" is the most destructive one available, and the user pays unsaved client state for it every time. Worth considering: detect whether the catalog actually changed and skip the desktop restart when it did not; restart app-servers alone when that suffices; or name the specific unsaved desktop state at risk before quitting rather than describing the scope generically.
Expected: refreshing the catalog should not cost the user their unsaved desktop state unless that is genuinely the only way to apply the change, and the command should say so when it is.
Reproduction
- Start the proxy and connect Codex desktop:
ocx start --port 10100. - In the Codex desktop app, open a thread and leave unsaved client-side state: type a composer draft without sending it, change the model in the picker without starting a turn, and leave an approval prompt open.
- Run
ocx system codex-restart --yes. - The desktop app fully quits and relaunches. The draft, the unsent picker selection, and the pending approval are gone.
Compare with upstream codex app-server daemon restart, which restarts only the managed app-server and leaves the desktop client running to reconnect.
Observed against the current restart path in src/codex/app-server-restart-service.ts, src/codex/desktop-app-restart.ts, and src/server/management/system-routes.ts. The upstream contract is in codex-rs/app-server-daemon/src/lib.rs and codex-rs/app-server/src/lib.rs.
Version
dev at 3070d64
Operating system
macOS 27.0 arm64 (the desktop-restart path is macOS and Windows specific)
Provider and model
No response
Logs or error output
Screenshots and supporting files
No response
Redacted configuration
Checks
- I searched existing issues and documentation.
- I removed secrets, tokens, account details, request credentials, and personal data.
Activity
lidge-jun commentedon Sep 16, 2026
리뷰 · 우선순위 66 / 80
이 이슈는
ocx system codex-restart가 업스트림처럼 app-server만 재시작하는 게 아니라 Codex 데스크톱 셸 전체를 종료·재실행해서, 저장 안 한 클라이언트 상태(작성 중 초안, 모델 피커, 승인 프롬프트)를 버린다는 범위 부채다. 현재devHEADb3035fe292에서도src/cli/system-command.ts(132–140행)가 ‘fully quits and relaunches the Codex desktop app’이라고--yes를 요구하고,/api/system/codex-restart로 그대로 호출한다.구현 경로도 tip에 있다.
src/codex/app-server-restart-service.ts가 카탈로그/재시작 오케스트레이션을 하고,src/codex/desktop-app-restart.ts가 루트 셸을 찾아 quit·force-stop·relaunch한다. 주석(약 5–18행)은 예전--restart-codex가 app-server만 시그널했다가 피커가 안 바뀌던 이유를 설명하고, 좁은 동작은--restart-app-server-only로 옮겼다고 적는다.src/server/management/system-routes.ts가 그 서비스를 대시보드/API에 연결한다. 코드는 start-time 재검증·불확실한 app-server 거부 등 조심스럽고, 회귀라기보다 의도된 넓은 범위다.업스트림
codex app-server daemon restart는 데몬이 관리하는 app-server만 멈추고 띄우며 readiness를 보고, 클라이언트는 재연결로 산다. 우리는 데스크톱을 죽여서 ‘카탈로그를 다시 읽게’ 만든다.model_catalog_json이 업스트림에서 startup-only인 한, 카탈로그 변경에 데스크톱 재시작이 필요한 경우도 진짜로 있다. 문제는 그 파괴적 도구가 ‘새 카탈로그 받기’의 유일한 공개 경로처럼 쓰인다는 점이다.#4720 L2로 #4564(멤버십/POSIX-only Windows 수정)와 #4610(재시작 범위 문구)이 이미
dev에 들어왔다. 그래서 ‘범위 설명이 모호하다’ 쪽은 많이 줄었다. 남은 것은 이슈가 말하는 제품 부채: 카탈로그가 실제로 안 바뀌었으면 데스크톱 재시작을 건너뛰기, app-server만으로 충분한 경우 그 경로를 기본으로 쓰기, 종료 전에 잃을 unsaved 상태를 구체적으로 말하기.긴급 런타임 장애는 아니다.
--yes게이트도 있다. 그래도 카탈로그 pull·서비스 수리 흐름에서 자주 눌리는 명령이라 UX 부채 우선순위는 중간 이상이다. types/config 스플릿과 무관하다.경로
src/cli/system-command.ts(132–140) -codex-restart가 데스크톱 전체 quit/relaunch를 명시하고--yes만 요구한다.경로
src/codex/desktop-app-restart.ts- 셸 종료·강제 종료·relaunch. app-server readiness probe를 직접 하지 않는다.경로
src/codex/app-server-restart-service.ts- 카탈로그/재시작 오케스트레이션이 데스크톱 재시작에 기대다.심볼
--restart-app-server-only(src/cli/restart-scope.ts) - 좁은 경로는 이미 있으나system codex-restart기본은 여전히 넓다.교차 #4564/#4610 via #4720 - 문구·멤버십 수정은 착륙. 범위 축소 정책은 아직 남았다.
메인테이너의 판단이 필요한 지점
system codex-restart기본을 app-server-only로 바꾸고 데스크톱은 별도 플래그로 둘지.너의 추천
받아라. 버그라기보다 범위 부채로 두고, 기본을 app-server-only(또는 catalog-unchanged 스킵)로 좁히는 설계 짧은 PR을 받아라. #4564/#4610은 이미
dev에 있으니 중복 수정하지 마라.이 댓글은 grok-bot이 작성했습니다
fix(desktop,cli): bundle lane G — sidecar signing, restart warning, p…
lidge-jun commentedon Sep 23, 2026
Partial progress from #5682 (squash-merged as 7f8d538, carrying #5488): the CLI now warns that a restart can discard unsaved client state.
codex-restartstill quits the whole desktop shell rather than only the app-server, so this stays open.lidge-jun commentedon Sep 27, 2026
Status update from the release train 4 bug-hardening lane. On current
dev,src/codex/app-server-restart-service.ts:157still restarts the whole desktop app, andocx system codex-restartwarns that unsaved drafts may be lost (src/cli/system-command.ts:221). An app-server-only restart does not currently refresh the model picker, so switching to it would trade this problem for a stale picker. Changing the consent flow or the desktop UI belongs to the GUI lane, so this stays open as a scope decision there.