The 2026-09 org migration (design: docs/superpowers/specs/2026-09-03-org-migration-design.md) is
functionally complete, but execution hit three conditions the design's
"Failure handling" table does not cover. Two of them would mislead someone
following the table literally. Recording them so the spec matches what
actually happens, and so a future migration does not repeat them.
1. Popular-repository namespace retirement blocks transfers permanently
What happened. Step 4 transferred 25 of 30 repos. Five failed with
HTTP 422:
Repository name smartwatermelon/<name> has been retired and cannot be reused
Affected: dotfiles, claude-config, personify, huddle-transcribe,
projectinsomnia. All five remain intact under twistedmelonman with
working redirects, so nothing is broken — but those five paths under the
org are permanently unavailable, including to gh repo create.
Why the table is wrong here. It says:
| Transfer fails mid-loop | Re-run transfer.sh; it skips completed repos. Report the refusing repo. |
That is correct for a transient error and useless for a 422. Retrying
confirms the block; it cannot clear it. Reversal requires GitHub Support
intervention with no self-service path and uncertain outcome (ticket
4729524 is open).
Cause. GitHub retires an OWNER/REPO path when, in the week before a
rename or transfer, the repo had >100 clones, >100 Actions runs, or
contained a Marketplace action. The retirement binds the path string, so
a new org inherits the retired paths of the user whose name it took.
Avoidable? Yes, by ordering: create the org under a temporary name →
transfer all repos → rename the user → rename the org. No official doc
prescribes a safe sequence (github/docs#17617, asking for exactly this,
was closed as not planned).
2. A post-transfer diff can be a gain, not a loss
What happened. Part F reported cleanroom with
fields changed besides owner: protection,rulesets. Its baseline value for
both was null. The repo did not lose settings — it gained branch
protection (claude-review / run-review) from the destination org's
ruleset.
Why the table is wrong here. It says:
| Post-transfer diff shows more than owner | Finding. Restore the setting by hand from the snapshot; record which setting GitHub dropped. |
"Restore from the snapshot" here means restoring null over working branch
protection — actively removing a protection the transfer correctly added.
The row assumes every diff is a loss.
Fix. Compare direction before acting: null in baseline and non-null
after is a gain, and the correct response is to accept it.
3. GitHub App installations do not follow transferred repos
What happened. After Step 4 and Step 5, claude-blocking-review failed
on a transferred repo at 36s:
Action failed with error: Claude Code is not installed on this repository.
Please install the Claude Code GitHub App at https://github.com/apps/claude
orgs/smartwatermelon/installations was empty. The Claude app installation
was bound to the user account and did not migrate with the repos.
nightowlstudiollc, never renamed, kept its installation
(claude id=107089099 repos=all) and passed the identical workflow
throughout.
Why this is easy to miss. The failure is silent until the next PR in
any of the 25 transferred repos, and it looks like a secrets problem. It is
not — the org secret was delivered correctly in the same run. It is also
distinct from the action install: the workflow downloads
anthropics/claude-code-action on every run and that succeeded; the app
installation is a separate persistent grant the action authenticates
against, and no workflow can create it.
Fix. Install the app on the org (done: claude id=159138570 repos=all).
Verified by PR #30 on archive-resolver — a repo with no repo-level
secret — where the claude app posted a real VERDICT: PASS review.
Also worth recording
Step 5 says to delete the repo-level CLAUDE_CODE_OAUTH_TOKEN on
networth-agent, photo-game-poc, and cleanroom. In practice:
networth-agent had no copy to delete.
photo-game-poc and cleanroom are private; they keep their repo-level
copies for the same reason scripts does. Both orgs currently report
plan=team, which would make org-secret delivery to private repos work
today, but that plan is temporary and nothing should depend on it.
Proposed changes
The 2026-09 org migration (design:
docs/superpowers/specs/2026-09-03-org-migration-design.md) isfunctionally complete, but execution hit three conditions the design's
"Failure handling" table does not cover. Two of them would mislead someone
following the table literally. Recording them so the spec matches what
actually happens, and so a future migration does not repeat them.
1. Popular-repository namespace retirement blocks transfers permanently
What happened. Step 4 transferred 25 of 30 repos. Five failed with
HTTP 422:
Affected:
dotfiles,claude-config,personify,huddle-transcribe,projectinsomnia. All five remain intact undertwistedmelonmanwithworking redirects, so nothing is broken — but those five paths under the
org are permanently unavailable, including to
gh repo create.Why the table is wrong here. It says:
That is correct for a transient error and useless for a 422. Retrying
confirms the block; it cannot clear it. Reversal requires GitHub Support
intervention with no self-service path and uncertain outcome (ticket
4729524 is open).
Cause. GitHub retires an
OWNER/REPOpath when, in the week before arename or transfer, the repo had >100 clones, >100 Actions runs, or
contained a Marketplace action. The retirement binds the path string, so
a new org inherits the retired paths of the user whose name it took.
Avoidable? Yes, by ordering: create the org under a temporary name →
transfer all repos → rename the user → rename the org. No official doc
prescribes a safe sequence (
github/docs#17617, asking for exactly this,was closed as not planned).
2. A post-transfer diff can be a gain, not a loss
What happened. Part F reported
cleanroomwithfields changed besides owner: protection,rulesets. Its baseline value forboth was
null. The repo did not lose settings — it gained branchprotection (
claude-review / run-review) from the destination org'sruleset.
Why the table is wrong here. It says:
"Restore from the snapshot" here means restoring
nullover working branchprotection — actively removing a protection the transfer correctly added.
The row assumes every diff is a loss.
Fix. Compare direction before acting:
nullin baseline and non-nullafter is a gain, and the correct response is to accept it.
3. GitHub App installations do not follow transferred repos
What happened. After Step 4 and Step 5,
claude-blocking-reviewfailedon a transferred repo at 36s:
orgs/smartwatermelon/installationswas empty. The Claude app installationwas bound to the user account and did not migrate with the repos.
nightowlstudiollc, never renamed, kept its installation(
claude id=107089099 repos=all) and passed the identical workflowthroughout.
Why this is easy to miss. The failure is silent until the next PR in
any of the 25 transferred repos, and it looks like a secrets problem. It is
not — the org secret was delivered correctly in the same run. It is also
distinct from the action install: the workflow downloads
anthropics/claude-code-actionon every run and that succeeded; the appinstallation is a separate persistent grant the action authenticates
against, and no workflow can create it.
Fix. Install the app on the org (done:
claude id=159138570 repos=all).Verified by PR #30 on
archive-resolver— a repo with no repo-levelsecret — where the
claudeapp posted a realVERDICT: PASSreview.Also worth recording
Step 5 says to delete the repo-level
CLAUDE_CODE_OAUTH_TOKENonnetworth-agent,photo-game-poc, andcleanroom. In practice:networth-agenthad no copy to delete.photo-game-pocandcleanroomare private; they keep their repo-levelcopies for the same reason
scriptsdoes. Both orgs currently reportplan=team, which would make org-secret delivery to private repos worktoday, but that plan is temporary and nothing should depend on it.
Proposed changes
terminal and naming the reordering that avoids it
orgs/<org>/installationsis non-empty before declaring the transfer done