Unified error type. Each driver still keeps its own rich error type for internal use; conversions to/from this one happen at the trait boundary.