Repository navigation
UX: distinguish hub model changes that are saved, synced, and active on each client #4209
Description
Area
Multiple areas
What are you trying to accomplish?
Change model visibility or ordering on a central hub and know whether the change is saved on the hub, fetched by a particular client, and visible in an already-running Codex instance.
What prevents this today?
The Models page's main description says changes apply on the next Codex turn and do not need a restart, while the picker-order explanation on the same page says the old catalog may remain until the client is reopened. Visibility and ordering may legitimately have different refresh semantics, but the user is not told which completion state applies to the action just taken, particularly when the dashboard is on a different machine from Codex.
The connection CLI already exposes catalog synchronization timestamps, yet those machine-specific facts are not the clear completion story of the model-editing flow. Operators have to compare terminals, browser pages, and the actual picker to work out which step remains.
What should OpenCodex do?
- Identify the scope of the edit: hub catalog versus a local client setting.
- After a save, distinguish “Saved on hub,” “Fetched by this client,” and “Running client state unknown/reopen needed” when applicable. Do not claim active adoption from a successful write alone.
- State the behavior for the specific action, such as visibility versus ordering, rather than presenting an unconditional no-restart promise above all controls.
- Surface the last client catalog sync time and the one applicable next action. Keep diagnostic paths/ports in an expandable detail view.
- If active-runtime acknowledgement is unavailable, say “not verified” rather than adding a green completed state.
- Never automatically restart a running client or interrupt work to make the status look complete.
Example usage or interface
Model visibility saved on Hub A.
This computer last fetched the catalog 8 minutes ago.
[Sync this computer]
After sync:
Catalog fetched. This running client may still show its previous list.
[Show application-specific refresh instructions]
For actions known to apply live, show their verified live semantics instead; this is not a proposal to require restarts everywhere.
Alternatives or workarounds
Manually compare ocx connect status --json, the hub configuration, and the client model picker. This exposes the raw facts but leaves the operator to infer their relationship.
Additional context
Observed in the Korean Models screen served by dev 2.51.0, commit 6d3ad12e3fbfd8423f1515a467db4d3349732886.
gui/src/i18n/ko.ts:529: next-turn/no-restart description.gui/src/i18n/ko.ts:590: may retain the old catalog until reopening the client.src/client/connect.ts:576: connection metadata includes catalog synchronization state.
Related #3729 covers catalog delivery mechanics and #3774 covers drag-and-drop picker ordering. This proposal covers action-specific status, scope, and recovery communication across the hub/client boundary. No propagation timing claim was measured in this audit, and no user model settings were changed to manufacture a reproduction.
Design rationale: truthful success/partial/stale states; one primary next action; preserve useful density in an expert tool instead of hiding everything behind a long wizard. Acceptance should cover hub-only save, unsynced client, synced-but-running client, already-current state, failed sync, and an offline hub.
Checks
- I searched existing issues and documentation.
- This request describes a concrete OpenCodex workflow rather than merely naming a desired technology.
- I removed secrets and personal data.
Activity
lidge-jun commentedon Sep 10, 2026
리뷰 · 우선순위 52 / 80
이 이슈는 허브에서 모델 표시/순서를 바꾼 뒤, 그 변경이 (1) 허브에 저장됐는지, (2) 특정 클라이언트가 카탈로그를 받아 왔는지, (3) 이미 켜 둔 Codex 인스턴스에 보이는지 — 세 단계를 사용자가 구분할 수 없다는 UX 문제다. 같은 Models 페이지 안에서 본문은 “다음 Codex 턴에 적용, 재시작 불필요”라고 하고, 피커 순서 설명은 “클라이언트를 다시 열기 전까지 이전 목록이 보일 수 있다”고 해서, 방금 한 동작이 어느 완료 상태인지 헷갈린다. 특히 대시보드와 Codex가 다른 기계에 있을 때 더하다.
현재
devHEAD6101140ff(2.51.0)의gui/src/i18n/ko.ts가 그 긴장을 그대로 보여 준다.models.subtitle(약 529행 근처)은 변경이 다음 Codex 턴에 적용되고 5분 모델 캐시를 무효화하니 재시작이 필요 없다고 하고,models.orderHint(약 590행 근처)와models.pickerOrder.saved(약 15행)는 이전 카탈로그가 남을 수 있어 클라이언트를 다시 열라고 한다.models.pickerOrder.pending은 “저장됨, 카탈로그 갱신은 아직”을 말하지만, 허브 저장 / 이 컴퓨터 fetch / 실행 중 클라이언트 활성 여부를 한 흐름의 완료 상태로 보여 주지는 않는다.models.staleBanner는 Codex가 오래된 목록을 보여 줄 때 재시작을 안내한다. 연결 CLI 쪽src/client/connect.ts는 카탈로그 스냅샷·핑거프린트·다운로드 메타데이터를 이미 다루므로, 기계별 “마지막 fetch” 사실은 있으나 Models 편집 UX의 완료 이야기로 연결되지 않았다.이 항목은 현재 레인 스택(L3 계정, L5 Cline 등)에 들어 있지 않다. 카탈로그 UX이고 connect/catalog 기차 뒤에 두거나 주차하는 편이 맞다. types/config 대규모 쪼개기와 직접 충돌하지는 않지만, 허브·클라이언트 상태 모델을 넓히면 표면이 커지므로 지금 레인에 끼워 넣지 않는 것이 좋다.
라인 ~529 -
gui/src/i18n/ko.tsmodels.subtitle: 다음 턴 적용·재시작 불필요 약속라인 ~590 -
gui/src/i18n/ko.tsmodels.orderHint: 재오픈 전까지 이전 카탈로그 가능라인 ~15-16 -
gui/src/i18n/ko.tsmodels.pickerOrder.saved/pending: 저장 vs 카탈로그 미완료경로/심볼 -
gui/src/i18n/ko.tsmodels.staleBanner: 오래된 목록 → 재시작 안내경로/심볼 -
src/client/connect.ts: 카탈로그 sync 메타데이터는 있으나 Models UX와 미연결메인테이너의 판단이 필요한 지점
너의 추천
현재 레인에는 넣지 말고, connect/catalog 기차 이후로 스케줄하거나 주차하라. 구현 시에는 저장 성공만으로 “적용됨” 초록을 주지 말고, 허브 저장 · 이 클라이언트 fetch · 실행 중 상태(미확인 가능)를 분리 표시하라.
ko.ts의 subtitle과 orderHint 모순을 같은 완료 스토리로 맞추는 것부터 시작하면 된다. 지금 닫을 필요는 없다.이 댓글은 grok-bot이 작성했습니다
lidge-jun commentedon Sep 18, 2026
Shipped on
devby #5031, squashed asa53e4c0269f9ef4c118cd7328d5ed5a9885272bd.The three states are now named separately, and the honest part is that only two of them can be proven.
"Saved on hub" has a persist-then-receipt. "Fetched by this client" has
catalogSyncedAt. "Active in a running client" has nothing — the nearest available signal compares app-server process start time against catalog mtime, which detects an old process rather than picker adoption. So it renders as not verified, following the disciplinecodex-app-server-state.tsand the stale banner already set.That is why the old copy said
Appliedand why removing it was the point rather than a side effect: it claimed the one state this proxy cannot observe.No new backend endpoint was needed.
GET /api/machine/statushas always carriedcatalogSyncedAtand the dashboard already fetched it;targetsFromMachineStatuswas simply dropping the field.Shipping in the next release off
dev.