gabriel / muse public
feat patch dev
AI Agent gabriel · 159 days ago · Apr 19, 2026 · Diff

feat: supercharge muse verify-tag — envelope JSON, TypedDicts, duration_ms, exit_code

- Switch --json output from per-tag NDJSON lines to a single envelope matching the name-rev/verify-pack pattern: {results, exit_code, duration_ms} - Add TypedDicts _TagResult and _TagVerifyJson for type-safe JSON construction - Add start_timer() call so duration_ms is always present in the envelope - Update module docstring to document all envelope fields and exit codes - Update 4 existing tests to parse the new envelope format (results[0]) - Add tests/test_verify_tag_supercharge.py: 50 tests across 10 classes covering envelope shape, TypedDicts, docstring, payload binding, algorithm branches, text output, no-prose-pollution, security, and stress scenarios

sha256:559f14897d08a726f9d29cbade670531eb1c90de20c3e2f47f079053498bf516 sha
+101 ~6 symbols
sha256:0d0c90383e4fee7b65ec8f5f3c7929ea2ddb00f0aedbb3651657d22ca7131222 snapshot
+101
symbols added
~6
symbols modified
0
dead code introduced
Semantic Changes 107 symbols
~ tests/test_verify_tag_supercharge.py .py 97 symbols added
+ TestAlgorithmBranches class class TestAlgorithmBranches L362–412
+ test_decode_pubkey_valueerror_returns_invalid method method test_decode_pubkey_valueerror_returns_invalid L393–401
+ test_empty_pubkey_returns_invalid method method test_empty_pubkey_returns_invalid L403–412
+ test_unknown_pubkey_algo_returns_error method method test_unknown_pubkey_algo_returns_error L379–391
+ test_unknown_sig_algo_returns_error method method test_unknown_sig_algo_returns_error L363–377
+ TestDocstring class class TestDocstring L286–295
+ _doc method method _doc L287–289
+ test_docstring_covers_duration_ms method method test_docstring_covers_duration_ms L294–295
+ test_docstring_covers_exit_code method method test_docstring_covers_exit_code L291–292
+ TestJsonEnvelopeDurationMs class class TestJsonEnvelopeDurationMs L219–242
+ test_not_found_has_duration_ms method method test_not_found_has_duration_ms L230–235
+ test_unsigned_has_duration_ms method method test_unsigned_has_duration_ms L237–242
+ test_valid_has_duration_ms method method test_valid_has_duration_ms L220–228
+ TestJsonEnvelopeExitCode class class TestJsonEnvelopeExitCode L149–211
+ test_batch_all_valid_exit_code_zero method method test_batch_all_valid_exit_code_zero L191–198
+ test_batch_one_invalid_exit_code_nonzero method method test_batch_one_invalid_exit_code_nonzero L200–211
+ test_invalid_tag_exit_code_nonzero method method test_invalid_tag_exit_code_nonzero L159–168
+ test_not_found_exit_code_nonzero method method test_not_found_exit_code_nonzero L185–189
+ test_unsigned_no_strict_exit_code_zero method method test_unsigned_no_strict_exit_code_zero L170–175
+ test_unsigned_strict_exit_code_nonzero method method test_unsigned_strict_exit_code_nonzero L177–183
+ test_valid_tag_exit_code_zero method method test_valid_tag_exit_code_zero L150–157
+ TestNoProsePollution class class TestNoProsePollution L482–525
+ test_json_stdout_is_valid_json method method test_json_stdout_is_valid_json L483–489
+ test_no_emoji_in_json_stdout method method test_no_emoji_in_json_stdout L491–498
+ test_no_traceback_in_output method method test_no_traceback_in_output L500–504
+ test_results_is_a_list method method test_results_is_a_list L506–513
+ test_results_order_matches_input_order method method test_results_order_matches_input_order L515–525
+ TestPayloadBinding class class TestPayloadBinding L303–354
+ _tag_with_tamper method method _tag_with_tamper L304–311
+ test_tamper_commit_id_invalidates method method test_tamper_commit_id_invalidates L320–326
+ test_tamper_created_at_invalidates method method test_tamper_created_at_invalidates L328–334
+ test_tamper_key_id_invalidates method method test_tamper_key_id_invalidates L336–341
+ test_tamper_message_invalidates method method test_tamper_message_invalidates L313–318
+ test_tamper_tag_name_invalidates method method test_tamper_tag_name_invalidates L343–354
+ TestSecurity class class TestSecurity L533–575
+ test_ansi_escape_in_tag_name_rejected method method test_ansi_escape_in_tag_name_rejected L544–547
+ test_invalid_name_rejected_with_error_on_stderr method method test_invalid_name_rejected_with_error_on_stderr L570–575
+ test_null_byte_in_tag_name_rejected method method test_null_byte_in_tag_name_rejected L534–537
+ test_path_traversal_in_tag_name_rejected method method test_path_traversal_in_tag_name_rejected L539–542
+ test_semicolon_in_tag_name_rejected method method test_semicolon_in_tag_name_rejected L554–557
+ test_space_in_tag_name_rejected method method test_space_in_tag_name_rejected L549–552
+ test_very_long_tag_name_rejected method method test_very_long_tag_name_rejected L559–568
+ TestStress class class TestStress L583–637
+ test_100_signed_tags_all_valid method method test_100_signed_tags_all_valid L584–593
+ test_100_tags_duration_ms_non_negative method method test_100_tags_duration_ms_non_negative L628–637
+ test_batch_json_has_correct_result_count method method test_batch_json_has_correct_result_count L595–605
+ test_mixed_valid_invalid_batch_exit_nonzero method method test_mixed_valid_invalid_batch_exit_nonzero L607–626
+ TestTextOutput class class TestTextOutput L420–474
+ test_invalid_sig_shows_bad_prefix method method test_invalid_sig_shows_bad_prefix L465–474
+ test_not_found_shows_err_prefix method method test_not_found_shows_err_prefix L437–441
+ test_signed_tag_shows_key_part method method test_signed_tag_shows_key_part L443–449
+ test_tag_name_appears_in_text_output method method test_tag_name_appears_in_text_output L458–463
+ test_unsigned_tag_no_key_part method method test_unsigned_tag_no_key_part L451–456
+ test_unsigned_tag_shows_bad_prefix method method test_unsigned_tag_shows_bad_prefix L430–435
+ test_valid_tag_shows_ok_prefix method method test_valid_tag_shows_ok_prefix L421–428
+ TestTypedDicts class class TestTypedDicts L250–278
+ test_tag_result_has_required_fields method method test_tag_result_has_required_fields L259–263
+ test_tag_result_typeddict_exists method method test_tag_result_typeddict_exists L251–253
+ test_tag_verify_json_has_duration_ms method method test_tag_verify_json_has_duration_ms L270–273
+ test_tag_verify_json_has_exit_code method method test_tag_verify_json_has_exit_code L265–268
+ test_tag_verify_json_has_results method method test_tag_verify_json_has_results L275–278
+ test_tag_verify_json_typeddict_exists method method test_tag_verify_json_typeddict_exists L255–257
+ _DT variable variable _DT L43–43
+ _REPO_ID variable variable _REPO_ID L42–42
+ _commit function function _commit L72–88
+ _counter variable variable _counter L44–44
+ _env function function _env L63–64
+ _envelope function function _envelope L139–141
+ _force_write_tag function function _force_write_tag L125–131
+ _init_repo function function _init_repo L52–60
+ _make_key function function _make_key L67–69
+ _make_tag function function _make_tag L91–122
+ _vt function function _vt L134–136
+ CliRunner import import CliRunner L38–38
+ CommitRecord import import CommitRecord L30–30
+ SnapshotRecord import import SnapshotRecord L30–30
+ TagRecord import import TagRecord L30–30
+ annotations import import annotations L15–15
+ blob_id import import blob_id L26–26
+ compute_commit_id import import compute_commit_id L29–29
+ compute_snapshot_id import import compute_snapshot_id L29–29
+ datetime import import datetime L17–17
+ decode_sig import import decode_sig L26–26
+ encode_public_key import import encode_public_key L28–28
+ encode_sig import import encode_sig L26–26
+ get_type_hints import import get_type_hints L21–21
+ json import import json L18–18
+ patch import import patch L22–22
+ pathlib import import pathlib L19–19
+ pytest import import pytest L24–24
+ sign_commit_ed25519 import import sign_commit_ed25519 L28–28
+ uuid import import uuid L20–20
+ write_commit import import write_commit L30–30
+ write_object import import write_object L27–27
+ write_snapshot import import write_snapshot L30–30
+ write_tag import import write_tag L30–30
+ runner variable variable runner L40–40
~ muse/cli/commands/verify_tag.py .py 4 symbols added, 2 symbols modified
+ _TagResult class class _TagResult L110–119
+ _TagVerifyJson class class _TagVerifyJson L122–127
+ TypedDict import import TypedDict L80–80
+ start_timer import import start_timer L87–87
~ Any
~ run
← Older Oldest on dev
All commits
Newer → Latest on dev

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