Skip to content

fix(codex-runtime): re-running /codex-runtime codex_app_server when already enabled now triggers migration - #26532

Closed
simpolism wants to merge 1 commit into
NousResearch:mainfrom
simpolism:fix/codex-runtime-reapply-runs-migration
Closed

fix(codex-runtime): re-running /codex-runtime codex_app_server when already enabled now triggers migration#26532
simpolism wants to merge 1 commit into
NousResearch:mainfrom
simpolism:fix/codex-runtime-reapply-runs-migration

Conversation

@simpolism

Copy link
Copy Markdown
Contributor

Fixes #26529

What

When model.openai_runtime is already set to codex_app_server, re-running /codex-runtime codex_app_server now triggers the migration (writes managed block to ~/.codex/config.toml, registers hermes-tools MCP callback, discovers native plugins) instead of short-circuiting with "already set".

Why

The current short-circuit at hermes_cli/codex_runtime_switch.py:148 returns early when new_value == current, skipping the entire migration block. This conflates "the config value is correct" with "the world state is converged" — which is fine for the auto → no-op case (disabling has no world-state side effects) but breaks for codex_app_server → no-op, where the user can have the config value correct but be missing the ~/.codex/config.toml managed block, the MCP callback, and the plugin discovery.

How users hit this: pre-set openai_runtime: codex_app_server in config.yaml (legitimate workflow — hermes profile create --clone does it automatically when cloning a profile that has codex runtime enabled), then run /codex-runtime codex_app_server to trigger migration. Silent no-op. The bot looks like it's on the app-server runtime but is actually on codex_responses fallback.

How

Fall through to the migration block when re-applying codex_app_server while skipping config persistence (no value-level change → no need to rewrite config.yaml). The migration is idempotent by design (uses _strip_existing_managed_block() before writing), so re-running is safe and cheap. The user-visible message changes to "openai_runtime already set to codex_app_server — re-applying migration" so re-runs surface what happened.

The auto re-apply path keeps the early-return short-circuit since disabling has no world-state side effects to converge.

Tests

New regression test test_reapply_codex_app_server_runs_migration asserts:

  • migrate() was called when re-applying
  • persist_callback was NOT called (no spurious config writes on no-op transitions)
  • Migration output (MCP servers, sandbox default) surfaces in the user-visible message
  • requires_new_session is True so callers know to /reset

Verified RED→GREEN locally: the test fails on origin/main with "migration must run on reapply, not just first enable" and passes with this fix.

$ python -m pytest tests/hermes_cli/test_codex_runtime_switch.py -o addopts="" -q
31 passed in 0.54s

Scope

Single-commit, two-file change. Production code change is ~15 lines (one new code path branching on reapplying_enable). Existing tests for the value-changing transitions remain green and unmodified.

…lready enabled now triggers migration

The /codex-runtime slash command short-circuits with "openai_runtime
already set" when invoked with the same value as the current config,
and crucially skips the entire migration block below. The check
conflates two things: (a) "the config value is correct" and (b) "the
world state (managed block in ~/.codex/config.toml, hermes-tools MCP
callback, plugin discovery) is converged".

Common footgun this exposes: a user who pre-sets
`model.openai_runtime: codex_app_server` directly in config.yaml
(reasonable thing to do) and then runs /codex-runtime codex_app_server
to trigger migration sees "already set" and silently gets no migration.
~/.codex/config.toml never receives the managed block, the hermes-tools
MCP callback never registers, and codex falls through to its default
runtime instead of the app-server one — visibly successful but
functionally partial setup.

The migration is idempotent by design (it replaces its own managed
block in place between MIGRATION_MARKER and MIGRATION_END_MARKER), so
re-running it is safe and cheap. Fix the short-circuit to fall through
to migration when re-applying codex_app_server while skipping the
config persist (no value-level change needed). The disable case
(re-applying "auto") still short-circuits because disabling doesn't
touch ~/.codex/config.toml at all.

The user-visible message changes to "openai_runtime already set to
codex_app_server — re-applying migration" so re-runs surface what
happened.

Regression test (test_reapply_codex_app_server_runs_migration) asserts:
- migrate() was called when re-applying
- persist_callback was NOT called (no config write on no-op transitions)
- migration output (MCP servers, sandbox default) surfaces in the
  user-visible message
- requires_new_session is True so callers know to /reset

Verified RED→GREEN: the test fails on origin/main with
"migration must run on reapply, not just first enable" and passes with
this fix. Full test_codex_runtime_switch.py suite: 31 passed.
@simpolism
simpolism requested a review from a team May 15, 2026 19:19
@alt-glitch alt-glitch added type/bug Something isn't working comp/cli CLI entry point, hermes_cli/, setup wizard provider/openai OpenAI / Codex Responses API P2 Medium — degraded but workaround exists labels May 15, 2026
@alt-glitch

Copy link
Copy Markdown
Collaborator

Competing fix: #26535 by @aqilaziz targets the same bug with the same approach. Both modify codex_runtime_switch.py identically in logic. Maintainer should pick one.

@austinpickett austinpickett left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Please use .github/PULL_REQUEST_TEMPLATE.md

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR fixes a /codex-runtime codex_app_server footgun where re-running the command while model.openai_runtime is already codex_app_server would previously short-circuit and skip the migration that converges Codex world-state (~/.codex/config.toml managed block, hermes-tools MCP callback registration, and plugin discovery).

Changes:

  • Adjusted codex_runtime_switch.apply() to not early-return when reapplying codex_app_server, allowing the migration block to run while skipping config persistence.
  • Updated the user-facing message to indicate the runtime is already set and that migration is being re-applied.
  • Added a regression test ensuring migration runs on reapply and that persist_callback is not invoked on no-op value transitions.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
hermes_cli/codex_runtime_switch.py Allows “reapply codex_app_server” to run migration while avoiding unnecessary config writes; updates messaging accordingly.
tests/hermes_cli/test_codex_runtime_switch.py Adds regression coverage for reapply behavior (migration runs, no persistence, messaging, requires new session).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@kshitijk4poor

Copy link
Copy Markdown
Collaborator

Merged via #56563 (#56563) — your commit was cherry-picked with authorship preserved (rebase-merge, 35eb93c8d on main).

Clean salvage onto current main. Your reapplying_enable fix and the test_reapply_codex_app_server_runs_migration regression test (asserting migration runs, persist_callback does NOT fire, requires_new_session=True) carried over unchanged and RED→GREEN reproduced.

One follow-up on top (7322da487, mine): a small control-flow tidy — collapsed the reapplying_enable predicate to a chained comparison and deduped the msg_lines literals. No behavior change.

Nice writeup distinguishing "config value correct" from "world state converged" — that's exactly the right framing, and delegating idempotency to migrate()'s strip-before-write rather than adding a parallel check was the clean call. Thanks!

hashbender added a commit to hashbender/hermes-agent that referenced this pull request Jul 1, 2026
…lready enabled now triggers migration (salvage of NousResearch#26532 by @simpolism, closes NousResearch#26529) (#468)

Co-authored-by: qbit-mirror-bot <qbit-mirror-bot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/cli CLI entry point, hermes_cli/, setup wizard P2 Medium — degraded but workaround exists provider/openai OpenAI / Codex Responses API type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

/codex-runtime codex_app_server silently skips migration when openai_runtime already set in config

5 participants