Twinned from https://github.com/cfsh/ninefold/issues/795 by tools/beads/import_github.py's reconcile pass.
Filed unclaimed by nf-dev-rev-pass-gate after hitting it on #786/#788. Not claimed, not labelled.
merge_pr.py owns the worktree for the minutes it runs: it checks out the PR head to run the presubmit, and after the merge it syncs local main with a git reset --hard. That reset lands on whatever branch is checked out at that moment — not necessarily the one it started on.
So a session that runs merge_pr.py <n> in the background (which CLAUDE.md effectively requires — *"⏱ It takes minutes … a 2-minute timeout kills the gate after the merge landed"*) and then does anything with git switch in the same worktree gets that other branch hard-reset to main.
Measured here, 2026-08-10:
``` 03:41:30 checkout: moving from feat/rev-pass-gate to chore/delete-dispatcher-cron (at fec4b99) 03:42:11 reset: moving to origin/main → 007a63a ```
chore/delete-dispatcher-cron — the branch behind open PR #788 — lost nine commits from its ref, including one that had never been pushed. The post-merge UI gate then reported itself as UI gate: chore/delete-dispatcher-cron @ 007a63a, naming a branch that had nothing to do with the merge.
origin had the rest, so nothing was actually lost. But the symptom is a branch that silently *looks* like main — no error, no warning, and git status reads clean. I found it because @aedanpope said *"I don't see the new commit on 788"*.mergeable=UNKNOWN, on an unclean ledger, on unresolved threads. Every one of those protects something smaller than "an unrelated branch's commits".git rev-parse --abbrev-ref HEAD at the start and refuse to reset if HEAD moved. Three lines, and it converts silent damage into an informative refusal — the shape the rest of the file already uses. It cannot fix a branch switched *and* switched back, but that is not the realistic case.git fetch origin main:main updates local main without touching the working tree at all, and is what the sync actually wants. Needs care when main *is* checked out.notes/merging.md — necessary either way, and not sufficient on its own.⚠️ Note the interaction with EXIT-trap restore: the tool restores the branch it checked out for the presubmit, which is why the hazard is specifically the *post-merge sync* and not the presubmit stage.
None.
No comments.