⚠ GitHub case-variant repos share storage on disk
Severity: critical Lesson date: 2026-06-22 Status: active (5 case-variant pairs deleted 2026-06-22 23:53; both casings 404; canonicals of the deleted pairs unknown without operator confirmation)
What happened
Helper executed 5 DELETE /repos/<owner>/<name> calls on case-variant dups. All returned 204. Both casings of all 5 pairs return 404 after. The canonicals of those pairs (assumed keepers) — FreshvibeUI, FreshVibe-Gallery, Home-studio, DominicsTasks, freshcards — are also gone.
The case-variant trap (per memory 2026-06-22): "Pushing a file to avidtech6/freshvibeui instantly makes it appear in avidtech6/FreshvibeUI. They are the same repo, only the URL casing differs." If true, deleting either casing deletes the underlying storage. Both URLs go 404.
The lesson: the case-variant trap is more dangerous than first thought. It means you cannot tombstone case-variants via content (tombstone hits both casings). You cannot delete them via API without potentially nuking the canonical too.
The rule
For case-variant repo pairs:
- Never delete via API without first verifying the canonical has no real content. Use
GET /repos/<owner>/<name>and inspect the contents tree. - Never tombstone via README/commit. Per the case-variant trap, the change hits both casings, including the canonical.
- Document the canonical case in memory + every project's AGENTS.md. Make it explicit which casing is the keeper.
- The dup is harmless as long as the canonical is always linked with the canonical case. If both URLs are referenced, dup users will be redirected on push.
- To actually clean up dups, the operator must use a fine-grained PAT with
Administration: Delete repositories(or web UI). Classic PATs cannot delete.
For ALL destructive GitHub ops:
- Inspect before delete. 30 seconds that prevents disasters.
- Never trust memory about repo contents. Verify with API.
- For destructive ops, get explicit "yes I have verified the target is safe to delete" from operator.
How to check before acting on a case-variant pair
- [ ] GET both casings — does each return 200 with the same head SHA + size? If yes, they're truly aliases.
- [ ] Inspect the canonical's contents — does it have real code, or is it a placeholder README?
- [ ] Check the dup's contents — is it a placeholder, or real code that happens to mirror the canonical?
- [ ] Confirm the canonical exists — if both casings are 404, the pair is already cleaned up; no action needed.
- [ ] If the pair is alive, ask: is the dup actually causing harm? (Drive-by clones, search confusion, etc.) If not, leave alone.
If you already did the wrong thing
- Stop and assess. The repos are gone. Reverting is not trivial.
- Contact GitHub support if the canonical had real code: https://support.github.com/contact
- Reference the repo + commit SHAs you remember
- GitHub's restore window for private repos is short (a few hours typically)
- Document the loss in a
decisions/D-XXX-...file with date, repos affected, and what was lost. - Update memory + the open-questions list so the next Mavis session knows about the loss.
Cross-references
- D-057 — Case-variant repo trap (the lesson that should have prevented this)
- D-059 — Inspect-before-delete protocol (the follow-up rule)
- Report: 2026-06-22-dup-cleanup — the full incident report
- Memory: 2026-06-22 case-variant-dup-trap entry — the original finding