Filed unassigned by the dev seat working #10167, which fixed the identical defect in
sdui_pick_free_port. Out of that card's declared file surface, so recorded rather than
fixed as a rider. Duplicate search first (quoted "smoke_pick_free_port",
"publish-smoke", port/TOCTOU wording): the only hits are #10167 itself and #10138, both
about the sdui script.
The defect
scripts/publish-smoke.sh, smoke_pick_free_port:
const isFree = (port) =>
new Promise((resolve) => { const probe = net.createServer(); probe.once('error', () => resolve(false));probe.once('listening', () =>probe.close(() => resolve(true))); // closes, then reports free
probe.listen(port);
});Bind, close, report free — then the caller binds. The scan walks base upward
deterministically, so concurrent callers do not diverge: they are handed the same port,
and the first one every time. This is not a probability, it is the construction. Measured
on the sibling helper before #10167 fixed it, eight concurrent callers from one base:
DISTINCT_PORTS=1 of 8
BIND_OK=2 BIND_ERR=6 # Error: listen EADDRINUSE 127.0.0.1:5180
Nothing about that measurement is specific to the sdui script; the two helpers differ
only in their default base (3210 vs 5180) and in probing the wildcard address rather
than 127.0.0.1.
Why it may bite less loudly here — and why that is not a reason to leave it
smoke_wait_for_own_server is documented as turning a lost race into a warning and a
retargeted BASE_URL, rather than the loud failure the sdui path takes. So the visible
symptom is likely a warning rather than a dequeued PR. But the contention is real:
packages/spec/scripts/publish-smoke-port-collision.test.ts draws from base 3210 four
times (:154, :159, :188, :221), and scripts/publish-smoke.sh draws once more in
the real path.
Shape of a fix (a lead, not a decision)
#10167 landed a claim-before-probe registry: O_EXCL file creation per port in a
host-shared directory, swept of claims whose owner process is gone, flock around the
sweep, and the claim released if the probe then loses to a process outside the registry.
Porting that is mostly mechanical — but it is a design port, not a spelling change, and
whoever takes it should decide deliberately whether the two helpers should share one
registry (they draw from disjoint bases today, which is the only reason they do not
already collide with each other).
⚠️ It also needs its own test surface: publish-smoke-port-collision.test.ts asserts the
current behaviour and would need the same vacuity guards #10167 added — an occupier that
silently loses its own bind reads as a picker that ignores busy ports, which is how the
sdui version accused the wrong function.
Filed unassigned by the dev seat working #10167, which fixed the identical defect in
sdui_pick_free_port. Out of that card's declared file surface, so recorded rather thanfixed as a rider. Duplicate search first (quoted
"smoke_pick_free_port","publish-smoke", port/TOCTOU wording): the only hits are #10167 itself and #10138, bothabout the sdui script.
The defect
scripts/publish-smoke.sh,smoke_pick_free_port:Bind, close, report free — then the caller binds. The scan walks
baseupwarddeterministically, so concurrent callers do not diverge: they are handed the same port,
and the first one every time. This is not a probability, it is the construction. Measured
on the sibling helper before #10167 fixed it, eight concurrent callers from one base:
Nothing about that measurement is specific to the sdui script; the two helpers differ
only in their default base (
3210vs5180) and in probing the wildcard address ratherthan
127.0.0.1.Why it may bite less loudly here — and why that is not a reason to leave it
smoke_wait_for_own_serveris documented as turning a lost race into a warning and aretargeted
BASE_URL, rather than the loud failure the sdui path takes. So the visiblesymptom is likely a warning rather than a dequeued PR. But the contention is real:
packages/spec/scripts/publish-smoke-port-collision.test.tsdraws from base3210fourtimes (
:154,:159,:188,:221), andscripts/publish-smoke.shdraws once more inthe real path.
Shape of a fix (a lead, not a decision)
#10167 landed a claim-before-probe registry:
O_EXCLfile creation per port in ahost-shared directory, swept of claims whose owner process is gone,
flockaround thesweep, and the claim released if the probe then loses to a process outside the registry.
Porting that is mostly mechanical — but it is a design port, not a spelling change, and
whoever takes it should decide deliberately whether the two helpers should share one
registry (they draw from disjoint bases today, which is the only reason they do not
already collide with each other).
publish-smoke-port-collision.test.tsasserts thecurrent behaviour and would need the same vacuity guards #10167 added — an occupier that
silently loses its own bind reads as a picker that ignores busy ports, which is how the
sdui version accused the wrong function.