# Ralph Persistence Mode vs Ultrawork Parallel Mode in oh‑my‑claudecode: Key Differences

> Understand the key differences between Ralph persistence mode and Ultrawork parallel mode in oh-my-claudecode. Learn how each mode handles tasks and verification for efficient coding workflows.

- Repository: [Bellman/oh-my-claudecode](https://github.com/Yeachan-Heo/oh-my-claudecode)
- Tags: deep-dive
- Published: 2026-03-27

---

**Ralph persistence mode maintains a single-task loop awaiting explicit Architect verification, while Ultrawork parallel mode orchestrates multiple concurrent subtasks with reinforcement counting until completion or limit.**

The `oh-my-claudecode` repository provides two distinct orchestration strategies for managing long-running LLM sessions. Understanding the difference between **Ralph persistence mode** and **Ultrawork parallel mode** is essential for selecting the correct workflow for your specific task complexity and concurrency requirements.

## Core Architectural Differences

### Ralph Persistence Mode (Stateful Single-Task Loop)

Ralph mode is designed for **deep, stateful work** that requires sustained focus on a single objective. When activated via the `ralph` keyword or `$ralph` skill, the system enters a persistent loop that prevents the LLM from terminating until an Architect explicitly verifies completion.

The mode stores session data in [`ralph-state.json`](https://github.com/Yeachan-Heo/oh-my-claudecode/blob/main/ralph-state.json) and operates at **priority 1** in the hook execution order. According to the source code in `templates/hooks/persistent-mode.mjs` (lines 44-80), the hook increments an `iteration` counter and blocks execution while `iteration < max_iterations`, optionally extending the limit when exhausted.

### Ultrawork Parallel Mode (Concurrent Worker Orchestration)

Ultrawork mode enables **maximally parallel execution** of independent subtasks. Triggered by the `ultrawork`, `ulw`, or `$ultrawork` keywords, this mode tracks multiple concurrent workers through [`ultrawork-state.json`](https://github.com/Yeachan-Heo/oh-my-claudecode/blob/main/ultrawork-state.json) and manages reinforcement limits rather than simple iteration counts.

Operating at **priority 4** in the hook chain (lines 940-979 of `persistent-mode.mjs`), Ultrawork increments `reinforcement_count` and continues blocking only while workers remain active or until `max_reinforcements` is reached. Unlike Ralph, this mode reports incomplete tasks/todos in its blocking reason and suggests cancellation once work appears finished.

## Implementation Details in the Source Code

### Hook Priority and Execution Order

The `persistent-mode.mjs` hook dispatcher processes modes sequentially by priority. Ralph executes first (priority 1) because it represents the most restrictive persistence contract—single-task loops that must survive until human verification.

Ultrawork executes later (priority 4) after Ralph checks complete, allowing the system to fall back to parallel orchestration when Ralph is inactive. This hierarchy ensures that single-task persistence takes precedence over parallel dispatching.

### State Management and Control Flow

#### Ralph State File ([`ralph-state.json`](https://github.com/Yeachan-Heo/oh-my-claudecode/blob/main/ralph-state.json))

The Ralph implementation relies on a state object containing `iteration`, `max_iterations`, an optional prompt, and an `active` flag. The core blocking logic evaluates:

```javascript
// templates/hooks/persistent-mode.mjs (lines 44-80)
if (ralph.state?.active) {
  const iteration = ralph.state.iteration || 1;
  const maxIter = ralph.state.max_iterations || 100;
  if (iteration < maxIter) {
    ralph.state.iteration = iteration + 1;
    // Write state and block
    console.log(JSON.stringify({
      continue: false, 
      decision: "block", 
      reason: `Ralph iteration ${iteration}/${maxIter}`
    }));
    return;
  }
  // Logic to extend max iterations when reached
}

```

#### Ultrawork State File ([`ultrawork-state.json`](https://github.com/Yeachan-Heo/oh-my-claudecode/blob/main/ultrawork-state.json))

Ultrawork tracks `reinforcement_count`, `max_reinforcements`, and the `original_prompt`. The termination condition reverses the inequality logic:

```javascript
// templates/hooks/persistent-mode.mjs (lines 940-979)
if (ultrawork.state?.active) {
  const newCount = (ultrawork.state.reinforcement_count || 0) + 1;
  const maxReinforcements = ultrawork.state.max_reinforcements || 50;
  
  if (newCount > maxReinforcements) {
    console.log(JSON.stringify({
      continue: true, 
      suppressOutput: true
    }));
    return;
  }
  
  ultrawork.state.reinforcement_count = newCount;
  // Build reason including incomplete task count
  console.log(JSON.stringify({
    continue: false, 
    decision: "block", 
    reason: `Ultrawork reinforcement ${newCount}/${maxReinforcements} - ${incompleteTasks} tasks remaining`
  }));
  return;
}

```

### Keyword Detection Architecture

Both modes share the detection pipeline in `src/hooks/keyword-detector.mjs` (lines 423-430). The detector maps input strings to mode constants defined in [`src/lib/mode-names.ts`](https://github.com/Yeachan-Heo/oh-my-claudecode/blob/main/src/lib/mode-names.ts):

- `ralph` → `RALPH` mode constant
- `ultrawork` or `ulw` → `ULTRAWORK` mode constant

State persistence utilizes the `stateRead` and `stateWrite` tools from [`src/tools/state-tools.ts`](https://github.com/Yeachan-Heo/oh-my-claudecode/blob/main/src/tools/state-tools.ts), with path resolution handled by [`src/lib/worktree-paths.ts`](https://github.com/Yeachan-Heo/oh-my-claudecode/blob/main/src/lib/worktree-paths.ts).

## Practical Usage Examples

### Activating Ralph for Deep Architectural Work

Use Ralph mode when you need the LLM to persist through multiple refinement cycles on a single complex task:

```bash

# Terminal activation

$ ralph

# Or inline in prompt

Ralph: Design a micro-service architecture for a real-time chat application with presence detection and history sharding.

```

The session continues looping until you execute verification:

```bash

# After reviewing the architecture output

/oh-my-claudecode:cancel

```

### Activating Ultrawork for Parallel Batch Operations

Use Ultrawork when generating or processing multiple independent artifacts:

```bash

# Terminal activation

$ ultrawork

# Or shorthand

$ ulw

# Example prompt

Ultrawork: Generate API client stubs for these 12 endpoints:
- GET /users/{id}
- POST /messages
- PUT /channels/{id}/members
...

```

The hook tracks completion status across all subtasks and automatically suggests cancellation when the worker queue empties, or you may force termination:

```bash
/oh-my-claudecode:cancel --force

```

## Summary

- **Ralph persistence mode** prioritizes single-task continuity with human-in-the-loop verification, storing iteration counts in [`ralph-state.json`](https://github.com/Yeachan-Heo/oh-my-claudecode/blob/main/ralph-state.json) and executing at hook priority 1.
- **Ultrawork parallel mode** maximizes throughput for concurrent subtasks, tracking reinforcements in [`ultrawork-state.json`](https://github.com/Yeachan-Heo/oh-my-claudecode/blob/main/ultrawork-state.json) at priority 4 and terminating when workers complete or hit `max_reinforcements`.
- Both modes rely on `templates/hooks/persistent-mode.mjs` for blocking logic and `src/hooks/keyword-detector.mjs` for activation triggers.
- Cancellation requires `/oh-my-claudecode:cancel` for Ralph (post-verification) and allows immediate cancellation for Ultrawork (upon task completion).

## Frequently Asked Questions

### How do I know which mode to use for my task?

Choose **Ralph persistence mode** when working on complex, interdependent tasks requiring sustained architectural focus—such as refactoring a core module or designing data models—where premature termination would lose critical context. Select **Ultrawork parallel mode** when dispatching independent, parallelizable work like generating multiple files, running test suites across different configurations, or processing batch operations that can complete asynchronously.

### Can I switch between Ralph and Ultrawork during a session?

No, the modes are mutually exclusive orchestration states. The hook dispatcher in `persistent-mode.mjs` checks Ralph (priority 1) before Ultrawork (priority 4), meaning if Ralph is active, Ultrawork logic never executes. You must cancel the current mode with `/oh-my-claudecode:cancel` before activating a different orchestration strategy.

### What are the default iteration and reinforcement limits?

According to the source implementation, Ralph defaults to **100 iterations** (`max_iterations || 100`) while Ultrawork defaults to **50 reinforcements** (`max_reinforcements || 50`). Ralph automatically extends its limit when reached, whereas Ultrawork terminates once `reinforcement_count` exceeds the maximum, allowing the session to close naturally.

### Where does oh-my-claudecode store the active state for these modes?

State persistence occurs in JSON files managed by [`src/tools/state-tools.ts`](https://github.com/Yeachan-Heo/oh-my-claudecode/blob/main/src/tools/state-tools.ts). Ralph writes to [`ralph-state.json`](https://github.com/Yeachan-Heo/oh-my-claudecode/blob/main/ralph-state.json), while Ultrawork writes to [`ultrawork-state.json`](https://github.com/Yeachan-Heo/oh-my-claudecode/blob/main/ultrawork-state.json). Both files are located via path resolution in [`src/lib/worktree-paths.ts`](https://github.com/Yeachan-Heo/oh-my-claudecode/blob/main/src/lib/worktree-paths.ts) and maintain counters, activation flags, and optional prompt context between hook invocations.