Moving 88 live resources without recreating a repo
The GitHub path has to move onto the new contract before GitLab can use it, and the old provider has already destroyed real files twice. So the move is adoption by name, one app first, and every step is measured against the repositories themselves.
Lessons already paid for
A Delete policy on a file destroyed cicd.yaml in five repos.
A changed identity field re-identified every live file.
An external-name fight burned 16,000 calls an hour.
So, by construction
The new RepositoryFile treats only a 404 as gone, never writes on adopt, never deletes, and keeps whatever external-name it observed.
Order
Flip the apiVersion only after every caller is ready, test on a copied Composition first (Argo CD self-heal reverts hand edits), and canary on a Skyport app before the fleet.