# Ponytail Runtime Modes Explained: How Off, Lite, Full, Ultra, and Review Work

> Explore Ponytail's five runtime modes off lite full ultra and review to control AI coding assistance. Learn how each mode works and how to manage them for your workflow.

- Repository: [DietrichGebert/ponytail](https://github.com/DietrichGebert/ponytail)
- Tags: deep-dive
- Published: 2026-09-11

---

**Ponytail supports five distinct runtime modes—`off`, `lite`, `full`, `ultra`, and `review`—that govern the intensity of its AI-assisted coding behavior, with the `review` mode restricted to session-only usage while the remaining four can persist as user defaults.**

Ponytail is an open-source AI coding assistant designed to operate as a "lazy senior developer" that adapts its involvement based on configurable intensity levels. Understanding Ponytail runtime modes is critical for developers who need to balance automated assistance with manual control. This guide examines the mode architecture as implemented in the [DietrichGebert/ponytail](https://github.com/DietrichGebert/ponytail) repository, detailing how modes are defined, resolved, and managed across sessions.

## The Five Runtime Modes

Ponytail categorizes its operational states into five valid modes, but treats them differently regarding persistence and scope.

### Valid Modes vs. Runtime-Only Modes

In [[`hooks/ponytail-config.js`](https://github.com/DietrichGebert/ponytail/blob/main/hooks/ponytail-config.js)](https://github.com/DietrichGebert/ponytail/blob/main/hooks/ponytail-config.js), the system defines two authoritative arrays that govern mode behavior:

```javascript
// hooks/ponytail-config.js
export const VALID_MODES = ['off', 'lite', 'full', 'ultra', 'review'];
export const RUNTIME_MODES = ['off', 'lite', 'full', 'ultra'];

```

The **VALID_MODES** array represents every mode the system recognizes, including the transient `review` state. The **RUNTIME_MODES** array contains the subset that users may set as persistent defaults in their configuration file. This distinction ensures that high-intensity review behavior cannot accidentally become a permanent setting.

### The Review Mode Restriction

The `review` mode activates aggressive code scrutiny for a single interaction only. Because [[`hooks/ponytail-config.js`](https://github.com/DietrichGebert/ponytail/blob/main/hooks/ponytail-config.js)](https://github.com/DietrichGebert/ponytail/blob/main/hooks/ponytail-config.js) explicitly checks against `RUNTIME_MODES` before persisting defaults, attempting to set `review` as a default mode will fail validation. This safety mechanism prevents the computationally expensive review behavior from persisting across all future sessions.

## Mode Resolution Architecture

Ponytail resolves the active mode through a hierarchical cascade that prioritizes environment context over stored preferences.

### Configuration Layer

Mode constants originate in [[`hooks/ponytail-config.js`](https://github.com/DietrichGebert/ponytail/blob/main/hooks/ponytail-config.js)](https://github.com/DietrichGebert/ponytail/blob/main/hooks/ponytail-config.js), which exports the canonical mode lists. User defaults are stored in [`.ponytail-config.json`](https://github.com/DietrichGebert/ponytail/blob/main/.ponytail-config.json) within the Claude configuration directory. However, the system validates any persisted default against `RUNTIME_MODES` to ensure only `off`, `lite`, `full`, or `ultra` survive across restarts.

### Resolution Hierarchy

When Ponytail initializes, [[`hooks/ponytail-runtime.js`](https://github.com/DietrichGebert/ponytail/blob/main/hooks/ponytail-runtime.js)](https://github.com/DietrichGebert/ponytail/blob/main/hooks/ponytail-runtime.js) executes the `readMode()` function, which resolves the active mode in the following priority order:

1. **Environment Variable**: The `PONYTAIL_MODE` environment variable (and legacy `QODER_SESSION_ID` detection via `isQoder()`) takes precedence.
2. **Configuration File**: If no environment override exists, the system reads the default from [`.ponytail-config.json`](https://github.com/DietrichGebert/ponytail/blob/main/.ponytail-config.json).
3. **Session Override**: Runtime slash commands like `/ponytail ultra` trigger immediate mode changes via the mode tracker.

The `readMode()` function returns a guaranteed valid runtime mode, defaulting to a safe state if validation fails.

### Persistence Mechanisms

Mode persistence operates through two distinct channels managed by [[`hooks/ponytail-mode-tracker.js`](https://github.com/DietrichGebert/ponytail/blob/main/hooks/ponytail-mode-tracker.js)](https://github.com/DietrichGebert/ponytail/blob/main/hooks/ponytail-mode-tracker.js):

- **Flag File**: The tracker writes the active mode to `.ponytail-active` in the project root, creating a filesystem marker.
- **Session Manager**: The tracker injects a custom entry with `type: "custom"` and `customType: "ponytail-mode"` into the session manager, ensuring the mode propagates to downstream instruction builders.

## Technical Implementation

The runtime mode system relies on three core components that handle detection, storage, and instruction generation.

### Core Runtime Functions

[[`hooks/ponytail-runtime.js`](https://github.com/DietrichGebert/ponytail/blob/main/hooks/ponytail-runtime.js)](https://github.com/DietrichGebert/ponytail/blob/main/hooks/ponytail-runtime.js) exports the low-level API for mode manipulation:

```javascript
// Example: Reading current mode
const { readMode, setMode, clearMode } = require('./ponytail-runtime');
const currentMode = readMode();  // Returns: 'off' | 'lite' | 'full' | 'ultra'

```

Key functions include:
- **`isQoder()`**: Detects legacy Qoder session environments.
- **`readMode()`**: Resolves the current mode from environment, config, or session.
- **`setMode(mode)`**: Validates and activates a new runtime mode.
- **`clearMode()`**: Removes the active mode configuration.
- **`writeHookOutput(data)`**: Serializes mode state for session propagation.

### Mode Tracking and Session Injection

The [[`hooks/ponytail-mode-tracker.js`](https://github.com/DietrichGebert/ponytail/blob/main/hooks/ponytail-mode-tracker.js)](https://github.com/DietrichGebert/ponytail/blob/main/hooks/ponytail-mode-tracker.js) hook bridges user commands and system state. When a user executes `/ponytail ultra`, the tracker:

1. Validates the requested mode against `VALID_MODES`.
2. Updates `.ponytail-active` with the new mode identifier.
3. Calls `writeHookOutput()` to emit a session entry: `{ type: "custom", customType: "ponytail-mode", data: { mode: "ultra" } }`.

This injection ensures [[`ponytail-mcp/instructions.js`](https://github.com/DietrichGebert/ponytail/blob/main/ponytail-mcp/instructions.js)](https://github.com/DietrichGebert/ponytail/blob/main/ponytail-mcp/instructions.js) receives the mode state for instruction generation.

### Instruction Building

The [[`ponytail-mcp/instructions.js`](https://github.com/DietrichGebert/ponytail/blob/main/ponytail-mcp/instructions.js)](https://github.com/DietrichGebert/ponytail/blob/main/ponytail-mcp/instructions.js) module consumes mode data through its `resolveMode()` function, which maps requested modes to concrete intensity levels. While the input may request any valid mode, `resolveMode()` guarantees the output is one of the three active assistance levels (`lite`, `full`, or `ultra`) or `off`, generating appropriate system instructions for the LLM context.

## Integration Points

Ponytail exposes runtime mode information to external interfaces and environment contexts.

### Extension API Exposure

The VS Code extension interface in [[`pi-extension/index.js`](https://github.com/DietrichGebert/ponytail/blob/main/pi-extension/index.js)](https://github.com/DietrichGebert/ponytail/blob/main/pi-extension/index.js) exports `RUNTIME_MODE_LIST`, making the canonical mode definitions available to UI components. This allows the extension to populate mode selectors and validate user input against the authoritative `RUNTIME_MODES` array.

### Environment Variable Detection

The system monitors `PONYTAIL_MODE` for Dockerized or CI/CD deployments where filesystem state is volatile. The `isQoder()` helper provides backward compatibility for legacy session detection, ensuring smooth migration from previous Qoder-based implementations.

## Summary

- Ponytail defines **five valid modes** (`off`, `lite`, `full`, `ultra`, `review`) in [`hooks/ponytail-config.js`](https://github.com/DietrichGebert/ponytail/blob/main/hooks/ponytail-config.js), but only **four runtime modes** can persist as defaults.
- The **`review` mode is session-only** and intentionally excluded from `RUNTIME_MODES` to prevent accidental persistence.
- Mode resolution follows a strict hierarchy: **environment variables** override **config file** settings, which yield to **slash commands**.
- [[`hooks/ponytail-runtime.js`](https://github.com/DietrichGebert/ponytail/blob/main/hooks/ponytail-runtime.js)](https://github.com/DietrichGebert/ponytail/blob/main/hooks/ponytail-runtime.js) provides the core API (`readMode`, `setMode`, `clearMode`) for mode manipulation.
- The **mode tracker** persists state via both `.ponytail-active` flag files and session manager custom entries.
- [[`ponytail-mcp/instructions.js`](https://github.com/DietrichGebert/ponytail/blob/main/ponytail-mcp/instructions.js)](https://github.com/DietrichGebert/ponytail/blob/main/ponytail-mcp/instructions.js) uses `resolveMode()` to translate mode requests into LLM instruction sets.

## Frequently Asked Questions

### What is the difference between `VALID_MODES` and `RUNTIME_MODES` in Ponytail?

`VALID_MODES` includes all five possible states (`off`, `lite`, `full`, `ultra`, `review`) that the system recognizes during a session. `RUNTIME_MODES` is a subset excluding `review`, representing only those modes that can be saved as persistent defaults in [`.ponytail-config.json`](https://github.com/DietrichGebert/ponytail/blob/main/.ponytail-config.json). This distinction prevents the intensive `review` behavior from becoming an accidental permanent setting.

### How does Ponytail determine which runtime mode to use?

Ponytail resolves the active mode through a three-tier hierarchy implemented in [`hooks/ponytail-runtime.js`](https://github.com/DietrichGebert/ponytail/blob/main/hooks/ponytail-runtime.js). First, it checks the `PONYTAIL_MODE` environment variable. If absent, it reads the default from [`.ponytail-config.json`](https://github.com/DietrichGebert/ponytail/blob/main/.ponytail-config.json). Finally, it accepts runtime overrides from slash commands like `/ponytail full`, which update both the `.ponytail-active` flag file and the session manager's custom entries.

### Can I set `review` mode as my default Ponytail behavior?

No. The `review` mode is explicitly excluded from `RUNTIME_MODES` in [`hooks/ponytail-config.js`](https://github.com/DietrichGebert/ponytail/blob/main/hooks/ponytail-config.js). While you can activate it for individual sessions using `/ponytail review`, the validation logic prevents persisting this mode to your configuration file. This design protects against accidentally enabling high-intensity scrutiny across all future coding sessions.

### Where does Ponytail store the current runtime mode state?

Ponytail maintains mode state in two locations: the `.ponytail-active` file in the project root (a filesystem flag) and a custom entry in the session manager with `customType: "ponytail-mode"`. The [`hooks/ponytail-mode-tracker.js`](https://github.com/DietrichGebert/ponytail/blob/main/hooks/ponytail-mode-tracker.js) module synchronizes these stores when mode changes occur, ensuring both the local environment and downstream instruction builders remain consistent.