# How Job IDs Are Generated for the Codex Plugin: A Deep Dive into the Source Code

> Discover how job IDs are generated for the Codex plugin. Explore the source code to understand the prefix, timestamp, and random suffix combination.

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

---

**The Codex plugin generates unique job IDs using a combination of a caller-defined prefix, a base-36 timestamp, and a six-character random suffix, formatted as `prefix-timestamp-random`.**

Every background operation in the **openai/codex-plugin-cc** repository—from code reviews to automated tasks—requires a unique identifier for tracking and state management. According to the source code, the plugin centralizes this logic in a single helper function that constructs deterministic yet highly unique identifiers using JavaScript's native timing and randomness APIs.

## The `generateJobId` Implementation in `state.mjs`

The core logic resides in `plugins/codex/scripts/lib/state.mjs`, where the **`generateJobId`** function constructs identifiers by concatenating three distinct elements:

```javascript
export function generateJobId(prefix = "job") {
  const random = Math.random().toString(36).slice(2, 8);
  return `${prefix}-${Date.now().toString(36)}-${random}`;
}

```

This implementation produces strings following the pattern `<prefix>-<base36-timestamp>-<random-suffix>`. The function accepts an optional prefix parameter that defaults to `"job"` if not specified by the caller.

### Timestamp Conversion to Base-36

The middle segment uses **`Date.now()`** to capture the current epoch milliseconds, then converts this integer to base-36 notation using `.toString(36)`. This yields a compact alphanumeric representation that grows chronologically with each millisecond.

### Random Entropy Suffix

The final segment generates six characters of pseudo-randomness via **`Math.random().toString(36).slice(2, 8)`**. By slicing from index 2 (removing the leading `0.`) and taking six characters, the function ensures a consistent-length suffix regardless of the random value generated.

## How Job Types Determine the Prefix

Different job categories supply distinct prefixes to categorize the generated ID. In `plugins/codex/scripts/codex-companion.mjs`, the **`createCompanionJob`** function passes context-specific prefixes based on the operation type:

```javascript
// From codex-companion.mjs (lines 66-78)
const job = createCompanionJob({
  prefix: "task",           // ← Dictates the ID prefix
  kind: "task",
  title: taskMetadata.title,
  workspaceRoot,
  jobClass: "task",
  summary: taskMetadata.summary,
  write
});

```

The **`createCompanionJob`** wrapper in `plugins/codex/scripts/lib/tracked-jobs.mjs` (lines 67-73) subsequently invokes `generateJobId` with this prefix, creating the final identifier. Common prefixes observed in the codebase include:

- **`"task"`** – For automated task execution jobs
- **`"review"`** – For code review operations
- **`"job"`** – Default fallback for generic background operations

## Practical Usage Examples

When initiating a task through the companion interface, the generated ID becomes accessible immediately after creation:

```javascript
// Creating a task job returns the generated ID
const job = createCompanionJob({
  prefix: "task",
  kind: "task",
  title: "Refactor authentication module",
  workspaceRoot: "/path/to/project",
  jobClass: "task",
  summary: "Security improvements",
  write: console.log
});

console.log(`Started job ${job.id}`);
// Output: "Started job task-lk3j9c-5f1a2b"

```

For direct usage in unit tests or custom scripts, import the helper directly:

```javascript
import { generateJobId } from "./plugins/codex/scripts/lib/state.mjs";

// Generate a review-specific ID
console.log(generateJobId("review"));
// Output: "review-lyx2q0-9c7d4e"

// Use default prefix
console.log(generateJobId());
// Output: "job-lk4m2p-9x3d7f"

```

## Collision Resistance and Design Rationale

The ID generation strategy prioritizes **uniqueness over sequential predictability**. Because `Date.now()` increases monotonically and the random suffix adds entropy, the probability of collision remains negligible even when multiple jobs initiate within the same millisecond.

The base-36 encoding reduces string length compared to decimal timestamps while maintaining chronological sortability. Six characters of randomness (36^6 possible combinations) provides sufficient entropy for the expected scale of background jobs in a single IDE session.

## Summary

- **Job IDs** in the Codex plugin follow the format `prefix-timestamp-random` using base-36 encoding.
- The **`generateJobId`** function in `plugins/codex/scripts/lib/state.mjs` centralizes this logic.
- Callers specify prefixes via **`createCompanionJob`** in `codex-companion.mjs` or `tracked-jobs.mjs` to categorize job types.
- The combination of millisecond timestamps and six-character random suffixes prevents collisions without requiring external UUID libraries.

## Frequently Asked Questions

### What format do Codex plugin job IDs follow?

Job IDs follow a three-part hyphenated format: `<prefix>-<base36-timestamp>-<random-suffix>`. For example, `task-lk3j9c-5f1a2b` indicates a task job created at a specific millisecond timestamp with a random six-character suffix.

### Where is the job ID generation logic located?

The generation logic resides in **`plugins/codex/scripts/lib/state.mjs`** within the `generateJobId` export. This utility is consumed by `createCompanionJob` in both `codex-companion.mjs` and `tracked-jobs.mjs` when creating new job records.

### How does the Codex plugin prevent job ID collisions?

The plugin prevents collisions by combining a monotonically increasing timestamp (converted to base-36) with six characters of pseudo-random entropy. Even if two jobs start simultaneously within the same millisecond, the random suffix (with 36^6 possible combinations) makes identical IDs statistically improbable.

### Can I customize the job ID prefix?

Yes, the prefix is fully customizable. When calling `createCompanionJob`, pass your desired prefix string (such as `"deploy"`, `"scan"`, or `"lint"`) to generate IDs like `deploy-lyx2q0-9c7d4e`. The `generateJobId` function accepts any string as the prefix parameter, defaulting to `"job"` if omitted.