gabriel / muse public
feat patch prune task/supercharge-prune #1 / 1
AI Agent gabriel · 163 days ago · Apr 17, 2026 · Diff

feat(prune): supercharge muse prune — fix sha256: prefix bug, add duration_ms/exit_code/reachable_count, rewrite tests

- Fix critical sha256: prefix mismatch: _collect_all_reachable_ids now strips sha256: prefix so bare-hex filesystem IDs match reachable set (was causing all objects to appear unreachable in production) - _find_prune_candidates now exposes sha256:-prefixed object_id in candidates, consistent with ecosystem-wide object ID convention - Add duration_ms, exit_code, reachable_count to both dry-run and live JSON output - Delete tests/test_cmd_prune.py (16/18 failing — pre-sha256: prefix helpers) - Add tests/test_prune_supercharge.py: 42 tests covering unit, integration, data integrity, performance, security, and stress tiers

sha256:fbfdf35bd9641bd51b9e48140f79207db2241080bbcb58a73161fe80b35c127f sha
+78 ~3 −44 symbols
sha256:1b34d86a053e1ee50d18a18dcfd53d85e99babf49143c9fb88bd4b40fc7fee75 snapshot
+78
symbols added
~3
symbols modified
−44
symbols removed
0
dead code introduced
Semantic Changes 125 symbols
~ tests/test_prune_supercharge.py .py 78 symbols added
+ TestCollectReachable class class TestCollectReachable L155–201
+ test_contains_committed_object_ids method method test_contains_committed_object_ids L175–181
+ test_empty_repo_returns_empty_set method method test_empty_repo_returns_empty_set L156–161
+ test_multiple_commits_all_reachable method method test_multiple_commits_all_reachable L193–201
+ test_orphan_not_in_reachable method method test_orphan_not_in_reachable L183–191
+ test_returns_bare_hex_ids method method test_returns_bare_hex_ids L163–173
+ TestDataIntegrity class class TestDataIntegrity L489–528
+ test_bytes_freed_matches_actual_file_sizes method method test_bytes_freed_matches_actual_file_sizes L490–507
+ test_dry_run_bytes_freed_matches_candidate_sizes method method test_dry_run_bytes_freed_matches_candidate_sizes L520–528
+ test_reachable_count_matches_committed_objects method method test_reachable_count_matches_committed_objects L509–518
+ TestDryRun class class TestDryRun L304–387
+ test_does_not_delete_objects method method test_does_not_delete_objects L305–313
+ test_json_candidates_have_sha256_prefix method method test_json_candidates_have_sha256_prefix L358–369
+ test_json_lists_candidates method method test_json_lists_candidates L315–326
+ test_json_schema_has_duration_ms method method test_json_schema_has_duration_ms L328–336
+ test_json_schema_has_exit_code method method test_json_schema_has_exit_code L338–345
+ test_json_schema_has_reachable_count method method test_json_schema_has_reachable_count L347–356
+ test_text_output_mentions_candidates method method test_text_output_mentions_candidates L371–377
+ test_zero_orphans_dry_run method method test_zero_orphans_dry_run L379–387
+ TestFindPruneCandidates class class TestFindPruneCandidates L209–296
+ test_candidate_has_size_field method method test_candidate_has_size_field L243–253
+ test_candidate_object_id_has_sha256_prefix method method test_candidate_object_id_has_sha256_prefix L230–241
+ test_candidates_sorted_by_object_id method method test_candidates_sorted_by_object_id L288–296
+ test_empty_store_returns_empty_list method method test_empty_store_returns_empty_list L255–259
+ test_excludes_reachable_object method method test_excludes_reachable_object L221–228
+ test_expire_before_filters_recent method method test_expire_before_filters_recent L261–270
+ test_expire_before_includes_old_objects method method test_expire_before_includes_old_objects L272–286
+ test_returns_orphan method method test_returns_orphan L210–219
+ TestLivePrune class class TestLivePrune L395–481
+ test_empty_repo_exits_zero method method test_empty_repo_exits_zero L468–473
+ test_json_has_duration_ms method method test_json_has_duration_ms L415–425
+ test_json_has_exit_code method method test_json_has_exit_code L427–435
+ test_json_has_reachable_count method method test_json_has_reachable_count L437–446
+ test_json_pruned_count method method test_json_pruned_count L459–466
+ test_json_schema_complete method method test_json_schema_complete L448–457
+ test_keeps_reachable_objects method method test_keeps_reachable_objects L406–413
+ test_no_orphans_exits_zero method method test_no_orphans_exits_zero L475–481
+ test_removes_unreachable_objects method method test_removes_unreachable_objects L396–404
+ TestPerformance class class TestPerformance L607–627
+ test_100_objects_under_1_second method method test_100_objects_under_1_second L608–620
+ test_duration_ms_is_positive_number method method test_duration_ms_is_positive_number L622–627
+ TestSecurity class class TestSecurity L536–599
+ test_does_not_touch_commits_or_snapshots method method test_does_not_touch_commits_or_snapshots L537–547
+ test_dry_run_is_truly_readonly method method test_dry_run_is_truly_readonly L549–562
+ test_merge_in_progress_exits_user_error method method test_merge_in_progress_exits_user_error L585–599
+ test_no_ansi_in_json_output method method test_no_ansi_in_json_output L578–583
+ test_reachable_objects_never_deleted method method test_reachable_objects_never_deleted L564–576
+ TestStress class class TestStress L635–659
+ test_50_percent_unreachable_200_objects method method test_50_percent_unreachable_200_objects L636–648
+ test_all_objects_reachable_prunes_nothing method method test_all_objects_reachable_prunes_nothing L650–659
+ _REPO_ID variable variable _REPO_ID L59–59
+ _bare function function _bare L73–76
+ _commit_files function function _commit_files L94–131
+ _counter variable variable _counter L60–60 ← moved from tests/test_cmd_prune.py
+ _env function function _env L90–91 ← moved from tests/test_cmd_prune.py
+ _init_repo function function _init_repo L79–87 ← moved from tests/test_cmd_prune.py
+ _invoke function function _invoke L134–136 ← moved from tests/test_cmd_prune.py
+ _object_count function function _object_count L139–147
+ _oid function function _oid L68–70
+ CliRunner import import CliRunner L51–51 ← moved from tests/test_cmd_prune.py
+ CommitRecord import import CommitRecord L54–54
+ Manifest import import Manifest L55–55 ← moved from tests/test_cmd_prune.py
+ SnapshotRecord import import SnapshotRecord L54–54
+ annotations import import annotations L40–40 ← moved from tests/test_cmd_prune.py
+ compute_commit_id import import compute_commit_id L53–53
+ compute_snapshot_id import import compute_snapshot_id L53–53 ← moved from tests/test_cmd_prune.py
+ datetime import import datetime L42–42 ← moved from tests/test_cmd_prune.py
+ has_object import import has_object L52–52
+ hashlib import import hashlib L43–43 ← moved from tests/test_cmd_prune.py
+ json import import json L44–44 ← moved from tests/test_cmd_prune.py
+ os import import os L45–45
+ pathlib import import pathlib L46–46 ← moved from tests/test_cmd_prune.py
+ pytest import import pytest L49–49 ← moved from tests/test_cmd_prune.py
+ time import import time L47–47 ← moved from tests/test_cmd_prune.py
+ write_commit import import write_commit L54–54
+ write_object import import write_object L52–52 ← moved from tests/test_cmd_prune.py
+ write_snapshot import import write_snapshot L54–54 ← moved from tests/test_cmd_prune.py
+ runner variable variable runner L57–57 ← moved from tests/test_cmd_prune.py
~ tests/test_cmd_prune.py .py 44 symbols removed
− _REPO_ID variable variable _REPO_ID L32–32
− _commit_files function function _commit_files L60–97
− _counter variable variable _counter L33–33 → moved to tests/test_prune_supercharge.py
− _env function function _env L56–57 → moved to tests/test_prune_supercharge.py
− _init_repo function function _init_repo L45–53 → moved to tests/test_prune_supercharge.py
− _invoke function function _invoke L100–102 → moved to tests/test_prune_supercharge.py
− _object_count function function _object_count L105–114
− _sha function function _sha L41–42
− CliRunner import import CliRunner L24–24 → moved to tests/test_prune_supercharge.py
− CommitRecord import import CommitRecord L27–27
− Manifest import import Manifest L28–28 → moved to tests/test_prune_supercharge.py
− SnapshotRecord import import SnapshotRecord L27–27
− annotations import import annotations L14–14 → moved to tests/test_prune_supercharge.py
− compute_commit_id import import compute_commit_id L26–26
− compute_snapshot_id import import compute_snapshot_id L26–26 → moved to tests/test_prune_supercharge.py
− datetime import import datetime L16–16 → moved to tests/test_prune_supercharge.py
− has_object import import has_object L25–25
− hashlib import import hashlib L17–17 → moved to tests/test_prune_supercharge.py
− json import import json L18–18 → moved to tests/test_prune_supercharge.py
− pathlib import import pathlib L19–19 → moved to tests/test_prune_supercharge.py
− pytest import import pytest L22–22 → moved to tests/test_prune_supercharge.py
− time import import time L20–20 → moved to tests/test_prune_supercharge.py
− write_commit import import write_commit L27–27
− write_object import import write_object L25–25 → moved to tests/test_prune_supercharge.py
− write_snapshot import import write_snapshot L27–27 → moved to tests/test_prune_supercharge.py
− runner variable variable runner L30–30 → moved to tests/test_prune_supercharge.py
− test_collect_all_reachable_ids_after_commit function function test_collect_all_reachable_ids_after_commit L129–135
− test_collect_all_reachable_ids_empty_repo function function test_collect_all_reachable_ids_empty_repo L122–126
− test_collect_all_reachable_ids_excludes_orphan function function test_collect_all_reachable_ids_excludes_orphan L138–146
− test_find_prune_candidates_excludes_reachable function function test_find_prune_candidates_excludes_reachable L167–174
− test_find_prune_candidates_expire_before_filters_recent function function test_find_prune_candidates_expire_before_filters_recent L177–188
− test_find_prune_candidates_expire_old_objects function function test_find_prune_candidates_expire_old_objects L191–209
− test_find_prune_candidates_returns_orphan function function test_find_prune_candidates_returns_orphan L154–164
− test_prune_50_percent_unreachable function function test_prune_50_percent_unreachable L344–357
− test_prune_does_not_touch_commits_or_snapshots function function test_prune_does_not_touch_commits_or_snapshots L326–336
− test_prune_dry_run_does_not_delete_objects function function test_prune_dry_run_does_not_delete_objects L217–227
− test_prune_dry_run_json_lists_candidates function function test_prune_dry_run_json_lists_candidates L230–242
− test_prune_dry_run_text_mentions_candidates function function test_prune_dry_run_text_mentions_candidates L245–251
− test_prune_empty_repo_exits_zero function function test_prune_empty_repo_exits_zero L304–309
− test_prune_json_pruned_count function function test_prune_json_pruned_count L294–301
− test_prune_json_schema function function test_prune_json_schema L281–291
− test_prune_keeps_reachable_objects function function test_prune_keeps_reachable_objects L271–278
− test_prune_no_orphans_exits_zero function function test_prune_no_orphans_exits_zero L312–318
− test_prune_removes_unreachable_objects function function test_prune_removes_unreachable_objects L259–268
← Older Oldest on task/supercharge-prune
All commits
Newer → Latest on task/supercharge-prune

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