Skip to content

fix(codex): multi-line TOML args, and sync that can't leave a host CLI broken - #232

Merged
pacphi merged 2 commits into
mainfrom
fix/codex-toml-multiline-args
Sep 23, 2026
Merged

pacphi merged 2 commits into
mainfrom
fix/codex-toml-multiline-args

Conversation

@pacphi

@pacphi pacphi commented Sep 23, 2026

Copy link
Copy Markdown
Owner

Problem

In a Codex-enabled project (reproduced in emailibrium on 4.0.0-alpha.53), ak sync kept failing with:

  • ruflo→codex MCP: migration could not remove the ak-owned legacy registration
  • still failing: [aqe-embedding] AQE embedding projection conflicts or missing registrations require reconciliation

It has two ak root causes. Neither needs an upstream fix.

1. Multi-line TOML args

Codex (codex mcp add, via toml_edit) and aqe platform setup codex write args as a multi-line array. Three ak readers only accepted a single-line array:

Reader Effect
rufloCodexMcpStatus args = null → canonical ak x ruflo-mcp entry reported as the "legacy cwd-only launcher" → sync re-migrated every run
aqeTomlEnvironment project .codex/config.toml rejected as unsupported AQE arguments encoding → permanent projection conflict
codexMcpSections / codexMcpTopology args missed on recursive-codex / legacy-ruflo tables → a real duplicate claude-flow + ruflo registration stayed hidden

2. Sync upgraded codex into a broken state and reported success

The migration's codex mcp remove failed because codex itself could not start (Missing optional dependency @openai/codex-darwin-arm64). Evidence from the machine's npm cache and the registry:

  • OpenAI published @openai/codex@0.156.1 at 02:45:25Z and its platform versions (for example 0.156.1-darwin-arm64, used as the optional-dependency alias target) 1.5–5 minutes later. The darwin-arm64 build came at 02:50:04Z.
  • ak sync's versions step upgraded codex at 02:53:07Z. npm fetched the main tarball, but the platform tarball was never cached; node_modules/@openai was left empty.
  • npm silently drops a failed optional dependency and exits 0. heal.upgradePackage trusted the exit code and reported "upgraded".
  • ak status then showed ✓ codex 0.156.1 (npm), read from package.json alone.

Rerunning the same install and upgrade today (fresh prefix, ak's exact args) works, and so does reinstalling over an install with the platform directory removed. So this was a transient failure that ak made permanent and invisible.

Changes

  • codex-toml-safety.mjs: one shared string-array reader for single- and multi-line arrays. Comments or non-string elements inside the array are still unsupported. mcp.mjs and aqe-embedding-toml.mjs use it.
  • npm-global-install.mjs installGlobalCli: install, prove bin --version, and retry once with --prefer-online when the CLI cannot start. installHost and heal.upgradePackage (for host packages, via sync's hostUpgradeOptions) share it. Non-host packages are unchanged.
  • sync hosts step: also reinstalls an npm-owned host whose CLI cannot start (external mise/native/brew installs untouched). It now runs before the Codex MCP and provider steps that shell out to host CLIs.
  • status hosts: an npm host that fails --version shows installed but not executable: <Error line> (fail for the primary host, warn otherwise), with fix sync reinstalls <pkg>.
  • docs/TROUBLESHOOTING.md: row for the new status.

Verification

  • New tests cover: multi-line args (ruflo status, AQE editor, topology repair classification); install retry with --prefer-online, failure after retry, and no retry when healthy; upgradePackage verification; sync repairing a broken npm host while leaving healthy and external hosts alone; step ordering; the status row.
  • pnpm run check: exit 0. Tests 4312 pass / 0 fail / 6 skipped; coverage 92.2% lines / 81.5% branches. Lint warnings identical to main (71).
  • ak sync --dry-run --no-upgrade from this branch in emailibrium now plans [hosts] sync reinstalls @openai/codex and the backed-up duplicate-Ruflo repair. The repair runs after the hosts step.

🤖 Generated with Claude Code

pacphi and others added 2 commits September 22, 2026 20:05
Codex (toml_edit) and `aqe platform setup codex` write MCP `args` as
multi-line arrays. Three readers accepted only single-line arrays, so:

- rufloCodexMcpStatus saw args=null, reported the canonical
  `ak x ruflo-mcp` entry as the legacy launcher, and sync re-ran the
  migration on every invocation;
- the AQE embedding TOML editor rejected the project .codex/config.toml
  as "unsupported AQE arguments encoding", leaving a permanent
  projection conflict after sync;
- codexMcpTopology missed args for recursive-codex / legacy-ruflo
  tables, hiding duplicate-transport repairs.

A shared string-array reader in codex-toml-safety.mjs now handles both
forms; comments or non-string elements inside the array stay unsupported.

`ak status` also reported an npm-installed host as healthy from its
package.json alone. A launcher that fails `--version` (e.g. codex
missing @openai/codex-darwin-arm64) now shows as installed but not
executable with a reinstall fix, which also explains downstream
`codex mcp` failures.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
`ak sync`'s versions step upgraded @openai/codex 0.156.0 -> 0.156.1 about
eight minutes after OpenAI published it. npm resolved the platform alias
(@openai/codex-darwin-arm64 -> @openai/codex@0.156.1-darwin-arm64,
published ~5 minutes after the main version), failed to install it, and
exited 0: npm silently drops a failed optional dependency. heal.upgradePackage
trusted the exit code, reported "upgraded", and left `codex` unable to start,
which then broke every later `codex mcp` operation in sync.

- installGlobalCli (npm-global-install.mjs): install, prove `bin --version`,
  and retry once with --prefer-online when the CLI cannot start. installHost
  and heal.upgradePackage (for host packages, via sync's hostUpgradeOptions)
  share it, so a broken upgrade is reported and usually repaired in place.
- sync `hosts` step: also reinstalls an npm-owned host whose CLI cannot
  start (external installs untouched), and now runs before the Codex MCP
  and provider steps that shell out to the host CLIs.
- status: the not-executable host row's fix is now `sync reinstalls <pkg>`.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@pacphi pacphi changed the title fix(codex): read multi-line TOML args and flag non-executable hosts fix(codex): multi-line TOML args, and sync that can't leave a host CLI broken Sep 23, 2026
@pacphi
pacphi merged commit ab2e41f into main Sep 23, 2026
16 checks passed
@pacphi
pacphi deleted the fix/codex-toml-multiline-args branch September 23, 2026 03:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant