# Codex

> Import Codex CLI, Codex desktop app, and Codex SDK sessions, and Codex cloud tasks on request.

The Codex CLI, the Codex desktop app, and the Codex SDK save to the same local
files but represent different kinds of work. Import all three local source IDs
for your full history. Use the cloud command only when you want Codex cloud
tasks.

## Source IDs

| Source          | Use it for                                                                                                                                                                                              |
| --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `codex-cli`     | Interactive terminal sessions.                                                                                                                                                                          |
| `codex-desktop` | Codex Desktop and ChatGPT Work Local sessions in the shared rollout store.                                                                                                                              |
| `codex-sdk`     | `codex exec` and SDK sessions, both delegated work and one-shot jobs.                                                                                                                                   |
| `codex-cloud`   | Codex cloud tasks, read from their task history with your saved ChatGPT sign-in, or through the Codex CLI without one. Runs when you ask for it or turn it on in **Settings → Imports → Cloud agents**. |

## How the import works

ChatGPT Work Local retains its own product identity. Hansard uses the recorded
`codex_work_desktop` origin to label those sessions **ChatGPT Work Local** in
history, search, and Stats. Existing captures need no reimport. The existing
`codex-desktop` import source discovers and watches their local rollout files.
Work Cloud orchestration and dots histories require separate capture paths.

The local Codex sources read Codex's session index and rollout JSONL files.
Hansard groups entries by Codex's session ID, then rebuilds user and assistant
messages, reasoning, tool calls and results, approvals, settings, model
details, and token usage in order. Where a session started decides whether it
appears as CLI, desktop, or SDK history. Delegated and one-shot SDK sessions
stay distinguishable, and each subagent becomes its own conversation linked to
its parent.

Codex compresses a rollout it has not written for seven days to a
`.jsonl.zst` file. Hansard reads the compressed rollout with its title,
surface, and subagent links. A rollout that is gone counts as a removed source,
not as a read failure.

Running a local import again updates the same session instead of adding a
copy. If Codex is still writing its final JSONL record, Hansard imports the
complete records before it. The next import adds the completed record once.
Malformed complete records still produce an import error, and the archive
retains the original raw bytes.

The `codex-cloud` source works differently: it reads the task history
Codex keeps for each cloud task, using the ChatGPT sign-in your Codex home
saved. Each task's prompts, replies, commands, file changes, and tool calls
come from that history, along with archived tasks. Without a ChatGPT sign-in,
it asks the Codex CLI instead, which returns only the task record and its
unified diff. Hansard stores what it receives and does not rebuild a
conversation from the diff.

## Import and keep current

**Import now**

```sh
hansard import --sources codex-cli,codex-desktop,codex-sdk --since all
hansard index rebuild
```

To add cloud tasks:

```sh
hansard import codex-cloud --since all
```

`codex-cloud` reads the default Codex home and every Codex profile you
registered with `hansard account`, and only reads from Codex. Add
`--profile <label>` to read one profile, or `--task <task-id>` to read one
task. Without a ChatGPT sign-in it uses the Codex CLI; if the CLI is also
missing, signed out, or out of plan usage, the import prints the CLI's
message and stops without an error.

Full imports and explicit task imports reread history even when the task's
update time has not changed. Identical captures leave the archive unchanged.
An older capture or one that loses recorded text, tools, models, usage, or a
task diff keeps the existing archive and remains retryable.

**Keep current**

With **Automatic** source selection, the watcher already includes the three
local Codex sources. With a **Custom** list, enable them. The watcher picks them up within 30 seconds:

```sh
hansard config sources enable codex-cli,codex-desktop,codex-sdk
```

To keep cloud tasks current, turn on **Codex cloud** in **Settings → Imports →
Cloud agents**. The watcher then refreshes it every six hours. Otherwise, run
the command again when you want newer cloud tasks.

## Review the import in the app

1. When the import finishes, open **Conversations** and select **Filter & sort**.
2. Set **Source** to **Codex CLI, Codex Desktop, Codex SDK jobs, or Codex cloud tasks** and set **Time** to the window you imported. Use **Folder** to narrow the list when you use this harness in several projects.
3. Select a conversation to check its messages, tool calls, files, commits, model, and token usage.

To keep archiving new sessions from a local harness, open **Settings → Imports**. **Automatic** follows every supported harness installed on this computer. **Custom** lets you turn individual harnesses on or off. Cloud sources and account exports never run from here; each needs its own import command. If a conversation you expect is missing after you reset the filters, run the import command on this page again with `--explain-skips` where the source supports it.

## What Hansard preserves

- User and assistant messages, reasoning, tool calls and results, shell
  commands, file changes, and token usage when Codex recorded them.
- Collaboration mode, model, reasoning effort, approvals, sandbox and network
  settings, task latency, failures, and context window and quota samples.
- Linked subagent sessions and the times of subagent activity.
- Screenshots and image previews that completed MCP tool calls return,
  including Codex's own tool screenshots. A JPEG that Codex declares as PNG
  is labeled by its bytes.
- The session name you set in Codex. When Codex saved only the raw prompt or
  an unreadable name, Hansard infers a short title.

### Subagent messages

Codex encrypts the assignments, follow-ups, and results it passes between
agents. The managed Codex integration asks each agent to call the Hansard
`capture_subagent_messages` tool with the messages it receives, in its current
conversation. Hansard imports those copies, and the transcript labels them
**agent-reported copy**. Capture depends on the agent calling the tool, and it
uses the agent's normal turn tokens. Earlier encrypted messages are not
recovered this way; `hansard repair codex-subagent-prompts` recovers them
through OpenAI. After updating Hansard, resume open Codex conversations to load
the tool.

## Known limitations

- Native local trials covered part of the store, not the complete store.
  Thirty-two rollouts passed import, repeat, raw replay, and consumer checks.
  A 135 MB rollout reached the trial scratch limit during replay. A 160 MB
  rollout exhausted a 640 MiB JavaScript heap during transcript derivation.
- Project and thread-section tables remain in raw state snapshots without a
  complete normalized organization model. External attachment bytes and
  account-wide resources require separate acquisition evidence.
- Ephemeral runs can leave no rollout. Complete paginated histories and every
  Python app-server SDK route have not passed native acceptance.
- One-shot SDK jobs stay searchable, but Stats leaves them out of its main
  totals. Delegated SDK work counts only when it has tool calls or at least two
  assistant messages.
- Codex cloud tasks appear under **Codex cloud**, apart from local Codex
  sessions. A turn whose events Codex did not record keeps only its output
  messages and diff, and a task read through the Codex CLI alone shows a
  status record and the diff. A model or token count appears only when the
  task history records one.
- Only the attempt a task kept is shown. The records of other attempts stay in
  the preserved raw record, but their commands and tool calls are not
  collected.
- If a changed conversation path no longer contains the archived messages,
  Hansard keeps the earlier capture. Full branch-history normalization remains
  unavailable; the replacement guard does not merge unrelated attempts.
- A cloud task is never matched to a local session, because Codex does not
  record the cloud task ID locally. Importing a cloud task never replaces a
  local Codex session.

## Refresh an existing archive

A refresh needs the original Codex state and rollout files:

```sh
hansard import --sources codex-cli,codex-desktop,codex-sdk --since all
hansard index rebuild
```

`hansard rebuild` works only from files already in the archive and does not
reread Codex's files. To refresh inferred titles alone, run
`hansard rebuild --provider codex --since all`.

To add MCP tool screenshots to older Codex desktop conversations, replay the
original files the archive kept, without Codex's own files:

```sh
hansard rebuild --from-raw --source-type codex-desktop-history
```

Earlier releases archived cloud tasks as Codex sessions with no transcript.
Run the cloud import once to move them to **Codex cloud** and add their
transcripts:

```sh
hansard import codex-cloud --since all
```
