Package upgradeable lets a realm at a permanent path serve behavior that can change.
A gno.land package path is immutable. The VM keeper refuses MsgAddPackage at a path that already holds a package, and the one exception -- private = true in gnomod.toml -- buys redeployability by giving up importability, and starts the realm's globals over from nothing besides. So a realm other people import cannot have its code replaced. What it can do is decide at call time which object it calls, and that object can live in a realm deployed years later. There is no delegatecall here and imports resolve statically: the indirection is an ordinary interface value, handed over by the realm that implements it.
Proxy is the bookkeeping for that. It holds the one live implementation, the candidates waiting to replace it, and the ones it used to be, with an Authority deciding who may move between them. What it deliberately does not hold is your state. State belongs in the realm at the permanent path, or in a realm of its own, so that replacing an implementation does not touch it -- see the counter example under r/ for both halves.
This is a p/ package on purpose. Pure packages can never be redeployed, so the rules below cannot be swapped out from under the realm that relies on them, which is exactly the property an upgrade mechanism has to have.
Threading cur
Every authority-sensitive method takes (_ int, rlm realm): the caller threads its own cur as data instead of crossing into this package. The leading int keeps rlm out of first position, where it would declare a crossing function. rlm.Previous() is then the realm that crossed into the caller -- the user sending the transaction, the governance realm executing a proposal, or the implementation realm registering itself -- and rlm.IsCurrent() is what makes that unforgeable: a realm value cannot be persisted, and a stale capture fails the check.