tool.assignment_changed webhook (12th event type)

When a tool's owner moves (assignedUserId / assignedVehicleId / assignedYardId / parentKitId), the same PATCH that emits the internal ASSIGNMENT ToolEvent now also fires a tool.assignment_changed webhook. A single PATCH that touches multiple assigned* fields produces one delivery whose `changes` array enumerates each kind that moved — accounting / HR systems mirroring tool ownership no longer have to poll the events feed. Best-effort emission (won't fail the PATCH if delivery enqueue rejects). 5 new contract tests cover single-field emission, multi-field aggregation, no-emit on no-op PATCH, no-emit on unchanged values, best-effort failure recovery, and ISO timestamp shape.