So from there the benefits are around being able to use the sequential features of the language in combination (error handling, flow control, &c). Stackless transformations are a middle ground but there are plenty of things that become inconvenient without green thread stacks which make composition much easier.
No, it's not. See my other reply.
> there are plenty of things that become inconvenient without green thread stacks
There are no such things. Because you can have all of the sequential code you want, but without any of the downsides of threads.
I've spent plenty of time with both green threaded languages and non-green threaded languages. There is a most definitely a difference. A lot of the critiques you've given apply to event loops as well.
For example, data access, sure you can't write half a value but interleaving callbacks for work broken up into multiple stages is just as complex in terms of interleaved flows and would require the same careful treatments you would need in threaded code. The solution there is not to share data, even with events. I'm sure you implicitly do this yourself but there is nothing that makes either better or worse at it.
What you've failed to address are all of the trade-offs event loops have, like forgetful stack traces (and any effective fix keeps a stack of event flow contexts on the side, ironically).
In reality neither green threads or event loops are all that amazing on their own. Great runtimes need a whole lot more, so it seems kind of silly to sit on one side of the fence shouting that there are no downsides on your side of things because there obviously are plenty of problems worth solving better in both camps.
I think you didn't have a pleasure to work with event loops in languages with first-class functions, that's why you think they are on the same boat with green thread. They are not, of course. There are no trade-offs. You have multiple scopes to share memory from, one for each handler, that can execute only atomically, one for all handlers created by that function, that may execute out of order, and a global scope of course. You can compose functions, give them names and what not. You can even have a console, like Erlang does.
I've tried like a dozen of concurrency models, you cannot really convince me, that threads are any good for that.
Regarding green threads and state machines I would however add that while green threads allow to ditch some state machines (e.g. ones that wait until a complete packet was received) you won't get rid of all of them, e.g. you will still need state machines for lots of protocol implementations. E.g. if you are implementing the websocket protocol or HTTP/2, you have some interaction between incoming data, data that must be sent out and requests from the [library] user. The state of the connection depends on all of these, so you need some kind of connection state machine which would run most likely in it's own green thread (in addition to a sending thread and a receiving thread and a user thread). And now you have to implement clean synchronization between all of those threads. The lack of necessary synchronization (and the ability to observe a huge amount of state at once without danger) can make the implementation a little bit more easy in my experience. But here I also have to agree with strmpnk that a good design is necessary for both approaches, and accessing lots of shared mutable data in multiple callbacks is probably also not the cleanest approach.