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:
- Loads
SKILL.mdfrom the skills directory - Extracts the section matching the resolved mode
- 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
MODESatponytail-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()atponytail-mcp/instructions.js:13-22 - Actual rule content is parsed from
skills/ponytail/SKILL.mdand filtered byhooks/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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →