Tear down the producer when an advertisement hits its size limit
Commit

Bugbot caught a regression in the previous commit: bounding the advertisement read stopped the in-memory growth but left the process on the other end still writing, so the limit turned an out-of-memory into a hang. Both transports were affected.
SSH: requestInfoRefsWithCommand called cmd.wait() with stdout still open. A remote that keeps writing fills the pipe, blocks in write(), and never exits, so Wait never returns. Now the read-error path goes through cleanupSSHCommand, which closes stdout first so the write side fails and the process can exit. The resulting non-zero exit is a consequence of that teardown rather than the cause, so the read error stays the reported failure, with ssh's stderr still attached.
Remote helper: RequestInfoRefs called finish() unconditionally, and finish() drained remaining stdout into io.Discard with no bound — so an endless advertisement hung in the drain instead of returning the limit error. The read-error path now uses cleanup() (which closes stdout) instead, and finish()'s drain is bounded at 1 MiB, closing the pipe if output continues past that, so the success path cannot hang either.
Both are covered by tests that run the operation in a goroutine and fail if it does not return: each was confirmed to hang for the full timeout against the pre-fix code (30s and 60s respectively) and to return a limit error in about a second after it.
Co-Authored-By: Claude Opus 5 (1M context) noreply@anthropic.com Entire-Checkpoint: 01M0D0SS9HH9AVZME1XB200NVJ