derive Solver Name
Effective solver name for the persisted spec. Uses explicitSolverName when non-blank; otherwise derives a name from the chosen algorithm so reports and summary.toml describe what was run instead of the substrate's Identity(null) → "ID_<counter>" fallback.
Order of preference:
user-supplied explicitSolverName,
algorithmKind.displayName(e.g."Stochastic Hill Climbing").
Returns null only when algorithmKind is also null — in that case the host hasn't picked an algorithm yet and the question of a solver name is moot.