OK... after doing a thorough review of the logs and some research, it appears I'm actually dealing with a CyberPower bug in how it handles the ondelay parameter. Easiest to quote what I found online:
The nut manual says set ups.delay.start (default 30) as the interval to wait before restarting the load (seconds) [after UPS power returns]. CyberPower UPSs restart ups.delay.start seconds after the UPS shutdown commences, regardless of the wall power status. Nut sets the value of ups.delay.start using the value of "ondelay" in ups.conf. Regardless of mains status, with:
ondelay = 0, UPS powers on the load immediately mains return;
ondelay = -1, UPS never powers on the load, even when mains return;
ondelay = xx, UPS powers on the load after xx (roughly) seconds after /usr/sbin/upsdrvctl shutdown is executed.
So, what I found in the logs was that my system did in fact shutdown properly on the first low battery. However, the UPS (which was already in a low battery state) came back online only a minute after it had shutdown (because I had ondelay set to 60). The system then wanted to go up and down till the UPS completely died.
What I thought I saw was that my outlets had been powered off before the low battery was signaled because I saw my system rebooting while the UPS was on when I walked into my server room. Should have done a more comprehensive review of the logs before posting.
I haven't fully tested the new ondelay = 0 setting yet, but, assuming that does keep the UPS powered off until line power is restored, I think use @dennypage 's suggestion to use the override.battery.charge.low so that, if line power goes up and own (which would make my CyberPower UPS come back on immediately), the system will still have time to shutdown again.
~Dan