# Ponytail Intensity Modes Explained: lite, full, ultra, and off

> Understand Ponytail intensity modes lite full ultra and off. Control your coding assistant's YAGNI rule enforcement with the /ponytail command. Optimize your development workflow.

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

---

**Ponytail supports three active intensity levels—lite, full, and ultra—plus an off state that disables the agent entirely.** The `/ponytail [lite|full|ultra|off]` command lets developers control how aggressively the coding assistant enforces its YAGNI-inspired rules.

DietrichGebert/ponytail is an MCP (Model Context Protocol) server that injects software engineering discipline into AI-assisted coding sessions. The **intensity mode** system determines which behavioral rules are active during code generation, from gentle suggestions to aggressive minimalism. This article breaks down how each mode works, where they're defined in the source code, and how to switch between them programmatically.

## How Intensity Modes Are Defined

The core mode definitions live in [`ponytail-mcp/instructions.js`](https://github.com/DietrichGebert/ponytail/blob/main/ponytail-mcp/instructions.js). This file exports the `MODES` constant and the `resolveMode()` function that determines which ruleset to apply.

```js
// ponytail-mcp/instructions.js (simplified)
const MODES = ["lite", "full", "ultra"];

function resolveMode(requested) {
  if (!requested || requested === "off") return "full"; // fallback
  if (MODES.includes(requested)) return requested;
  return "full"; // default for unknown values
}

```

The `MODES` array explicitly excludes **off** because it produces no instructions—it simply toggles persistence. When a user requests **off**, `resolveMode()` falls through to the configured default (or **full**), and the caller suppresses instruction generation.

## The Four Ponytail Intensity Modes

### lite Mode: Minimal Friction

**lite** applies the softest touch. The assistant satisfies the request but appends a one-line suggestion of a lazier alternative. It nudges toward simplicity without blocking progress.

Use this when you want occasional reminders about simpler approaches without the full enforcement overhead.

### full Mode: Balanced Enforcement (Default)

**full** is the default intensity. It enforces the complete "ladder" of Ponytail principles:

- YAGNI (You Aren't Gonna Need It)
- Reuse existing code
- Prefer standard library solutions
- Avoid premature abstraction

The behavioral contract for **full** is specified in [`skills/ponytail/SKILL.md`](https://github.com/DietrichGebert/ponytail/blob/main/skills/ponytail/SKILL.md) lines 77-84, which [`hooks/ponytail-instructions.js`](https://github.com/DietrichGebert/ponytail/blob/main/hooks/ponytail-instructions.js) parses to assemble the final instruction payload.

### ultra Mode: Aggressive Minimalism

**ultra** pushes YAGNI to its extreme. The assistant ships the smallest possible one-liner and actively challenges the rest of the requirement. This mode is designed for rapid prototyping and deliberate technical debt.

In [`SKILL.md`](https://github.com/DietrichGebert/ponytail/blob/main/SKILL.md), **ultra** is described as questioning whether any code is needed at all—the strictest interpretation of "do the simplest thing that could possibly work."

### off Mode: Complete Disable

**off** stops all Ponytail instruction injection. The server continues running, but `buildInstructions()` returns an empty string, and the agent effectively disappears from the conversation.

Unlike the three active modes, **off** is handled at the persistence layer rather than in `MODES`. It updates `~/.config/ponytail/config.json` to disable the hook until re-enabled.

## Switching Modes: CLI and Programmatic APIs

### Slash Commands in Chat

```bash
/ponytail lite      # enable lite mode

/ponytail full      # enable full (default) mode

/ponytail ultra     # enable ultra mode

/ponytail off       # disable Ponytail entirely

```

These commands are parsed by the host and passed to `resolveMode()` in [`ponytail-mcp/instructions.js`](https://github.com/DietrichGebert/ponytail/blob/main/ponytail-mcp/instructions.js).

### Node.js SDK Usage

```js
import { resolveMode, buildInstructions } from "./ponytail-mcp/instructions.js";

// Resolve user input to valid mode
console.log(resolveMode("lite"));   // → "lite"
console.log(resolveMode("off"));    // → "full" (fallback, caller handles disable)
console.log(resolveMode("unknown")); // → "full" (default)

// Get instruction payload for a mode
const ultraRules = buildInstructions("ultra");
// Returns filtered content from SKILL.md's ultra section

```

### Reading Current Mode from Config

```js
const fs = require("fs");
const cfgPath = `${process.env.HOME}/.config/ponytail/config.json`;
const { mode } = JSON.parse(fs.readFileSync(cfgPath, "utf8"));
console.log(`Current Ponytail mode: ${mode}`); // e.g., "full"

```

## How Instructions Are Filtered and Delivered

The intensity mode flows through three core files:

| File | Role in Mode Resolution |
|------|------------------------|
| [`ponytail-mcp/instructions.js`](https://github.com/DietrichGebert/ponytail/blob/main/ponytail-mcp/instructions.js) | Defines `MODES`, implements `resolveMode()`, exports `buildInstructions()` |
| [`skills/ponytail/SKILL.md`](https://github.com/DietrichGebert/ponytail/blob/main/skills/ponytail/SKILL.md) | Contains human-readable behavior contracts for lite/full/ultra |
| [`hooks/ponytail-instructions.js`](https://github.com/DietrichGebert/ponytail/blob/main/hooks/ponytail-instructions.js) | Parses [`SKILL.md`](https://github.com/DietrichGebert/ponytail/blob/main/SKILL.md), filters by active intensity, assembles payload |

When `buildInstructions(mode)` is called, it delegates to [`hooks/ponytail-instructions.js`](https://github.com/DietrichGebert/ponytail/blob/main/hooks/ponytail-instructions.js), which:

1. Loads [`SKILL.md`](https://github.com/DietrichGebert/ponytail/blob/main/SKILL.md) from the skills directory
2. Extracts the section matching the resolved mode
3. Returns the filtered rule text for injection into the MCP context

This separation lets the JSON-configurable `MODES` array drive behavior without hardcoding rules in JavaScript.

## Summary

- **lite**, **full**, and **ultra** are the three active Ponytail intensity modes defined in `MODES` at `ponytail-mcp/instructions.js:10-12`
- **off** disables the agent without being a true mode—it triggers fallback logic and suppresses instruction generation
- **full** is the default when no mode is specified, when **off** is requested, or for unknown values
- Mode resolution happens in `resolveMode()` at `ponytail-mcp/instructions.js:13-22`
- Actual rule content is parsed from [`skills/ponytail/SKILL.md`](https://github.com/DietrichGebert/ponytail/blob/main/skills/ponytail/SKILL.md) and filtered by [`hooks/ponytail-instructions.js`](https://github.com/DietrichGebert/ponytail/blob/main/hooks/ponytail-instructions.js)

## Frequently Asked Questions

### What happens when I request an invalid Ponytail mode?

`resolveMode()` returns `"full"` as the fallback for any unknown or empty input. This default is hardcoded in [`ponytail-mcp/instructions.js`](https://github.com/DietrichGebert/ponytail/blob/main/ponytail-mcp/instructions.js) to ensure predictable behavior when configuration drifts or typos occur.

### Can I set a permanent default mode other than full?

Yes. The config file at `~/.config/ponytail/config.json` stores your preferred mode. When `resolveMode()` receives `"off"` or an empty request, it falls back to this configured value before finally defaulting to `"full"`.

### Why is off not included in the MODES array?

**off** is intentionally excluded because it produces no instructions. The `MODES` array drives `buildInstructions()`, which returns rule text. Since **off** means zero instructions, it's handled as a persistence toggle rather than a true intensity level. The slash command still accepts it for user convenience.

### How does ultra mode differ from lite?

Both modes aim for minimal code, but **ultra** actively challenges requirements while **lite** merely suggests alternatives. In **lite**, the assistant completes your request then mentions a simpler approach. In **ultra**, the assistant ships the smallest possible solution and questions whether the remaining work is necessary at all.