# Forgejo Cutover Rollback Runbook Date: 2026-07-09 Workplan: `RAIL-HO-WP-0005-T11` / `T12` Canon: `the-custodian/docs/forgejo-tier3-remote-url-sweep-playbook.md`, `the-custodian/docs/forgejo-production-decisions.md` § T12 ## Current production state (post-T11) | Layer | Canonical | Fallback | | --- | --- | --- | | Git forge | `forgejo.coulomb.social` (`forgejo-remote`) | `gitea.coulomb.social` (archived, read-only) | | State Hub `remote_url` | `forgejo-remote:coulomb/.git` | — | | Workstation `origin` | `forgejo-remote:coulomb/.git` | `gitea` legacy remote retained | | ArgoCD (coulombcore) | `https://forgejo.coulomb.social/coulomb/*.git` | Gitea URLs in AppProject allow-list for emergency | Gitea safety contract (T12 Option A, 2026-07-09): **no repo deletes** for **30 days** after cutover (2026-07-08 → rollback window ends **2026-08-07**). coulombcore Gitea Helm retained as read-only fallback. Archived repos remain cloneable; pushes are rejected. Revisit Helm retirement after **2026-08-07**. ## Per-repo git rollback When a single repo must revert to Gitea as canonical: ```bash cd ~/ git remote rename origin forgejo git remote rename gitea origin git fetch origin git status # confirm tracking branch ``` Optional: re-mirror last known-good Forgejo SHA to Gitea (requires temporarily un-archiving the repo via Gitea admin API — operator only). ## State Hub rollback ```bash SLUG= API=http://127.0.0.1:8000 curl -s -X PATCH "${API}/repos/${SLUG}" \ -H "Content-Type: application/json" \ -d '{"remote_url": "gitea-remote:coulomb/'"${SLUG}"'.git"}' | python3 -m json.tool statehub fix-consistency --repo "${SLUG}" ``` ## ArgoCD rollback (coulombcore) Re-point the affected `Application` `spec.source.repoURL` to Gitea, or re-apply a known-good manifest: ```bash cd ~/railiance-platform KUBECONFIG=~/.kube/config kubectl apply -f argocd/applications/.application.yaml ``` AppProjects `railiance-tenants` and `railiance-platform-addons` retain Gitea URLs in `sourceRepos` for emergency rollback. ## Gitea read-only reversal (operator) To allow pushes again on a Gitea repo (rollback window only): ```bash # Un-archive one repo source ~/.railiance_gitea.conf curl -sS -X PATCH -H "Authorization: token ${GITEA_TOKEN}" \ -H "Content-Type: application/json" \ -d '{"archived":false}' \ "https://gitea.coulomb.social/api/v1/repos/coulomb/" ``` Org-wide un-archive: `the-custodian/tools/gitea-set-readonly.sh` inverted patch — use only with explicit operator approval. ## Verification after rollback - [ ] `git push origin main` succeeds on Gitea - [ ] State Hub `remote_url` matches `gitea-remote:coulomb/.git` - [ ] `statehub fix-consistency --repo ` → PASS - [ ] Dependent CI/deploy paths re-tested ## Emergency org-wide freeze (not primary plan) If staged drift is unacceptable, invoke org-wide freeze per `the-custodian/docs/forgejo-production-decisions.md` § Cutover Option A fallback. Document the decision via State Hub `POST /decisions/` before executing. ## References - `docs/forgejo-migration-inventory.md` - `the-custodian/tools/gitea-set-readonly.sh` - `the-custodian/tools/patch-forgejo-remote-urls.sh` - `railiance-enablement/tools/promote-repo-to-forgejo.sh`