--- type: reference title: OMP Subagent Limits & Fan-out Policy description: The live caps on omp subagents — concurrency 2, no nested spawns, per-endpoint in-flight ceilings, 30-min runtime, soft request budget, and the isolated-workspace policy; includes the maxRecursionDepth=0 trap. tags: - omp - subagents - config - fleet timestamp: 2026-10-19 --- # OMP Subagent Limits & Fan-out Policy Enforced caps on subagents spawned through the `task` tool / eval `agent()`+`workpool()` from this workstation (config root `agent/config.yml`, machine-live tier — the live-sync heartbeat commits it). Set 2026-10-19; values verified against the live config and the enforcement code in the installed bundle (`@oh-my-pi/pi-coding-agent/dist/cli.js`). ## The caps in force | Key | Value | Default | Effect | |---|---|---|---| | `task.maxConcurrency` | 2 | 32 | Session-scoped semaphore; excess spawns queue, never drop. | | `task.maxRecursionDepth` | 1 | 2 | Subagents cannot spawn their own subagents. See depth semantics. | | `task.maxRuntimeMs` | 1800000 | 0 (off) | Hard 30-min wall clock per subagent; overrun = `aborted`. | | `task.softRequestBudget` | 120 | 200 | Wrap-up notice at 120 assistant requests; force-stopped to yield at 180 (1.5×). | | `task.agentIdleTtlMs` | 420000 | same | Finished subagents parked to disk after 7 min idle (revivable via `agent://`). | | `task.enableEffort` | false | false | Per-spawn `effort` hint hidden from the schema. | | `task.isolation.enabled` | true | false | `isolated: true` spawns run in a copy of the checkout; only successful patches land (merge=patch, apply). Opt-in per spawn. | | `task.completionProbe` | false | true | No periodic completeness side-requests into running subagents. | | `tools.maxTimeout` | 600 | 0 (off) | No agent may request a tool timeout above 10 min; kills `timeout: 0` runaways. | | `providers.maxInFlightRequests` | see below | {} (unlimited) | Per-provider ceiling on concurrent LLM requests, shared across local omp processes. | ## Depth semantics — never set `maxRecursionDepth: 0` Bundle predicate (`U_`): a session at `taskDepth` *s* keeps the `task` tool iff `n < 0 || s < n` where `n = maxRecursionDepth`. The preflight repeats the check (`Cannot spawn another agent at task depth s; maximum depth is n`). - `n = 1` → main (depth 0) spawns; children (depth 1) have `task` stripped. **This is "no nested subagents".** - `n = 0` → `0 < 0` fails → **not even the main session can spawn anything.** Don't. - `n < 0` → cap disabled. ## Per-endpoint in-flight ceilings ```yaml providers: maxInFlightRequests: "llamacpp (dankserver)": 3 # main session + up to 2 task/reviewer subagents "llamacpp (dankclaw)": 2 # frank-dragoon: security-reviewer + fallbacks "llamacpp (dankclaw-3090)": 3 # frank-zealot: scout/sonic/librarian/designer + smol/tiny/plan/commit/vision roles ``` - Keys are **provider ids** = the quoted block labels in `agent/models.yml` (one provider per host:port). The consumer does a flat map lookup by provider id; absent or ≤0 = unlimited, otherwise clamped to ≥1. - Scope is **per machine, per config root**: it bounds what *this workstation's* omp processes put on each endpoint. Other workstations, OpenWebUI, and any non-omp client are not counted. Requests past the ceiling queue, never fail. - `web/searxng` intentionally uncapped. ## Isolation note `task.isolation.enabled: true` makes the per-spawn `isolated` flag available — it is **opt-in per spawn**, not a blanket sandbox. Requires a git repo; unavailable in plan mode; baseline snapshot capped at 1 GiB; backends resolve via `isolation.backend: auto` (overlayfs/reflink/rcopy chain on this box). Given *the checkout is the deployment*, prefer `isolated: true` for any subagent that edits tracked files. ## Deliberately not set - `bash.gitGuard` — offered 2026-10-19, declined; destructive-git protection stays opt-in. - `task.disabledAgents` — no bundled agent type warrants a ban. - `task.agentAccountPools`, `tier.subagent` — no-op against keyless local endpoints. - `PI_TASK_MAX_OUTPUT_BYTES` / `PI_TASK_MAX_OUTPUT_LINES` — 500 KB / 5000 line defaults are sane. - `before_subagent_spawn` hook — programmable spawn policy; revisit if these caps prove insufficient. ## Verification `cfg://task`, `cfg://providers/maxInFlightRequests` reflect all rows above; persisted copies in `agent/config.yml`. Depth semantics confirmed against the shipped bundle, not just the setting description. # Citations - `agent/config.yml` (live config, this repo) - `agent/models.yml` — provider id block labels - `@oh-my-pi/pi-coding-agent/dist/cli.js` — `U_` depth predicate, in-flight map lookup - omp docs: `omp://tools/task.md` § Limits & Caps # See Also - [/core/statusline.md](/core/statusline.md) — the omp-era bundle-audit page pattern this page follows - [/pi/packages/pi-subagents.md](/pi/packages/pi-subagents.md) — retired pi-era subagent system (historical) - [/system/index.md](/system/index.md) — fleet endpoints these ceilings target