040. The Codex databases hold no link from a TUI to its thread
- Date
- 2026-10-30
- Agents
- Codex CLI
- Measured on
- real machine
Measured
2026-10-30, Codex CLI 0.164.0 (standalone install,
x86_64-unknown-linux-musl), on Linux (Debian 13, x64), in the default
daemon mode, in a private tmux server with a throwaway HOME and a
copied login. The scenario scenarios/codex/daemon-life.sh read the
table layout of each ~/.codex/*.sqlite file while two TUIs ran, with
sqlite3 -readonly and only .tables and .schema. It read no row. It
also read /proc/<pid>/fd of each process. Two runs gave the same
layout. The file list of scenarios/codex/deny.sh gave the names and
sizes below ~/.codex.
Measured on: real machine.
What was measured
~/.codexholds six SQLite files, each in WAL mode (with-waland-shmfiles):state_5.sqlite,logs_2.sqlite,thread_history_1.sqlite,goals_1.sqlite,memories_1.sqliteandqueue_1.sqlite.- The tables of
state_5.sqlite:threads,thread_attachments,thread_dynamic_tools,thread_read_receipts,thread_sections,thread_spawn_edges,projects,project_roots,project_idempotency_keys,backfill_state,rollout_migration_state,rollout_migration_skipped_rollouts,external_agent_config_imports,guardian_review_feedback,remote_control_enrollmentsand_sqlx_migrations. - No column of
state_5.sqliteholds a pid, a tty, a pane or a client of the daemon.threadshasid,rollout_path,cwd,source,originator,cli_version,created_atandupdated_at, and more.thread_read_receiptshasthread_id,first_unread_turn,revisionandlast_published_turn: one row for each thread, not for each client.remote_control_enrollmentshasapp_server_client_name, for remote control. logs_2.sqlitehas one tablelogswith the columnsthread_idandprocess_uuid, and an index onprocess_uuidfor rows with no thread. This is the only layout that joins a process to a thread. Theprocess_uuidis not a pid, and no table maps it to a pid.- The other tables:
thread_history_1.sqlitehasthread_items,thread_turns,thread_realtime_itemsandthread_history_projection_state.goals_1.sqlitehasthread_goalsandthread_goal_continuation_deferrals.queue_1.sqlitehasqueued_itemsandqueued_thread_revisions.memories_1.sqlitehasjobs,stage1_outputsandconsolidation_progress. - Each daemon-mode TUI holds
state_5,logs_2,goals_1,memories_1andqueue_1open, but notthread_history_1. The daemon and the--no-daemonTUI hold all six. Thus the open databases of a TUI do not name its thread. - Codex makes an empty file (0 bytes)
~/.codex/tui-thread-reference-capabilities/<session id>when a session starts, before the first prompt. Two daemon-mode TUIs and one--no-daemonTUI left two such files; a third daemon-mode TUI added one more. No process held one open, while a TUI ran or after.
Mechanism
The daemon keeps the threads. The tables describe threads, not the clients that show them. A reader that must link a daemon-mode TUI to its thread finds no pid in these layouts.
Incident
None recorded. aw asked for an exact link from a Codex TUI to its thread in daemon mode (fact 26).
Screens
None.
Not measured
- The rows. A row of
logscould hold aprocess_uuidof a TUI, and the text of a log line could name a pid. Neither was read. - The content of the files below
tui-thread-reference-capabilities/other than their size, and which process makes them. - The app-server protocol on the daemon socket, which could list clients.
codex agents, which browses the sessions of the daemon.- macOS and Windows.