Fifty-nine hours of a Codex that would not start
From the morning of 25 September until we noticed on the afternoon of
the 27th, ovm install codex on macOS gave you the latest
Codex in a form its terminal UI could not start. Our verification
gate looked at both affected versions and admitted them. This is what
happened, with the clock on it, and what we changed so the gate says
no next time.
If you installed Codex 0.157.0 or 0.157.1 through OVM and got
this CLI has no complete local package, we are sorry. The
break was ours, not Codex's, and it took us two and a half days to
notice something our own pipeline should have caught within hours.
OVM 0.1.10 fixes new installs and repairs existing ones;
ovm self update then ovm install codex
is the whole recovery. Until you update, codex --no-daemon
works.
1What broke
From 0.157, the Codex terminal UI runs on a background app server —
a daemon it starts on first launch. It will only start that server
from a complete package: the binary, a manifest
(codex-package.json), a bundled rg, and a
codex-resources/ folder. OpenAI publishes that package as
its own release asset, codex-package-<target>.tar.gz,
alongside the bare binary it has always shipped.
OVM 0.1.9 installs the bare binary. It always has, and until 0.156.1
that was the whole program. On 0.157 the bare binary reports its
version, runs codex exec, and does everything except the
one thing most people launch it for: the interactive UI fails at
startup with
this CLI has no complete local package; install a packaged Codex CLI or use the standalone installer … rerun with --no-daemon
The message is Codex's own. It does not say that the installer at fault was OVM, and there was nothing in our output to say it either.
One qualification. Codex installs its daemon into your Codex home the first time a complete package starts, and any Codex after that finds it there. If another install on the machine — the desktop app, an npm or standalone Codex — had already done that, the bare OVM install started fine. The break was for people whose Codex came from OVM alone, which is what OVM is for.
2Timeline
All times UTC.
- Codex rust-v0.157.0 is published as a stable release. From this moment
ovm install codexresolves to a version whose UI cannot start from what OVM installs. - Our gate withholds 0.157.0 from the registry — not because it found anything, but because nothing had qualified the version yet.
- The gate admits 0.157.0: every state-migration and recovery contract passed, and the launch check reported ready.
- Codex rust-v0.157.1 is published.
- The gate admits 0.157.1 with degraded evidence — one of four lanes failed verification and was not credited — and clears it fully at 03:18.
- We hit the error ourselves, launching Codex through OVM on a laptop. Nobody had reported it; we found it by using it.
- Fix on
main: on macOS, when a release publishes the package, OVM installs the package. - Repair on
main: an existing bare 0.157 install is reinstalled with the package on the nextovm install codex. - Gate fix on
main: the launch check no longer calls a UI that draws and dies "ready"; the daemon-package error is a recognised failure. - OVM 0.1.10 is published as Latest.
ovm self updatepicks it up from here.
59 hours from the first broken version to detection.
Six minutes from detection to a fix on main, which says
the fix was easy and the finding was the whole problem.
Eight and a half hours from there to a release, most of it the gates a
stable release goes through — CI, a rehearsal cut, the private canary,
the public rebuild with signing, notarisation and attestation — plus
two of our own release rules that had never met a hotfix branch.
3Why the gate said yes
Every Codex release goes through a verification gate before the registry vouches for it: state-database downgrade and recovery contracts on both platforms, a launch of the interactive UI in a real terminal, and a signature assessment of the binary. A version that fails is withheld and pages us. This one passed, eight times.
The launch check decided ready when it had seen two terminal control sequences — the ones that turn on bracketed paste and focus reporting — and the process was still alive half a second later. That heuristic was written for the failure it had seen: a UI that never comes up, or exits at once. The bare 0.157 binary emits both sequences as its very first output, then goes looking for its package, and fails. By then the check had already recorded a pass.
The gate was measuring the terminal being prepared, and calling that the program working. It is the same shape as the npm that answered from the past: a signal that looks like success, read at the same confidence as success.
The other checks could not have caught it either. The state contracts
test the database, which this bug does not touch; codex exec
does not need the daemon. And the one lane that did fail on 0.157.1
was recorded as a degraded platform, which by design is a report, not
a hold.
4What changed
-
OVM 0.1.10 installs the complete package on macOS
whenever a release publishes one: size-checked, SHA-256 checked
against the digest GitHub publishes for the asset, extracted with
the same hardened extractor as every other download, manifest and
code signature verified. Older releases install exactly as before.
If the package download fails, OVM falls back to the bare binary
and tells you about
--no-daemon. -
Existing installs are repaired. A 0.157 tree
installed without the package is reinstalled by the next
ovm install codex <version>, the same way an install missing a sidecar already was. - The launch check no longer trusts the first two bytes. Ready now needs a rendered prompt and a longer stable window, and the daemon-package error is recognised as the fatal error it is. Replayed against what the bare 0.157.1 binary prints, the check now fails, and a failing launch on the latest run withholds the version even if an earlier run had passed.
- 0.1.10 is a patch cut from 0.1.9 with these fixes only. Everything else that has landed since ships as 0.2.0, on its own schedule.
5What we are still doing
- Linux. OVM still installs the bare binary there. The Linux package needs checking first — including where it expects its sandbox helper — before the same switch is made.
- Catching this class earlier. A launch that comes up is not a launch that works. We are looking at sending one keystroke through the UI and requiring a render, and at diffing a version's first second of output against the previous version's, so a new fatal line is a review trigger rather than noise.
- The lane that failed. One of the four verification lanes did fail on 0.157.1. We have not yet established whether that failure was this bug wearing a different face.
6References
- openai/codex — rust-v0.157.0 · the first release whose UI requires the complete package
- ovm-sh/ovm-oss — releases · OVM 0.1.10
- The npm that answered from the past · the earlier post on signals that look like answers