technical overview
How OVM works
OVM keeps several versions of Claude Code, Codex, and Pi installed at
once and decides which one runs when you type claude. Everything
else — instant switching, rollback that always works, updates that never
make you wait — falls out of one design choice: versions are
immutable directories, and the active one is a pointer. This
page is the whole system, from the symlink under your shell to the
release pipeline that got the bytes there.
- Immutable versions, mutable pointer
- Installing writes a new directory and never touches an existing one. Switching moves a symlink. That is why a switch is instant and a rollback cannot fail halfway.
- The foreground never waits on the network
- Launching reads local state only. Version checks and downloads happen in a detached background process, so a slow or wedged network can't delay the tool you're trying to run.
- OVM manages itself the same way
- OVM is its own product: immutable snapshots, a pointer, an activation probe, and automatic rollback if a new version can't run.
01The layout on disk
Everything lives under ~/.ovm/. Each product gets a
directory of installed versions plus a current pointer, and
~/.ovm/bin/ holds the launchers that go on your
PATH. Nothing is installed system-wide and nothing outside
~/.ovm/ is modified.
storage layout
~/.ovm/
├── bin/ // on your PATH — these are what you run
│ ├── claude → ovm // multi-call launcher: argv[0] picks the product
│ ├── codex → ovm
│ └── ovm // the control plane (a real binary, not a link)
├── products/
│ └── codex/
│ ├── current → versions/rust-v0.145.0 // the pointer
│ └── versions/
│ ├── rust-v0.145.0/release/bin/codex
│ ├── rust-v0.130.0/release/bin/codex
│ └── dev:my-fix/dev/bin/codex // your own build, same treatment
├── self/ // OVM's own versions — see 05
│ ├── current → versions/0.0.3-alpha.7
│ └── versions/…
├── cache/ // version indexes; never authoritative
└── config.json
A version directory is complete or it does not count: each carries a
.complete marker written last, so an install interrupted
by a crash or a lost connection is invisible rather than half-usable.
02Switching versions
A switch is a single atomic symlink replacement. The versions themselves are untouched — the one you leave stays on disk, byte for byte, which is what makes going back an instant, guaranteed operation rather than a re-download and a hope.
ovm use codex rust-v0.145.0
Because ~/.ovm/bin/codex is a link to the OVM binary itself,
the same mechanism handles your own local builds. A patched Codex
installs as dev:my-fix and sits in the list beside the
released versions, so flipping between "what shipped" and "what I'm
hacking on" is the same one-second operation.
03What happens when you launch
The launch path is deliberately boring: resolve the pointer, then spawn the real binary with your terminal handed straight to it — stdin, stdout, and stderr are inherited rather than piped, so nothing is buffered, wrapped, or rewritten on the way through. OVM stays on as the parent process, does nothing but wait, and exits with the tool's own exit code. Anything that might touch the network is pushed into a detached child that cannot delay you.
launch path
This split is enforced by a test that points every upstream at a black-hole socket — one that accepts connections and never answers — and fails if a launch takes longer than three seconds. Reintroduce a synchronous fetch on the launch path and it goes red.
04Installing a version
Downloads are treated as untrusted until proven otherwise, and a version becomes visible only at the end, in one atomic step. There is no window where a partly-written version can be selected.
- Resolve. The version index says where the bytes are — a signed CDN binary, an npm tarball, or a GitHub release asset, depending on the product.
- Download into a private staging directory. Redirects are constrained, response sizes are bounded, and the archive is never extracted over a live install.
- Verify. Every path enforces the length the publisher declared, so a
connection that drops mid-stream can never pass as a complete download. Past that,
verification is only ever as strong as what upstream actually publishes, and it
differs by product. Claude's CDN binaries are checked against a SHA-256 manifest and
its npm tarballs against the registry's SHA-512 integrity metadata. Codex publishes
no digest for its GitHub release assets, so there the declared length and the code
signature are what stands. Pi is checked against the
SHA256SUMSits newer releases publish — and if that manifest exists but cannot be read, the install is refused rather than quietly falling back to length alone. On macOS, Claude and Codex binaries must additionally carry an intact Apple code signature from the publisher's own signing team before they are ever executed; Pi ships unsigned, and on Linux there is no signature check to make. - Publish atomically. The staged directory is moved into place and the
.completemarker is written last. A crash before that leaves an unreferenced directory, which is cleaned up — never a half-installed version. - Switch, if asked. Installing and activating are separate:
ovm installleaves your active version alone.
Concurrency is real here, not theoretical: two shells can install the same version at once. An install holds a lock, and if the owning process is killed mid-download the next one recovers the staging directory and completes it — the tested outcome is exactly one complete install.
05OVM updating itself
A version manager that can strand itself is worse than none. So OVM
treats itself as another managed product, with one addition: a
control plane. The binary on your PATH
(~/.ovm/bin/ovm) is a stable copy that survives any swap; it
hands off to whichever immutable snapshot is currently selected.
atomic self-update, with rollback
06Staying current without waiting
Updates are split across two invocations so that no command ever pays for a download. The first invocation notices work is due and stages the new version in the background; the next one activates it atomically and tells you it happened. If a staging attempt dies mid-download, the retry is held for five minutes rather than waiting out the whole check window — and that wait doubles with each consecutive failure, so a release that can never be staged backs off instead of retrying forever.
update lifecycle
07How a release reaches you
OVM's own releases go through a pipeline built on one rule: the bytes you download are built from the public source tag they claim to come from. Development happens in a private repository, but no private binary is ever copied into a public release — the public build is rebuilt and attested from the public tag, and a release is only published after the artifacts have been verified.
private development → public release
The same discipline decides which upstream versions OVM offers you: releases are held back until they provably run. That system is documented in methodology.
08claudex: Claude Code on GPT-5.6
One feature deserves its own diagram, because it routes your prompts
somewhere unusual. claudex runs the Claude Code interface
against OpenAI models through a local translating proxy, on your own
ChatGPT subscription. It is an unofficial integration and is opt-in.
where a claudex prompt goes
09The properties this buys
Each of these is a consequence of the design above rather than a feature bolted on top, which is why they hold even when things go wrong.
| property | why it holds |
|---|---|
| instant switch | Switching moves a pointer. No download, no rebuild, no reinstall — the other versions were never removed. |
| rollback always works | The previous version is still on disk, complete and immutable. Going back is the same pointer move, in reverse. |
| no launch latency | The foreground reads local state only; every network operation is detached and rate-limited. Enforced by a black-hole-socket test. |
| no half states | Versions are published atomically with a completion marker written last; interrupted work is invisible and reclaimed. |
| self-update is safe | A new OVM must answer a probe before it keeps the pointer; if it can't, the exact prior selection is restored automatically. |
| verifiable downloads | Declared lengths enforced on every path, published digests compared wherever upstream publishes one, macOS signature checks before execution for the products that ship signed binaries, and public OVM builds attested to the tag they came from. |
| your Codex builds are first-class | A local Codex build installs as a normal version and switches identically, so comparing it against a release is one command. Codex is the only product with dev installs today. |
10Where to go next
Methodology covers the other half of the system: how upstream releases are verified, benchmarked, and published before OVM offers them to you. Releases is the live registry. The source, including the architecture notes this page summarizes, is on GitHub.