I don't know that I'd nearly qualify as an "expert", but I would enjoy being a part of that if it comes to fruition.
I ended up changing my approach from what I initially sketched, since the initial sketch was meant to be something that could be used just in //remoting, while the prototype instead tries to integrate into //base to be more widely usable. The basic concept is "posting a coroutine task should be as similar to posting a regular task as possible." Specifically:
- BindOnce() must be used to bind a coroutine's arguments to it prior to posting.
- A coroutine OnceCallback can be posted as a task by passing it to a TaskRunner's PostTask() method. (This required updating a few sites that take a reference to PostTask() to explicitly select the desired overload. The alternative would be to have a distinctly named PostCoroutine() or some such.)
- When a coroutine is passed to PostTaskAndReply(), the reply callback will be invoked when the coroutine has fully executed.
 
- All of the code within a posted coroutine task runs on the same runner. If the coroutine awaits on something from a different thread / sequence / et cetera, the implementation ensures that it is still resumed on the expected sequence. (This is in contrast to many implementations, where the coroutine must be prepared to resume on any arbitrary thread.) This allows sequence-bound and thread-affine objects to be used within a coroutine.- However, the coroutine may be interleaved with other tasks on the same runner when suspending via co_await, and it may resume on a different physical thread (unless it was posted to a SingleThreadTaskRunner).
 
- To do work on a different runner a new task must be posted using that runner.- I added PostTaskAndAwait() and PostTaskAndAwaitResult() methods (that work with both coroutine and regular tasks) to make it easy to co_await such a task.
 
- Like with regular tasks, if the a task posted to PostTaskAndReply() is canceled, the reply callback will not be invoked.- Unlike with regular tasks, a coroutine task can be can canceled at a suspend point after it has started execution. (Or manually canceled by awaiting a special CancelTask value.)
 
- If a task posted to PostTaskAndAwait() is canceled, the implementation makes a best-effort attempt to cancel the caller as well to prevent the waiting coroutine from leaking.
 
Handling WeakPtrs is a little tricky, since a WeakPtr might be invalidated by a interleaved task any time the coroutine suspends. Manually rechecking WeakPtrs after every resume isn't tenable, as the currently-executing coroutine might not even know the pointer / reference it was passed was derived from a WeakPtr, let alone have access to it. This is especially true for methods, which can only be passed their receiver as a raw pointer, and being able to co_await another method in the same class is pretty important for usability.
My solution is to allow coroutines to create a scoped guard declaring the use of a given WeakPtr. The implementation keeps a list of all such guards that are currently live on the coroutine stack, and will automatically check them all each time the task resumes. If any guarded WeakPtrs are invalid, the implementation will immediately cancel the task instead of resuming execution of the coroutine. When a WeakPtr is bound as the receiver for a coroutine method, BindOnce() will automatically ensure that such a guard exists for the lifetime of the bound coroutine's execution.
Like with a regular task, a coroutine task will be destroyed on the appropriate runner if it is canceled. However, since the coroutine task may have already started execution, there's more state to destroy than just the bound arguments in a regular task, and thus more of a chance that a destructor in the coroutine stack might try to access a pointer derived from a now-invalid WeakPtr. A coroutine needs to take care that, for objects that live across a suspend point, their destructors don't access any pointers or references that are not guaranteed to point to objects also on the coroutine stack. The alternative would be to leak any canceled coroutine instead of destroying it, but that seems undesirable.
There is one major caveat with my prototype: it currently crashes if the posted coroutine never actually suspends. I'm pretty sure the crash is due to a miscompilation of 
ExecuteInTaskImpl, but please let me know if there's a bug in that function that I'm missing. The resulting assembly looks like this:
0x5555593d887c  <+ 2172>        48 8b bd c0 fe ff ff     mov    rdi,QWORD PTR [rbp-0x140]
// Call to delete for the coroutine state (sample value for $rdi: 0x964000f0000)
0x5555593d8883  <+ 2179>        e8 38 12 44 00           call   0x555559819ac0 <_ZdlPv>
0x5555593d8888  <+ 2184>        8b 85 c4 fd ff ff        mov    eax,DWORD PTR [rbp-0x23c]
0x5555593d888e  <+ 2190>        85 c0                    test   eax,eax
0x5555593d8890  <+ 2192>        74 04                    je     0x5555593d8896
0x5555593d8892  <+ 2194>        eb 00                    jmp    0x5555593d8894
0x5555593d8894  <+ 2196>        eb 02                    jmp    0x5555593d8898
0x5555593d8896  <+ 2198>        eb 00                    jmp    0x5555593d8898
0x5555593d8898  <+ 2200>        eb 00                    jmp    0x5555593d889a
0x5555593d889a  <+ 2202>        eb 00                    jmp    0x5555593d889c
// Calls to destructors for copies of |task| and |current_runner| within the already-deleted coroutine state
0x5555593d889c  <+ 2204>        48 8b bd 48 fe ff ff     mov    rdi,QWORD PTR [rbp-0x1b8]
// $rdi here is 0x964000f00d8, within the just-freed allocation.
// Crashes because that memory has been overwritten with 0xcdcdcdcdcdcdcdcd.
0x5555593d88a3  <+ 2211>        e8 d8 79 f8 fd           call   0x555557360280 <_ZN13scoped_refptrIN4base10TaskRunnerEED2Ev>
0x5555593d88a8  <+ 2216>        48 8b bd 40 fe ff ff     mov    rdi,QWORD PTR [rbp-0x1c0]
0x5555593d88af  <+ 2223>        e8 dc e4 f6 fd           call   0x555557346d90 <_ZN4base12OnceCallbackIFNS_5AsyncIvEEvEED2Ev>
0x5555593d88b4  <+ 2228>        48 81 c4 40 02 00 00     add    rsp,0x240
0x5555593d88bb  <+ 2235>        5d                       pop    rbp
0x5555593d88bc  <+ 2236>        c3                       ret
If I uncomment line 219, suspending ExecuteInTaskImpl never to be resumed (leaking its state), then all the tests pass, but obviously that's not a tenable solution.