Call Harmony inside the rebase replay loop for per-commit conflict learning
Background
When muse merge --history rebase runs, the feature branch commits are replayed linearly on top of the target branch. Today, Harmony is called once at the end of the rebase — at commit time — which means it sees the final squash-equivalent result, not each individual replayed commit.
This was explicitly deferred in issue #86 (Phase 4):
muse rebasecalls Harmony inside the replay loop. Deferred —--history rebaseruns squash-equivalent in Phase 3; per-commit Harmony during replay not yet implemented.
The consequence: when a rebase produces a conflict mid-replay (e.g. commit 3 of 7 conflicts with the target), Harmony has no per-commit context to learn from. It cannot record a resolution keyed to the original commit IDs. Future rebases of similar branches won't benefit from any auto-resolution learned during the first rebase.
The correct model: Harmony must be called inside the rebase replay loop, once per replayed commit, at the moment each commit is applied. This mirrors how --history merge works — resolutions are recorded per-conflict, per-commit, with full provenance.
Goal
muse merge --history rebase calls Harmony inside the replay loop so that:
- Per-commit conflicts during rebase are auto-resolved by Harmony when a matching pattern exists.
- Manually resolved conflicts during rebase are recorded by Harmony (human_verified=true, confidence=1.0) at the commit that introduced them.
- A subsequent rebase of a similar branch auto-resolves the same per-commit conflicts without human intervention.
Phases
Phase 1 — Rebase engine Harmony integration
Deliverables:
RB_01— Identify the rebase replay loop inmuse/core/ormuse/cli/commands/rebase.py; confirm it is distinct from the squash path.RB_02— Callharmony_auto_apply(root, conflict_paths, …)inside the replay loop after each commit is applied and any conflicts are detected — not only at final commit time.RB_03— Callrecord_resolutions(root, …)at each replayed commit's resolution point so Harmony learns from per-commit context (not just the final squash-equivalent state).RB_04— Harmony recording during rebase uses the replayed commit'sours_id/theirs_id(not the squash snapshot IDs), preserving full per-commit provenance.
Phase 2 — Tests
One new test file: tests/test_harmony_rebase_loop.py.
Deliverables:
HR_01— After a--history rebasemerge that had a mid-replay conflict resolved manually, re-running the same rebase auto-resolves via Harmony. (Previously: HA_03 passed only via squash-equivalent path — this test must verify the per-commit Harmony path specifically.)HR_02— Harmony records the resolution keyed to the replayed commit's conflict context, not the final squash snapshot.HR_03— A rebase with multiple conflicting commits records independent Harmony entries for each conflict.HR_04— No regression to HA_02 (squash Harmony path) or HA_03 (existing rebase squash-equivalent path).
Acceptance criteria
muse merge --history rebasecalls Harmony once per replayed commit, not once at the end.- HR_01–HR_04 all green.
- No regression to existing Harmony tests (HA_02, HA_03, HC_01–HC_04) or rebase tests.
Out of scope
- Changes to Harmony's storage format or confidence-gating logic (Phase 7 of #86).
- Changes to
--history mergeor--history squashHarmony paths (already correct). - New rebase features beyond the Harmony integration.