Skip to content

fix(codex): warn or restart stale app-server after sync - #518

Closed
Wibias wants to merge 11 commits into
lidge-jun:devfrom
Wibias:fix/476-codex-app-server-sync
Closed

fix(codex): warn or restart stale app-server after sync#518
Wibias wants to merge 11 commits into
lidge-jun:devfrom
Wibias:fix/476-codex-app-server-sync

Conversation

@Wibias

@Wibias Wibias commented Jul 26, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • Addresses Model catalog changes are not reflected in running Codex app-server until it is restarted #476: after ocx sync / ocx sync-cache rewrite on-disk catalogs, long-lived Codex app-server processes can keep serving a stale in-memory model list.
  • Detect matching codex … app-server and codex-code-mode-host processes (UID-scoped on Unix; narrow cmdline match — no broad *codex* kills).
  • Warn by default; ocx sync --restart-codex / ocx sync-cache --restart-codex send SIGTERM only (no SIGKILL escalation).
  • Docs + GUI stale hint updated; /api/sync returns shared hint and optional staleAppServerPids.

Test plan

  • bun test tests/codex-app-server-processes.test.ts
  • bun run typecheck
  • Cross-platform CI green
  • Manual: with Codex app-server running, ocx sync prints warning; ocx sync --restart-codex stops matching PIDs and refreshed list appears

Summary by CodeRabbit

  • New Features
    • Added optional --restart-codex to ocx sync and ocx sync-cache to refresh stale long-running Codex app-server processes.
    • Restart messaging/handling now triggers only when the catalog or cache is actually updated.
  • Documentation
    • Updated the Codex troubleshooting checklist and the CLI reference with the new flag and stale-process warnings.
  • UI/Localization
    • Improved the “stale app server” hint across languages to include the exact restart command.
  • Tests
    • Added cross-platform tests covering stale-process detection, warning text, restart outcomes, and CLI/API wiring.

Disk catalog updates do not refresh Codex's in-memory app-server list (lidge-jun#476). Warn on sync/sync-cache when matching processes are present, and offer --restart-codex for targeted SIGTERM.
@coderabbitai

coderabbitai Bot commented Jul 26, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds cross-platform detection and scoped restarting of stale Codex app-server processes after catalog updates, wires --restart-codex into both sync commands, gates handling on successful writes, exposes shared stale-process metadata through the API, updates localized guidance, and documents the behavior.

Changes

Codex app-server lifecycle

Layer / File(s) Summary
Catalog and cache write gates
src/codex/catalog/sync.ts, src/codex/refresh.ts, src/codex/sync.ts, tests/codex-*, tests/injection-model-api.test.ts
Propagates explicit catalog and cache write status through refresh and sync results, preventing stale-process handling when no write occurred.
Process detection and restart lifecycle
src/codex/app-server-processes.ts, tests/codex-app-server-processes.test.ts
Adds cross-platform discovery, narrow command matching, stale warnings, PID-safe SIGTERM restarting, and lifecycle coverage.
CLI restart flag integration
src/cli/index.ts, src/cli/help.ts, tests/codex-app-server-processes.test.ts
Adds --restart-codex to sync and sync-cache, invokes post-write handling, and updates usage and detailed help text.
API and dashboard stale-process guidance
src/server/management/config-routes.ts, gui/src/pages/dashboard-overview-sections.tsx, gui/src/i18n/*.ts
Returns the shared stale-process hint through /api/sync and renders localized guidance containing the restart command.
CLI and troubleshooting documentation
docs-site/src/content/docs/reference/cli.md, docs-site/src/content/docs/guides/codex-integration.md
Documents stale in-memory model catalogs, scoped SIGTERM behavior, the restart flag, and manual remediation steps.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant CLI as ocx sync
  participant Catalog as Codex catalog sync
  participant Handler as afterCatalogWriteHandleAppServers
  participant Detector as listCodexAppServerProcesses
  participant Processes as Codex app-server processes
  CLI->>Catalog: write catalog or models_cache
  Catalog-->>CLI: return catalog/cache write status
  CLI->>Handler: pass restart option after successful write
  Handler->>Detector: detect stale processes
  Detector->>Processes: inspect platform snapshots
  Handler->>Processes: send SIGTERM when restart is enabled
  Processes-->>Handler: stopped, surviving, or failed PIDs
Loading

Possibly related issues

Possibly related PRs

  • lidge-jun/opencodex#333 — Changes the same syncModelsToCodex control path and external-provider early-return result fields.

Suggested reviewers: ingwannu, lidge-jun

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 35.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: handling stale Codex app-server processes after sync by warning or restarting them.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

chatgpt-codex-connector[bot]

This comment was marked as resolved.

coderabbitai[bot]

This comment was marked as resolved.

Tighten app-server argv matching, scope Windows listing to the current user, add macOS ps discovery, revalidate PIDs before SIGTERM, gate CLI handling on catalog writes, keep CLI samples out of i18n, and avoid blocking /api/sync on process enumeration.
coderabbitai[bot]

This comment was marked as resolved.

Wibias added 3 commits July 27, 2026 00:09
Match code-mode-host only as argv0/entrypoint, require pid+cmdline identity before SIGTERM, and add CLI//api/sync wiring regressions.
CIM instance GetOwner must go through Invoke-CimMethod; the direct call failed closed on every row and broke --restart-codex on Windows.
Match Windows Install-path CommandLines with a closing quote after codex.exe/cmd, and only warn/restart after sync-cache when models_cache was actually rewritten.
coderabbitai[bot]

This comment was marked as resolved.

Keep upstream comboOmissions on the refresh result while preserving the boolean models_cache write gate from this branch.
@Wibias Wibias added enhancement New feature or request and removed bug Something isn't working labels Jul 26, 2026
Treat catalogExists as insufficient proof of a write so ocx sync --restart-codex does not warn or restart when the catalog path exists but is malformed or unreadable.
@github-actions github-actions Bot added bug Something isn't working and removed enhancement New feature or request labels Jul 26, 2026
Wibias added 4 commits July 27, 2026 02:16
Only attach staleAppServerHint from POST /api/sync when a catalog or models_cache write succeeded, so the dashboard does not imply a restart after a no-op sync.
Skip supported Codex global options (enable/config/profile and related forms) when locating the app-server subcommand, while still rejecting later-argument and non-app-server invocations.
Recognize --ask-for-approval/-a, --local-provider, and --add-dir when locating the app-server subcommand so common Codex root option forms still match.
Recognize platform-baked binaries like codex-x86_64-unknown-linux-musl in argv0 and the Windows candidate prefilter without accepting arbitrary codex-* tools.

@Wibias Wibias left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Security review: PASS

Reviewed tip d93b469src/codex/app-server-processes.ts, CLI --restart-codex, and POST /api/sync hint wiring. Excluded unrelated issue-translation/issue-quality workflow changes from this pass.

Summary

No medium+ findings. Process termination stays local, owner/UID-scoped, and narrowly matched; SIGTERM is preceded by PID+cmdline identity revalidation; PowerShell enumeration uses fixed script + Invoke-CimMethod GetOwner with fail-closed owner checks; logs/API expose PIDs and a static hint only (no cmdlines).

Checked

  • Cross-user kill: Unix UID filter + macOS ps -u + Windows GetOwner vs current identity
  • Injection: execFile argv array; regex literals only in PS -match operands
  • argv0 / subcommand matching + target-triple basenames; negatives for opencodex/hermes
  • /api/sync: hint only, no enumerate/kill
  • Privacy: no command-line logging on warn/restart paths

Verdict: Security review: PASS

@lidge-jun

Copy link
Copy Markdown
Owner

Split this into two stacked PRs so the process-termination half can be reviewed on its own:

Both are derived from this PR at d93b469, and the union of their diffs matches this PR's 21 files exactly (verified against a frozen manifest at that SHA).

The reasoning: the second half sends SIGTERM to matching processes, and process matching is where a mistake is expensive — it drew four rounds of review feedback here. Separating the signal from the action gives that half a small diff to review against.

@Wibias this is your PR, so the call is yours: close this in favour of the two, or keep it and treat the split as a review aid. Nothing here was force-pushed or changed on your branch.

@Wibias

Wibias commented Jul 27, 2026

Copy link
Copy Markdown
Collaborator Author

Looks good — thanks for splitting this out.

I'll close this PR in favor of the two stacked ones (#526 + #527). Review can continue there.

@Wibias

Wibias commented Jul 27, 2026

Copy link
Copy Markdown
Collaborator Author

Closing in favor of the stacked split: #526 (catalogWritten/cacheSynced signal) + #527 (stale app-server detection / --restart-codex).

@Wibias Wibias closed this Jul 27, 2026
@Wibias
Wibias deleted the fix/476-codex-app-server-sync branch July 27, 2026 03:54
lidge-jun added a commit that referenced this pull request Jul 27, 2026
syncCatalogModels() and invalidateCodexModelsCache() both succeeded
silently whether or not they wrote anything, so a caller could not tell a
real catalog update from a no-op on a missing or unreadable catalog.

Return that fact: syncCatalogModels() gains catalogWritten, and
invalidateCodexModelsCache() returns whether it rewrote models_cache.
refreshCodexModelCatalog() carries both outward.

This is the signal half of #518, split out so it can be reviewed on its
own. Nothing acts on it yet — the consumer (warning about, and optionally
restarting, stale app-server processes) is the other half, and it touches
process termination, which deserves its own review.
lidge-jun added a commit that referenced this pull request Jul 27, 2026
syncCatalogModels() and invalidateCodexModelsCache() both succeeded
silently whether or not they wrote anything, so a caller could not tell a
real catalog update from a no-op on a missing or unreadable catalog.

Return that fact: syncCatalogModels() gains catalogWritten, and
invalidateCodexModelsCache() returns whether it rewrote models_cache.
refreshCodexModelCatalog() carries both outward.

This is the signal half of #518, split out so it can be reviewed on its
own. Nothing acts on it yet — the consumer (warning about, and optionally
restarting, stale app-server processes) is the other half, and it touches
process termination, which deserves its own review.
lidge-jun added a commit that referenced this pull request Jul 27, 2026
syncCatalogModels() and invalidateCodexModelsCache() both succeeded
silently whether or not they wrote anything, so a caller could not tell a
real catalog update from a no-op on a missing or unreadable catalog.

Return that fact: syncCatalogModels() gains catalogWritten, and
invalidateCodexModelsCache() returns whether it rewrote models_cache.
refreshCodexModelCatalog() carries both outward.

This is the signal half of #518, split out so it can be reviewed on its
own. Nothing acts on it yet — the consumer (warning about, and optionally
restarting, stale app-server processes) is the other half, and it touches
process termination, which deserves its own review.
lidge-jun added a commit that referenced this pull request Jul 27, 2026
* fix(codex): report whether a sync actually wrote the catalog or cache

syncCatalogModels() and invalidateCodexModelsCache() both succeeded
silently whether or not they wrote anything, so a caller could not tell a
real catalog update from a no-op on a missing or unreadable catalog.

Return that fact: syncCatalogModels() gains catalogWritten, and
invalidateCodexModelsCache() returns whether it rewrote models_cache.
refreshCodexModelCatalog() carries both outward.

This is the signal half of #518, split out so it can be reviewed on its
own. Nothing acts on it yet — the consumer (warning about, and optionally
restarting, stale app-server processes) is the other half, and it touches
process termination, which deserves its own review.

* test(codex): cover real catalog sync write signals
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.

2 participants