[Bug]: plugin SubagentLifecycleService.launch ignores the delegation pause, max_spawn_depth and the one-shot child budget
Pre-flight
- Searched existing issues and PRs by
SubagentLifecycleService,subagent_lifecycle,is_spawn_paused,max_spawn_depth bypass,ctx.subagent_lifecycle, "delegation spawning is paused", "plugin subagent depth limit". #106647 / #106696 (100yenadmin, open orchestration feature stacks of 77 / 89 files) each add a_validate_spawn_admission(...)call insidelaunchas part of a larger feature that depends on their new worker store; nothing focused on main or in review. - Confirmed on current
main(95db0e2ada) -
hermes debug share: N/A. Reproduced through the realdelegate_task,SubagentLifecycleService.launchand_build_child_agentwith theAIAgentclass and the child's run body stubbed.
Bug Description
SubagentLifecycleService.launch (agent/subagent_lifecycle.py, reached by plugins through ctx.subagent_lifecycle.launch()) builds and starts a child without the admission checks delegate_task runs first (tools/delegate_tool.py):
- the operator kill switch (
is_spawn_paused(),pin/agentsor thedelegation.pauseRPC); - the
_delegate_depth >= delegation.max_spawn_depthrefusal; - the one-shot
delegation.oneshot_max_childrenbudget (_oneshot_spawn_budget).
The depth bypass can recurse. _build_child_agent only downgrades an at-limit child to a leaf, and the child keeps the parent's plugin toolsets, so a child can call the plugin tool again and launch a grandchild one level deeper, and so on.
The lifecycle API doc says launch uses "the same host-owned path as delegate_task", and neither #63359 nor its salvage #72501 mentions skipping these checks, so the gap is an oversight.
Steps to Reproduce
- A plugin tool that calls
ctx.subagent_lifecycle.launch(...). - Pause delegation (
pin/agents), or run withdelegation.max_spawn_depth: 1from a child already at depth 1. - Call the plugin tool.
Probe output on main:
max_spawn_depth : 1
delegate_task at depth limit : Delegation depth limit reached (depth=1, max_spawn_depth=1).
lifecycle.launch at depth limit : ACCEPTED (child depth 2)
delegate_task while paused : Delegation spawning is paused. Clear the pause via the TUI (
lifecycle.launch while paused : ACCEPTED (child depth 1)
children actually run at depths : [2, 1]Expected Behavior
launch refuses with the same reason delegate_task gives, before any child is built.
Actual Behavior
launch accepts the request and the child runs, while paused and past the depth limit.
Affected Component
Tools (terminal, file ops, web, code execution, etc.)
Messaging Platform (if gateway-related)
N/A (CLI only)
Debug Report
N/A, reproduced in code (see Pre-flight).
Operating System
macOS 26
Python Version
3.14
Hermes Version
main 95db0e2ada
Source: NousResearch/hermes-agent