# How Codex Plugin Job Log Files Are Created and Managed

> Discover how the Codex plugin creates and manages job log files. Learn about log file generation, timestamped entries, and organized log rotation for efficient workspace management.

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

---

**TLDR:** The Codex plugin generates a unique log file for every asynchronous operation using the `resolveJobLogFile()` helper, writes timestamped entries throughout the job lifecycle, and rotates completed logs into categorized collections to maintain workspace hygiene.

The openai/codex-plugin-cc repository implements a robust file-based logging system that tracks every review, task, and adversarial operation as a distinct **job**. Each job receives a dedicated log file stored in the workspace's `jobs` directory, creating a persistent audit trail that enables debugging and post-hoc analysis beyond the current session.

## Log File Path Resolution and Initial Creation

### The resolveJobLogFile Helper

The canonical path for any job log is constructed by the `resolveJobLogFile()` function defined in `plugins/codex/scripts/lib/tracked-jobs.mjs`. This helper combines the workspace root with the **job identifier** to produce a deterministic path: `<workspace>/jobs/<jobId>.log`.

When a job starts, the plugin immediately creates or truncates this file and writes the initial entry. According to the test suite in `tests/runtime.test.mjs` (lines 1302-1303), the first line typically records the initiation timestamp:

```javascript
`[${new Date().toISOString()}] Starting Codex Task.\n`

```

```javascript
import { resolveJobLogFile } from './tracked-jobs.mjs';
import { writeFileSync } from 'fs';

const jobId = 'task-123-abc';
const logFile = resolveJobLogFile(workspace, jobId);

// Initialize with timestamped header
writeFileSync(
  logFile,
  `[${new Date().toISOString()}] Starting Codex Task.\n`,
  'utf8'
);

```

## Structured Logging During Job Execution

Throughout the job lifecycle, the plugin appends structured messages using `fs.appendFileSync`. The `job-control.mjs` module manages these writes, capturing everything from reasoning summaries to sub-agent activity.

### Reasoning Summaries and Review Output

For review jobs, the log captures the reasoning summary and file review status. The test cases in `tests/runtime.test.mjs` (lines 475-479) demonstrate entries such as `Reasoning summary:` and `Reviewed the changed files…`, providing a complete narrative of the decision process.

### Assistant Messages and Task Completion

Standard task jobs log assistant messages and completion status. As shown in `tests/runtime.test.mjs` (lines 804-808), entries include `Assistant message:` and `Handled the requested task`, documenting the interaction flow between the user and the AI agent.

### Sub-Agent Prefix Tracking

When jobs spawn sub-agents, the **prefix** identifies the parent-child relationship. The logs capture `Starting subagent …` and `Subagent … reasoning:` entries (referenced in `tests/runtime.test.mjs`, lines 828-831), enabling hierarchical traceability of distributed operations.

```javascript
import { appendFileSync } from 'fs';

// Append reasoning summary during review
appendFileSync(
  logFile,
  `[${new Date().toISOString()}] Reasoning summary: ${summary}\n`,
  'utf8'
);

// Log assistant response
appendFileSync(
  logFile,
  `[${new Date().toISOString()}] Assistant message: ${msg}\n`,
  'utf8'
);

// Track sub-agent activity
appendFileSync(
  logFile,
  `[${new Date().toISOString()}] Starting subagent ${subAgentId}...\n`,
  'utf8'
);

```

## Log Access and Lifecycle Management

### Runtime Access via job.logFile

The active log path is stored on the job object itself as `job.logFile`, allowing runtime introspection. Test suites access this property directly to verify log contents, as demonstrated in `tests/runtime.test.mjs` (lines 475-479) where `fs.readFileSync(state.jobs[0].logFile, "utf8")` retrieves the current log state for assertions.

### Log Rotation and Cleanup

When jobs finish, the plugin organizes logs into categorized collections to prevent clutter. The implementation moves completed job logs into `completed.log`, active jobs into `running.log`, and other statuses into corresponding log files (see rotation logic in `tests/runtime.test.mjs`, lines 1815-1878). This rotation strategy maintains a clean workspace while preserving historical records for compliance and debugging.

## Summary

- The **Codex plugin** creates a dedicated log file for every job using `resolveJobLogFile()` in `plugins/codex/scripts/lib/tracked-jobs.mjs`, storing it at `<workspace>/jobs/<jobId>.log`.
- **Log initialization** happens immediately upon job scheduling, with an ISO timestamp header written via `fs.writeFileSync`.
- Throughout execution, **structured entries** (reasoning summaries, assistant messages, sub-agent prefixes) are appended using `fs.appendFileSync`, as verified in `runtime.test.mjs`.
- The **job object** exposes the log path via `job.logFile`, enabling runtime access and test verification.
- **Log rotation** moves completed, running, and other job logs into categorized files to maintain workspace organization.

## Frequently Asked Questions

### Where are Codex plugin job log files stored?

Job log files are stored in the `jobs` subdirectory of the workspace root, with the filename pattern `<jobId>.log`. The `resolveJobLogFile()` function in `plugins/codex/scripts/lib/tracked-jobs.mjs` constructs this path deterministically from the workspace and job identifier.

### What content is written to job log files?

Log files contain timestamped, structured entries including initiation markers, reasoning summaries, assistant messages, and sub-agent activity prefixes. These entries append throughout the job lifecycle using `fs.appendFileSync`, creating a complete audit trail of the operation.

### How does the plugin manage log file rotation?

When jobs complete, the plugin rotates logs into categorized collections such as `completed.log`, `running.log`, and other status-specific logs (as shown in `tests/runtime.test.mjs`, lines 1815-1878). This prevents the jobs directory from accumulating stale files while preserving history.

### Can I access a job's log file while it is running?

Yes. The job object exposes the log file path via the `job.logFile` property, allowing runtime access for monitoring or debugging. Test implementations demonstrate this by reading `state.jobs[0].logFile` directly to verify logged content during execution.