# How Threads, Turns, and Job Records Work Together in the OpenAI Codex Plugin

> Understand how threads, turns, and job records in the OpenAI Codex plugin create persistent conversation sessions and track background tasks for resumability and status.

- Repository: [OpenAI/codex-plugin-cc](https://github.com/openai/codex-plugin-cc)
- Tags: internals
- Published: 2026-07-29

---

**In the OpenAI Codex plugin, threads are persistent conversation sessions, turns are individual request/response exchanges within those threads, and job records are persistent objects that store `threadId` and `turnId` fields to link background tasks back to their originating conversation context for resumability and status tracking.**

The `openai/codex-plugin-cc` repository implements a sophisticated session management system where **threads, turns, and job records** form the backbone of background execution. Understanding how these three entities interact is essential for developers extending the plugin or debugging background task behavior in the Codex CLI.

## Core Architectural Concepts

### Threads: Persistent Conversation Containers

A **thread** represents a persistent conversation or session with Codex. When you initiate a dialogue with the model, the plugin creates a thread that maintains context across multiple interactions. Threads serve as high-level containers that preserve the state of your conversation, allowing you to resume work later without losing context.

### Turns: Individual Request/Response Pairs

Within each thread, **turns** represent discrete request/response cycles. Each turn captures a single exchange: your prompt and the model's reply. When you issue a command like `codex task "write a function"`, that command executes within a specific turn of the current thread. The plugin tracks turn identifiers to pinpoint exactly which request triggered subsequent background operations.

### Job Records: Background Task Persistence

When you execute a Codex command as a **background job**—using flags like `--background`—the plugin creates a **job record** that persists execution state. According to the source code in `plugins/codex/scripts/lib/tracked-jobs.mjs`, each job record contains two critical linking fields:

- **`threadId`**: Identifies the conversation thread where the job originated
- **`turnId`**: Identifies the specific turn that initiated the background work

This linkage enables the CLI to reconstruct context when resuming sessions or displaying status information.

## Implementation Details

### Job Registration in tracked-jobs.mjs

The `registerJob` function in `plugins/codex/scripts/lib/tracked-jobs.mjs` (lines 86-88) normalizes and stores job records. When a background task starts, the plugin captures the current `threadId` and `turnId`, binding the job to its conversational origin:

```javascript
import { registerJob } from "./tracked-jobs.mjs";

function startBackgroundTask(threadId, turnId, payload) {
  const job = {
    id: `task-${Date.now()}`,
    threadId,               // Ties job to conversation thread
    turnId,                 // Ties job to specific request turn
    status: "running",
    // …additional metadata
  };
  registerJob(job);        // Persists to state
}

```

### CLI Rendering and Thread Display

The `plugins/codex/scripts/lib/render.mjs` file handles how job information appears in the terminal. Lines 119-140 generate the status table that includes a `Thread ID` column, while lines 106-108 contain logic for constructing resume commands based on stored thread associations.

When you run `codex status`, the output includes the thread relationship:

```bash
$ codex status
| Job ID     | Kind   | Status    | Phase | Elapsed | Thread ID | Summary |
|------------|--------|-----------|-------|---------|-----------|---------|
| task-live  | task   | running   |       | 12s     | thr_1     | …       |

```

### State Management

The `plugins/codex/scripts/lib/state.mjs` module maintains the in-memory state for all three entities, ensuring that thread context, turn history, and job records remain synchronized during execution. The `plugins/codex/scripts/lib/codex.mjs` file provides helper functions for managing thread and turn lifecycles, including resume handling logic.

## Working with Background Jobs

### Starting a Background Task

To launch work that continues after you disconnect, use the `--background` flag. The plugin immediately creates a job record linked to your current thread:

```bash

# Initiates background task linked to current thread

$ codex task --background "Write a function that shuffles an array"

# Output includes job ID (e.g., task-live)

```

### Resuming Thread Context

The job record's `threadId` field enables seamless context restoration. When you resume a thread, the plugin locates the most recent job matching that thread to rebuild the conversation state:

```bash

# Resume using the thread ID from status output

$ codex resume thr_1

# CLI reconstructs original thread context and continues interaction

```

### Cancelling Linked Jobs

Because job records maintain thread associations, cancellation affects the linked conversation context appropriately:

```bash

# Cancel specific job by ID

$ codex cancel task-live

# Job status changes to "cancelled"; thread marked as interrupted

```

## Summary

- **Threads** serve as persistent conversation containers that maintain context across multiple interactions with Codex.
- **Turns** represent individual request/response pairs within threads, tracking exactly which user prompt initiated specific operations.
- **Job records** store `threadId` and `turnId` fields to bind background tasks to their originating conversation context, enabling resumability and status tracking.
- The `tracked-jobs.mjs` module normalizes these relationships at lines 86-88, while `render.mjs` displays them in CLI output at lines 119-140.
- Unit tests in `tests/runtime.test.mjs` validate these linkages by asserting that `payload.threadId` matches `job.threadId`.

## Frequently Asked Questions

### How does the Codex plugin maintain context when resuming a background task?

The plugin retrieves the `threadId` from the job record stored in `tracked-jobs.mjs`, then uses the `codex resume <threadId>` command to reconstruct the conversation thread. The job record's stored `turnId` ensures the plugin can locate the exact request that triggered the background work, allowing seamless continuation of the dialogue.

### What happens to the thread relationship when a job is cancelled?

When you execute `codex cancel <job-id>`, the plugin updates the job record's status to "cancelled" and marks the associated thread as interrupted in the state managed by `plugins/codex/scripts/lib/state.mjs`. The thread remains accessible for inspection but indicates that the background operation terminated abnormally.

### Can a single thread have multiple active job records?

Yes, a single thread can spawn multiple background jobs across different turns. Each job record maintains its own `turnId` pointer to the specific request that created it, while sharing the same `threadId`. This allows the `codex status` command to display all active jobs grouped by their parent thread, as implemented in `plugins/codex/scripts/lib/render.mjs`.

### Where is the thread-turn-job relationship tested in the codebase?

The relationship is validated in `tests/runtime.test.mjs`, which contains unit tests asserting that job records correctly store `payload.threadId` and that these identifiers match the expected thread contexts during background execution scenarios.