# How the ponytail-instructions.js Module Filters Skill Content by Mode

> Learn how ponytail-instructions.js filters skill content by mode. Discover how the filterSkillBodyForMode function isolates markdown lines matching your target mode for worked examples and intensity tables.

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

---

**The ponytail-instructions.js module filters skill content by mode through the `filterSkillBodyForMode(body, mode)` function, which normalizes the input mode, strips YAML front-matter, and selectively retains only markdown lines that match the target mode in intensity tables or worked examples while discarding all other mode-specific content.**

The ponytail-instructions.js module in the DietrichGebert/ponytail repository provides the core logic for presenting mode-specific guidance in the Ponytail project. Located at [`hooks/ponytail-instructions.js`](https://github.com/DietrichGebert/ponytail/blob/main/hooks/ponytail-instructions.js), this module implements a precise filtering mechanism that extracts only relevant portions of skill documentation based on the selected operating mode—**lite**, **full**, or **ultra**—ensuring users receive contextually appropriate instructions without extraneous content.

## The Filter Algorithm Implementation

The filtering logic resides in [`hooks/ponytail-instructions.js`](https://github.com/DietrichGebert/ponytail/blob/main/hooks/ponytail-instructions.js) at lines 11-41. The function processes raw markdown skill files and returns only the segments relevant to the requested Ponytail mode.

### Step 1: Normalize the Target Mode

First, the function determines the effective operating mode by normalizing the input and falling back to the repository default:

```js
const effectiveMode = normalizeMode(mode) || DEFAULT_MODE;

```

The `normalizeMode` helper, imported from [`ponytail-config.js`](https://github.com/DietrichGebert/ponytail/blob/main/ponytail-config.js), handles case normalization (e.g., converting `"LiTe"` to `"lite"`). If normalization fails, the function uses `DEFAULT_MODE` as the fallback.

### Step 2: Strip YAML Front-matter

All YAML front-matter at the top of the markdown file is removed to prevent metadata from interfering with content filtering:

```js
const withoutFrontmatter = String(body || '').replace(/^---[\s\S]*?---\s*/, '');

```

### Step 3: Split and Inspect Line by Line

The remaining markdown is split into individual lines using the `/\r?\n/` delimiter. The function then iterates through each line to identify mode-specific markers.

### Step 4: Filter Intensity Table Rows

For intensity tables that define mode-specific capabilities, the function matches lines starting with bolded mode labels:

```js
const tableLabel = line.match(/^\|\s*\*\*(.+?)\*\*\s*\|/);
if (tableLabel) {
  const labelMode = normalizeMode(tableLabel[1].trim());
  if (labelMode) return labelMode === effectiveMode;
}

```

Only rows where the label (e.g., `| **lite** | ... |`) exactly matches the `effectiveMode` are retained. Rows labeled with other modes are discarded.

### Step 5: Filter Worked Examples

For bulleted worked examples, the function matches lines following the pattern `- mode: "description"`:

```js
const exampleLabel = line.match(/^-\s*([^:]+):\s*"/);
if (exampleLabel) {
  const labelMode = normalizeMode(exampleLabel[1].trim());
  if (labelMode) return labelMode === effectiveMode;
}

```

Examples prefixed with the current mode are kept; all others are filtered out.

### Step 6: Preserve Neutral Content and Reassemble

Any line that does not match the table row or worked example patterns is treated as neutral prose and retained verbatim. After filtering, the remaining lines are rejoined with newline characters to produce the final markdown.

## Practical Usage Examples

### Filtering Skill Content for a Specific Mode

To extract only the "lite" mode content from a skill file:

```js
const { filterSkillBodyForMode } = require('./hooks/ponytail-instructions');
const fs = require('fs');
const path = require('path');

const skillPath = path.join(__dirname, '..', 'skills', 'ponytail', 'SKILL.md');
const skillBody = fs.readFileSync(skillPath, 'utf8');

const liteContent = filterSkillBodyForMode(skillBody, 'lite');
console.log(liteContent);

```

### Retrieving Full Instructions

For internal use, the module exposes `getPonytailInstructions()` which returns the complete instruction text for the currently persisted mode:

```js
const { getPonytailInstructions } = require('./hooks/ponytail-instructions');

console.log(getPonytailInstructions('full'));

```

## Summary

- The **filterSkillBodyForMode** function in [`hooks/ponytail-instructions.js`](https://github.com/DietrichGebert/ponytail/blob/main/hooks/ponytail-instructions.js) (lines 11-41) implements the core filtering logic that powers mode-specific content display
- Input modes are normalized using the **normalizeMode** helper from [`ponytail-config.js`](https://github.com/DietrichGebert/ponytail/blob/main/ponytail-config.js), with **DEFAULT_MODE** serving as the fallback when invalid modes are provided
- YAML front-matter is stripped before processing to isolate content from metadata
- The function recognizes two specific patterns: intensity table rows with bolded mode labels (`| **mode** |`) and worked examples with mode prefixes (`- mode: "..."`)
- Content not matching these patterns is preserved as neutral text, while mode-specific lines are included only if they match the effective mode

## Frequently Asked Questions

### How does ponytail-instructions.js determine which mode to use?

The function calls `normalizeMode(mode)` to standardize the input string (handling case variations like "LiTe"), then falls back to the repository-wide `DEFAULT_MODE` constant if normalization returns null or undefined. This ensures the filter always operates against a valid mode identifier defined in [`hooks/ponytail-config.js`](https://github.com/DietrichGebert/ponytail/blob/main/hooks/ponytail-config.js).

### What happens to lines that don't match any mode-specific patterns?

Lines that do not match the intensity table regex (`/^\|\s*\*\*(.+?)\*\*\s*\|/`) or the worked example regex (`/^-\s*([^:]+):\s*"/`) are treated as neutral prose, rules, or standard markdown content. These lines pass through the filter unchanged and appear in the final output regardless of the selected mode.

### Where is the normalizeMode function defined?

The `normalizeMode` helper function is defined in [`hooks/ponytail-config.js`](https://github.com/DietrichGebert/ponytail/blob/main/hooks/ponytail-config.js), which serves as the central configuration module for the Ponytail repository. This file also exports `DEFAULT_MODE` and `normalizePersistedMode` utilities used throughout the filtering pipeline in [`ponytail-instructions.js`](https://github.com/DietrichGebert/ponytail/blob/main/ponytail-instructions.js).

### Can the filtering logic handle malformed markdown?

Yes. The function defensively handles null or undefined input by casting the body to a String (`String(body || '')`). The regex patterns specifically target the expected structural patterns for mode labels, so malformed or non-standard lines are simply passed through as neutral content rather than causing errors or exceptions.