gabriel / muse public
feat patch task/reject-bare-hex-cli #1 / 1
AI Agent gabriel · 161 days ago · Apr 18, 2026 · Diff

feat: reject bare hex at all CLI boundaries — TDD

sha256: prefix is a type tag (algorithm identifier), not decoration. Accepting bare hex at CLI boundaries forecloses future algorithm agility: if blake3: IDs are ever added, bare hex becomes fatally ambiguous.

Rule: bare hex is never accepted at any CLI input point. The only place bare hex exists is on disk (filenames) — stripped on write, restored on read.

Changes: - snapshot_cmd.py: add _is_bare_hex / _reject_if_bare_hex guards; call in run_snapshot_read and run_snapshot_export before any resolution - snapshot_diff.py: _resolve_snapshot_prefix now requires sha256: prefix (bare hex returns None immediately); run() checks both refs at CLI entry before _compute_diff is ever called - verify_commit.py: bare hex detected in the existing ref validation loop; clear error message with sha256: guidance emitted before any resolution - show.py: bare hex detected before the SHA256_FULL/PREFIX regex block; same helpful error message with sha256: guidance

Tests: - test_bare_hex_rejection.py (new, 27 tests): covers all four boundaries — snapshot read, snapshot export, snapshot-diff (both refs), verify-commit, show — for bare full hex, bare short hex, and sha256:-prefixed acceptance - Updated existing tests that were passing bare hex: flip rejection tests to assert exit_code != 0; update acceptance tests to use sha256: prefix

sha256:9ccfb1f37ad067e0091e3ba70c87d346bd336ad5d950f36f99a6165aef9bcf05 sha
+61 ~13 −2 symbols
sha256:f832d7a00e9157da7e2741a9cc965ac283a77354a906a6065ae06c62f07d4b17 snapshot
+61
symbols added
~13
symbols modified
−2
symbols removed
0
dead code introduced
Semantic Changes 76 symbols
~ tests/test_bare_hex_rejection.py .py 57 symbols added
+ TestShowBareHexRejected class class TestShowBareHexRejected L369–409
+ test_bare_full_hex_rejected method method test_bare_full_hex_rejected L377–380
+ test_bare_short_hex_rejected method method test_bare_short_hex_rejected L382–385
+ test_branch_name_still_accepted method method test_branch_name_still_accepted L395–401
+ test_head_still_accepted method method test_head_still_accepted L403–409
+ test_prefixed_full_id_accepted method method test_prefixed_full_id_accepted L387–393
+ TestSnapshotDiffBareHexRejected class class TestSnapshotDiffBareHexRejected L234–334
+ test_both_prefixed_full_ids_accepted method method test_both_prefixed_full_ids_accepted L269–276
+ test_both_prefixed_short_accepted method method test_both_prefixed_short_accepted L302–313
+ test_branch_name_still_accepted method method test_branch_name_still_accepted L315–325
+ test_head_still_accepted method method test_head_still_accepted L327–334
+ test_ref_a_bare_hex_full_rejected method method test_ref_a_bare_hex_full_rejected L237–243
+ test_ref_a_bare_short_hex_rejected method method test_ref_a_bare_short_hex_rejected L253–259
+ test_ref_a_prefixed_short_accepted method method test_ref_a_prefixed_short_accepted L278–288
+ test_ref_b_bare_hex_full_rejected method method test_ref_b_bare_hex_full_rejected L245–251
+ test_ref_b_bare_short_hex_rejected method method test_ref_b_bare_short_hex_rejected L261–267
+ test_ref_b_prefixed_short_accepted method method test_ref_b_prefixed_short_accepted L290–300
+ TestSnapshotExportBareHexRejected class class TestSnapshotExportBareHexRejected L179–226
+ test_full_bare_hex_rejected method method test_full_bare_hex_rejected L182–190
+ test_prefixed_id_accepted method method test_prefixed_id_accepted L202–211
+ test_prefixed_short_id_accepted method method test_prefixed_short_id_accepted L213–226
+ test_short_bare_hex_rejected method method test_short_bare_hex_rejected L192–200
+ TestSnapshotReadBareHexRejected class class TestSnapshotReadBareHexRejected L130–171
+ test_8_char_bare_hex_rejected method method test_8_char_bare_hex_rejected L143–146
+ test_error_message_mentions_sha256_prefix method method test_error_message_mentions_sha256_prefix L148–154
+ test_full_bare_hex_rejected method method test_full_bare_hex_rejected L133–136
+ test_prefixed_full_id_accepted method method test_prefixed_full_id_accepted L156–160
+ test_prefixed_short_id_accepted method method test_prefixed_short_id_accepted L162–171
+ test_short_bare_hex_rejected method method test_short_bare_hex_rejected L138–141
+ TestVerifyCommitBareHexRejected class class TestVerifyCommitBareHexRejected L342–361
+ test_bare_64hex_rejected method method test_bare_64hex_rejected L345–350
+ test_prefixed_id_not_found_is_not_bare_hex_error method method test_prefixed_id_not_found_is_not_bare_hex_error L352–361
+ _BARE_HEX_FULL variable variable _BARE_HEX_FULL L57–57
+ _BARE_HEX_SHORT variable variable _BARE_HEX_SHORT L58–58
+ _INVALID_LOOK variable variable _INVALID_LOOK L59–59
+ _commit function function _commit L96–114
+ _create_snapshot_and_commit function function _create_snapshot_and_commit L117–122
+ _env function function _env L73–74
+ _init_repo function function _init_repo L62–70
+ _obj function function _obj L77–80
+ _snap function function _snap L83–93
+ cli variable variable cli L49–49
+ CliRunner import import CliRunner L47–47
+ CommitRecord import import CommitRecord L41–41
+ Manifest import import Manifest L38–38
+ SnapshotRecord import import SnapshotRecord L41–41
+ annotations import import annotations L32–32
+ blob_id import import blob_id L38–38
+ compute_commit_id import import compute_commit_id L40–40
+ compute_snapshot_id import import compute_snapshot_id L40–40
+ datetime import import datetime L34–34
+ json import import json L35–35
+ pathlib import import pathlib L36–36
+ write_commit import import write_commit L41–41
+ write_object import import write_object L39–39
+ write_snapshot import import write_snapshot L41–41
+ runner variable variable runner L50–50
~ muse/cli/commands/show.py .py 1 symbol modified
~ run
~ muse/cli/commands/snapshot_cmd.py .py 2 symbols added, 2 symbols modified
+ _is_bare_hex function function _is_bare_hex L260–269
+ _reject_if_bare_hex function function _reject_if_bare_hex L272–286
~ muse/cli/commands/verify_commit.py .py 1 symbol modified
~ run
~ tests/test_cmd_snapshot_diff_supercharge.py .py 1 symbol added, 1 symbol removed, 4 symbols modified
− test_bare_hex_prefix_resolves method method test_bare_hex_prefix_resolves L836–847
+ test_bare_hex_prefix_rejected method method test_bare_hex_prefix_rejected L836–846
~ tests/test_cmd_snapshot_supercharge.py .py 1 symbol added, 1 symbol removed, 1 symbol modified
− test_read_by_hex_prefix_succeeds method method test_read_by_hex_prefix_succeeds L308–315
+ test_bare_hex_prefix_rejected method method test_bare_hex_prefix_rejected L308–315
← Older Oldest on task/reject-bare-hex-cli
All commits
Newer → Latest on task/reject-bare-hex-cli

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