These details probably belong on separate thread about the Debounce on a pushbutton tutorial's Debounce.ino example. Maybe a thread like Debounce Time Code Explanation or Leading edge debouncing or something new.
But I'd still quibble a bit with:
The side effects do need to be considered, or rather the effects of the placement of the lastMillis=currentMillis update within which set of braces for which condition. The timestamp reset needs to be updated inside the inner set of braces of the two conditions to work properly, not wrapped around the outside:
if (A){
if (B){
C();
// update the time here inside the (A AND B)
lastMillis = currentMillis;
}
//lastMillis = currentMillis; // not here inside only A
}
If you put it outside you get a non-blocking, but unwanted behavior of C() like the brain-dead delay(600000) on every loop. It also needs to be initialized strangely (lastMillis = -interval) to duplicate the delay(600000) behavior that would feed both the t=1s & t=601s button-pecking pigeons.
Transforming the example's delay() to use millis() needs some special care to get the same behavior.