How can you achieve any level of security and safety with un-trusted cooperative apps? Any app can get hold of the CPU for an indefinite amount of time, possibly stalling the kernel and other apps. There's a reason we are using OS-es with preemptive scheduling - any misbehaving app can be interrupted without compromising the rest of the system.

I remember Microsoft Research had a prototype OS written entirely in .NET some time in mid 2000s; IIRC they used pre-emptive multitasking, but didn't enforce memory protection. Instead, the compiler was a system service: only executables produced (and signed?) by the system compiler were allowed to run, and the compiler promised to enforce memory protection at build time. This made syscalls/IPC extremely cheap!

I think a slightly more fancy compiler could do something similar to "enforce" coop-multitasking: insert yield calls into the code where it deems necessary. While the halting problem is proven to be unsolvable for the general case, there still exists a class of programs where static analysis can prove that the program terminates (or yields). Only programs that can't be proven to yield/halt need to be treated in such fashion.

You can also just set up a watchdog timer to automatically interrupt a misbehaving program.

You might be thinking of Midori. Joe Duffy has written a lot about it on his blog: <https://joeduffyblog.com/2015/11/03/blogging-about-midori/>

They forked C#/.Net, taking the async concept to its extreme and changed the exception/error model, among other things.

There are several other OS projects based on Rust, relying on the memory-safety of the language for memory-protection. Personally, I think the most interesting of those might be Theseus: <https://github.com/theseus-os/Theseus>