You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Nothing coordinates concurrent local:gate runs across worktrees #2339
The fifth aspect of #2338, and the one none of the others can reach.
The gap
#2323, #2327, #2333, #2335 and #2336 are all changes inside one gate run. None
of them composes across runs, because no in-repo configuration can observe
another session's gate:
That is not an argument against those issues. It is the statement that they
optimize a single session's footprint, while the thing that actually varies is how many sessions are running, which is precisely the working mode #2338
exists to support: three or four concurrent agent sessions, each in its own
worktree, each free to run the full gate.
Evidence that it is the dominant term
From #2323's survey, during ordinary parallel work on an 8-logical-core machine:
6x to 8.5x oversubscription, sustained — four worktrees, 27 node
processes, 9 matching vitest|eslint. Nothing in vitest.shared.mts can see any
of that.
Sampling during a single gate on an otherwise quiet machine puts steady
background at 1.5–2 cores and shows the spikes coming from the gate itself, so
one session already saturates the box. The multi-session case is not a small
multiple of a solved problem; it is the unsolved one.
The shape of a fix
An advisory lease on local:gate: a run takes a lock, and a second run
either waits for it or proceeds at reduced parallelism. Cross-process, so a
lockfile under a well-known path rather than anything in-repo — core/'s
existing proper-lockfile usage (#2082) is prior art in this codebase for
cross-process locking done carefully, including stale-holder takeover.
⚠️One trap to design around, recorded in #2323 and worth restating because it
is easy to build by accident: two sessions each running a naive "wait until
the machine is clear" loop deadlock on each other — neither ever clears,
because each is the reason the other is waiting. A lease has to grant, not poll
a threshold.
Questions a design needs to answer, none of which has an obvious default:
Queue or degrade? Waiting is simple and makes the second session slow to
report. Degrading (fewer workers) keeps both moving and makes neither run's
timing comparable to a solo run — which matters, because Make the test gate trustworthy on a machine running several agents at once #2338's whole method
is measuring against a baseline.
What is the lease unit? The whole local:gate, or only its parallel
stages? Its serial stages (lint, build, the smokes) do not contend the same
way.
A design decision is recorded on this issue for each of the five questions
above — including "not worth building", if that is the answer, with the
reasoning.
If built: two sessions starting local:gate within seconds of each other both
complete green, and neither blocks indefinitely when the other is killed
mid-run.
Activity
fix: address Copilot review round 1 (#2339)
fix: address Copilot review round 2 (#2339)
fix: address Copilot review round 3 (#2339)
fix: address Copilot review round 4 (#2339)
Merge pull request #2344 from modelcontextprotocol/v2/feat/2339-gate-…
feat: queue concurrent local:gate runs on a machine-wide lease (model…
docs: record why maxWorkers stays unset, with the measurement (modelc…
docs: bring quality-gate.md up to date after modelcontextprotocol#2338 …
fix(gate-lease): key the lock on a fixed per-user path, not TMPDIR (m…