The flag that subsumes the others
A token whose code can be replaced can acquire a fee it never declared. A framework built on declaring behaviour cannot leave that one out, however uncomfortable it is to include.

Upgradeability is the behaviour that swallows every other one. A token whose implementation can be replaced can acquire a fee, a pause, a freeze or a hook it never declared, and the word an integrator cached last month describes a contract that no longer exists.
Which makes it the flag a framework like this is most tempted to leave out, and the one it can least afford to. So the upgradeable assembly sets the bit in its initialiser, and an integrator reading the word learns in the same call that the rest of it is only as durable as the upgrade authority.
The obligation the chain cannot enforce
Registration happens in the initialiser, and an initialiser cannot run twice. So the registry keeps whatever the first implementation wrote, and every later implementation inherits the extension set the token was born with.
That is a guarantee in one direction and a hazard in the other. A new implementation inheriting an additional module would run that module's transfer phases while the discovery surface kept reporting the old set — undeclared behaviour, which is the single failure this framework exists to prevent. Dropping a module is wrong the same way, from the other side.
Nothing on chain can stop it. The proxy cannot inspect the module set of an implementation it has not yet delegated into, so there is no check to write. It is a governance obligation, and the flag is the warning that the obligation exists. The upgrade suite pins the extension set across a real upgrade, which is where the constraint can actually be enforced: in the tests of whoever ships the next implementation.
Why the storage layout stopped mattering
Every module keeps its state in its own namespaced slot, derived from a string rather than assigned by declaration order. That is required for the upgradeable variant and free for the immutable one, and it buys the property that makes upgrades survivable at all: a later implementation can add fields to any module's struct, or add modules anywhere in the inheritance list, without moving anything already written.
Declaring upgradeability does not make it safe. It makes it visible, which is the only thing a specification can honestly offer.