--- model: openai/gpt-5.6-sol service: opencode timestamp: 2026-08-13T23:07:44Z git_ref: ddac3553 diff_cmd: git diff HEAD~1..HEAD --- The user asked to continue the piker broadcast-consumer audit after committing the Deribit ownership fix. The next isolated item was IB's actor-local `_quote_streams` cache, which retained a raw channel owned by its first caller and constructed competing broadcaster roots for later callers. > `git diff HEAD~1..HEAD -- piker/brokers/ib/feed.py` Factored `_open_aio_quote_channel()` as the raw asyncio-channel context and made `open_aio_quote_stream()` cache that context by symbol through `maybe_open_context()`. Every caller now receives a lexical child from the retained `LinkedTaskChannel` broadcaster, while the raw source remains alive until its final cache user exits. Removed the manual `_quote_streams` registry and teardown mutation. > `git diff HEAD~1..HEAD -- tests/test_ib_broadcast.py` Added a concurrent ownership regression using real Tractor broadcast state. It proves miss and hit callers use the same symbol/context factory, receive the same quote through distinct children, close independently, and leave the owner live after the hit exits. Verification output: ```text . [100%] 1 passed in 0.01s ``` The new test passes through a source-isolated IB feed import. Test Ruff, E501, Python compilation and whitespace checks pass. Normal package collection remains blocked by the existing Qt environment mismatch.