Ethereum has different client software, they must all use the same consensus rules: produce/gossip/accept transactions and blocks that follow a certain format and respect certain invariants. When that specification is updated, a hard-fork occurs. It's not a problem if all clients meet the new spec perfectly but sometimes bug happens and different clients disagree on what constitutes the canon chain. This is what happened here: the OpenEthereum client (11% of the network) has had a bug following the Berlin hard-fork (network upgrade). Nodes runnning this client are stalling at a certain block because they don't recognize the new "post-Berlin" blocks as legitimate because of a bug in the implementation.
So are procotol-level changes announced ahead of time with a precise date when they get into force and the clients hard code that date as a transition? Or perhaps a block number is used?