If the accept loop has already exited (#failSessions ran), a waiter pushed here never settles — unlike ConnectionMux.acceptOpen, there's no error-state check. The in-repo sftp caller happens to call this immediately after accept(), but any public-API user calling acceptSession() on a dead connection hangs forever. Storing the loop-exit error and rejecting here would match the mux behaviour.
Fable review pass over the whole diff. I ran the full unit suites (ssh 104/104, sftp 109/109, 0 cancelled) and also stood up a local OpenSSH sshd and ran both opt-in interop suites (SSH_TEST_* forwarding tests and SFTP_TEST_*) — all pass, so the wire-level claims in the description check out. The split itself is clean (pure renames, no @webnet/vfs dependency left in @webnet/ssh), window accounting including extended-data is correct, and global-request reply ordering matches RFC 4254 §4.
A second tcpip-forward for the same bindHost:port overwrites the map entry, orphaning the previous listener and its #forwardAccept loop (never closed, even by close()). Rejecting the duplicate (return null) or closing the old listener first would avoid the leak. Related nit: RemoteForward.close()/_shutdown drop #queue without closing the queued transports, leaving those accepted channels dangling.
The comment says "unique port match" but this returns the first forward with a matching port. With two forwards on the same port on different hosts (the exact scenario the "two forwards sharing a port" test exercises via exact-match), a server that reports the bound host differently than requested (the OpenSSH behaviour this fallback exists for) can get its connections routed to the wrong forward. Making the fallback apply only when exactly one forward has that port would fail closed (reject) instead of misrouting.
Confirmed deadlock. If the remote window is exhausted and the peer sends CHANNEL_EOF/CHANNEL_CLOSE (or just closes) instead of WINDOW_ADJUST, this waiter is never woken: _deliverClose and _deliverEof don't touch #windowWaiters, and the CHANNEL_CLOSE dispatch deletes the channel from #channels, so even a later connection-level #failAll can't fail it. send() then hangs forever — and in pipe() that wedges the whole forward, leaving the other transport open. Repro: send 1MiB to a non-reading peer, start a second send, then close the peer channel — the second send never settles.
Both neutral-review findings addressed in eff16c5 — both were correct:
Pipelined ClientHello (server-side race): confirmed — after a completed read() the socket stays in flowing mode, so…
Thanks — addressed in 2ef788e / 7df49d3.
Short-read data corruption (client read pipeline) — fixed. This was the real one. Each in-flight READ now carries its {offset, want}; on a short…
Thanks — this second pass caught real issues. All five addressed in 118a3d1:
Availability bug — failed connect cached forever (#ensure): a rejected #doConnect() no longer wedges the…
Minor/robustness: writes are accepted only when offset === handle.pos, i.e. strictly sequential append from 0. This matches how the bundled client and sftp put behave, but a client that legitimately seeks (partial-file update, resumed upload at a non-zero offset via OPEN without TRUNC) gets SSH_FX_FAILURE. Worth documenting as a server limitation so it's a known constraint rather than a surprise.
Autonomous review (Claude Fable 5). This is an impressive, careful package — I read the whole SSH stack. Highlights that check out: the AES-CTR non-ETM frame reconstruction (headerSize/bodySize/open byte math is exactly right, incl. the +20 = 32-byte MAC minus the 12 packet bytes already consumed with the length block), the GCM RFC 5647 invocation-nonce increment, curve25519 exchange-hash + RFC 4253 KDF, all-zero-secret rejection, the rekey send-gate (kex packets bypass the app gate via #sendPacket, app send() blocks on #kexGate — no interleave, no deadlock), and the bounds-checked cursor. The publickey server path correctly verifies the signature over session-id-bound data before accepting. No memory-safety or crypto-correctness bugs found.
SETSTAT/FSETSTAT return SSH_FX_OK without doing anything. The inline rationale (make sftp put succeed) is reasonable, but silently succeeding on chmod/timestamp/truncate means a client's put -p or chmod reports success while nothing changed — surprising for a filesystem server. Since the VFS exposes setProps, honoring at least the timestamp/permission bits of the incoming ATTRs (and truncate via size) would make this a real success rather than a lie; otherwise a doc note on the server option is warranted.