--- model: openai/gpt-5.6-sol service: opencode timestamp: 2026-08-28T01:42:47Z git_ref: wkt/fix_broadcast_lag_count diff_cmd: git diff --- ## Prompt Get PR #490 primed and landed. Continue after rebasing, but keep the review and fix pass focused. ## Response The mutable `{}` default is safe because `msgspec.Struct` creates a fresh dictionary per instance. A separate concurrency defect remains: two tasks can call `receive()` through one `BroadcastReceiver`, and the second call overwrites the only `_wait_scope`. Closing that receiver can then leave the first task blocked indefinitely. > `git diff -- tractor/trionics/_broadcast.py tests/test_task_broadcasting.py` Added a per-receiver in-progress guard that raises `trio.BusyResourceError` for an overlapping receive. Added a regression test that blocks the first receive, verifies the second call is rejected, and releases the source to prove the first call still works. The complete broadcast test file passes: 28 tests in 4.57 seconds. ## Follow-up prompt Clarify that the guard is per receiver, preserves lossless consumer semantics, and document the contract on the public method, type, and surrounding guide. ## Follow-up response > `git diff -- tractor/trionics/_broadcast.py docs/guide/streaming.rst` Documented that each `BroadcastReceiver` owns one logical cursor, each concurrent consumer needs its own subscribed receiver, overlapping calls on one handle raise `BusyResourceError`, and strict lag handling never skips values silently. ## Second follow-up prompt Explain that the polling loop waits until the background receive is blocked before making the concurrent call, and include the first consumer task's runtime information in the busy exception. ## Second follow-up response Replaced the boolean guard with the active `trio.lowlevel.Task`, added its name and representation to `BusyResourceError`, named the fixture task for a deterministic assertion, and documented the checkpoint-loop interleaving directly above the poll.