The existing semaphore tests mock `p.runCLI`, which proves the channel
arithmetic but not that the semaphore actually serializes real subprocess
spawns alongside the new opencode 1.14+ flag construction (Agent-Field#519). Adds
two functional tests that drive the full Execute path through RunCLI:
- TestOpenCodeConcurrencyLimit_RealSubprocess: a fake `opencode` shell
script writes per-invocation start/end timestamps; a sweep-line over
the recorded spans asserts the maximum overlap never exceeds
OPENCODE_MAX_CONCURRENT (and, conversely, that real overlap was
observed — guarding against a future change that accidentally
serializes everything to 1).
- TestOpenCodeSemaphore_ReleasedOnSubprocessFailure: with limit=1, three
sequential calls into a script that exits non-zero must all complete.
If a slot leaked on the failure path the second call would block
forever.
Manually smoke-tested against a real opencode 1.14.29 binary as well:
4 concurrent Execute calls with limit=2 produced the expected ~2x
single-call duration (paired stair pattern), and the binary accepted
the new `run --dir <project> -m <model> --dangerously-skip-permissions
<prompt>` invocation without help-screen fallback.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Summary
Adds a concurrency limit to OpenCodeProvider.Execute to prevent unbounded subprocess spawning under parallel workloads.
Changes
Motivation
Previously, each Execute() call spawned a subprocess without any limit, causing:
This change introduces backpressure and stabilizes execution.
Notes
Testing
./scripts/test-all.shAdditional verification (please describe):
Added concurrency test ensuring at most N executions run simultaneously
Added context cancellation test to ensure blocked callers exit immediately
Checklist
CHANGELOG.md(or this change does not warrant a changelog entry).Screenshots (if UI-related)
Related issues