[Windows App][Remote SSH] Ultra chat selection silently downgrades the remote config.toml default

Open 💬 1 comment Opened Jul 25, 2026 by sun-binwen
💡 Likely answer: A maintainer (github-actions[bot], contributor) responded on this thread — see the highlighted reply below.

What version of the Codex App are you using (From “About Codex” dialog)?

Windows Codex Desktop client 26.721.41059 (captured in the remote app-server logs as app_server.client_name="Codex Desktop").

Remote-side components observed during the incident:

  • global codex-cli 0.145.0
  • long-lived app-server reported as 0.144.1
  • bundled remote binary codex-cli 0.146.0-alpha.3.1

What subscription do you have?

ChatGPT-authenticated account. The exact tier is not exposed in the redacted remote-side diagnostics.

What platform is your computer?

Windows Codex Desktop connecting over Remote SSH to:

Linux 6.8.0-124-generic x86_64 x86_64

What issue are you seeing?

I intentionally keep the remote Linux user default pinned in ~/.codex/config.toml:

model = "gpt-5.6-sol"
model_reasoning_effort = "ultra"
plan_mode_reasoning_effort = "ultra"
service_tier = "default"

After using the Windows Codex App with an SSH project, the remote model_reasoning_effort has intermittently been changed to low, so later local CLI threads on the Linux host start below the explicit durable default. I have to edit it back to ultra manually.

The most concerning behavior is the scope mismatch: Ultra is presented as applying “for this conversation”, but the implementation computes a non-Ultra fallback for future threads and persists that fallback to the user-level config. On an SSH project, the config belongs to the remote Linux user, so a desktop chat can silently change defaults used later by unrelated local CLI sessions.

Local forensic timeline on 2026-07-25 (AEST, UTC+10):

  • 17:30:22: an SSH-launched codex app-server proxy started.
  • 17:30:23: the remote config.toml inode was created/replaced, consistent with an atomic config rewrite.
  • The file was later observed with the lower effort and manually repaired to ultra at 18:35:19.
  • 18:44:32: another SSH/app-server proxy started.
  • 18:44:47: config.toml was automatically written again. The retained diff for this second write only changed marketplaces.openai-bundled.last_updated, which confirms that the connection lifecycle can mutate the remote config, although it did not reproduce the effort downgrade on that pass.

Important evidence boundary: the pre-repair file containing low was not retained, so the exact RPC payload for that specific downgrade is not available. The recurring ultra -> low observation is user-reported; the connection-correlated remote config rewrites and the source behavior below are confirmed.

I also ruled out the normal override layers on the remote host: there was no project .codex/config.toml, no profile config, no /etc/codex/config.toml or managed config, and no active agent-role TOML overriding the effort.

What steps can reproduce the bug?

The issue is intermittent in the Windows frontend, but the suspected path is:

  1. On a Linux SSH host, set the user-level config to gpt-5.6-sol with model_reasoning_effort = "ultra" and record its hash/mtime.
  2. From Windows Codex Desktop, connect to that host through Settings > Connections > SSH and open a remote project.
  3. Start or restore a remote chat and use/retain Ultra for the current conversation. Do not manually edit the Linux config during the test.
  4. Start a new chat, reconnect the SSH project, or later launch the Linux CLI locally.
  5. Re-read the remote ~/.codex/config.toml and inspect the new thread’s effort.
  6. The current remote chat may remain Ultra while the durable remote default has been replaced with a lower non-Ultra catalog fallback (observed as low).

A useful control is to leave the Windows App disconnected and start only local Linux CLI threads; the durable value should remain unchanged.

What is the expected behavior?

Selecting Ultra “for this conversation” should not silently lower an explicitly configured user-level default, especially on another host.

Any of these would be acceptable:

  • keep the conversation-only Ultra state separate and preserve the explicit remote durable default;
  • store a future-thread fallback in session/client state rather than overwriting model_reasoning_effort;
  • or clearly prompt that this action will modify the remote host’s user-level default and show the exact fallback value.

Remote connection housekeeping should also avoid touching unrelated model/reasoning keys.

Additional information

The current open-source implementation closely matches the symptom:

This is related to #26472, where general model/reasoning selection persistence was described as intentional. This report is narrower: the UI says “for this conversation”, transforms Ultra into a different lower durable value, and writes that value across the SSH host boundary, affecting future local CLI threads.

There was also version skew on the remote host, and the long-lived app-server repeatedly logged failed to load models cache: missing field supports_reasoning_summaries. That may amplify the fallback behavior, but I am not claiming it as the root cause.

View original on GitHub ↗

1 Comment

github-actions[bot] contributor · 1 month ago

Potential duplicates detected. Please review them and close your issue if it is a duplicate.

  • #35292

Powered by Codex Action