# Risk & Failure-Mode Report — output of risk-assessor Task: Add a per-wave concurrency cap to trekexecute headless launches. ## Risks (ranked) | # | Risk | Severity | Mitigation | |---|------|----------|------------| | R1 | A cap that is too low **serializes** independent waves, erasing the parallelism trekexecute exists to provide. | high | Default the cap to the batch size (no-op) and only clamp when the operator/profile asks; never silently throttle. | | R2 | Bash semaphore bugs **deadlock** the `wait` (slots never released on subprocess crash). | high | Prefer `xargs -P ` over a hand-rolled counting semaphore — release-on-exit is built in. Guard with a per-subprocess `--max-turns`/timeout already present. | | R3 | The cap interacts with the **proliferation classifier** (S7 F4): a large parallel fan-out under `auto`/`bypass` is already scrutinised. A cap *reduces* this exposure, but mis-set to 0/negative could stall the pipeline. | medium | Clamp to `≥ 1`; reject `0`/negatives with a stable error code (`issue()`), do not coerce. | | R4 | Index-lock contention under high concurrency (multiple `git` subprocesses) is *masked* today by luck; raising the cap re-exposes it. | medium | Document that `GIT_OPTIONAL_LOCKS=0` is necessary-not-sufficient; the cap is the real fix. | | R5 | Drift between the JS resolver default and the Bash template's actual `-P` value. | low | Single source: prose passes the resolved integer into the template; a test asserts the template consumes `$MAX_PARALLEL`. | ## Edge cases - Wave of size 1 → cap is irrelevant (no fan-out). - Cap ≥ batch size → must be a pure no-op (R1). - Non-integer / missing flag → fall through resolver to profile default, not crash. ## Complexity hotspots The straddle between JS (resolver, testable) and Bash (launcher, hard to unit test) is the main hazard. Keep ALL arithmetic in the resolver; the template should only consume one already-validated integer.