gabriel / muse public
feat BREAKING task/semver-classifier #1 / 1
gabriel · 167 days ago · Apr 13, 2026 · Diff

feat: replace infer_sem_ver_bump with structured semver classifier

- Add muse/core/semver_classifier.py: VisibilityTier, StabilityTier, ChangeKind, ChangeClassification, SemVerClassification, StabilityManifest, classify_delta — evidence-driven classification with confidence scores - Delete infer_sem_ver_bump from domain.py (removed from __all__ earlier) - Update cli/commands/commit.py to call classify_delta instead - Rewrite tests/test_sem_ver.py: 121 tests covering the new classifier - Fix _glob_star_match: regex-based ** expansion (was matching everything) - Fix _classify_move: use old_address as canonical address

sha256:05d74f1339933f271493f80d9ea71d8719e762af3c3e15c96e52d306c7d14c64 sha
+146 ~23 −20 symbols
sha256:d85770312ebfc61b883770573f61a025148f9c8dd5240900bdae008f44e22ea9 snapshot
+146
symbols added
~23
symbols modified
−20
symbols removed
0
dead code introduced
Semantic Changes 189 symbols
~ muse/core/semver_classifier.py .py 44 symbols added
+ ChangeClassification class class ChangeClassification L301–327
+ ChangeKind variable variable ChangeKind L134–134
+ SemVerClassification class class SemVerClassification L331–370
+ all_classifications class method all_classifications L368–370
+ breaking_addresses method method breaking_addresses L358–365
+ StabilityManifest class class StabilityManifest L186–292
+ _matches method method _matches L286–292
+ empty method method empty L224–226
+ is_invisible method method is_invisible L275–284
+ load method method load L229–255
+ stability_for method method stability_for L257–273
+ StabilityTier variable variable StabilityTier L133–133
+ VisibilityTier variable variable VisibilityTier L132–132
+ _BUMP_RANK variable variable _BUMP_RANK L175–177
+ _UNIVERSAL_INVISIBLE_PATTERNS variable variable _UNIVERSAL_INVISIBLE_PATTERNS L145–172
+ __all__ variable variable __all__ L118–126
+ _aggregate function function _aggregate L783–827
+ _bump_for function function _bump_for L830–846
+ _classify_delete class function _classify_delete L546–578
+ _classify_directory_rename class function _classify_directory_rename L725–775
+ _classify_insert class function _classify_insert L511–543
+ _classify_move class function _classify_move L665–695
+ _classify_mutate class function _classify_mutate L698–722
+ _classify_ops class function _classify_ops L444–467
+ _classify_patch_op class function _classify_patch_op L471–508
+ _classify_replace class function _classify_replace L581–662
+ _file_part function function _file_part L911–917
+ _fnmatch_path function function _fnmatch_path L920–924
+ _glob_star_match function function _glob_star_match L927–934
+ _is_private function function _is_private L897–908
+ _is_universally_invisible function function _is_universally_invisible L876–894
+ _visibility function function _visibility L854–873
+ classify_delta class function classify_delta L378–436
+ DomainOp import import DomainOp L112–112
+ Literal import import Literal L110–110
+ SemVerBump import import SemVerBump L112–112
+ StructuredDelta import import StructuredDelta L112–112
+ annotations import import annotations L103–103
+ dataclass class import dataclass L108–108
+ field import import field L108–108
+ fnmatch import import fnmatch L109–109
+ pathlib import import pathlib L105–105
+ re import import re L106–106
+ tomllib import import tomllib L107–107
~ muse/cli/commands/commit.py .py 1 symbol added, 1 symbol removed, 5 symbols modified
− infer_sem_ver_bump import import infer_sem_ver_bump L67–67
+ classify_delta class import classify_delta L67–67
~ run
~ muse/domain.py .py 1 symbol removed, 1 symbol modified
− infer_sem_ver_bump function function infer_sem_ver_bump L385–463
~ tests/test_sem_ver.py .py 101 symbols added, 18 symbols removed, 17 symbols modified
− TestInferSemVerBump class class TestInferSemVerBump L94–219
− test_delete_private_symbol_not_major method method test_delete_private_symbol_not_major L122–132
− test_delete_public_symbol_is_major method method test_delete_public_symbol_is_major L117–120
− test_empty_delta_is_none method method test_empty_delta_is_none L95–98
− test_insert_private_function_is_at_most_minor method method test_insert_private_function_is_at_most_minor L105–115
− test_insert_public_function_is_minor method method test_insert_public_function_is_minor L100–103
− test_major_wins_over_minor method method test_major_wins_over_minor L165–170
− test_minor_wins_over_patch method method test_minor_wins_over_patch L172–177
− test_move_op_is_handled method method test_move_op_is_handled L209–219
− test_multiple_breaking_changes_accumulated method method test_multiple_breaking_changes_accumulated L179–187
− test_patch_op_with_child_ops method method test_patch_op_with_child_ops L189–207
− test_replace_implementation_changed_is_patch method method test_replace_implementation_changed_is_patch L144–148
− test_replace_metadata_only_unrecognized_summary method method test_replace_metadata_only_unrecognized_summary L150–156
− test_replace_reformatted_summary method method test_replace_reformatted_summary L158–163
− test_replace_renamed_public_is_major method method test_replace_renamed_public_is_major L134–137
− test_replace_signature_changed_public_is_major method method test_replace_signature_changed_public_is_major L139–142
− test_infer_returns_semverbump_type method method test_infer_returns_semverbump_type L285–287
− infer_sem_ver_bump import import infer_sem_ver_bump L36–36
+ TestChangeClassification class class TestChangeClassification L393–420
+ test_frozen_is_immutable method method test_frozen_is_immutable L410–420
+ test_frozen_stores_all_fields method method test_frozen_stores_all_fields L394–408
+ TestClassifyDeltaDelete class class TestClassifyDeltaDelete L517–535
+ test_delete_private_symbol_is_invisible method method test_delete_private_symbol_is_invisible L532–535
+ test_delete_public_stable_is_major method method test_delete_public_stable_is_major L526–530
+ test_delete_public_unstable_is_minor method method test_delete_public_unstable_is_minor L518–524
+ TestClassifyDeltaDirectoryRename class class TestClassifyDeltaDirectoryRename L766–794
+ _dir_rename_op method method _dir_rename_op L767–774
+ test_code_domain_rename_is_breaking_low_confidence method method test_code_domain_rename_is_breaking_low_confidence L776–781
+ test_invisible_directory_rename_is_invisible method method test_invisible_directory_rename_is_invisible L790–794
+ test_non_code_domain_rename_is_invisible method method test_non_code_domain_rename_is_invisible L783–788
+ TestClassifyDeltaEmpty class class TestClassifyDeltaEmpty L485–493
+ test_empty_ops_is_none method method test_empty_ops_is_none L486–493
+ TestClassifyDeltaExperimental class class TestClassifyDeltaExperimental L672–690
+ test_delete_public_experimental_is_patch method method test_delete_public_experimental_is_patch L673–677
+ test_insert_public_experimental_is_patch method method test_insert_public_experimental_is_patch L679–682
+ test_signature_change_experimental_is_patch method method test_signature_change_experimental_is_patch L684–690
+ TestClassifyDeltaInsert class class TestClassifyDeltaInsert L496–514
+ test_insert_private_symbol_is_invisible method method test_insert_private_symbol_is_invisible L510–514
+ test_insert_public_stable_is_minor method method test_insert_public_stable_is_minor L505–508
+ test_insert_public_unstable_is_patch method method test_insert_public_unstable_is_patch L497–503
+ TestClassifyDeltaInvisibleGates class class TestClassifyDeltaInvisibleGates L620–664
+ test_delete_on_invisible_file_produces_no_bump method method test_delete_on_invisible_file_produces_no_bump L644–646
+ test_insert_on_invisible_file_produces_no_bump method method test_insert_on_invisible_file_produces_no_bump L634–637
+ test_mix_invisible_and_visible_ops method method test_mix_invisible_and_visible_ops L656–664
+ test_patch_op_on_invisible_file_is_invisible method method test_patch_op_on_invisible_file_is_invisible L648–654
+ TestClassifyDeltaMoveAndMutate class class TestClassifyDeltaMoveAndMutate L734–758
+ test_move_op_private_symbol_is_invisible method method test_move_op_private_symbol_is_invisible L741–745
+ test_move_op_public_exported_is_implementation method method test_move_op_public_exported_is_implementation L735–739
+ test_mutate_op_private_symbol_is_invisible method method test_mutate_op_private_symbol_is_invisible L753–758
+ test_mutate_op_public_is_implementation method method test_mutate_op_public_is_implementation L747–751
+ TestClassifyDeltaPatchOp class class TestClassifyDeltaPatchOp L698–726
+ test_patch_op_invisible_file_skips_children method method test_patch_op_invisible_file_skips_children L713–719
+ test_patch_op_no_child_ops_is_implementation method method test_patch_op_no_child_ops_is_implementation L707–711
+ test_patch_op_recurses_into_children method method test_patch_op_recurses_into_children L699–705
+ test_patch_op_with_stable_child_delete_is_major method method test_patch_op_with_stable_child_delete_is_major L721–726
+ TestClassifyDeltaPromotion class class TestClassifyDeltaPromotion L585–612
+ test_major_wins_over_minor method method test_major_wins_over_minor L586–592
+ test_minor_wins_over_patch method method test_minor_wins_over_patch L594–600
+ test_multiple_breaking_addresses method method test_multiple_breaking_addresses L602–612
+ TestClassifyDeltaReplace class class TestClassifyDeltaReplace L538–582
+ test_replace_implementation_change_is_patch method method test_replace_implementation_change_is_patch L539–544
+ test_replace_private_symbol_is_invisible method method test_replace_private_symbol_is_invisible L579–582
+ test_replace_rename_stable_is_major method method test_replace_rename_stable_is_major L561–567
+ test_replace_rename_unstable_is_minor method method test_replace_rename_unstable_is_minor L569–571
+ test_replace_signature_change_stable_is_major method method test_replace_signature_change_stable_is_major L546–554
+ test_replace_signature_change_unstable_is_minor method method test_replace_signature_change_unstable_is_minor L556–559
+ test_replace_unrecognised_summary_is_conservative_low_confidence method method test_replace_unrecognised_summary_is_conservative_low_confidence L573–577
+ TestClassifyDeltaRepoRoot class class TestClassifyDeltaRepoRoot L802–834
+ test_explicit_manifest_overrides_repo_root method method test_explicit_manifest_overrides_repo_root L820–834
+ test_repo_root_loads_stability_toml method method test_repo_root_loads_stability_toml L803–811
+ test_repo_root_missing_stability_toml_falls_back_to_empty method method test_repo_root_missing_stability_toml_falls_back_to_empty L813–818
+ test_classify_delta_returns_valid_bump class method test_classify_delta_returns_valid_bump L893–895
+ TestSemVerClassification class class TestSemVerClassification L423–477
+ _make_cc method method _make_cc L424–432
+ test_all_classifications_flat class method test_all_classifications_flat L459–477
+ test_breaking_addresses_empty_when_no_breaking method method test_breaking_addresses_empty_when_no_breaking L448–457
+ test_breaking_addresses_sorted method method test_breaking_addresses_sorted L434–446
+ TestStabilityManifestEmpty class class TestStabilityManifestEmpty L204–218
+ test_empty_has_no_declarations method method test_empty_has_no_declarations L205–210
+ test_empty_is_invisible_is_always_false method method test_empty_is_invisible_is_always_false L216–218
+ test_empty_stability_for_defaults_to_unstable method method test_empty_stability_for_defaults_to_unstable L212–214
+ TestStabilityManifestIsInvisible class class TestStabilityManifestIsInvisible L316–327
+ test_invisible_pattern_matches method method test_invisible_pattern_matches L317–319
+ test_no_pattern_returns_false method method test_no_pattern_returns_false L321–323
+ test_unmatched_pattern_returns_false method method test_unmatched_pattern_returns_false L325–327
+ TestStabilityManifestLoad class class TestStabilityManifestLoad L221–282
+ test_load_all_sections_together method method test_load_all_sections_together L263–282
+ test_load_parses_experimental method method test_load_parses_experimental L244–251
+ test_load_parses_invisible_patterns method method test_load_parses_invisible_patterns L253–261
+ test_load_parses_stable_patterns method method test_load_parses_stable_patterns L235–242
+ test_load_parses_stable_symbols method method test_load_parses_stable_symbols L226–233
+ test_load_returns_empty_when_no_file method method test_load_returns_empty_when_no_file L222–224
+ TestStabilityManifestStabilityFor class class TestStabilityManifestStabilityFor L285–313
+ test_declared_experimental_exact_match method method test_declared_experimental_exact_match L290–292
+ test_declared_stable_exact_match method method test_declared_stable_exact_match L286–288
+ test_empty_manifest_always_unstable method method test_empty_manifest_always_unstable L311–313
+ test_stable_pattern_glob method method test_stable_pattern_glob L298–301
+ test_stable_wins_over_experimental_when_both_match method method test_stable_wins_over_experimental_when_both_match L303–309
+ test_undeclared_defaults_to_unstable method method test_undeclared_defaults_to_unstable L294–296
+ TestUniversalInvisiblePatterns class class TestUniversalInvisiblePatterns L335–385
+ test_invisible method method test_invisible L372–373
+ test_not_invisible method method test_not_invisible L384–385
+ _manifest_with_experimental function function _manifest_with_experimental L195–196
+ _manifest_with_stable function function _manifest_with_stable L191–192
+ _move function function _move L160–167
+ _mutate function function _mutate L170–177
+ _patch function function _patch L180–188
+ ChangeClassification class import ChangeClassification L94–94
+ ChangeKind import import ChangeKind L94–94
+ MutateOp import import MutateOp L104–104
+ SemVerClassification class import SemVerClassification L94–94
+ StabilityManifest import import StabilityManifest L94–94
+ StabilityTier import import StabilityTier L94–94
+ VisibilityTier import import VisibilityTier L94–94
+ _is_universally_invisible import import _is_universally_invisible L94–94
+ annotations import import annotations L86–86
+ classify_delta class import classify_delta L94–94
+ pathlib import import pathlib L88–88
+ textwrap import import textwrap L89–89
~ _delta
~ MoveOp
← Older Oldest on task/semver-classifier
All commits
Newer → Latest on task/semver-classifier

0 comments

No comments yet. Be the first to start the discussion.

To add a comment, use the Muse CLI: muse hub commit comment sha256:05d74f1339933f271493f80d9ea71d8719e762af3c3e15c96e52d306c7d14c64 --body "your comment"