Repository navigation
infra(git): rename Dev_new_gui to main and main to release, without breaking the live updater #16461
Description
Activity
Found while preparing the rename (not changed): the ruleset named "Main" (rules:
deletion,non_fast_forward) has emptyconditions.ref_name.includeandexclude, so it protects no branch today. Only the classic branch protection on each branch and the "Require review for external contributors" ruleset (refs/heads/Dev_new_gui) actually apply. The rename script re-points only that second ruleset, torefs/heads/main. Whether "Main" should covermainandreleaseagainst deletion and force-push is a separate settings call for the owner, so it's left as it is here.Step 1 done (2026-09-12):
mainis renamed torelease, at b94f51a. Its classic protection (2 required checks) moved with it. No open PR was based on it, and the default branch is stillDev_new_gui. Until the swap PR lands,release.ymland the weekly sync workflow still namemain, so a run in that window would fail harmlessly. Step 2 (Dev_new_gui→main) follows once no merge batch is in flight.- added a commit that references this issue
on Sep 12, 2026 Step 6 needs one more action than planned (found 2026-09-12, read-only). The live updater takes its branch from the active CodeSource record (
git_tracker._get_active_code_source_config()readssource.branch). It falls back to theSLM_REPO_BRANCHdefault only when no record exists. The live record saysbranch=Dev_new_gui, active, at 4a7e76e. So shipping #16487's new defaults alone leaves production tracking theDev_new_guimirror, and deleting the mirror afterwards would silently freeze production updates.Corrected step 6:
- After chore(git): rename Dev_new_gui to main and main to release across the repo (#16479) #16487 lands and the mirror carries it, set the active CodeSource
branchtomainthrough the product's own admin API (POST /api/code-source/assign, same repository and node). Never edit the database directly. - Run one update through the builtin updater, and confirm on the host that it fetched
mainand deployed its head. - Only then delete the mirror branch, its workflow, and the "kept for the mirror" entries (the listed files plus the push-protection hook).
- After chore(git): rename Dev_new_gui to main and main to release across the repo (#16479) #16487 lands and the mirror carries it, set the active CodeSource
Owner decision, 2026-09-12: the coordinator switches the active CodeSource record to
mainthrough the admin API (POST /api/code-source/assign, same repository and node) after #16487 lands and the mirror carries it. Then it runs one update through the builtin updater and verifies on the host before the mirror is removed.Step 6 progress (2026-09-12): the owner switched the active CodeSource
branchtomainin the SLM settings. The record now readsbranch=main, active, at 4a7e76e, and the updater followsmaindirectly. Remaining: after #16487 lands, run one update through the builtin updater (refresh, then update-all), and verify on the host that the deployed commit equalsmain's head. The playbook runner'sAUTOBOT_GIT_BRANCHdefault staysDev_new_guiuntil #16487's code is deployed, so only after that verification are the mirror branch, its workflow and the "kept for the mirror" entries removed.One more dependency before the mirror is deleted: the local main checkout on the host is still on its local
Dev_new_guibranch. Its periodic refresh runsgit pull --tags origin Dev_new_gui, visible in its reflog every few hours, and it currently works through the mirror. Before the mirror goes, that refresh and the checkout's upstream have to trackorigin/main, or the checkout silently stops updating. Adding this to the mirror-removal checklist, alongside the playbook runner'sAUTOBOT_GIT_BRANCHdefault (fixed once #16487 deploys) and the "kept for the mirror" entries.Mirror-removal checklist additions (found 2026-09-12):
- Local worktree tooling: the refresh, reap, claim and parked-drain scripts pick their base from a candidate list that starts with
Dev_new_gui, thendevelop,main,master. While the mirror exists they track it, which equalsmain. After the mirror is deleted they fall through tomain, but only once the staleorigin/Dev_new_guiremote-tracking ref is pruned. A frozen ref would otherwise stay first in the list. So after deleting the mirror, rungit fetch --prune, or better, putmainfirst in those candidate lists beforehand. - The host's main checkout: it sits on a local
Dev_new_guibranch trackingorigin/Dev_new_gui, and its periodicgit pull --tags origin Dev_new_guilooks like an IDE sync. Switch it tomain(trackingorigin/main) before the mirror is removed. That's the owner's working copy, so it's the owner's step. origin/HEADalready resolves torefs/remotes/origin/main.
- Local worktree tooling: the refresh, reap, claim and parked-drain scripts pick their base from a candidate list that starts with
The mirror-removal checklist, extended after a link sweep. Things that break the moment the
Dev_new_guimirror is deleted:What Today After the mirror is deleted Tracked by install.shDEFAULT_BRANCH="Dev_new_gui"(also still on the #16487 head)clones the mirror every fresh install fails at git clone -b. The published one-liners fetchraw/.../main/install.sh, and raw URLs are never redirected#16482 AC1. It must land before deletion docs/_config.ymlfooterblob/Dev_new_gui/LICENSEresolves to the mirror 404, or a redirect (see below) #16482 AC1 github-pagesenvironment branch policy listsDev_new_guiandmainstale entry, harmless dead policy entry add: remove the Dev_new_guientry at deletionPages sourcefield readsDev_new_gui:/docsinert, since build_type=workflowandpages.ymltriggers onmainon the #16487 headstill inert, but misleading add: set it to mainat deletionWiki Development-Guidesteps 1 and 4 ("branch from / targetDev_new_gui(notmain)")wrong since the rename wrong fixed locally. The push to the wiki's masteris refused by the branch-protection hook, so this is for the owner (two lines, web editor)On links in general: GitHub redirects web URLs for a renamed branch, but raw file URLs aren't redirected (GitHub docs, "Renaming a branch"). While the mirror exists, old
tree/andblob/links resolve to the mirror itself. The docs don't say whether the rename redirect comes back once a same-named branch is deleted, so the first check after deletion is one oldtree/Dev_new_guiURL.The installer one-liners that name
mainkeep their meaning: the oldmaincopy ofinstall.shclonedDev_new_guianyway, so they always installed the working line, andmainis now that line.Local clone on the dev machine switched to the new names. The old local
main(the release line) was verified to be contained inorigin/releasebefore being renamed torelease, trackingorigin/release.Dev_new_guibecamemain, trackingorigin/main, andorigin/HEADismain. The main checkout is now onmain. The hook rules keyed on the current branch already treatedmainlikeDev_new_gui(no bare push, no checking out the protected branch in the main tree), so no session's behaviour changes. That removes the "the main checkout switches tomain" item from the mirror-removal checklist. The main tree's hooks still carry pre-#16487 text until it fast-forwards after #16487 lands.- added a commit that references this issue
on Sep 12, 2026 Mirror-removal note: the temporary
Dev_new_guimirror has no branch protection. The classic protection API returns 404, and no ruleset targets it.mainkept the classic protection through the rename (10 required contexts, no force-push, no deletion), andreleaseis protected. While a deployment still tracks the mirror, a direct push or force-push to it would deploy without any required check. Switching the deployment to trackmaincloses this. Until then, nothing but the mirror-sync workflow should write toDev_new_gui, and it comes off the checklist when the mirror is deleted.- added a commit that references this issue
on Sep 13, 2026 Removal condition: everything in this repository already points at
main. One check remains, and it is outside the repo.mirror-main-to-legacy-dev-branch.ymlstates its own exit criterion:Remove this workflow, and the
Dev_new_guibranch it mirrors, once production is confirmed tracking
main(#16461).Here is the evidence gathered against that condition on 2026-09-17, and the one thing it does not settle.
What is established
Every branch default in the codebase is already
main:autobot-backend/api/branch_health.py:38,68,102,137 base_branch: str = "main" autobot-backend/api/marketplace.py:78 getattr(config, "GITHUB_DEFAULT_BRANCH", "main") autobot-backend/api/codebase_analytics/source_service.py:64 branch: str = "main"Outside docs, changelogs and workflows, only four tracked files mention
Dev_new_guiat all, and
none is the production updater:autobot_shared/user_management/models/core_test.py (test fixture) repo_tests/parked_branch_merge_workflow_test.py (tests the mirror workflow itself) pipeline-scripts/release_sync_main.py (release tooling) scripts/cleanup-worktrees.sh (worktree cleanup)No updater branch configuration names it. Searches for
CODE_SYNC_BRANCH,UPDATE_BRANCH,
GIT_BRANCHandcode_sync_branchacrossautobot-backend/services,autobot-backend/api,
autobot_shared, the SSOT config and the infrastructure config return nothing pointing at
Dev_new_gui.The deployed tree is not a git checkout.
/opt/autobotexists on this host and
git -C /opt/autobot rev-parse --abbrev-ref HEADreports "not a git repository". So production is
not a clone tracking a branch, and "which branch does production track" cannot be answered by
inspecting it as one.The mirror itself is healthy, not stale:
Dev_new_guisits at59868efe4, byte-identical to
main, 0 ahead and 0 behind, fast-forwarded on every push by the workflow above. It is the only branch
in the repository that was already in sync when the other 81 were not — which is exactly why it keeps
appearing in branch listings and looking like leftover debris when it is not.What is NOT established
Whether the deployed updater still fetches
Dev_new_gui. The workflow's justification — "the live
production updater ... still fetchesDev_new_guiuntil it is switched over" — is not supported by
anything findable in this repository. Two readings fit the evidence equally:- The updater's branch lives in deployed configuration outside the repo (the code-sync settings
reachable from the maintenance UI), and still names the old branch. - That dependency is already stale, and the mirror has been running for nothing.
I am not concluding either. Getting this wrong in the permissive direction breaks the live code-sync
path, and the difference is not visible from the codebase.The single check that settles it
What branch the deployed updater is configured to fetch, read from its deployed configuration or
the code-sync settings in the maintenance UI. That is host state, not repository state, so it needs
someone with host access — it is not something a diff can answer, in the same way #16310's and
#16427's host-evidence criteria are not.If that check says
main, these go togetherRemoving the branch alone would break the mirror workflow and leave five workflows special-casing a
name that no longer exists. The full set:- the
Dev_new_guibranch itself .github/workflows/mirror-main-to-legacy-dev-branch.yml(delete — its whole purpose ends)- exclusions in
auto-merge-base-into-parked-branches.ymlandauto-update-pr-branches.yml - references in
branch-cleanup.yml,dependabot-retarget.yml,stale-branches-warning.yml,
branch-health-report.yml,codeql.yml repo_tests/parked_branch_merge_workflow_test.py, which asserts the exclusion exists and will fail
correctly when it is removed — that test is the guard proving the cleanup was complete, so it should
be updated rather than deletedscripts/cleanup-worktrees.shandpipeline-scripts/release_sync_main.py
Worth doing as one PR: a partial removal leaves the tree in a state where the branch is gone and the
guards still expect it.- The updater's branch lives in deployed configuration outside the repo (the code-sync settings
Status sweep against current
main. Steps 1–4 are done. Step 5 is further along than the issue body suggests, and the one thing actually blocking closure is host evidence for AC3 — which I could not obtain, for a reason worth recording.What is verified done
Item Evidence on mainDefault branch main, confirmed via the repository APIUpdater default git_tracker.py:35—DEFAULT_BRANCH = os.environ.get("SLM_REPO_BRANCH", "main")Playbook default playbook_executor.py:649—os.getenv("AUTOBOT_GIT_BRANCH", "main")Ansible deploy_refno longer names the old branch anywhere So the code half of step 5's riskiest part — "a bare rename would leave production unable to fetch updates, including the one that fixes it" — is landed. The defaults point at
main.What the remaining references actually are
The count is down from 699 in 268 files to 83 files. Categorised, because the raw number is misleading:
Category Files Should they change? Workflows 8 No, not yet Tooling / hooks 4 No, not yet Code 3 No — historical statements of fact Live docs 55 Yes, drift Changelogs / archived analysis 13 Never — historical record Nearly every functional reference is deliberate and protective, not drift. They name the old branch in order to defend it — push guards, deletion filters, never-target lists — and each carries a comment of the form
temporary mirror of main for the live updater; remove with #16461. Examples:block-dangerous-commands.sh:56-62,branch-cleanup.yml:88,156,stale-branches-warning.yml:88,auto-merge-base-into-parked-branches.yml:96,cleanup-worktrees.sh:161,202,237,parked_branch_merge_workflow_test.py:38.So AC2 and AC4 are coupled and cannot be done in either order independently. Removing those references while the mirror branch still exists would expose it to the very cleanup jobs that currently skip it. They come out in the same change that deletes the branch and the mirror workflow — not before.
The three code references are correct as they stand and should not be rewritten:
core_test.py:15,37andrelease_sync_main.py:10state where a measurement was taken and what the historical split was. Rewriting those would falsify a record.One genuine stale comment:
codeql.yml:27describes advanced-setup uploads landing "on Dev_new_gui" — that is now justmain, and is safe to fix independently of the mirror.The blocker: AC3 cannot be verified from the filesystem
AC3 requires production to be confirmed updating from
main, on the host. I could not determine which branch the live system tracks, and I am recording that rather than inferring it.The live install is not a git checkout —
rev-parsefinds no repository at the install root, and the code-source tree the updater maintains has no branch, no upstream and no remote refs either. The sync copies files rather than cloning, so the source branch is simply not represented on disk. I found no sync metadata recording it.That is a gap in the evidence path, not necessarily a defect: the code defaults say
main, and the mirror is fast-forwarded on every push, so a host still fetching the old name would keep working and look identical from outside. Which is exactly why this needs positive confirmation rather than absence of a symptom — the bridge is designed to make the two cases indistinguishable.One observation, offered as a fact and not a diagnosis: the code-source tree was last modified 2026-09-14, three days before this sweep.
What would close AC3: a reading from the updater's own state — the code-sync API's record of the ref it last pulled, or the SLM's git-tracker service reporting its configured branch — rather than anything inspectable on disk. Whoever has that surface should paste it here.
Then, and only then, in one change: delete the mirror branch and
mirror-main-to-legacy-dev-branch.yml, strip the ~12 protective references together, fix thecodeql.ymlcomment, and sweep the 55 docs.A suggestion for AC3's own sake
If the updater cannot currently report the ref it synced from, that is worth its own issue regardless of this rename. An update mechanism whose source ref is unobservable after the fact makes every future "is production actually on X?" question unanswerable the same way this one was.
Triage: the rename itself is done; the issue stays open for a real, tracked reason unrelated to the candidate branch
The single candidate branch,
issue-16461-branch-rename, is 1630 files / -119k lines off currentorigin/main— an ancient snapshot from before this rollout, not a plausible source for anything still needed. Not reviving it.What's actually still open, confirmed by reading, not assumed from the issue staying open:
mainis already the live default/primary branch (confirmed independently — this session's own git context already reportsmainas current and default). What remains is explicit and self-documenting:.github/workflows/mirror-main-to-legacy-dev-branch.ymlfast-forwards a temporary legacyDev_new_guibranch on every push tomain, because "the live production updater still fetchesDev_new_guiuntil it is switched over." Its own header says exactly what closes this issue: "Remove this workflow, and theDev_new_guibranch it mirrors, once production is confirmed trackingmain." 7 more workflow files carry the same# Dev_new_gui: ... remove with #16461marker, all pointing at the same single remaining condition.This is a production-verification task (does the live updater actually pull
mainnow), not a code change and not something any branch here can carry — no repo branch triages it away. Leaving the issue open is correct; the candidate branch is dead weight regardless. Not recommending closure here, unlike #15933/#15306 — this one genuinely isn't done yet, just not blocked on anything a branch-freeze sweep can fix.Premise count has moved — the defect is live, the number is stale. Measured against
origin/mainduring the v0.10.0 full-coverage triage (#17863).This issue states 699 mentions across 268 files Measured now 83 files Counted with
git grep -c Dev_new_gui origin/main. The in-repo swap and the mirror workflow have landed; the mirror removal and the production-updater step are host or GitHub state and not checkable from the tree.The number gets re-pinned in the same change that does the work, not before it and not separately. Re-pinning first makes the issue look edited to fit the work; leaving it makes an acceptance criterion that fails on its own terms. This is
docs/developer/RATCHET_BASELINES.mddiscipline applied to an issue body rather than a baseline file.Nothing else about this issue is changed by the recount — it is still open and still live.
Owner decision, 2026-09-12: follow standard branch naming.
Dev_new_guibecomesmain(the working and default branch), and the currentmainbecomesrelease. Scheduled to run after merge batch #16438 lands.Inventory (base at the time of filing)
Dev_new_guiappears 699 times in 268 files. 155 are executable or config files, including 54 workflows,.github/dependabot.yml,.pre-commit-config.yaml,.claude/hooks/,tools/git-hooks/andscripts/.The live update path fetches the branch by name:
autobot-slm-backend/services/git_tracker.py(SLM_REPO_BRANCH, defaultDev_new_gui)autobot-slm-backend/services/playbook_executor.py(AUTOBOT_GIT_BRANCH, defaultDev_new_gui)deploy_ref: "Dev_new_gui"inpre-flight-code-sync.yml,provision-fleet-roles.ymlandupdate-all-nodes.ymlA bare rename would leave production unable to fetch updates, including the one that fixes it.
The release flow targets
mainby name:release.yml(gh pr create --base main) andsync-main-to-dev.yml(--source Dev_new_gui --base main).Rulesets: "Require review for external contributors" includes
refs/heads/Dev_new_guiexplicitly. Classic protection exists on both branches (main: 2 required checks,Dev_new_gui: 10).Pages deploys from
Dev_new_gui/docs, and dependabot's 6 package configs targetDev_new_gui.Plan
main→release. GitHub retargets PRs based on it and moves its classic protection.Dev_new_gui→main. GitHub retargets the ~55 open PRs; the default branch follows the rename.refs/heads/main. Confirm the classic protection moved with both renames, and thatreleasekeeps its protection.Dev_new_guibranch mirroringmain, fast-forwarded by a workflow on every push tomain, so the live updater and in-flight sessions keep working. Its removal is tracked here.mainreplacing the branch names across the repo:Dev_new_guibecomesmain, and oldmain(in release contexts) becomesrelease, as a swap and never a blind replace.main.main→release.main; the Pages source moves tomain.CLAUDE.mdand the docs are updated.main, then delete the mirror branch and its workflow.Acceptance criteria
mainis the working and default branch, andreleaseis the release branch. Protection and rulesets are equivalent to before, under the new names.Dev_new_gui. Oldmainrelease references namerelease.main, verified on the host.Dev_new_guimirror and its workflow are removed.main.