The plan9 libthread (which reimplemented the Alef concurrency model for C) did have seamless use of the C API/ABI.
The mechanism was that it had threads and coroutines, a function needing to make use of the C API in a seamless manner would simply run as a thread rather than a coroutine. It was then easy to share data as the CSP model (with channels) worked between both coroutines, threads, and coroutines within a thread.
So if one wishes to use stackful coroutines, and still have that seamless compatibility, an approach mixing the Go and Alef approaches would seem necessary. i.e. the Go migrating coroutines as a default, but with the option to use Alef like thread bound coroutines when necessary.
This reintroduces the colored functions that we were trying to get away from in the first place, by adopting stackful coroutines/fibers. Why not use async at that point? I can understand that Alef didn't, because stackless mechanisms were not well understood at the time. But it's plausible that we can do better.
Stackless coroutines are even more efficient for that case, and Rust makes them comparatively easy. (And slated to get even easier in future versions, as the async support is improved further.)
Moreover stackful coroutines/fibers as used in Golang also makes it infeasible to have seamless FFI with the standard C API/ABI, which cuts you off from the bulk of the ecosystem. There are other issues too with having fibers in a C-like systems programming language - see https://www.open-std.org/JTC1/SC22/WG21/docs/papers/2018/p13... for a nice summary of them.