bnewbold's recent leaflet discusses a recently discovered predicament wherein AT URIs, as currently designed, are not valid IETF URIs for subtle reasons, and presents some ideas for how to move forward. As he astutely notes,
There are billions of AT URIs in the wild today. Many of these are in content-addressed data records which can not be update without changing the record version (hash). Or in millions of cryptographically signed label objects from hundreds of providers. This means that the current syntax is going to be encountered and needs to be at least partially supported by atproto implementations indefinitely.
This is clearly one of those pivotal moments where the right decision makes everything easier going forward, and the wrong decision makes everything harder.
Thus far, ATProto has assumed immutable references. If changing AT URI syntax is now on the table, it seems prudent to challenge this assumption now, and to treat this like the biggest possible case of forced link rot, rather than the only case. Users may wish to have their PDS internally redirect a link they originally posted 10 years ago if the website restructured, for example, or perhaps folks would occasionally like to update links to point to updated records of new lexicons.
With that in mind, here the problem to solve, the solution, and a further recommendation.
The Problem
At some level, reference immutability is required for ATProto's data integrities to work at all. All data is signed and added to a Merkle Search Tree. Modifying this data would require resigning and rehashing all the way up the tree, which is practically intractable when your PDS gets large enough. Ideally, the affordance we want is some way of maintaining data integrity internally while allowing references to change externally.
The Solution
Data sovereignty gives us superpowers we never had before on the internet, and the means to avoid the kind of cruft that has built up around the incumbent standards. Since we own our data now, backwards compatibility is easier to maintain than before, because we can put whatever we want in front of our data for that purpose. I draw inspiration from the Spritely Institute's Petnames idea, except in this case human readability is not required, and I have expanded it to cover entire URIs rather than just DIDs (more on that later). The address book is simply an internal mapping inside a PDS, binding external URIs to internal references. This gives us the affordance we want. Specifically, the behavior is that when a record is requested, all references in the record are swapped with their corresponding address book entries on the way out. The caller never sees the address book; they only receive the patched record and proceed as usual. You can think of it like an internal redirect. For efficiency, address book entries can be added only when a reference needs to be updated for the first time, and before that references can be served directly without adjustment.
This address book lives in the user's PDS, alongside the repo. The user takes it with them whenever they migrate, wherever they go, and most of the time they don't even have to know it's there.
While we're at it
I still think identity sovereignty is important, and eventually users will care. Therefore, in addition to the above solution, and in keeping with the original spirit of Petnames, I suggest implementing the address book for DIDs as well. This is because DIDs are identity references and often, the same DID may appear in several references just as one reference may appear in several records. So, we would like to only require one table entry per redirected DID.
These address books can easily coexist in parallel. One of them swaps DIDs and the other swaps URIs, and as long as the order in which they do so is fixed, this is not a problem. I have put that sentence in bold, because PDS implementations will need to use the same order to be compatible.