Skip to content

fix(bin): allow collision-safe fast-forwards with local changes - #2236

Open
4mb1t10n wants to merge 3 commits into
kunchenguid:mainfrom
4mb1t10n:fm/fm-1041
Open

fix(bin): allow collision-safe fast-forwards with local changes#2236
4mb1t10n wants to merge 3 commits into
kunchenguid:mainfrom
4mb1t10n:fm/fm-1041

Conversation

@4mb1t10n

Copy link
Copy Markdown

Intent

Implement #1041 against main exactly as specified in the issue. Reuse the established collision-precision behavior for every fm-ff-lib fast-forward consumer: refuse genuine collisions including incoming deletes over locally modified paths and incoming additions over untracked paths, fail closed on unclassifiable states, report the colliding paths, and preserve spaces and non-ASCII names through NUL-delimited parsing; allow unrelated modified and untracked paths to proceed safely. Keep the current local-material-only config push behavior and exclude unrelated sync redesign. Add executable behavioral regressions proving both refusal and safe progress in local-HEAD and origin modes. No database or browser stack and never run local Cypress. Fully close the issue in the PR body with a standalone Closes #1041 line. Complete No Mistakes plus exact-head CI and mergeability evidence, and never merge the PR. The broader secondmate-harness concurrency timeout was reproduced identically on unchanged origin/main b5d430d, so accept the green collision-specific suites and repository lint as equivalent relevant evidence and do not repeat that timed-out invocation.

What Changed

  • Make shared local fast-forward consumers reject only colliding uncommitted paths, report those paths, and fail closed when working-tree state cannot be classified.
  • Preserve unrelated modified and untracked files, including paths with spaces and non-ASCII characters, while retaining local-material-only config pushes and remote clean-tree guards.
  • Add local-HEAD and origin-mode regressions for collisions, incoming deletes/additions, unclassifiable states, and safe progress with unrelated changes.

Closes #1041

Risk Assessment

✅ Low: The shared fast-forward boundary now rejects genuine and unclassifiable collisions while permitting unrelated dirt, with executable coverage for refusal and safe progress in both local-HEAD and origin modes.

Testing

Inspected the target diff, ran the focused local-HEAD and origin-mode behavioral suites, and manually exercised the shared fast-forward interface: it reported and refused an incoming delete over a locally modified spaced Unicode path while preserving HEAD and content, then safely advanced across unrelated untracked material without disturbing it. No browser evidence applies because this is shell CLI behavior.

Evidence: Collision refusal and safe-progress CLI transcript

demo: skipped: uncommitted paths collide with fast-forward: old file 雪.txt - uncommitted changes here, while the fast-forward removes it status=skipped head_unchanged=yes local_content=operator edit preserved demo: updated e0efbc1..8185340 status=updated head_reached_target=yes unrelated_content=unrelated local edit

=== genuine collision: incoming delete over local edit ===
demo: skipped: uncommitted paths collide with fast-forward:
  old file 雪.txt - uncommitted changes here, while the fast-forward removes it
status=skipped
head_unchanged=yes
local_content=operator edit preserved
=== safe progress: unrelated untracked path ===
demo: updated e0efbc1..8185340
status=updated
head_reached_target=yes
unrelated_content=unrelated local edit
Evidence: Local-HEAD collision suite
ok - T1 updated: a behind home fast-forwards to the primary's local HEAD
ok - T2 current: an already-current home is a no-op and reports no instruction change
ok - T3 collision: an incoming path with local edits is skipped and named
ok - collision precision proceeds past unrelated tracked and untracked paths
ok - collision precision refuses and reports an incoming delete over a modified path
ok - collision precision refuses and reports an untracked incoming-add path
ok - collision precision fails closed on an unclassifiable in-progress state
ok - T4 diverged: a home that is not an ancestor of the primary's HEAD is skipped
ok - T5 in-flight: a home on a feature branch is skipped, its work preserved
ok - T6 no fetch: the local-HEAD sync never invokes git fetch
ok - T7 sweep nudges on a real instruction change only, but still fast-forwards
ok - T8 bootstrap sweeps live homes and sends exactly one marked nudge for the instruction change
ok - T8a bootstrap nudge send respects FM_STATE_OVERRIDE
ok - T8f bootstrap nudge retry rejects malformed marker ids
ok - T8c failed bootstrap nudge is surfaced and recorded for retry
ok - T8d bootstrap nudge retry is idempotent after success
ok - T8e bootstrap nudge retry refuses a changed home instead of guessing
ok - T8b stale herdr nudge failures leave a retry marker after respawn rotates fm-<id> metadata
ok - T9 bootstrap surfaces a skipped colliding live secondmate home
ok - T10 spawn fast-forwards a secondmate worktree to the primary's local HEAD before launch
ok - T11 spawn warns when pre-launch sync is skipped
ok - T12 gitignored marker: a freshly seeded home reads clean to fleet-sync and the ff sweep
ok - T13 gitignored marker: an existing marker-only-dirty home converges, then reads clean
ok - T14 marker convergence preserves unrelated genuine dirt
# all fm-secondmate-sync tests passed
Evidence: Origin collision suite
ok - T1 main + secondmate fast-forward (single-parent), reread + nudge signalled
ok - T3 reread gates on instruction surface, nudge on advancement
ok - T4 colliding secondmate skipped, local edit preserved
ok - origin-mode consumers proceed past unrelated modified and untracked paths
ok - T5 diverged secondmate skipped, local commit preserved
ok - T6 idempotent: a second run is a no-op
ok - T7 registry backstop resolves, dedups meta+registry, excludes the firstmate repo
ok - T9 firstmate off its default branch is skipped, not forced
ok - T10 firstmate detached HEAD is skipped
ok - T11 unsafe secondmate home is not fast-forwarded
# all fm-update tests passed

Pipeline

Updates from git push no-mistakes

✅ **intent** - passed

✅ No issues found.

✅ **Rebase** - passed

✅ No issues found.

✅ **Review** - passed

✅ No issues found.

✅ **Test** - passed

✅ No issues found.

  • Inspected git diff b5d430d6fdcd961ce9b681bf196f365c1825c284..9c5c32069273f86b64414040ab03a293372dcbc9 and the affected executable test entry points.
  • bash tests/fm-secondmate-sync.test.sh
  • bash tests/fm-update.test.sh
  • /tmp/no-mistakes-evidence/01KZTA1YR99CG2SD2FG3ZKSEYT/collision-demo.sh "$PWD" /tmp/no-mistakes-evidence/01KZTA1YR99CG2SD2FG3ZKSEYT
  • Verified git status --short was empty after testing.
✅ **Document** - passed

✅ No issues found.

✅ **Lint** - passed

✅ No issues found.

✅ **Push** - passed

✅ No issues found.

@4mb1t10n

Copy link
Copy Markdown
Author

Decisions

  • origin/main counterfactual accepted as a materially different validation path. The lane's own validation path was exhausted without a verdict, so Firstmate authorized comparing against unchanged origin/main instead of retrying the same failing route.
  • Secondmate-harness timeout recorded as pre-existing. That counterfactual reproduced an identical secondmate-harness timeout on unchanged origin/main at b5d430d. It is therefore pre-existing and unrelated to this change. Firstmate accepted the collision-suite and lint evidence as equivalent coverage for the affected behavior rather than expanding this PR to chase an upstream defect.
  • No other non-obvious defaults were taken; the collision-safe fast-forward behavior is exactly the accepted scope of fm-ff-lib.sh: dirty_status refuses on any dirty tree, not just genuine collisions #1041.

Recorded by Firstmate under delegated routine authority.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fm-ff-lib.sh: dirty_status refuses on any dirty tree, not just genuine collisions

1 participant