The alembic cartridge
The distillation layer is named alembic. It knows how to load Codex and Claude session formats, strip them to the portable conversation, and materialize the target runtime's native session.
The pipeline
source session file
-> load (codex / claude reader)
-> neutral IR [ {role, text}, ... ]
-> sanitize (drop tool/reasoning, drop scaffold, redact secrets)
-> target native session file (claude / codex writer)
-> native resume (claude -r <id> / codex resume <id>)It is a two-hop pivot through a neutral intermediate model, never a direct converter. The payload (text, role, timestamp) rides through almost untouched; the envelope and the threading are the real work, because that is where the runtimes differ.
Native resume is strict
Writing the file is not enough; the target's loader must accept it. Constant matches each runtime's native schema exactly, down to the installed version string, so the session resumes as the runtime's own scrollback. Miss a field and the runtime rejects the whole file.
Stable projections, no proliferation
Each logical conversation gets a stable pair of Constant-owned projections, one
per runtime. A switch reuses and overwrites its own projection for the target,
rather than minting a new file each time, so ping-ponging keeps exactly one
codex projection and one claude projection, both kept in sync and both visible
in each CLI's own /resume.
Your original sessions are read as the seed but never written. See the Trust boundary.
Prior art
The low-level format codecs and the neutral IR are vendored from transession (MIT, Yiming Zhang). Constant adds the sanitize/redact distillation, native-resume hardening, stable projections, trail naming, and the live host.