# Understanding the broker-lifecycle Module in OpenAI Codex Plugin CC

> Discover the broker-lifecycle module in OpenAI Codex Plugin CC. Learn how this persistence layer creates, loads, and saves broker sessions, ensuring efficient reuse of a single broker instance.

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

---

**The broker-lifecycle module is a persistence layer in `openai/codex-plugin-cc` that creates, loads, and saves broker sessions across plugin commands, ensuring a single broker instance is reused rather than recreated on every run.**

This module lives in `plugins/codex/scripts/lib/broker-lifecycle.mjs` and serves as the central authority for all broker-session handling in the Codex plugin. By storing session state (broker ID, authentication token, endpoint) to disk, it eliminates redundant broker creation and enables features like session resumption and cross-machine transfer.

## Core Responsibilities of the broker-lifecycle Module

The module exposes three primary functions that manage the complete lifecycle of a broker session:

| Function | Purpose | Key Behavior |
|----------|---------|--------------|
| `ensureBrokerSession()` | Guarantees a valid session exists | Creates new session if none found; returns session object |
| `loadBrokerSession()` | Reads persisted session from disk | Parses JSON from deterministic file path; throws on invalid data |
| `saveBrokerSession(session)` | Persists session to disk | Serializes session object atomically to prevent corruption |

These functions are implemented in `broker-lifecycle.mjs` and imported by multiple components: `app-server.mjs`, `codex.mjs`, `session-lifecycle-hook.mjs`, and the test suite in `runtime.test.mjs`.

## How broker-lifecycle Manages Broker Sessions

The session management follows a strict deterministic flow designed for reliability across process restarts.

### Session Startup and Validation

When the plugin initializes, `ensureBrokerSession()` serves as the entry point:

```javascript
// From app-server.mjs – guarantees session before server starts
import { ensureBrokerSession } from "./lib/broker-lifecycle.mjs";

async function startServer() {
  const session = await ensureBrokerSession();
  // Server now has guaranteed access to valid broker credentials
}

```

This function implements a fail-safe pattern: it attempts to load an existing session, and only creates a new one when the load fails. This prevents accidental session proliferation.

### Session Creation and Persistence

If `loadBrokerSession()` throws (missing file, corrupted JSON, or schema mismatch), `ensureBrokerSession()` constructs a fresh session object:

```javascript
// Example: obtaining a validated broker session
import { ensureBrokerSession } from "./lib/broker-lifecycle.mjs";

async function run() {
  const session = await ensureBrokerSession();

  console.log("Broker ID:", session.id);
  console.log("Current endpoint:", session.endpoint);
  // session.token is available for authenticated API calls
}
run();

```

The new session receives a generated UUID for `id`, a fresh authentication token, and the default endpoint. It is immediately persisted via `saveBrokerSession()` before return, ensuring no window exists where a valid session exists only in memory.

### Manual Session Updates

Components that refresh tokens or modify endpoint configuration use the explicit load-save pattern:

```javascript
// Example: persisting a token refresh
import { loadBrokerSession, saveBrokerSession } from "./lib/broker-lifecycle.mjs";

async function refreshToken() {
  const session = await loadBrokerSession();
  session.token = await getNewTokenFromOAuthProvider();
  await saveBrokerSession(session);
  // Subsequent plugin commands automatically use refreshed token
}

```

This pattern appears in `codex.mjs`, where the Codex client wrapper attaches the broker token from `loadBrokerSession()` to outgoing requests.

## Files That Depend on broker-lifecycle

The module's API is consumed across the plugin architecture, demonstrating its role as a shared dependency:

- **`app-server.mjs`** – Calls `ensureBrokerSession()` at server startup to guarantee session availability for the entire process lifetime
- **`codex.mjs`** – Imports `loadBrokerSession` to attach broker authentication tokens to Codex API requests
- **`session-lifecycle-hook.mjs`** – Triggers session validation before each Codex command execution
- **`tests/runtime.test.mjs`** – Exercises `loadBrokerSession` and `saveBrokerSession` to verify persistence across simulated restarts

## Testing Session Persistence

The module's behavior is validated through restart simulation:

```javascript
// From runtime.test.mjs – verifying session survives process restart
import {
  loadBrokerSession,
  saveBrokerSession,
} from "../plugins/codex/scripts/lib/broker-lifecycle.mjs";

test("session persists across loads", async () => {
  const original = await loadBrokerSession();
  original.foo = "bar";
  await saveBrokerSession(original);

  const reloaded = await loadBrokerSession();
  expect(reloaded.foo).toBe("bar");
});

```

This test confirms that the serialization-deserialization roundtrip preserves all session properties, including ad-hoc extensions.

## Design Rationale: Why Centralize Session Management?

The `broker-lifecycle` module prevents three specific failure modes that would occur with distributed session handling:

1. **Race conditions** – Concurrent commands cannot create duplicate broker instances because `ensureBrokerSession()` serializes access through filesystem state
2. **State drift** – Token refreshes in one component automatically propagate to others via shared persistence
3. **Orphaned brokers** – Explicit session tracking enables intentional cleanup rather than leaving brokers active indefinitely

The deterministic file location (relative to the plugin's working directory) also enables "transfer session to another machine" workflows by copying the session JSON.

## Summary

- The **broker-lifecycle module** (`broker-lifecycle.mjs`) centralizes all broker session operations in the OpenAI Codex plugin
- **`ensureBrokerSession()`** guarantees a valid session exists, creating one only when necessary
- **`loadBrokerSession()`** and **`saveBrokerSession()`** provide explicit persistence control for components that modify session state
- The module enables **session resumption** across plugin commands and **cross-machine transfer** through deterministic file-based storage
- All major components—`app-server.mjs`, `codex.mjs`, `session-lifecycle-hook.mjs`—depend on this module for consistent broker session access

## Frequently Asked Questions

### What happens if the broker session file is corrupted?

`loadBrokerSession()` throws an error when parsing fails or required fields are missing. `ensureBrokerSession()` catches this exception and creates a fresh session with new credentials, which is immediately persisted to replace the corrupted file.

### Can multiple plugin commands run simultaneously with the same session?

Yes. Because the session is stored on disk, concurrent processes read the same broker ID and token. However, token refresh operations should be serialized to prevent race conditions where one process overwrites another's fresh token.

### How does broker-lifecycle differ from session-lifecycle-hook.mjs?

`broker-lifecycle.mjs` is the **storage and retrieval layer**—it knows how to read and write session state. `session-lifecycle-hook.mjs` is the **trigger layer**—it invokes broker-lifecycle functions at specific points in command execution. The hook depends on the module, not vice versa.

### Where is the session file stored on disk?

The module uses a deterministic path relative to the plugin's working directory, typically in a subdirectory of `plugins/codex/`. The exact path is encapsulated within `broker-lifecycle.mjs` and not exposed to consuming code, ensuring consistent location across all imports.