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

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:

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:

// 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:

// 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:

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.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →