← Back to PRs

#17921: feat: add spawnableBy bidirectional sub-agent spawn authorization

by jacobot01 open 2026-02-16 09:21 View on GitHub →
agents stale size: M
## Summary Adds a `subagents.spawnableBy` config key on the target agent, enabling bidirectional spawn authorization. Currently only the spawning agent controls who it can target (`allowAgents`). This adds the inverse — the target agent can restrict who is allowed to spawn it. ## Config ```json5 { agents: { list: [ { id: "worker-coding", subagents: { spawnableBy: ["orchestrator"] // only orchestrator can spawn me } } ] } } ``` ## Behavior - `spawnableBy` **not set** → any agent can spawn (backwards compatible) - `spawnableBy: ["agent-a"]` → only `agent-a` can spawn this agent - `spawnableBy: ["*"]` → explicitly allow any spawner - Both `allowAgents` (sender) and `spawnableBy` (target) must pass for cross-agent spawns ## Changes - `src/config/types.agents.ts` — Added `spawnableBy?: string[]` to subagents type - `src/config/zod-schema.agent-runtime.ts` — Added zod validation - `src/agents/tools/sessions-spawn-tool.ts` — Added spawnableBy check after existing allowAgents check - `src/agents/openclaw-tools.subagents.sessions-spawn.spawnable-by.e2e.test.ts` — E2E tests mirroring allowAgents test patterns ## Tests 6 e2e tests covering: - Allows any spawner when spawnableBy not set (backwards compat) - Forbids when spawnableBy excludes requester - Allows when spawnableBy includes requester - Allows any with wildcard `["*"]` - Normalizes agent ids (case-insensitive) - Skips check for same-agent spawns ## Error When rejected: `Target agent "X" does not allow being spawned by "Y"` <!-- greptile_comment --> <h3>Greptile Summary</h3> Adds a `subagents.spawnableBy` config key to enable bidirectional spawn authorization. Previously, only the spawning agent controlled targeting via `allowAgents`; now the target agent can also restrict who can spawn it via `spawnableBy`. The implementation is clean and mirrors the existing `allowAgents` patterns across types, schema validation, runtime checks, and tests. - Adds `spawnableBy?: string[]` to the `AgentConfig` type and Zod schema, matching the `allowAgents` pattern - Runtime check in `sessions-spawn-tool.ts` runs after the `allowAgents` check, correctly handling wildcards (`["*"]`), case-insensitive matching, same-agent bypass, and backwards compatibility (no `spawnableBy` = allow all) - 6 E2E tests cover all documented behaviors using the shared test harness - Minor style note: `resolveAgentConfig(cfg, targetAgentId)` is called twice in `sessions-spawn-tool.ts` (once in the new `spawnableBy` block, once in the pre-existing model resolution block) and could be consolidated <h3>Confidence Score: 4/5</h3> - This PR is safe to merge — the authorization logic is correct, backwards compatible, and well-tested. - The changes are focused and well-structured: type, schema, runtime check, and tests all align. The new spawnableBy check correctly handles all edge cases (wildcard, missing config, same-agent, case normalization). The only minor concern is a redundant resolveAgentConfig call that has no functional impact. - No files require special attention. The minor redundancy in `src/agents/tools/sessions-spawn-tool.ts` is a style concern, not a correctness issue. <sub>Last reviewed commit: 0c8a3f1</sub> <!-- greptile_other_comments_section --> <sub>(2/5) Greptile learns from your feedback when you react with thumbs up/down!</sub> <!-- /greptile_comment -->

Most Similar PRs