gabriel / muse public
feat BREAKING describe task/version-tags-phase0-label-rename #2 / 7
AI Agent gabriel · 20 days ago · Jun 29, 2026 · Diff

feat(describe): rewrite muse describe for clean version-tag-only API (Phase 4, VT_34–VT_40)

- Rewrite muse/core/describe.py to use list_version_tags instead of label tags; DescribeResult now has description (not name), distance=None on no-tag, short_sha is raw hex without sha256: prefix, exit 1 when no eligible tags found - Rewrite muse/cli/commands/describe.py: clean pristine surface — positional ref, --pre, --first-parent, --abbrev; remove --long, --require-tag, --exact-match, --match, --ref flags entirely - Add tests/test_cmd_describe_version_tags.py: 30 new tests (VT_34–VT_40), all green - Rewrite tests/test_cmd_describe.py, test_cmd_describe_hardening.py, test_describe_envelope.py, test_describe_walk.py to match new API - Check off VT_34–VT_40 in docs/issues/version-tags.md

sha256:894647ed295b70815ea76af263faca6f8f4d4892417eb887d8c0ceb187f54a5a sha
+119 ~49 −51 symbols
sha256:414a8688a6937bb507c6d622d56e44a83bd0adf6e64df5a87c589ebb910560fb snapshot
+119
symbols added
~49
symbols modified
−51
symbols removed
0
dead code introduced
Semantic Changes 219 symbols
+ TestVT34ExactTag class class TestVT34ExactTag L103–138
+ test_commit_id_in_json method method test_commit_id_in_json L125–131
+ test_description_is_tag_name_when_exactly_on_tag method method test_description_is_tag_name_when_exactly_on_tag L117–123
+ test_exact_stable_tag_distance_zero method method test_exact_stable_tag_distance_zero L106–115
+ test_exit_code_zero_on_hit method method test_exit_code_zero_on_hit L133–138
+ TestVT35DistanceFromTag class class TestVT35DistanceFromTag L145–187
+ test_description_contains_tag_distance_and_hex method method test_description_contains_tag_distance_and_hex L162–177
+ test_distance_three method method test_distance_three L148–160
+ test_exact_false_when_not_on_tag method method test_exact_false_when_not_on_tag L179–187
+ TestVT36PreFlag class class TestVT36PreFlag L194–237
+ test_stable_tag_always_found_without_pre method method test_stable_tag_always_found_without_pre L217–227
+ test_with_pre_includes_rc_tags method method test_with_pre_includes_rc_tags L207–215
+ test_with_pre_picks_highest_version method method test_with_pre_picks_highest_version L229–237
+ test_without_pre_excludes_rc_tags method method test_without_pre_excludes_rc_tags L197–205
+ TestVT37NoTags class class TestVT37NoTags L244–285
+ test_commit_id_still_present_when_no_tags method method test_commit_id_still_present_when_no_tags L274–279
+ test_description_null_when_no_tags method method test_description_null_when_no_tags L267–272
+ test_distance_null_when_no_tags method method test_distance_null_when_no_tags L260–265
+ test_exit_code_one_when_no_tags method method test_exit_code_one_when_no_tags L247–251
+ test_no_tags_with_pre_flag_still_exit_one method method test_no_tags_with_pre_flag_still_exit_one L281–285
+ test_tag_null_when_no_tags method method test_tag_null_when_no_tags L253–258
+ TestVT38DescribeFromRef class class TestVT38DescribeFromRef L292–332
+ test_positional_ref_branch method method test_positional_ref_branch L295–310
+ test_positional_ref_commit_id method method test_positional_ref_commit_id L312–322
+ test_ref_is_positional_not_flag method method test_ref_is_positional_not_flag L324–332
+ TestVT39Abbrev class class TestVT39Abbrev L339–394
+ test_abbrev_16_gives_16_hex_chars method method test_abbrev_16_gives_16_hex_chars L376–385
+ test_abbrev_4_gives_4_hex_chars method method test_abbrev_4_gives_4_hex_chars L354–363
+ test_default_abbrev_is_8 method method test_default_abbrev_is_8 L342–352
+ test_exact_match_description_has_no_hash_suffix method method test_exact_match_description_has_no_hash_suffix L387–394
+ test_no_sha256_colon_prefix_in_description method method test_no_sha256_colon_prefix_in_description L365–374
+ TestVT40Integration class class TestVT40Integration L401–465
+ _build_five_commit_repo method method _build_five_commit_repo L404–420
+ test_describe_envelope_fields_present method method test_describe_envelope_fields_present L458–465
+ test_describe_pre_from_commit0_distance_0 method method test_describe_pre_from_commit0_distance_0 L430–438
+ test_describe_pre_from_commit4_distance_4 method method test_describe_pre_from_commit4_distance_4 L422–428
+ test_describe_with_stable_tag_found_without_pre method method test_describe_with_stable_tag_found_without_pre L448–456
+ test_describe_without_pre_only_rc_tags_exits_1 method method test_describe_without_pre_only_rc_tags_exits_1 L440–446
+ _env function function _env L29–30
+ _init_repo function function _init_repo L33–48
+ _make_commit function function _make_commit L51–80
+ _make_version_tag function function _make_version_tag L83–96
+ CliRunner import import CliRunner L17–17
+ Manifest import import Manifest L19–19
+ annotations import import annotations L10–10
+ content_hash import import content_hash L19–19
+ datetime import import datetime L12–12
+ json import import json L13–13
+ muse_dir import import muse_dir L20–20
+ pathlib import import pathlib L14–14
+ pytest import import pytest L16–16
+ ref_path import import ref_path L20–20
+ runner variable variable runner L22–22
~ muse/cli/commands/describe.py .py 1 symbol removed, 3 symbols modified
sanitize_display import import sanitize_display L66–66
~ run
~ muse/core/describe.py .py 3 symbols added, 3 symbols removed, 2 symbols modified
_StrMap variable variable _StrMap L43–43
fnmatch import import fnmatch L34–34
get_all_tags import import get_all_tags L41–41
+ VersionTagRecord import import VersionTagRecord L34–34
+ list_version_tags import import list_version_tags L34–34
+ semver_key import import semver_key L34–34
~ tests/test_cmd_describe.py .py 12 symbols added, 12 symbols removed, 10 symbols modified
_make_tag function function _make_tag L95–102
TagRecord import import TagRecord L29–29
_content_hash import import _content_hash L37–37
blob_id import import blob_id L33–33
write_object import import write_object L19–19
write_tag import import write_tag L29–29
test_describe_cli_help function function test_describe_cli_help L156–159
test_describe_cli_long_flag function function test_describe_cli_long_flag L196–202
test_describe_cli_require_tag_fails_without_tags function function test_describe_cli_require_tag_fails_without_tags L189–193
test_describe_cli_short_flags function function test_describe_cli_short_flags L205–212
test_describe_long_format function function test_describe_long_format L140–148
test_describe_no_tags_returns_shortblob_id function function test_describe_no_tags_returns_shortblob_id L110–116
+ test_default_include_pre_is_false method method test_default_include_pre_is_false L261–268
+ test_pre_flag_sets_include_pre method method test_pre_flag_sets_include_pre L252–259
+ _make_vtag function function _make_vtag L81–91
+ VersionTagRecord import import VersionTagRecord L22–22
+ content_hash import import content_hash L24–24
+ parse_semver import import parse_semver L23–23
+ write_version_tag import import write_version_tag L22–22
+ test_describe_cli_no_tags_exits_1 function function test_describe_cli_no_tags_exits_1 L159–167
+ test_describe_cli_pre_flag function function test_describe_cli_pre_flag L192–199
+ test_describe_excludes_pre_by_default function function test_describe_excludes_pre_by_default L131–136
+ test_describe_includes_pre_with_flag function function test_describe_includes_pre_with_flag L139–145
+ test_describe_no_tags_returns_none_fields function function test_describe_no_tags_returns_none_fields L99–106
~ tests/test_cmd_describe_hardening.py .py 24 symbols added, 34 symbols removed, 27 symbols modified
test_elapsed_with_require_tag method method test_elapsed_with_require_tag L789–796
test_exit_code_zero_long_format method method test_exit_code_zero_long_format L841–847
test_exit_code_zero_no_tag method method test_exit_code_zero_no_tag L817–822
test_all_eight_base_fields_present method method test_all_eight_base_fields_present L731–740
test_elapsed_present_long_format method method test_elapsed_present_long_format L703–711
test_elapsed_present_with_match method method test_elapsed_present_with_match L713–720
test_exit_code_field_is_zero method method test_exit_code_field_is_zero L742–749
_make_tag function function _make_tag L105–115
TagRecord import import TagRecord L39–39
write_tag import import write_tag L39–39
test_ansi_in_tag_name_preserved_in_json function function test_ansi_in_tag_name_preserved_in_json L343–352
test_ansi_in_tag_name_stripped_in_text_output function function test_ansi_in_tag_name_stripped_in_text_output L333–340
test_core_exact_match_off_tag_returnsblob_id function function test_core_exact_match_off_tag_returnsblob_id L247–254
test_core_exact_match_on_tag function function test_core_exact_match_on_tag L238–244
test_core_long_format_on_tag function function test_core_long_format_on_tag L193–198
test_core_long_format_with_distance function function test_core_long_format_with_distance L201–207
test_core_match_pattern_filters_tags function function test_core_match_pattern_filters_tags L219–226
test_core_match_pattern_no_match_returnsblob_id function function test_core_match_pattern_no_match_returnsblob_id L229–235
test_core_multi_tag_same_commit_lex_greatest function function test_core_multi_tag_same_commit_lex_greatest L277–285
test_core_no_tags_returns_shortblob_id function function test_core_no_tags_returns_shortblob_id L160–167
test_exact_match_not_on_tag_error function function test_exact_match_not_on_tag_error L381–387
test_flag_abbrev function function test_flag_abbrev L519–525
test_flag_exact_match_off_tag_fails function function test_flag_exact_match_off_tag_fails L495–501
test_flag_exact_match_on_tag function function test_flag_exact_match_on_tag L485–492
test_flag_match_filters_tags function function test_flag_match_filters_tags L464–472
test_flag_match_no_matching_tag function function test_flag_match_no_matching_tag L475–482
test_help_contains_new_flags function function test_help_contains_new_flags L582–586
test_integration_long_and_match_combined function function test_integration_long_and_match_combined L546–555
test_integration_ref_to_branch_tip function function test_integration_ref_to_branch_tip L533–543
test_integration_require_tag_passes_when_tag_exists function function test_integration_require_tag_passes_when_tag_exists L558–565
test_integration_text_output_sanitized function function test_integration_text_output_sanitized L568–574
test_json_schema_no_tag function function test_json_schema_no_tag L425–433
test_ref_not_found_error_on_stderr function function test_ref_not_found_error_on_stderr L367–371
test_require_tag_no_tags_error function function test_require_tag_no_tags_error L374–378
+ test_exit_code_one_no_tag method method test_exit_code_one_no_tag L691–696
+ test_all_base_fields_present method method test_all_base_fields_present L598–607
+ test_exit_code_field_is_one_on_no_tag method method test_exit_code_field_is_one_on_no_tag L627–633
+ test_exit_code_field_is_zero_on_tag method method test_exit_code_field_is_zero_on_tag L618–625
+ test_name_field_not_present method method test_name_field_not_present L609–616
+ _make_vtag function function _make_vtag L101–111
+ VersionTagRecord import import VersionTagRecord L38–38
+ parse_semver import import parse_semver L42–42
+ write_version_tag import import write_version_tag L38–38
+ test_core_default_abbrev_is_8 function function test_core_default_abbrev_is_8 L199–203
+ test_core_excludes_prerelease_by_default function function test_core_excludes_prerelease_by_default L206–211
+ test_core_includes_prerelease_with_flag function function test_core_includes_prerelease_with_flag L214–220
+ test_core_multi_tag_same_commit_highest_semver_wins function function test_core_multi_tag_same_commit_highest_semver_wins L238–246
+ test_core_no_tags_returns_none_description function function test_core_no_tags_returns_none_description L156–165
+ test_flag_abbrev_changes_short_sha_length function function test_flag_abbrev_changes_short_sha_length L410–418
+ test_flag_pre_absent_excludes_prerelease function function test_flag_pre_absent_excludes_prerelease L386–393
+ test_flag_pre_includes_prerelease function function test_flag_pre_includes_prerelease L376–383
+ test_help_contains_expected_flags function function test_help_contains_expected_flags L464–468
+ test_help_no_removed_flags function function test_help_no_removed_flags L476–479
+ test_integration_head_is_one_hop_past_tag function function test_integration_head_is_one_hop_past_tag L426–435
+ test_integration_positional_ref_branch function function test_integration_positional_ref_branch L449–456
+ test_integration_pre_flag_and_abbrev_combined function function test_integration_pre_flag_and_abbrev_combined L438–446
+ test_json_schema_no_tag_exits_1 function function test_json_schema_no_tag_exits_1 L336–345
+ test_positional_ref_not_found_error function function test_positional_ref_not_found_error L294–298
~ tests/test_describe_envelope.py .py 21 symbols added, 1 symbol removed, 1 symbol modified
test_describe_has_envelope method method test_describe_has_envelope L21–24
+ test_describe_has_envelope_no_tag method method test_describe_has_envelope_no_tag L90–95
+ test_describe_has_envelope_on_tag method method test_describe_has_envelope_on_tag L82–88
+ _REPO_ID variable variable _REPO_ID L24–24
+ _init_repo function function _init_repo L33–41
+ _make_commit function function _make_commit L44–65
+ _make_vtag function function _make_vtag L68–78
+ CommitRecord import import CommitRecord L14–14
+ Manifest import import Manifest L18–18
+ SnapshotRecord import import SnapshotRecord L15–15
+ VersionTagRecord import import VersionTagRecord L16–16
+ content_hash import import content_hash L18–18
+ datetime import import datetime L4–4
+ hash_commit import import hash_commit L13–13
+ hash_snapshot import import hash_snapshot L13–13
+ muse_dir import import muse_dir L19–19
+ parse_semver import import parse_semver L17–17
+ pathlib import import pathlib L6–6
+ ref_path import import ref_path L19–19
+ write_commit import import write_commit L14–14
+ write_snapshot import import write_snapshot L15–15
+ write_version_tag import import write_version_tag L16–16
~ tests/test_describe_walk.py .py 6 symbols added, 3 symbols modified
+ _REPO_ID variable variable _REPO_ID L31–31
+ _make_vtag function function _make_vtag L77–87
+ VersionTagRecord import import VersionTagRecord L26–26
+ content_hash import import content_hash L28–28
+ parse_semver import import parse_semver L27–27
+ write_version_tag import import write_version_tag L26–26
~ _repo

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:894647ed295b70815ea76af263faca6f8f4d4892417eb887d8c0ceb187f54a5a --body "your comment"