Remembering now, the undervoltage and overvoltage protection could both be put under the MCU's control, in which case you could get by with just a diode, or equivalent. It wouldn't be as failsafe in the sense that an unforeseen bug in your code might defeat it, but it could be done. In the end, I'm not sure that the chance of encountering a failure in software is necessarily any higher than that of encountering a failure due to defective hardware.
Alternatively, you could put two cells in series, and in principle that would eliminate any chance of overcharging. With that configuration, if you used a 5v solar panel instead of a 6v, then you'd also eliminate any chance of burning out the atmega328p and wouldn't need extra hardware to ensure against that.
For that matter, you could stick with one cell and just use a 3.5v solar panel. With just that one stroke you wouldn't need anything extra to guard against overcharging the battery or over-volting the atmega328p.
That's what makes embedding solar such a fun problem--depending on the use case, there are such a large number of different ways to solve it. So many that the real game is in comparing the trade-offs.
@skywatch You are referring to the snippet that combines sleep on timer with pin change interrupts?
I just pasted that code in two randomly picked MySensor example sketches (UVSensor and ClearEepromConfig) and it compiled just fine (MySensors 2.3.2 and IDE 1.8.13). What kind of error do you get?
Edit: If it complains about getSleepRemaining() not being declared, you may be using an older MySensors version. I think it has been added with 2.3.2