In a nutshell
Without a shared clock, processes order events with counters. Each holds a vector counting the events it knows of from every process. A local event bumps its own entry; a receive takes the element-wise max with the message's vector. Comparing vectors reveals causality — who came before whom, and which events are concurrent.