fix: recover safe fleet sync drift#111
Merged
Merged
Conversation
A pooled clone that drifts off its default branch was silently skipped forever by both the post-merge teardown sync and bootstrap fleet-sync, falling further behind on every merge with only an easy-to-miss skip line. - Auto-recover the one safe case: a clean, detached HEAD that is an ancestor of origin/<default> and whose <default> is free to check out is re-attached and fast-forwarded, reported as 'recovered:'. - Every other off-default state (dirty, non-default named branch, detached with unique commits, diverged) is left untouched and reported as a quantified 'STUCK: ... N commits behind ... - needs attention' warning instead of a quiet drift. Nothing is forced, stashed, or discarded. - Relay the new recovered:/STUCK: outcomes through bootstrap FLEET_SYNC lines; document both in AGENTS.md section 3. - Add tests/fm-fleet-sync.test.sh covering recover, every stuck variant, ordinary fast-forward, already-current, local-only/no-origin skips, the whole-fleet form, and the bootstrap relay.
9e9efd9 to
8d89ec2
Compare
leo1oel
added a commit
to leo1oel/nemo
that referenced
this pull request
Jun 29, 2026
…nes (#14) Port upstream kunchenguid#111 to the herdr fork. A pooled clone that drifted off its default branch was silently skipped forever by the per-spawn and post-merge teardown syncs, falling further behind on every merge with only an easy-to-miss skip line. - Auto-recover the one safe case: a clean, detached HEAD that is an ancestor of origin/<default> and whose <default> is free to check out is re-attached and fast-forwarded, reported as 'recovered:'. Re-attaching to an already-published commit strands nothing. - Every other off-default state (dirty, non-default named branch, detached with unique commits, diverged, or <default> checked out in another worktree) is left untouched and reported as a quantified 'STUCK: ... N commits behind ... - needs attention' warning instead of a quiet drift. Nothing is forced, stashed, or discarded. Also align fm-fleet-sync.sh with the rest of the fork's FM_HOME contract (AGENTS.md section 2): it now resolves projects/ from FM_HOME (honoring FM_ROOT_OVERRIDE for bin/), matching fm-project-mode.sh and fm-guard.sh, so a secondmate home syncs its own clones rather than the primary's. This was a latent bug; the new whole-fleet test exercises it. Wire the recovered:/STUCK: outcomes into AGENTS.md (prime-directive fleet-sync exception, teardown, layout) and the docs. Upstream's bootstrap FLEET_SYNC relay has no analogue here: this fork has no fm-bootstrap; fleet-sync output flows through fm-spawn and fm-teardown directly. Add tests/fm-fleet-sync.test.sh (11 cases, self-contained per the fork's harness convention): recover, every stuck variant, ordinary fast-forward, already-current, local-only/no-origin benign skips, and the whole-fleet form. Upstream's bootstrap-relay case is dropped (N/A).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Intent
Close a real gap in firstmate's project-clone syncing: a pooled clone that drifts off its default branch was silently skipped forever by both the post-merge teardown sync and the bootstrap fleet-sync, so it fell further behind on every merge with only an easy-to-miss 'skipped' line (a live clone left on a detached HEAD by a stray 'git checkout origin/main' sat 17 commits behind, skipped on every bootstrap).
The change is to bin/fm-fleet-sync.sh (plus tests and an AGENTS.md section 3 doc update), with two behavioral additions on top of the existing fast-forward-when-safe logic; nothing is ever forced, stashed, or discarded.
Auto-recover the one unambiguously safe drift: in sync_project, when the clone is on a detached HEAD that is NOT the default branch AND the working tree is clean AND the detached HEAD is an ancestor of origin/ (holds no unique commits) AND no other worktree currently has checked out, re-attach with 'git checkout ' and let the existing fast-forward path run. Reported distinctly as ': recovered: re-attached , synced ..'. This is a non-destructive checkout of an already-published commit, so it strands nothing; it exactly self-heals the live 17-behind example.
Keep every unsafe case a skip but make it loud and quantified instead of a quiet drift: a clone that is dirty, on a non-default named branch, detached with unique commits (HEAD not an ancestor of origin/), or diverged is left untouched and reported as ': STUCK: on , N commits behind origin/ - needs attention', with N computed via 'git rev-list --count HEAD..origin/'. A chronically-stuck clone (growing N) is now visibly distinct from a benign one-off skip.
Deliberate decisions and constraints, so the diff does not look surprising:
What Changed
origin/<default>, reattaching them to the default branch before the existing fast-forward path runs.STUCKreports with behind counts instead of quiet skips.recoveredandSTUCKoutcomes through bootstrap, documents the behavior, and adds coverage for safe recovery, unsafe stuck states, whole-fleet sync, and bootstrap reporting.Risk Assessment
✅ Low: Captain, the change is narrowly scoped, keeps unsafe git states read-only, and adds focused coverage for the important detached, dirty, branch, diverged, and bootstrap relay cases.
Testing
Inspected the scoped diff and implementation, ran the focused fleet-sync behavior test, ran every
tests/*.test.shshell test, captured an end-to-end CLI transcript showing safe detached recovery, quantified STUCK warnings, preserved unsafe state, ordinary fast-forward, and bootstrap FLEET_SYNC relay, then confirmed the working tree stayed clean.Evidence: fleet-sync end-to-end CLI transcript
Key excerpt: recover: recovered: re-attached main, synced 0ae3203..09c1b91 unique: STUCK: on detached HEAD with unique commits, 1 commits behind origin/main - needs attention FLEET_SYNC: boot-recover: recovered: re-attached main, synced 057de7a..93f7086 FLEET_SYNC: boot-stuck: STUCK: on branch main with uncommitted changes, 1 commits behind origin/main - needs attentionPipeline
Updates from git push no-mistakes
✅ **intent** - passed
✅ No issues found.
✅ **Rebase** - passed
✅ No issues found.
🔧 **Review** - 1 issue found → auto-fixed ✅
bin/fm-fleet-sync.sh:198- When the clone is detached at a clean ancestor of origin/main, this checkout runs before verifying that the local default branch itself is safe. If local main contains unique/diverged commits and is merely not checked out elsewhere, fleet sync will move the pool clone onto that unsafe local main, then report STUCK, violating the intended 'unsafe cases are left untouched' invariant and potentially basing later work on unlanded commits. Check that an existing local $DEFAULT is an ancestor of $BASE before checkout, or report the divergence without switching branches.🔧 Fix: Guard detached recovery from diverged local defaults
✅ Re-checked - no issues remain.
✅ **Test** - passed
✅ No issues found.
bash tests/fm-fleet-sync.test.shfor t in tests/*.test.sh; do printf '== %s ==\n' "$t"; bash "$t"; doneManual isolated fleet fixture:FM_HOME=/var/folders/5x/4nqprlbx0518k3ybcb1sz6gr0000gn/T/no-mistakes-evidence/01KW5JBQEX9335CC171AT08YH5/fleet-sync-e2e-fixture/home-fleet FM_ROOT_OVERRIDE=/Users/kunchen/.no-mistakes/worktrees/016d88035d58/01KW5JBQEX9335CC171AT08YH5 bin/fm-fleet-sync.shManual bootstrap relay fixture:FM_HOME=/var/folders/5x/4nqprlbx0518k3ybcb1sz6gr0000gn/T/no-mistakes-evidence/01KW5JBQEX9335CC171AT08YH5/fleet-sync-e2e-fixture/home-bootstrap FM_ROOT_OVERRIDE=/Users/kunchen/.no-mistakes/worktrees/016d88035d58/01KW5JBQEX9335CC171AT08YH5 bin/fm-bootstrap.sh | grep '^FLEET_SYNC:'git status --short✅ **Document** - passed
✅ No issues found.
✅ **Lint** - passed
✅ No issues found.
✅ **Push** - passed
✅ No issues found.