How Ponytail Filters Mode-Specific Instructions from Skill Files
Ponytail filters mode-specific instructions by parsing the Markdown skill file line-by-line, keeping only intensity table rows and worked-example bullets that match the active mode (lite, full, ultra, or review) while preserving all generic content.
Ponytail stores its prompting rules in a Markdown skill file located at skills/ponytail/SKILL.md. When a user activates a specific intensity level, the system dynamically tailors the prompt by extracting only the relevant sections from this master file. This filtering mechanism ensures that the language model receives precisely calibrated instructions based on the selected operational mode.
The Skill File Structure
The source of truth for Ponytail’s behavior lives in skills/ponytail/SKILL.md. This file contains the complete set of rules organized into three distinct content types:
- Generic prose – Universal guidelines that apply regardless of mode
- Intensity tables – Markdown tables with rows labeled by mode (e.g.,
| **lite** | ... |) - Worked examples – Bullet lists with mode prefixes (e.g.,
- lite: "...")
The filtering system treats these content types differently, preserving generic prose while conditionally extracting table rows and bullets based on the active mode.
Core Filtering Logic in filterSkillBodyForMode
The heart of the filtering system resides in hooks/ponytail-instructions.js, specifically within the filterSkillBodyForMode function. This function executes a four-stage pipeline to transform the raw skill file into mode-specific instructions.
Step 1: Normalizing the Requested Mode
Before processing content, the function canonicalizes the mode string via normalizeMode (defined in hooks/ponytail-config.js). Supported modes include lite, full, ultra, and review. If the requested mode is undefined or invalid, the system falls back to the DEFAULT_MODE constant.
// From hooks/ponytail-config.js
const normalizeMode = (mode) => {
const valid = ['lite', 'full', 'ultra', 'review'];
return valid.includes(mode) ? mode : DEFAULT_MODE;
};
Step 2: Stripping Front-Matter
The function removes the leading YAML front-matter block (delimited by ---) from the skill file. This ensures that metadata headers do not contaminate the instruction set sent to the language model.
Step 3: Line-by-Line Inspection
The body content splits on line breaks, and each line undergoes pattern matching against two specific regex filters:
Intensity Table Rows
Lines matching ^\|\s*\*\*(.+?)\*\*\s*\| indicate table rows with bold mode labels. The capture group extracts the mode name (e.g., lite). The line is retained only if the extracted mode matches the effective mode.
Worked-Example Bullets
Lines matching ^-\s*([^:]+):\s*" indicate mode-prefixed bullet points. The capture group extracts the leading word before the colon. If this word normalizes to a valid mode, the line is kept only when it matches the active mode.
All Other Lines Any line failing to match either pattern is preserved verbatim, ensuring generic rules survive every mode filter.
Step 4: Reconstructing the Output
The filtered lines concatenate back into a single string. This processed content becomes the mode-specific instruction set returned by getPonytailInstructions.
Mode Detection and Injection
The hooks/ponytail-mode-tracker.js file orchestrates the detection and injection workflow. When a user issues a /ponytail command followed by a mode name, the hook:
- Detects the mode switch
- Stores the mode via
setMode() - Calls
getPonytailInstructions(mode)to retrieve filtered content - Injects the result into the prompt using
writeHookOutput()
// From hooks/ponytail-mode-tracker.js
if (mode && mode !== 'off') {
setMode(mode); // Persist session mode
writeHookOutput('UserPromptSubmit',
mode,
getPonytailInstructions(mode)); // Inject filtered rules
}
Error Handling and Fallbacks
If getPonytailInstructions fails to read skills/ponytail/SKILL.md (due to missing files or permission errors), the function invokes getFallbackInstructions(). This returns a hard-coded description ensuring the system remains functional even when the skill file is unavailable.
Practical Implementation Examples
To programmatically retrieve instructions for a specific mode:
const { getPonytailInstructions } = require('./hooks/ponytail-instructions');
const instructions = getPonytailInstructions('lite');
console.log(instructions);
Within the hook execution context, after detecting a valid mode transition:
if (mode && mode !== 'off') {
setMode(mode);
writeHookOutput('UserPromptSubmit',
mode,
getPonytailInstructions(mode));
}
Summary
- Primary filter:
filterSkillBodyForModeinhooks/ponytail-instructions.jsprocessesskills/ponytail/SKILL.md - Mode normalization:
normalizeModeinhooks/ponytail-config.jsvalidateslite,full,ultra,review - Content parsing: Regex patterns
^\|\s*\*\*(.+?)\*\*\s*\|(tables) and^-\s*([^:]+):\s*"(bullets) identify mode-specific lines - Preservation logic: Generic prose survives all filters; only table rows and worked examples undergo mode matching
- Injection point:
ponytail-mode-tracker.jscallswriteHookOutput()to send filtered instructions to the LLM - Resilience:
getFallbackInstructions()provides hard-coded defaults when the skill file is inaccessible
Frequently Asked Questions
What file contains the main filtering logic for Ponytail modes?
The hooks/ponytail-instructions.js file contains the filterSkillBodyForMode function, which implements the core filtering algorithm. This function handles mode normalization, front-matter stripping, line-by-line pattern matching, and content reconstruction.
How does Ponytail handle missing skill files?
When getPonytailInstructions encounters a file read error (such as a missing skills/ponytail/SKILL.md), it automatically falls back to getFallbackInstructions(). This function returns a hard-coded description of Ponytail's capabilities, ensuring the hook continues functioning even without the skill file present.
What regex patterns does Ponytail use to identify mode-specific content?
Ponytail employs two specific regular expressions: ^\|\s*\*\*(.+?)\*\*\s*\| matches intensity table rows with bold mode labels, while ^-\s*([^:]+):\s*" matches worked-example bullets prefixed with mode names. The first capture group in each pattern extracts the mode identifier for comparison against the active mode.
Which modes does Ponytail support for instruction filtering?
The system supports four distinct intensity levels: lite, full, ultra, and review. These modes are defined in hooks/ponytail-config.js alongside the DEFAULT_MODE constant and the normalizeMode validation function that ensures only recognized modes trigger specific filtering logic.
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 →