As usual, Quinn was immensely helpful in the TSI (and, I assume, various other engineers -- please thank them for me, especially if I know them 😄), and determined the root cause: a flow could not have more than 128k of data pre-macOS 12.3. This doesn't seem to have been documented, and instead of returning an error in the .write method, it closed the file descriptor. ooops. In 12.3 and later, it breaks the data into chunks to keep it working; I had, based on Quinn's analysis, added code to do the same (but at 48k chunks, since I didn't know what the limit was at that point). (And I just changed the code to use #available(macos 12.3, *) to set the limit, and it's going through QA now.)