"""muse#91 — semver classifier flags breaking_changes on a reorder-only diff despite its own "no semantic change" summary. Root cause: `build_diff_ops()` (muse/plugins/code/symbol_diff.py) falls back to a whole-file ReplaceOp labeled " (reformatted -- no semantic change)" when every symbol's content_id in a modified file is unchanged -- e.g. a pure reorder of two top-level functions, or a comment-only edit (muse#92). `_classify_replace()` (muse/core/semver_classifier.py) pattern- matches `new_summary` for "renamed to"/"signature"/"implementation" but had no case for this exact fallback text, so it fell through to the conservative "unrecognised summary" catch-all and was classified breaking/minor -- directly contradicting the op's own "no semantic change" claim one field over. Fixed by adding a recognized branch for "no semantic change" in `_classify_replace()`, classifying it `invisible` (no API impact, no bump). Reproduces the ticket's exact repro steps through the real CLI: commit a file with two functions, commit again with ONLY their order swapped, and assert the resulting commit's structured_delta reports sem_ver_bump="none" and breaking_changes=[]. """ from __future__ import annotations import json import os import pathlib from tests.cli_test_helper import CliRunner, InvokeResult runner = CliRunner() def _run(repo: pathlib.Path, *args: str) -> InvokeResult: saved = os.getcwd() try: os.chdir(repo) return runner.invoke(None, list(args)) finally: os.chdir(saved) def test_reorder_only_diff_is_zero_bump_and_not_breaking(tmp_path: pathlib.Path) -> None: repo = tmp_path r = _run(repo, "init") assert r.exit_code == 0, r.stderr (repo / "extra.py").write_text( "def helper_a(x):\n return x\n\n\ndef helper_b(x):\n return x * 2\n" ) r = _run(repo, "code", "add", "extra.py") assert r.exit_code == 0, r.stderr r = _run(repo, "commit", "-m", "base") assert r.exit_code == 0, r.stderr # Reorder only -- swap the two functions, no other edits. (repo / "extra.py").write_text( "def helper_b(x):\n return x * 2\n\n\ndef helper_a(x):\n return x\n" ) r = _run(repo, "code", "add", "extra.py") assert r.exit_code == 0, r.stderr r = _run(repo, "commit", "-m", "reorder only") assert r.exit_code == 0, r.stderr r = _run(repo, "read-commit", "HEAD", "--json") assert r.exit_code == 0, r.stderr delta = json.loads(r.output)["structured_delta"] assert delta["sem_ver_bump"] == "none", ( f"reorder-only diff must not trigger a version bump: {delta}" ) assert delta["breaking_changes"] == [], ( f"reorder-only diff must not be flagged breaking: {delta}" )