Skip to content

infra(git): rename Dev_new_gui to main and main to release, without breaking the live updater #16461

Description

@mrveiss

Owner decision, 2026-09-12: follow standard branch naming. Dev_new_gui becomes main (the working and default branch), and the current main becomes release. Scheduled to run after merge batch #16438 lands.

Inventory (base at the time of filing)

  • Dev_new_gui appears 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/ and scripts/.

  • The live update path fetches the branch by name:

    • autobot-slm-backend/services/git_tracker.py (SLM_REPO_BRANCH, default Dev_new_gui)
    • autobot-slm-backend/services/playbook_executor.py (AUTOBOT_GIT_BRANCH, default Dev_new_gui)
    • deploy_ref: "Dev_new_gui" in pre-flight-code-sync.yml, provision-fleet-roles.yml and update-all-nodes.yml

    A bare rename would leave production unable to fetch updates, including the one that fixes it.

  • The release flow targets main by name: release.yml (gh pr create --base main) and sync-main-to-dev.yml (--source Dev_new_gui --base main).

  • Rulesets: "Require review for external contributors" includes refs/heads/Dev_new_gui explicitly. 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 target Dev_new_gui.

Plan

  1. Rename main → release. GitHub retargets PRs based on it and moves its classic protection.
  2. Rename Dev_new_gui → main. GitHub retargets the ~55 open PRs; the default branch follows the rename.
  3. Point the review ruleset at refs/heads/main. Confirm the classic protection moved with both renames, and that release keeps its protection.
  4. Bridge: create a temporary Dev_new_gui branch mirroring main, fast-forwarded by a workflow on every push to main, so the live updater and in-flight sessions keep working. Its removal is tracked here.
  5. One PR on main replacing the branch names across the repo:
    • Old Dev_new_gui becomes main, and old main (in release contexts) becomes release, as a swap and never a blind replace.
    • The updater and playbook defaults move to main.
    • The release flow becomes main → release.
    • dependabot targets main; the Pages source moves to main.
    • CLAUDE.md and the docs are updated.
  6. Update production through the builtin updater (still fetching the mirror, so it receives the new defaults). Confirm the live system tracks main, then delete the mirror branch and its workflow.

Acceptance criteria

  • main is the working and default branch, and release is the release branch. Protection and rulesets are equivalent to before, under the new names.
  • No workflow, script, hook, config or code default names Dev_new_gui. Old main release references name release.
  • Production updates through the builtin updater from main, verified on the host.
  • The temporary Dev_new_gui mirror and its workflow are removed.
  • Every open PR targets main.

Activity

  1. added this to the v0.9.0 milestone on Sep 12, 2026
  2. self-assigned this
    on Sep 12, 2026
  3. mrveiss commented on Sep 12, 2026

    @mrveiss
    OwnerAuthor

    Found while preparing the rename (not changed): the ruleset named "Main" (rules: deletion, non_fast_forward) has empty conditions.ref_name.include and exclude, 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, to refs/heads/main. Whether "Main" should cover main and release against deletion and force-push is a separate settings call for the owner, so it's left as it is here.

  4. mrveiss commented on Sep 12, 2026

    @mrveiss
    OwnerAuthor

    Step 1 done (2026-09-12): main is renamed to release, at b94f51a. Its classic protection (2 required checks) moved with it. No open PR was based on it, and the default branch is still Dev_new_gui. Until the swap PR lands, release.yml and the weekly sync workflow still name main, so a run in that window would fail harmlessly. Step 2 (Dev_new_gui → main) follows once no merge batch is in flight.

  5. mrveiss commented on Sep 12, 2026

    @mrveiss
    OwnerAuthor

    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() reads source.branch). It falls back to the SLM_REPO_BRANCH default only when no record exists. The live record says branch=Dev_new_gui, active, at 4a7e76e. So shipping #16487's new defaults alone leaves production tracking the Dev_new_gui mirror, and deleting the mirror afterwards would silently freeze production updates.

    Corrected step 6:

    1. 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 branch to main through the product's own admin API (POST /api/code-source/assign, same repository and node). Never edit the database directly.
    2. Run one update through the builtin updater, and confirm on the host that it fetched main and deployed its head.
    3. Only then delete the mirror branch, its workflow, and the "kept for the mirror" entries (the listed files plus the push-protection hook).
  6. mrveiss commented on Sep 12, 2026

    @mrveiss
    OwnerAuthor

    Owner decision, 2026-09-12: the coordinator switches the active CodeSource record to main through 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.

  7. mrveiss commented on Sep 12, 2026

    @mrveiss
    OwnerAuthor

    Step 6 progress (2026-09-12): the owner switched the active CodeSource branch to main in the SLM settings. The record now reads branch=main, active, at 4a7e76e, and the updater follows main directly. Remaining: after #16487 lands, run one update through the builtin updater (refresh, then update-all), and verify on the host that the deployed commit equals main's head. The playbook runner's AUTOBOT_GIT_BRANCH default stays Dev_new_gui until #16487's code is deployed, so only after that verification are the mirror branch, its workflow and the "kept for the mirror" entries removed.

  8. mrveiss commented on Sep 12, 2026

    @mrveiss
    OwnerAuthor

    One more dependency before the mirror is deleted: the local main checkout on the host is still on its local Dev_new_gui branch. Its periodic refresh runs git 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 track origin/main, or the checkout silently stops updating. Adding this to the mirror-removal checklist, alongside the playbook runner's AUTOBOT_GIT_BRANCH default (fixed once #16487 deploys) and the "kept for the mirror" entries.

  9. mrveiss commented on Sep 12, 2026

    @mrveiss
    OwnerAuthor

    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, then develop, main, master. While the mirror exists they track it, which equals main. After the mirror is deleted they fall through to main, but only once the stale origin/Dev_new_gui remote-tracking ref is pruned. A frozen ref would otherwise stay first in the list. So after deleting the mirror, run git fetch --prune, or better, put main first in those candidate lists beforehand.
    • The host's main checkout: it sits on a local Dev_new_gui branch tracking origin/Dev_new_gui, and its periodic git pull --tags origin Dev_new_gui looks like an IDE sync. Switch it to main (tracking origin/main) before the mirror is removed. That's the owner's working copy, so it's the owner's step.
    • origin/HEAD already resolves to refs/remotes/origin/main.
  10. mrveiss commented on Sep 12, 2026

    @mrveiss
    OwnerAuthor

    The mirror-removal checklist, extended after a link sweep. Things that break the moment the Dev_new_gui mirror is deleted:

    What Today After the mirror is deleted Tracked by
    install.sh DEFAULT_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 fetch raw/.../main/install.sh, and raw URLs are never redirected #16482 AC1. It must land before deletion
    docs/_config.yml footer blob/Dev_new_gui/LICENSE resolves to the mirror 404, or a redirect (see below) #16482 AC1
    github-pages environment branch policy lists Dev_new_gui and main stale entry, harmless dead policy entry add: remove the Dev_new_gui entry at deletion
    Pages source field reads Dev_new_gui:/docs inert, since build_type=workflow and pages.yml triggers on main on the #16487 head still inert, but misleading add: set it to main at deletion
    Wiki Development-Guide steps 1 and 4 ("branch from / target Dev_new_gui (not main)") wrong since the rename wrong fixed locally. The push to the wiki's master is 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/ and blob/ 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 old tree/Dev_new_gui URL.

    The installer one-liners that name main keep their meaning: the old main copy of install.sh cloned Dev_new_gui anyway, so they always installed the working line, and main is now that line.

  11. mrveiss commented on Sep 12, 2026

    @mrveiss
    OwnerAuthor

    Local clone on the dev machine switched to the new names. The old local main (the release line) was verified to be contained in origin/release before being renamed to release, tracking origin/release. Dev_new_gui became main, tracking origin/main, and origin/HEAD is main. The main checkout is now on main. The hook rules keyed on the current branch already treated main like Dev_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 to main" item from the mirror-removal checklist. The main tree's hooks still carry pre-#16487 text until it fast-forwards after #16487 lands.

  12. mrveiss commented on Sep 13, 2026

    @mrveiss
    OwnerAuthor

    Mirror-removal note: the temporary Dev_new_gui mirror has no branch protection. The classic protection API returns 404, and no ruleset targets it. main kept the classic protection through the rename (10 required contexts, no force-push, no deletion), and release is 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 track main closes this. Until then, nothing but the mirror-sync workflow should write to Dev_new_gui, and it comes off the checklist when the mirror is deleted.

  13. mrveiss commented on Sep 17, 2026

    @mrveiss
    OwnerAuthor

    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.yml states its own exit criterion:

    Remove this workflow, and the Dev_new_gui branch 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_gui at 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_BRANCH and code_sync_branch across autobot-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/autobot exists on this host and
    git -C /opt/autobot rev-parse --abbrev-ref HEAD reports "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_gui sits at 59868efe4, 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 fetches Dev_new_gui until it is switched over"
    — is not supported by
    anything findable in this repository. Two readings fit the evidence equally:

    1. 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.
    2. 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 together

    Removing 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_gui branch itself
    • .github/workflows/mirror-main-to-legacy-dev-branch.yml (delete — its whole purpose ends)
    • exclusions in auto-merge-base-into-parked-branches.yml and auto-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 deleted
    • scripts/cleanup-worktrees.sh and pipeline-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.

  14. modified the milestones: v0.9.0, v0.10.0 on Sep 17, 2026
  15. mrveiss commented on Sep 17, 2026

    @mrveiss
    OwnerAuthor

    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 main
    Default branch main, confirmed via the repository API
    Updater 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_ref no 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,37 and release_sync_main.py:10 state where a measurement was taken and what the historical split was. Rewriting those would falsify a record.

    One genuine stale comment: codeql.yml:27 describes advanced-setup uploads landing "on Dev_new_gui" — that is now just main, 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-parse finds 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 the codeql.yml comment, 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.

  16. mrveiss commented on Sep 20, 2026

    @mrveiss
    OwnerAuthor

    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 current origin/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: main is already the live default/primary branch (confirmed independently — this session's own git context already reports main as current and default). What remains is explicit and self-documenting: .github/workflows/mirror-main-to-legacy-dev-branch.yml fast-forwards a temporary legacy Dev_new_gui branch on every push to main, because "the live production updater still fetches Dev_new_gui until it is switched over." Its own header says exactly what closes this issue: "Remove this workflow, and the Dev_new_gui branch it mirrors, once production is confirmed tracking main." 7 more workflow files carry the same # Dev_new_gui: ... remove with #16461 marker, all pointing at the same single remaining condition.

    This is a production-verification task (does the live updater actually pull main now), 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.

  17. mrveiss commented on Oct 2, 2026

    @mrveiss
    OwnerAuthor

    Premise count has moved — the defect is live, the number is stale. Measured against origin/main during 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.md discipline 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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Projects

No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions