* fix(ports): ignore malformed lsof listener pids
* fix(infra): strictly reject malformed lsof pid tokens
Number.parseInt truncated tokens like "111abc" to 111, silently accepting
a corrupted lsof pid record. Switch to parseStrictPositiveInteger so the
whole token must be a valid positive integer, and restore the deduped
listener test that a prior change had replaced instead of extended.
* fix(cli): strictly reject malformed lsof pid tokens
Harden the force-free lsof parser to reject digit-prefixed garbage like
p111abc instead of truncating it to pid 111, and cover the sibling parser
with a focused regression test.
* fix(infra): strictly parse stale lsof pid tokens
Harden the stale gateway cleanup parser to reject digit-prefixed garbage
like p111abc instead of truncating it to pid 111, and add a focused
regression test without dropping the existing argv verification coverage.
* fix(ports): fail closed on malformed lsof pids
---------
Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
* fix(ports): validate lsof PID parsing before assignment
Add Number.isFinite guard on lsof 'p' line PID parsing in
parseLsofOutput, consistent with the netstat branch in the same
function which already validates with Number.isNaN.
While the downstream if (current.pid) truthiness check catches
NaN (falsy), adding validation at the parse site is defense-in-
depth and eliminates an inconsistency within the same function.
* test(ports): add edge case tests for parseLsofOutput
Add test coverage for malformed lsof 'p' lines (empty PID, non-numeric
suffix), zero PID, and empty input to verify the Number.isFinite guard
correctly filters invalid entries.
* fix(ports): route isPortBusy through checkPortInUse to catch IPv4-only occupants
* fix(ports): treat PortUsageStatus unknown as busy in isPortBusy
Per ClawSweeper review: checkPortInUse returns 'unknown' when every host
probe fails for a non-EADDRINUSE reason. Treating unknown as 'not busy'
could cause forceFreePortAndWait to exit before lsof/fuser inspects the
port. Conservative fix: only 'free' means not busy; everything else
(busy or unknown) triggers further inspection.
* fix(ports): reuse canonical multi-address probe
* fix(ports): reuse canonical multi-address probe
---------
Co-authored-by: Vincent Koc <25068+vincentkoc@users.noreply.github.com>