It looks sane- you start emitting lists when you have at least one value from each flow, and the list always contains the latest value from each. You’re using a channelFlow, so that should be thread-safe.
I suspect the joinAll() isn’t needed, the coroutineScope won’t finish until all the children jobs have finished.