is_ready() has precedent on futures, but doesn't generalise well so when we talked about this in SG1 earlier in the executors discussion we decided not to include it. The primary reason for that is that we are targeting lazy futures (tasks, senders, conceptually we can see them as futures for this purpose). is_ready may *never* be true in that space, so we would instead need to restrict to constructs that have some known forward progress. Threads possess that, so I think I'm more comfortable with the idea of checking if a thread has completed, though it's not fool proof of course.

Jonathan's concerns are more fundamental. We can always achieve this by setting a flag at the end of the thread's main function if we really want to. So thread could be wrapped in a thread class that wraps the function and sets a completion flag, which can be read by the is_ready function. It's bad enough that we now have thread and jthread, queryable_completion_thread just adds options to choose between.