The distinction between structured and unstructured tasks maps well to a pattern I've seen in async Python too — the difference between TaskGroup and fire-and-forget coroutines. Your point about parent-child task cancellation propagation is particularly useful because it highlights where most concurrency bugs actually hide: in cleanup paths that never execute when the parent scope exits early.