# Ponytail Configuration Hierarchy: How Default Mode Resolution Works

> Understand Ponytail's default mode configuration hierarchy. Discover how environment variables, JSON files, and built-in constants determine runtime modes for your project.

- Repository: [DietrichGebert/ponytail](https://github.com/DietrichGebert/ponytail)
- Tags: internals
- Published: 2026-08-27

---

**Ponytail determines its default mode through a strict three-level configuration hierarchy that checks environment variables first, JSON configuration files second, and built-in constants last, always validating against the set of valid runtime modes.**

Ponytail, an open-source intensity management system, relies on a predictable configuration hierarchy to decide which operational mode activates when no explicit flag is provided. This resolution cascade ensures that deployment-specific settings override user preferences, which in turn override hardcoded defaults. The entire resolution logic resides in [`hooks/ponytail-config.js`](https://github.com/DietrichGebert/ponytail/blob/main/hooks/ponytail-config.js) within the DietrichGebert/ponytail repository.

## The Three-Level Configuration Hierarchy

Ponytail's resolver implements a fixed priority order. When `getDefaultMode()` executes, it evaluates sources sequentially until it finds a valid runtime mode.

### Level 1: Environment Variable (PONYTAIL_DEFAULT_MODE)

The resolver first checks `process.env.PONYTAIL_DEFAULT_MODE` at lines 5-8 of [`hooks/ponytail-config.js`](https://github.com/DietrichGebert/ponytail/blob/main/hooks/ponytail-config.js). If this variable exists and contains a valid runtime mode—`off`, `lite`, `full`, or `ultra`—the function returns it immediately. This provides DevOps teams with deployment-specific overrides without modifying filesystem state.

### Level 2: Platform-Aware Configuration File

If no environment variable is set, the system looks for [`config.json`](https://github.com/DietrichGebert/ponytail/blob/main/config.json) inside Ponytail's configuration directory. The platform-specific resolution logic determines the directory path:

- **Linux/macOS**: `$XDG_CONFIG_HOME/ponytail` or fallback to `~/.config/ponytail`
- **Windows**: `%APPDATA%\ponytail`

The resolver reads the `defaultMode` field from this JSON file. Lines 6-10 handle this filesystem lookup and parsing.

### Level 3: Built-in Fallback Constant

When neither the environment nor the configuration file provides a valid mode, Ponytail defaults to the constant `DEFAULT_MODE`, hardcoded to `'full'` at lines 10-11. This ensures the application always launches with a functional intensity level rather than failing.

## Runtime Mode Validation Rules

The configuration hierarchy only accepts values from the `RUNTIME_MODES` array: `['off', 'lite', 'full', 'ultra']`. The resolver explicitly excludes the `review` mode from default assignment. According to the guard clause at lines 78-84, `review` is session-only and cannot persist as a default, preventing accidental deployment of debug configurations.

## Working with Default Mode Configuration

### Reading the Current Default Mode

Access the resolved default anywhere in your plugin or script:

```javascript
const { getDefaultMode } = require('./hooks/ponytail-config');
const currentDefault = getDefaultMode();   // → 'full', 'lite', etc.

```

### Persisting a New Default Mode

Write a validated default to the configuration file:

```javascript
const { writeDefaultMode } = require('./hooks/ponytail-config');
const saved = writeDefaultMode('lite');    // returns 'lite' or null if invalid

```

### Temporary Session Override

Set the environment variable for single-session changes without touching disk:

```javascript
// Directly set the session flag (used internally by the mode-tracker)
process.env.PONYTAIL_DEFAULT_MODE = 'ultra';

```

## Core Implementation Files

The configuration hierarchy spans four primary files:

- **[`hooks/ponytail-config.js`](https://github.com/DietrichGebert/ponytail/blob/main/hooks/ponytail-config.js)**: Contains the core resolver implementing the environment → config → fallback cascade.
- **[`hooks/ponytail-mode-tracker.js`](https://github.com/DietrichGebert/ponytail/blob/main/hooks/ponytail-mode-tracker.js)**: Initializes session state using the resolver's output.
- **[`hooks/ponytail-activate.js`](https://github.com/DietrichGebert/ponytail/blob/main/hooks/ponytail-activate.js)**: Handles the active-mode flag that downstream components consume.
- **[`pi-extension/index.js`](https://github.com/DietrichGebert/ponytail/blob/main/pi-extension/index.js)**: Exposes the `/ponytail default <mode>` CLI command, which invokes `writeDefaultMode()`.

## Summary

- Ponytail's configuration hierarchy follows a strict three-level priority: environment variables override JSON configs, which override the built-in `'full'` constant.
- Valid runtime modes include `off`, `lite`, `full`, and `ultra`; the `review` mode is explicitly excluded from default assignment at lines 78-84.
- Platform-aware paths locate [`config.json`](https://github.com/DietrichGebert/ponytail/blob/main/config.json) at `$XDG_CONFIG_HOME/ponytail` (Linux/macOS) or `%APPDATA%\ponytail` (Windows).
- The `getDefaultMode()` and `writeDefaultMode()` functions in [`hooks/ponytail-config.js`](https://github.com/DietrichGebert/ponytail/blob/main/hooks/ponytail-config.js) provide programmatic access to read and modify defaults.

## Frequently Asked Questions

### What happens if I set PONYTAIL_DEFAULT_MODE to an invalid value?

The resolver treats invalid environment values as unset, proceeding to check the configuration file. If that also fails, it falls back to `'full'`. Only values matching the `RUNTIME_MODES` array (`off`, `lite`, `full`, `ultra`) are accepted at lines 5-8.

### Can I use the review mode as my default intensity?

No. The `review` mode is session-only by design. Lines 78-84 in [`hooks/ponytail-config.js`](https://github.com/DietrichGebert/ponytail/blob/main/hooks/ponytail-config.js) explicitly filter out `review` from default mode assignment, preventing accidental persistence of debug configurations across restarts.

### Where does Ponytail store its configuration on Windows systems?

On Windows, Ponytail looks for [`config.json`](https://github.com/DietrichGebert/ponytail/blob/main/config.json) inside `%APPDATA%\ponytail`. This follows standard Windows application data conventions and ensures the configuration persists across user sessions without requiring administrator privileges.

### How do I temporarily test a different default without changing my config file?

Set the `PONYTAIL_DEFAULT_MODE` environment variable before launching Ponytail. This overrides the configuration file without modifying disk state, making it ideal for CI/CD pipelines or temporary testing sessions.