# How to Control Which Subagents Ponytail Injects Rules Into Using PONYTAIL_SUBAGENT_MATCHER

> Control Ponytail rule injection with PONYTAIL_SUBAGENT_MATCHER. Use regex to target specific subagents or unset to affect all, enhancing your agent management.

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

---

**Set the `PONYTAIL_SUBAGENT_MATCHER` environment variable to a regular expression to restrict Ponytail's rule injection to only sub-agents whose `agent_type` matches the pattern, or unset it entirely to inject into all sub-agents.**

The Ponytail system, available in the `DietrichGebert/ponytail` repository, automatically injects rule sets into sub-agents spawned via the Agent tool. By configuring **`PONYTAIL_SUBAGENT_MATCHER`**, you can precisely control which sub-agent types receive these rules using case-insensitive regular expressions defined in the hook script at [`hooks/ponytail-subagent.js`](https://github.com/DietrichGebert/ponytail/blob/main/hooks/ponytail-subagent.js).

## How PONYTAIL_SUBAGENT_MATCHER Filters Sub-Agents

The [`ponytail-subagent.js`](https://github.com/DietrichGebert/ponytail/blob/main/ponytail-subagent.js) hook intercepts every sub-agent initialization and evaluates whether to inject the rule set based on the environment variable state.

### Default Behavior: Inject Into All Sub-Agents

When **`PONYTAIL_SUBAGENT_MATCHER`** is unset or undefined, Ponytail injects its rules into **every** sub-agent spawned through the Agent tool. This ensures maximum compatibility but may overwhelm specialized agents with irrelevant instructions.

### Regex Matching Against agent_type

When the variable is set, the hook compiles the value into a case-insensitive regular expression using `new RegExp(..., 'i')`. It then reads the sub-agent's `agent_type` from the JSON payload received via `stdin`. If the `agent_type` matches the regex, the hook proceeds with rule injection; if it fails to match, the hook exits silently without modifying the sub-agent.

## Configuration Examples

### Target Multiple Agent Types

Use the pipe character to match any of several agent types:

```bash
export PONYTAIL_SUBAGENT_MATCHER='explore|general'

```

- A sub-agent with type `"explore"` receives the rules.
- A sub-agent with type `"search"` receives no injection.

### Require Exact Matches

Anchor the pattern to match specific strings exactly:

```bash
export PONYTAIL_SUBAGENT_MATCHER='^general$'

```

Only a sub-agent whose `agent_type` is exactly `"general"` receives the rules.

### Target Plugin Agents

Plugin agents use the format `plugin:name`. Match all plugins with:

```bash
export PONYTAIL_SUBAGENT_MATCHER='^plugin:.*$'

```

This scopes rules to all plugin-based sub-agents while excluding built-in types.

### Disable Filtering

To restore the default behavior and inject into every sub-agent:

```bash
unset PONYTAIL_SUBAGENT_MATCHER

```

## Safety Mechanisms and Edge Case Handling

The implementation in [`hooks/ponytail-subagent.js`](https://github.com/DietrichGebert/ponytail/blob/main/hooks/ponytail-subagent.js) includes defensive programming to prevent accidental lockouts.

**Invalid Regex Handling**
If the environment variable contains an invalid regular expression, the hook catches the error in a `try/catch` block and falls back to injecting rules into all sub-agents. This prevents configuration typos from silently breaking the system.

**Missing or Unparsable agent_type**
If the `stdin` JSON lacks a parsable `agent_type` field, the hook treats this condition as a match and proceeds with injection. This ensures rules are not silently omitted due to malformed input.

**Timeout and Stdin Errors**
If reading from `stdin` times out or encounters an error, the hook defaults to injection. This avoids deadlocks that could prevent sub-agents from initializing.

## Implementation in the Source Code

The filtering logic resides in [`hooks/ponytail-subagent.js`](https://github.com/DietrichGebert/ponytail/blob/main/hooks/ponytail-subagent.js), which executes during sub-agent spawning. The hook reads `PONYTAIL_SUBAGENT_MATCHER` from `process.env`, validates it as a regex, and compares it against the parsed `agent_type` from the initialization payload.

Documentation in [`README.md`](https://github.com/DietrichGebert/ponytail/blob/main/README.md) under the "Subagent scoping" section describes the variable's behavior and use cases. Comprehensive test coverage exists in [`tests/hooks.test.js`](https://github.com/DietrichGebert/ponytail/blob/main/tests/hooks.test.js), which validates the matcher logic against invalid regex patterns, missing `agent_type` fields, and timeout scenarios.

## Summary

- **`PONYTAIL_SUBAGENT_MATCHER`** accepts a regular expression string to filter which sub-agents receive rule injections.
- Matching is **case-insensitive** and performed against the sub-agent's `agent_type` read from `stdin`.
- When **unset**, rules inject into **all** sub-agents; when set, only matching types receive rules.
- **Safety fallbacks** ensure injection occurs if the regex is invalid, if `agent_type` is missing, or if `stdin` operations fail.
- The logic is implemented in [`hooks/ponytail-subagent.js`](https://github.com/DietrichGebert/ponytail/blob/main/hooks/ponytail-subagent.js) with tests in [`tests/hooks.test.js`](https://github.com/DietrichGebert/ponytail/blob/main/tests/hooks.test.js).

## Frequently Asked Questions

### What happens if PONYTAIL_SUBAGENT_MATCHER contains an invalid regex?

The hook catches the syntax error in a `try/catch` block and falls back to the default behavior, injecting rules into all sub-agents rather than crashing or blocking initialization.

### Does the matching respect case sensitivity?

No. The hook compiles the pattern with the `i` flag (`new RegExp(..., 'i')`), making the match case-insensitive. An agent type of `"General"` will match a pattern of `'^general$'`.

### Which sub-agents are affected when PONYTAIL_SUBAGENT_MATCHER is unset?

When the variable is unset, Ponytail injects rules into **every** sub-agent spawned via the Agent tool, regardless of type.

### Where is the matching logic implemented in the source code?

The core logic resides in [`hooks/ponytail-subagent.js`](https://github.com/DietrichGebert/ponytail/blob/main/hooks/ponytail-subagent.js) within the `DietrichGebert/ponytail` repository. The README documents this behavior in the "Subagent scoping" section, and [`tests/hooks.test.js`](https://github.com/DietrichGebert/ponytail/blob/main/tests/hooks.test.js) verifies the regex matching and edge case handling.