How terrible software design decisions led to Uber's deadly 2018 crash