Old blocks in the chain are still valid under the current consensus rules.
In a broad sense, this is because the code will be written to enact rule changes at specific block heights, and thus older blocks will not be subject to said new rules.
To put it differently: the consensus ruleset doesn't just cover what new blocks are supposed to look like, they also cover what the historical valid chain looks like!
Sometimes, specific exceptions are written in, such as is the case with BIP 30.