Model events lie about who made the change

An ORM observer sees that a row changed and has no idea who changed it or why, so it invents an actor from whatever ambient context exists.

// a queue worker has no authenticated user, so this
// records null and the audit trail says 'system'
Order::updated(function (Order $o) {
    AuditLog::record(['actor_id' => auth()->id(), ...]);
});

// and it misses entirely:
DB::table('orders')->where(...)->update([...]);
Order::withoutEvents(fn () => $order->save());

// explicit recording at the point of the decision knows
// the actor, the reason and the intent

The bulk update bypassing events is the gap that matters most, because it is what a data fix uses. Observer-based auditing is attractive because it is one file and it produces a log that is silently incomplete — which is worse than no log, since it will be relied upon during a dispute.