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

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. This file exports the MODES constant and the resolveMode() function that determines which ruleset to apply.

// 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 lines 77-84, which 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, 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

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

Node.js SDK Usage

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

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 Defines MODES, implements resolveMode(), exports buildInstructions()
skills/ponytail/SKILL.md Contains human-readable behavior contracts for lite/full/ultra
hooks/ponytail-instructions.js Parses SKILL.md, filters by active intensity, assembles payload

When buildInstructions(mode) is called, it delegates to hooks/ponytail-instructions.js, which:

  1. Loads 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 and filtered by 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 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.

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 →