The four AI clients threw bare Errors on an empty reply (and, for Codex, on a
stream-level failure) with no httpStatus, so the provider-chain classifier saw
the same null-status shape as a genuine transport failure (ECONNRESET, DNS,
timeout) and could not tell them apart in observability. Attach a sentinel
`httpStatus: 0` plus a `kind` discriminator (`empty_response` /
`stream_failed`) on those throws. The cascade is unchanged:
`isHardProviderFailure` already treats a status <= 0 as a hard failure and
walks to the next provider — this only sharpens the logs.