Fully self-custodial upgrades

Hello, and first of all my apologies if this question has been answered before; kindly refer to it if that is the case.

At our company we're looking for an upgradability solution that enables full self-custody. We are in the process of developing a DApp with an underlying ERC1155-type contract with a potential for a relatively large number of users. Our moonshot is an upgradable mechanism that allows users to choose whether or not to upgrade (opt-in), instead of forcing upgrades or time-locking (which is opt-out), much as in traditional software version management, probably with a locking mechanism + escape hatch for deprecated/unsupported versions. Essentially what we're thinking about is a fine-grained control of user-version mappings at the proxy level. A simple example use case would be:

  1. We deploy version 1 of the contract
  2. Alice interacts with the contract
  3. We deploy version 2 of the contract (upgrade)
  4. Bob interacts with the contract and gets v2
  5. Alice interacts with the contract and gets v1
  6. Alice upgrades
  7. Alice interacts with the contract and gets v2

To avoid a maintenance hell, we could add a mechanism to lock deprecated versions, and only allow upgrades to the latest version, for example. A time-locked rollback operation could also be valuable to avoid having users get stuck after upgrading to a new version that is found to have some bug/vulnerability, for example.

From my relatively superficial understanding of proxy patterns, I cannot deduce any major obstacles to implementing something like that, but I was surprised to find very little information about fully self-custodial upgrades. It makes me think I'm missing some "gotcha", or that the idea is not really valuable.

Could you shed some light on similar ideas or implementations that you might know, or clarify why this would be unfeasible and/or a bad idea, that being the case?

Any help would be much appreciated.