This note outlines what’s involved in letting the codex exec subcommand (implemented in the codex-exec crate) resume a prior session by id, and clarifies where session data is persisted locally.
- Add a way to continue an existing session context in non‑interactive
execmode by passing either:--resume-session-id <UUID>: resume the most recent rollout file for that id.--resume-rollout <PATH>: resume from an explicit rollout file path.
Core already supports resuming via a rollout file path (wired through experimental_resume), so this is a thin CLI change.
Invocation note: end users run codex exec "...". Internally, the top‑level codex binary’s Exec subcommand delegates to the codex-exec crate. Any new flags added to codex-rs/exec are exposed to users via codex exec automatically.
Implemented:
-
--resume-rollout <PATH>and--resume-session-id <UUID>incodex exec. -
Initial
SessionConfiguredis forwarded to stdout in--jsonmode so callers can capturesession_idfor subsequent resumes. -
CLI flags: add to
codex-rs/exec/src/cli.rs.--resume-session-id <UUID>--resume-rollout <PATH>
-
Main logic:
codex-rs/exec/src/lib.rs::run_main()before loading theConfig.- Parse flags.
- If
--resume-rolloutis provided, use it directly. - Else if
--resume-session-idis provided, locate the corresponding rollout file under~/.codex/sessions/**/rollout-*-<uuid>.jsonl:- Search in
config.codex_home/sessions(resolveconfig_homebefore loading full config if needed; it’s usually~/.codex). - If multiple files match, choose the newest by mtime or file name timestamp; otherwise error with a clear message.
- Search in
- Once a rollout path is determined, set
experimental_resume = <absolute path>via the standard overrides path (splice a-c experimental_resume=<path>intoCliConfigOverridesor set it onConfigOverridesprior toConfig::load_with_cli_overrides).
No core/protocol changes are required: Session::new() already detects resume_path and restores state.
-
Session resume plumbing (
codex-rs/core/src/codex.rs):- If
resume_pathis set,RolloutRecorder::resume(path, cwd)is invoked. - The session id is read from the file’s first line (meta) and replaces the fresh UUID.
- Prior
ResponseItems are replayed into in‑memory history so the agent continues with the same context. - A
SessionConfiguredEventis emitted with the finalsession_id, history metadata, and model info.
- If
-
Rollout persistence (
codex-rs/core/src/rollout.rs):- Location:
~/.codex/sessions/YYYY/MM/DD/rollout-<timestamp>-<session_id>.jsonl - File format:
- First line: meta JSON with
{ id, timestamp, instructions, git }. - Subsequent lines: serialized
ResponseItems (user/assistant messages, tool/tool-output calls, local shell call records, reasoning), plus periodicstaterecords.
- First line: meta JSON with
- Writer runs asynchronously; resume reopens the file and continues appending.
- Location:
-
Cross‑session message history (optional) (
codex-rs/core/src/message_history.rs):- Location:
~/.codex/history.jsonl - Schema per line:
{ "session_id": "<uuid>", "ts": <unix_seconds>, "text": "<message>" } - Controlled by
history.persistencein config.execcurrently doesn’t auto‑append user prompts here; the TUI does viaOp::AddToHistory.
- Location:
-
Server‑side storage toggle:
- Each request sets
store: !disable_response_storage(codex-rs/core/src/codex.rs). This affects the model provider’s own storage but is independent of local rollout persistence.
- Each request sets
- Prefer
--resume-rolloutfor direct control; layer--resume-session-idas convenience. --resume-session-idsearch strategy:- Walk
config.codex_home/sessionswith a fast glob; match suffix-<uuid>.jsonl. - If multiple candidates exist, select the newest (by name timestamp or mtime). If ambiguous, print the list and ask the user to pick via
--resume-rollout. - If none found, exit with a helpful error.
- Walk
- Conflicts: if both flags are provided, prefer
--resume-rolloutand warn, or reject as an error. - CWD rules:
Session::new()requires an absolutecwd; the CLI already resolves this inConfig.
- Resume by id:
codex-exec --resume-session-id 5973b6c0-94b8-487b-a530-2aeb6098ae0e -m gpt-5 "Continue the previous task by …"
- Resume by file:
codex-exec --resume-rollout ~/.codex/sessions/2025/05/07/rollout-2025-05-07T17-24-21-5973b6c0-94b8-487b-a530-2aeb6098ae0e.jsonl -m gpt-5 - < prompt.txt
- Invalid UUID: validation should fail early with a clear message.
- Multiple matches: pick newest or require
--resume-rolloutto disambiguate. - Missing file or unreadable path: clear error and non‑zero exit.
- Cross‑machine reuse: rollout files reference only serialized conversation; they can be copied across machines, but
cwd/git info may not align. - Permissions: history file uses 0600; rollouts are created under
~/.codex/sessionswith standard FS permissions.
- Unit: minimal parsing/selection helpers for locating a rollout by id.
- E2E (when implementing):
- Start a session, exchange a couple of turns.
- Capture the
session_idfromSessionConfiguredEvent. - Run
codex-execwith--resume-session-id <id>and confirm restored context affects the model’s next response.
- This feature can be implemented entirely in the
execcrate by resolving a rollout path and settingexperimental_resumebefore loadingConfig. - Session data is persisted locally in rollout JSONL files; optional cross‑session history is in
~/.codex/history.jsonl.