rr
In the C/C++ world rr seems to be the greatest thing ever because you can go backwards in time. Should we consider something similar here? We could just (1) deepcopy the original inputs, and then (2) push!(statements, (stmt, scopeof(frame), pc)) for each statement we encounter, where statements is a single linear record of everything you did. This would unwind all the loops, all the calls, etc. You'd have to figure out some scheme for recording "name changes" from passing objects in as arguments, but perhaps the slot numbers basically already do that.
(wrong button, sorry)
I don't see how you could go back in time (other than to the start of the function where you did the deepcopy) based on this.
https://stackoverflow.com/questions/1470434/how-does-reverse-debugging-work
Definitely requires saving the initial state and irreversible changes. That is, x += 1 would not need saving the old value but x = 5 would. The point being, since we know every change that's being made, we could record adequate history information to go in either direction.