How Ponytail Mode Precedence Works: Runtime, Config, and Default Resolution

Ponytail resolves the effective mode by checking three sources in strict priority: runtime slash commands override configuration files, which override the built-in default of "full".

The DietrichGebert/ponytail repository implements a deterministic mode precedence system that controls which parts of the built-in skill are injected into LLM prompts. Understanding Ponytail mode precedence is essential for configuring how the tool behaves across different environments and sessions.

The Three-Tier Mode Resolution Hierarchy

Ponytail determines the effective mode by evaluating three independent sources in descending order of priority. This ensures that the most specific instruction always governs the injected context.

1. Runtime Slash Commands (Highest Priority)

The /ponytail <mode> slash command provides immediate, session-specific control. When invoked, the _handle_mode_command() function (defined in __init__.py at lines 167–177) normalizes the argument via _normalize_runtime_mode() and stores the result in the module-level variable _current_mode. This runtime setting persists for the duration of the session and overrides all other configuration sources.

2. Configuration Layer

If no runtime mode is active, Ponytail falls back to the configuration layer via the _default_mode() function (lines 52–63 in __init__.py). This function checks two sources in order:

  • Environment variable: PONYTAIL_DEFAULT_MODE takes precedence if set.
  • Config file: ~/.config/ponytail/config.json is parsed for the defaultMode field if the environment variable is absent.

3. Built-in Default Fallback

When neither runtime nor configuration sources provide a value, Ponytail uses the hard-coded constant DEFAULT_MODE = "full" defined in __init__.py. This ensures the system always has a valid mode even in clean environments.

Resolution Flow and Skill Content Filtering

The resolution logic combines these sources in build_injected_context() (lines 105–122) using the following flow:

configured = _normalize_config_mode(mode) or _default_mode()          # ← step 2

effective = _normalize_runtime_mode(configured) or DEFAULT_MODE      # ← step 1

Once the effective mode is determined, the system filters the skill content. The _filter_skill_body_for_mode() function (lines 70–85 in __init__.py) parses the markdown in skills/ponytail/SKILL.md and removes any block whose mode label does not match the effective mode. For example, sections marked with | **lite** | or - lite: … are preserved only when the effective mode is "lite".

This filtering enables a single skill file to contain tiered advice, with granular control over which sections reach the LLM prompt based on the resolved precedence.

Special Mode Behaviors

Two modes trigger unique behaviors beyond standard content filtering:

  • "off" → Injected context becomes an empty string, effectively disabling Ponytail's skill injection.
  • "review" → Loads the separate review skill from skills/ponytail-review/SKILL.md instead of the standard ponytail skill.

Practical Configuration Examples

Configure Ponytail mode precedence using these patterns:


# 1️⃣ Set mode at runtime (slash command)

# In a chat with Hermes:

#   /ponytail ultra

# The command triggers `_handle_mode_command`, storing `_current_mode = "ultra"`.

# 2️⃣ Set a default via environment variable

import os
os.environ["PONYTAIL_DEFAULT_MODE"] = "lite"

# No runtime command; Ponytail will use "lite" for every session.
// 3️⃣ Provide a config file (~/.config/ponytail/config.json)
{
  "defaultMode": "full"
}
// With no env var and no runtime command, "full" is used.

# 4️⃣ Disable injection completely

os.environ["PONYTAIL_DEFAULT_MODE"] = "off"

# or `/ponytail off` → injected context becomes an empty string.

# 5️⃣ Inspect which text is injected

from ponytail import build_injected_context
print(build_injected_context())   # respects the precedence rules above

Summary

  • Runtime commands take precedence over all other sources via _current_mode.
  • Configuration follows the order: PONYTAIL_DEFAULT_MODE environment variable, then ~/.config/ponytail/config.json (defaultMode field).
  • Built-in default is "full" when no other value is set.
  • Content filtering applies the effective mode to skill markdown sections via _filter_skill_body_for_mode().
  • Special modes "off" and "review" modify behavior by disabling injection or loading alternate skills.

Frequently Asked Questions

What is the default mode if I don't configure anything?

The built-in constant DEFAULT_MODE = "full" in __init__.py serves as the final fallback when no runtime command is active and neither the PONYTAIL_DEFAULT_MODE environment variable nor the config file exists.

How do I temporarily override the mode for a single session?

Use the /ponytail <mode> slash command, which triggers _handle_mode_command() and sets the module-level _current_mode variable. This persists for the session but does not modify configuration files or environment variables.

What happens when I set the mode to "off"?

The system returns an empty string for the injected context, effectively disabling Ponytail's skill injection. This is processed early in build_injected_context() before any skill content filtering occurs.

Where is the mode resolution logic implemented in the source code?

All core logic resides in __init__.py within the DietrichGebert/ponytail repository. Key functions include _default_mode() for configuration resolution, _handle_mode_command() for runtime overrides, and _filter_skill_body_for_mode() for content filtering.

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 →