Exec mode: auto-save session metadata via self_metadata tool before exit
Problem
Non-interactive exec mode (aka codex e / codex exec) finishes after a single task with no built-in way for the agent to persist a discoverable “name” and metadata that helps users find and resume that session later. Today, naming requires a follow-up codex save <name> and metadata is implicit in the rollout file path/contents.
Proposal
Introduce a built-in tool exposed to the model in exec sessions to persist session metadata and a friendly name, and invoke it automatically just before exit.
High-level design
- New built-in tool:
self_metadata.save - Purpose: persist a lightweight record that maps a friendly name and rich metadata to the underlying rollout file so users can discover and resume sessions later.
- Reusable: implemented in core so it can be reused outside exec (e.g., TUI, MCP server) when desired.
- Annotations: no-approval, safe, idempotent; visible to the model as a normal tool.
- Input shape (strings unless noted):
name(optional): user- or model-provided session labelcurrent_branchdatetime(ISO 8601, UTC)working_dir(absolute)repo(remote URL if known, else repo root path)commit(full SHA)worktree(path or null)summarize(short summary by the model)
- Exec-mode behavior:
1) On session start, make self_metadata.save available to the model (Responses tool list and Chat Completions mapping).
2) On TaskComplete/Shutdown (just before exit), enqueue a final turn that instructs the model to call self_metadata.save:
- Pre-populate all fields except
summarizefrom host info (git, cwd, time). - Ask the model to fill
summarizeonly. Use the existing compact prompt to keep it concise and stable. - If the model doesn’t call the tool within a small budget, fallback to generating the summary via a programmatic compact step and then call the tool ourselves (so exit stays deterministic).
3) Tool implementation persists to ~/.codex/saves.json by inserting an entry in by_name and by_id that points to the current rollout file path. Optionally also write a small sidecar (e.g., ~/.codex/saves/<id>.json) containing the metadata for search/filtering later.
- Configuration (opt-in/opt-out):
exec.auto_save_metadata(bool, default: true)exec.save_name_pattern(string template for default name if none provided; can include tokens like{branch},{date},{cwd_basename})
- TUI parity (future):
- Expose the same tool so the assistant can save metadata mid-session or on
/save.
Why this helps
- Makes exec discoverable: users can list and resume sessions without remembering a manual name.
- Standardizes metadata capture for portability (branch/commit/cwd/worktree) and allows richer UX (filter by branch/repo/time).
- Keeps LLM use minimal and deterministic: the model only produces the
summarizestring; everything else is host-filled.
Implementation notes
- The saving path can reuse the existing
codex savelogic (saves.json) to avoid duplicating index semantics. - For Responses, add the tool to the
toolsarray; for Chat Completions, map to a function tool and capture arguments as JSON. - Ensure the final “save” turn does not produce noisy output in exec; suppress streaming and only print a short confirmation.
- Consider rate-limiting/throttling to avoid extra tokens when exec runs very short tasks.
Acceptance criteria
- In
codex exec, sessions auto-save a name + metadata before exit by default. saves.jsoncontains a new entry for the session, with a friendly name and id mapping.- The summary is either model-provided (tool call) or fallback-generated via compact.
- Feature can be disabled via config.
Related
- Current manual save command:
codex save <name> - Rollout format: first JSONL line contains session id; this feature ties that id to a name + metadata.