gabriel / muse public
feat patch update-ref task/supercharge-update-ref #1 / 1
AI Agent gabriel · 160 days ago · Apr 18, 2026 · Diff

feat(update-ref): supercharge — elapsed_ms, exit_code, JSON errors to stdout, TypedDicts

- elapsed_ms and exit_code in every JSON success path (create, update, delete) - _emit_error() helper: JSON mode errors route to stdout so agents always receive parseable output; text mode errors go to stderr - All error keys now structured: invalid_branch, invalid_commit_id, ref_not_found, cas_mismatch, missing_commit_id, write_error, invalid_format - CAS mismatch errors include current and expected fields in JSON output - TypedDicts: _UpdateRefJson and _DeleteRefJson for both success shapes - Module docstring updated: JSON error contract, CAS error schema, all exit codes - Fixed 2 pre-existing test failures (bare hex IDs without sha256: prefix) - 49 new tests (test_cmd_update_ref_supercharge.py) using long_id, short_id, blob_id utilities throughout: elapsed_ms/exit_code in all success paths, JSON errors to stdout on all error paths, schema completeness (error and success payloads), data integrity (exit_code 1 vs 3 semantics, previous field, CAS current/expected), performance bounds, security (no traceback on any error path, path traversal rejection, ANSI rejection), concurrency (16 threads updating independent branches in parallel)

sha256:f3d32594fe276d7432e986342461e5fb9b827a48eac879de87a9c06f353a891f sha
+91 ~7 symbols
sha256:7b12fe7d3dac47994afadef6e1d1dbbe07f9b4dd2ba7e12958dd7f29b8296b61 snapshot
+91
symbols added
~7
symbols modified
0
dead code introduced
Semantic Changes 98 symbols
+ TestCASSchema class class TestCASSchema L493–542
+ test_cas1_null_guard_mismatch_has_elapsed_ms method method test_cas1_null_guard_mismatch_has_elapsed_ms L496–505
+ test_cas2_mismatch_error_to_stdout_not_stderr method method test_cas2_mismatch_error_to_stdout_not_stderr L507–520
+ test_cas3_success_has_elapsed_ms method method test_cas3_success_has_elapsed_ms L522–531
+ test_cas4_invalid_old_value_format_error_on_stdout method method test_cas4_invalid_old_value_format_error_on_stdout L533–542
+ TestConcurrency class class TestConcurrency L646–676
+ test_c1_parallel_independent_branch_updates method method test_c1_parallel_independent_branch_updates L649–676
+ TestDataIntegrity class class TestDataIntegrity L392–485
+ test_d10_short_id_is_prefix_of_long_id method method test_d10_short_id_is_prefix_of_long_id L479–485
+ test_d1_previous_is_none_for_new_ref method method test_d1_previous_is_none_for_new_ref L395–400
+ test_d2_previous_matches_old_commit method method test_d2_previous_matches_old_commit L402–410
+ test_d3_branch_field_matches_arg method method test_d3_branch_field_matches_arg L412–417
+ test_d4_deleted_true_on_delete method method test_d4_deleted_true_on_delete L419–424
+ test_d5_exit_code_1_for_user_errors method method test_d5_exit_code_1_for_user_errors L426–431
+ test_d6_exit_code_3_for_write_failure method method test_d6_exit_code_3_for_write_failure L433–443
+ test_d7_cas_mismatch_includes_current_and_expected method method test_d7_cas_mismatch_includes_current_and_expected L445–457
+ test_d8_blob_id_produces_unique_valid_ids method method test_d8_blob_id_produces_unique_valid_ids L459–465
+ test_d9_long_id_produces_correct_prefix method method test_d9_long_id_produces_correct_prefix L467–477
+ TestElapsedMsExitCode class class TestElapsedMsExitCode L105–201
+ test_u10_short_id_in_output_is_not_expected method method test_u10_short_id_in_output_is_not_expected L192–201
+ test_u1_create_ref_has_elapsed_ms method method test_u1_create_ref_has_elapsed_ms L108–115
+ test_u2_create_ref_has_exit_code_zero method method test_u2_create_ref_has_exit_code_zero L117–124
+ test_u3_update_ref_has_elapsed_ms method method test_u3_update_ref_has_elapsed_ms L126–135
+ test_u4_update_ref_has_exit_code_zero method method test_u4_update_ref_has_exit_code_zero L137–145
+ test_u5_delete_ref_has_elapsed_ms method method test_u5_delete_ref_has_elapsed_ms L147–155
+ test_u6_delete_ref_has_exit_code_zero method method test_u6_delete_ref_has_exit_code_zero L157–164
+ test_u7_elapsed_ms_is_float method method test_u7_elapsed_ms_is_float L166–173
+ test_u8_elapsed_ms_non_negative method method test_u8_elapsed_ms_non_negative L175–181
+ test_u9_no_verify_success_has_elapsed_ms method method test_u9_no_verify_success_has_elapsed_ms L183–190
+ TestErrorJsonSchema class class TestErrorJsonSchema L300–384
+ _parse_error method method _parse_error L303–304
+ _required_keys method method _required_keys L306–307
+ test_s1_invalid_branch_error_schema method method test_s1_invalid_branch_error_schema L309–315
+ test_s2_commit_not_found_error_schema method method test_s2_commit_not_found_error_schema L317–323
+ test_s3_cas_mismatch_error_schema method method test_s3_cas_mismatch_error_schema L325–335
+ test_s4_write_failure_error_schema method method test_s4_write_failure_error_schema L337–348
+ test_s5_error_elapsed_ms_is_float_non_negative method method test_s5_error_elapsed_ms_is_float_non_negative L350–356
+ test_s6_error_exit_code_matches_process_exit method method test_s6_error_exit_code_matches_process_exit L358–363
+ test_s7_success_json_all_fields_present method method test_s7_success_json_all_fields_present L365–373
+ test_s8_delete_json_all_fields_present method method test_s8_delete_json_all_fields_present L375–384
+ TestJsonErrorsToStdout class class TestJsonErrorsToStdout L209–292
+ test_e1_invalid_branch_json_error_on_stdout method method test_e1_invalid_branch_json_error_on_stdout L212–219
+ test_e2_commit_not_found_json_error_on_stdout method method test_e2_commit_not_found_json_error_on_stdout L221–229
+ test_e3_invalid_commit_id_json_error_on_stdout method method test_e3_invalid_commit_id_json_error_on_stdout L231–238
+ test_e4_delete_nonexistent_json_error_on_stdout method method test_e4_delete_nonexistent_json_error_on_stdout L240–247
+ test_e5_cas_mismatch_json_error_on_stdout method method test_e5_cas_mismatch_json_error_on_stdout L249–260
+ test_e6_no_commit_id_json_error_on_stdout method method test_e6_no_commit_id_json_error_on_stdout L262–269
+ test_e7_text_mode_errors_on_stderr method method test_e7_text_mode_errors_on_stderr L271–277
+ test_e8_write_failure_json_error_on_stdout method method test_e8_write_failure_json_error_on_stdout L279–292
+ TestPerformance class class TestPerformance L550–576
+ test_p1_single_update_under_2000ms method method test_p1_single_update_under_2000ms L553–559
+ test_p2_delete_under_2000ms method method test_p2_delete_under_2000ms L561–567
+ test_p3_200_sequential_updates_all_have_elapsed_ms method method test_p3_200_sequential_updates_all_have_elapsed_ms L569–576
+ TestSecurity class class TestSecurity L584–638
+ test_sec1_no_traceback_invalid_branch_json_mode method method test_sec1_no_traceback_invalid_branch_json_mode L587–593
+ test_sec2_no_traceback_write_failure_json_mode method method test_sec2_no_traceback_write_failure_json_mode L595–606
+ test_sec3_no_traceback_write_failure_text_mode method method test_sec3_no_traceback_write_failure_text_mode L608–619
+ test_sec4_path_traversal_in_branch_rejected method method test_sec4_path_traversal_in_branch_rejected L621–629
+ test_sec5_ansi_in_branch_rejected_json_mode method method test_sec5_ansi_in_branch_rejected_json_mode L631–638
+ _COMMITTED_AT variable variable _COMMITTED_AT L39–39
+ _SNAP_ID variable variable _SNAP_ID L38–38
+ _commit function function _commit L66–77
+ _fake_id function function _fake_id L95–97
+ _make_repo function function _make_repo L47–54
+ _snap function function _snap L57–63
+ _ur function function _ur L86–92
+ _write_ref function function _write_ref L80–83
+ CliRunner import import CliRunner L34–34
+ CommitRecord import import CommitRecord L32–32
+ ExitCode import import ExitCode L30–30
+ InvokeResult import import InvokeResult L34–34
+ SnapshotRecord import import SnapshotRecord L32–32
+ annotations import import annotations L20–20
+ blob_id import import blob_id L33–33
+ compute_commit_id import import compute_commit_id L31–31
+ compute_snapshot_id import import compute_snapshot_id L31–31
+ datetime import import datetime L22–22
+ json import import json L23–23
+ long_id import import long_id L33–33
+ mock import import mock L26–26
+ pathlib import import pathlib L24–24
+ pytest import import pytest L28–28
+ short_id import import short_id L33–33
+ threading import import threading L25–25
+ write_commit import import write_commit L32–32
+ write_snapshot import import write_snapshot L32–32
+ runner variable variable runner L36–36
~ muse/cli/commands/update_ref.py .py 4 symbols added, 1 symbol modified
+ _DeleteRefJson class class _DeleteRefJson L94–99
+ _UpdateRefJson class class _UpdateRefJson L85–91
+ TypedDict import import TypedDict L73–73
+ time import import time L72–72
~ run
← Older Oldest on task/supercharge-update-ref
All commits
Newer → Latest on task/supercharge-update-ref

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