Skip to content
This repository was archived by the owner on Aug 25, 2026. It is now read-only.

fix: fleet-sync follows branch upstream on controlled forks - #89

Merged
JTInventory merged 6 commits into
mainfrom
fm/firstmate-fleet-sync-tracking-base-0806
Aug 6, 2026
Merged

JTInventory merged 6 commits into
mainfrom
fm/firstmate-fleet-sync-tracking-base-0806

Conversation

@JTInventory

Copy link
Copy Markdown
Owner

Intent

Make fleet-sync follow controlled-fork delivery upstream so delivery-current clones stop false-STUCK against diverged origin/main

What Changed

  • Update bin/fm-fleet-sync.sh to resolve each clone’s sync base from its configured default-branch upstream, refresh the selected remote and branch safely, and prune after refresh.
  • Increase bootstrap’s calculated fleet-sync timeout to account for delivery-remote fetches and document controlled-fork base selection.
  • Add focused coverage for incomplete and local upstream configurations, plus controlled-fork clones that follow fork/main while origin/main diverges.

Risk Assessment

✅ Low: The change is well-bounded and the latest fixes preserve the controlled-fork behavior while avoiding redundant origin fetches and force-updating delivery refs safely.

Testing

The focused suite, full behavior suite, and direct CLI scenario all completed successfully. The worktree remained clean, and CLI evidence was captured in the dedicated temporary evidence directory.

Evidence: Controlled-fork CLI transcript

--- delivery-current clone with diverged origin/main --- main=6321ccd fork/main=6321ccd origin/main=9bd3848 forked: already current --- same clone after delivery advance --- forked: synced 6321ccd..0d50709 main=0d50709 fork/main=0d50709 origin/main=9bd3848

branch 'main' set up to track 'fork/main'.
--- delivery-current clone with diverged origin/main ---
main=6321ccd fork/main=6321ccd origin/main=9bd3848
forked: already current
--- delivery remote advances ---
--- same clone after delivery advance ---
forked: synced 6321ccd..0d50709
main=0d50709 fork/main=0d50709 origin/main=9bd3848

Pipeline

Updates from git push no-mistakes

✅ **intent** - passed

✅ No issues found.

✅ **Rebase** - passed

✅ No issues found.

🔧 **Review** - 3 issues found → auto-fixed (4) ✅
  • 🚨 bin/fm-fleet-sync.sh:267 - Required criterion: "Make fleet-sync follow controlled-fork delivery upstream so delivery-current clones stop false-STUCK against diverged origin/main." Contradicting hunk: line 267 accepts the configured upstream only when "$upstream^{commit}" is already cached; otherwise line 271 falls back to origin/<default>. A delivery-current clone with a missing fork/main tracking ref can therefore be judged against diverged origin/main again. Resolve and fetch the configured upstream before fallback, or confirm this fallback is intentional.
  • ⚠️ bin/fm-fleet-sync.sh:332 - If a cached non-origin tracking ref remains while its remote is missing, line 332 silently skips the delivery fetch, and later validation still accepts the stale BASE. This can report already-current or fast-forward from obsolete delivery state. Require the selected remote to exist and refresh successfully before accepting the cached ref.
  • ⚠️ tests/fm-fleet-sync.test.sh:511 - The controlled-fork test pre-fetches fork at line 511 and then checks an already-current clone. It never proves that fleet-sync refreshes a changed fork/main, so an implementation that omits or misroutes the new delivery fetch would still pass. Advance the delivery remote after setup, remove this pre-fetch, and assert the sync and resulting HEAD.

🔧 Fix: Refresh fork upstream before fleet sync; focused tests pass
2 warnings still open:

  • ⚠️ bin/fm-fleet-sync.sh:343 - If the branch has a stale or incomplete config (remote=fork but no valid merge), resolve_sync_base falls back to origin/$DEFAULT, while this block still forces a fetch of fork and returns skipped when it is unavailable. Keep the selected fetch remote consistent with the resolved BASE.
  • ⚠️ bin/fm-fleet-sync.sh:351 - The delivery remote is fetched after prune_gone_branches runs. Branches tracking that remote can therefore remain locally present for one extra sync cycle after deletion. Run gone-branch pruning after all selected remotes have been refreshed.

🔧 Fix: Align fetch remote with resolved base; prune after refresh
4 warnings still open:

  • ⚠️ bin/fm-fleet-sync.sh:338 - ${BASE%%/*} cannot distinguish the remote from the branch when the configured upstream is local (remote=. with release/main) or when a remote name contains /. The script can fetch the wrong remote or skip a valid local upstream. Preserve the selected remote separately from BASE.
  • ⚠️ bin/fm-fleet-sync.sh:347 - A successful fetch only proves that the remote's configured refspec completed. If that refspec omits the configured merge branch, an old fork/main remains and line 364 accepts it as the sync base, allowing false-current or stale fast-forward decisions. Fetch the selected branch explicitly or verify the tracking ref was refreshed.
  • ⚠️ bin/fm-fleet-sync.sh:347 - Controlled-fork projects now perform two serial remote fetches, but bootstrap's default timeout remains max(20, 5 + 3 * origin-backed project count). A slow origin fetch can consume the budget before the delivery fetch completes, leaving the clone stale until a later run. Include delivery fetches in the timeout budget or enforce per-fetch limits.
  • ⚠️ tests/fm-fleet-sync.test.sh:538 - The controlled-fork test advances and removes fork/main before its only sync call, so it proves ref refresh for a delivery-behind clone but not the primary delivery-current case where main == fork/main while origin/main diverges. Add an initial sync assertion for that state before retaining the refresh scenario.

🔧 Fix: Separate upstream refs, refresh branches, and budget bootstrap
2 warnings still open:

  • ⚠️ bin/fm-fleet-sync.sh:358 - Every normal origin-tracked project now performs the initial origin fetch plus the secondary generic origin fetch and explicit branch fetch because fallback sets SYNC_REMOTE=origin. This triples network work and adds new failure points. Only run the secondary delivery-fetch sequence for non-origin remotes.
  • ⚠️ bin/fm-fleet-sync.sh:376 - The explicit delivery refspec lacks a leading +, so a force-pushed or rebased delivery branch can fail with a non-fast-forward remote-tracking update. Fleet sync then skips instead of refreshing the delivery base. Force-update the remote-tracking refspec safely.

🔧 Fix: Avoid origin refetches and force-update delivery refs
✅ Re-checked - no issues remain.

✅ **Test** - passed

✅ No issues found.

  • bash bin/fm-run-behavior-tests.sh
  • bash tests/fm-fleet-sync.test.sh
  • bash bin/fm-run-behavior-tests.sh
  • Direct bin/fm-fleet-sync.sh controlled-fork scenario with diverged origin/main
  • Final git status --porcelain=v1 check
✅ **Document** - passed

✅ No issues found.

✅ **Lint** - passed

✅ No issues found.

✅ **Push** - passed

✅ No issues found.

JTInventory and others added 6 commits August 6, 2026 13:15
Prefer the local default branch's configured upstream (e.g. fork/main)
as the sync base instead of hardcoding origin/<default>. Controlled-fork
homes keep origin fetching the upstream owner while main tracks fork;
comparing only to origin/main false-STUCK a delivery-current clone.
Also fetch the delivery remote when it differs from origin.
@JTInventory
JTInventory merged commit 098f5ac into main Aug 6, 2026
32 of 38 checks passed
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant