6bcee12669
Round-2 audit of the openBidiStreamsBatch / openUniStreamsBatch landing. (1) Tests overpromised. The previous "holds streamsLock for the whole batch" test only verified the API didn't crash and stream ids were unique. A future regression that released the lock between opens (the 2026-05-06 bug shape) would not break it. Added `assertTrue(client.streamsLock.isLocked)` inside both batch init lambdas. Now the test name matches what's verified. (2) `*Batch` docstrings didn't warn that `init` runs under streamsLock. A naive caller might do encoding / IO inside, defeating the lock-hold-time goal that motivated pre-encoding outside. Added the warning + the canonical caller shape (encode outside, enqueue inside) to both function docs. (3) Empty-batch corner: an empty `items` list was still acquiring the lock and entering withLock. Added an `if (items.isEmpty()) return emptyList()` short-circuit. New test pins the contract — `init` must not run for an empty batch. Test count: 6 → 7. All green; no production-API change. https://claude.ai/code/session_01HcvfQq1ttPV9PkRoJb4nyT