The 'desync' stuff was surprisingly easy to resolve. Instead of trying to make all game state deterministic (a near impossible task in some languages, where for example even basic math functions don't have fully defined rounding charactistics), I went for another approach...
Detect desyncs by periodically taking a ram snapshot of the whole game and calculating a CRC over it. It means your game state needs to be serializable, but you probably need that anyway so a new player can join the game mid game.
If the CRC doesn't match, do a majority vote to find out which player is wrong, then do the rsync algorithm to sync differences between the players. In nearly all cases there will only be a few bytes of differences.
There is no need for the game to halt or lag during any of this - the game can continue as normal. Players are likely seeing the exact same thing on the screen, because the differences between game states are probably an error of 0.00001 in some player position.
When the corrected state has arrived, replay frames to bring it up to the current timestamp and switch out states. Job done. User sees no glitchyness. Developers don't have to worry about tiny bits of nondeterministic behaviour in libraries out of their control. Everyone's happy.
Make sure it doesn't happen every frame though, or you'll waste a lot of CPU.