Skip to main content

Module codex_watcher

Module codex_watcher 

Source
Expand description

The Codex rollout watcher, which supplements the Codex hook feed.

An engine-owned background task over $CODEX_HOME/sessions/YYYY/MM/DD/rollout-*.jsonl (#1909, ADR-0087), the Codex twin of the Claude transcript watcher.

Hooks own a Codex session’s state; this watcher covers what they miss:

  1. Discovery — a session started before the daemon (or before the hooks were installed and trusted) still has a rollout file. Its head-of-file session_meta line yields the session’s id and cwd, so the session lands on the right worktree row even before a hook fires.
  2. Ends hooks cannot report. Archiving an IDE or Desktop chat moves its rollout into $CODEX_HOME/archived_sessions/, which is outside the watched tree, so a rollout that vanishes reads as an end. And a Codex process killed by SIGHUP (closing its terminal tab), SIGTERM or SIGKILL fires no SessionEnd: while a thread is loaded, Codex holds an exclusive flock on $CODEX_HOME/thread-writer-locks/<session-id>.lock, and the kernel drops it when the process dies, however it dies. A lock this watcher has seen held that is later free (or gone) ends the session, instead of it lingering for the registry’s TTL.
  3. Idle liveness. An idle Codex session emits nothing, so it would age out on the TTL while its process lives on. A held lock is re-reported as a state-preserving heartbeat.

What it reads, and what it never does:

  • Only the first line of a rollout (session_meta, bounded to [MAX_HEAD_BYTES]), and from it only id/session_id, cwd and source; never a conversation line. Growth is size/mtime only. Nothing is logged.
  • Subagent threads are skipped: their source is an object ({"subagent": …}), and their hook events already carry the parent’s id.
  • It never reports a state: growth is a heartbeat, not working, because a rollout keeps being written around the turn’s Stop and would otherwise hold an idle session at working. So a session only this watcher sees reads idle. It can never report an approval either — the rollout records none.
  • The lock probe is a non-blocking shared flock taken and dropped at once: on a session’s first sight, then once per scan while it is tracked and not ended (an ended session is left alone until its rollout grows). Against a live holder it fails harmlessly; it can only collide with Codex acquiring the lock for that same thread in the same instant.
  • On first sight a rollout whose lock is free or gone is recorded but not announced — a daemon restart must not list sessions that already ended.

Functions§

spawn
Spawns the watcher loop, returning its JoinHandle.