Exercise the exit-signal handling fixed in 4dfcf6f6 using the real
`to_asyncio.open_channel_from()` API in an infected child actor.
An expected `TrioTaskExited` must not escape graceful teardown or
be raised again as an unhandled asyncio done-callback exception.
Deats,
- run six cases with native and Greenback-wrapped asyncio tasks:
direct channel closure, last cached caller exit/cancellation,
strict TTE reporting, and distinct RuntimeError/TTE cleanup faults;
- use `block_until_trio_side_exit()` to record task identity,
complete startup, send one channel value and block until signalled;
- wrap the channel API in `maybe_open_context()` for cached cases,
proving overlapping `trio.Task`s receive the same channel;
- synchronize the second subscription with `tn.start()` and an
event, then join its task before checking asyncio is still alive;
- open two asyncio tasks sequentially, checking each finishes when
its channel closes and retains the expected exception identity;
- raise a NEW TTE during cleanup to reject blanket type-based
suppression, retaining the issued TTE as the new error's cause;
- drain a host-loop callback before checking unhandled exceptions
for expected shutdown, separately from actor/RPC usability;
- await two sequential `Portal.run()` calls in the same child,
then explicitly cancel the actor before leaving its nursery.
Keep the Piker reproduction as context rather than describing the
blocking asyncio task as a quote/feed implementation. Document case
selection, closure contracts and the assertions at their call sites.
Qualification: latest matrix 12 passed. Earlier combined asyncio
and task-formatter run: 41 passed / 18 deselected. This matrix does
not yet cover an infected root or an asyncio task suppressing TTE
and returning or remaining blocked; those are follow-up coverage.
(this patch was generated in some part by `opencode` using
`gpt-6.1-sol` (`openai`))