How to Control Which Subagents Ponytail Injects Rules Into Using PONYTAIL_SUBAGENT_MATCHER
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.
How PONYTAIL_SUBAGENT_MATCHER Filters Sub-Agents
The 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:
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:
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:
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:
unset PONYTAIL_SUBAGENT_MATCHER
Safety Mechanisms and Edge Case Handling
The implementation in 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, 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 under the "Subagent scoping" section describes the variable's behavior and use cases. Comprehensive test coverage exists in tests/hooks.test.js, which validates the matcher logic against invalid regex patterns, missing agent_type fields, and timeout scenarios.
Summary
PONYTAIL_SUBAGENT_MATCHERaccepts a regular expression string to filter which sub-agents receive rule injections.- Matching is case-insensitive and performed against the sub-agent's
agent_typeread fromstdin. - 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_typeis missing, or ifstdinoperations fail. - The logic is implemented in
hooks/ponytail-subagent.jswith tests intests/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 within the DietrichGebert/ponytail repository. The README documents this behavior in the "Subagent scoping" section, and tests/hooks.test.js verifies the regex matching and edge case handling.
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 →