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

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 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), the system defines two authoritative arrays that govern mode behavior:

// 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) 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), which exports the canonical mode lists. User defaults are stored in .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) 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.
  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):

  • 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) exports the low-level API for mode manipulation:

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

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. 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. First, it checks the PONYTAIL_MODE environment variable. If absent, it reads the default from .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. 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 module synchronizes these stores when mode changes occur, ensuring both the local environment and downstream instruction builders remain consistent.

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 →