gabriel / muse public
feat patch task/supercharge-narrative-and-test-speedup #1 / 1
AI Agent gabriel · 159 days ago · Apr 19, 2026 · Diff

feat: supercharge narrative + wire CallGraphCache into test selection

narrative (-j alias, exit_code, duration_ms in JSON envelope; run() docstring; _NarrativeJson TypedDict updated with new fields)

test selection speedup (select_tests now accepts callgraph_cache=; loads and saves CallGraphCache so build_forward_graph hits the warm path on second run, skipping read_object + ast.parse + AST walk per file; test_cmd.py loads one shared SymbolCache and passes it to both changed_symbols_from_diff and select_tests, eliminating a second disk load)

pre-existing fixes: test_core_test_selection.py, test_cmd_test.py blob_id patterns corrected (sha256:<hex> canonical format)

new tests: test_narrative_supercharge.py (65 tests), test_test_selection_speedup.py (12 tests), test_core_test_selection.py (11 pre-existing failures fixed)

sha256:fbd5bc4dd4020960a51af609b8e4bb290e7dc166d8b78511a3ec71c84feddf80 sha
+131 ~7 symbols
sha256:dbcfe31b37ce145a9d1dd7ce1aaa7db88aad1bbc1fd6f2bbcc5642d94010340b snapshot
+131
symbols added
~7
symbols modified
0
dead code introduced
Semantic Changes 138 symbols
~ tests/test_narrative_supercharge.py .py 98 symbols added
+ ADDR variable variable ADDR L98–98
+ CMD variable variable CMD L97–97
+ TestClassifyOp class class TestClassifyOp L274–320
+ _op method method _op L275–278
+ test_body_keyword_in_old_summary_is_impl method method test_body_keyword_in_old_summary_is_impl L308–311
+ test_delete_is_delete method method test_delete_is_delete L284–286
+ test_implementation_keyword_in_new_summary method method test_implementation_keyword_in_new_summary L303–306
+ test_insert_is_create method method test_insert_is_create L280–282
+ test_moved_keyword_in_new_summary method method test_moved_keyword_in_new_summary L293–296
+ test_other_op_kind_returns_other method method test_other_op_kind_returns_other L318–320
+ test_rename_keyword_in_new_summary method method test_rename_keyword_in_new_summary L288–291
+ test_signature_keyword_in_new_summary method method test_signature_keyword_in_new_summary L298–301
+ test_unknown_replace_defaults_to_impl method method test_unknown_replace_defaults_to_impl L313–316
+ TestDaysAgo class class TestDaysAgo L422–457
+ _dt method method _dt L423–425
+ test_few_days method method test_few_days L435–438
+ test_months method method test_months L445–448
+ test_none_returns_unknown method method test_none_returns_unknown L455–457
+ test_today method method test_today L427–429
+ test_weeks method method test_weeks L440–443
+ test_years method method test_years L450–453
+ test_yesterday method method test_yesterday L431–433
+ TestEventDetail class class TestEventDetail L551–582
+ _raw_event method method _raw_event L552–563
+ test_create_event_returns_summary method method test_create_event_returns_summary L571–575
+ test_impl_event_returns_empty method method test_impl_event_returns_empty L577–582
+ test_rename_event_extracts_arrow method method test_rename_event_extracts_arrow L565–569
+ TestExtractRename class class TestExtractRename L514–543
+ test_case_insensitive_match method method test_case_insensitive_match L539–543
+ test_empty_summaries_return_empty method method test_empty_summaries_return_empty L533–537
+ test_fallback_from_colons method method test_fallback_from_colons L527–531
+ test_moved_x_to_y_pattern method method test_moved_x_to_y_pattern L521–525
+ test_renamed_x_to_y_pattern method method test_renamed_x_to_y_pattern L515–519
+ TestFormatDate class class TestFormatDate L363–414
+ _dt method method _dt L364–365
+ test_format_date_basic method method test_format_date_basic L367–372
+ test_format_date_long_11th_exception method method test_format_date_long_11th_exception L400–404
+ test_format_date_long_12th_exception method method test_format_date_long_12th_exception L406–409
+ test_format_date_long_13th_exception method method test_format_date_long_13th_exception L411–414
+ test_format_date_long_nd_suffix method method test_format_date_long_nd_suffix L385–388
+ test_format_date_long_rd_suffix method method test_format_date_long_rd_suffix L390–393
+ test_format_date_long_st_suffix method method test_format_date_long_st_suffix L380–383
+ test_format_date_long_th_suffix method method test_format_date_long_th_suffix L395–398
+ test_format_date_no_double_space method method test_format_date_no_double_space L374–378
+ TestJsonAlias class class TestJsonAlias L106–123
+ test_j_alias_emits_valid_json method method test_j_alias_emits_valid_json L111–114
+ test_j_alias_exits_zero method method test_j_alias_exits_zero L107–109
+ test_j_alias_same_as_json_flag method method test_j_alias_same_as_json_flag L116–123
+ TestJsonContextFields class class TestJsonContextFields L175–212
+ _json method method _json L176–179
+ test_kind_is_function method method test_kind_is_function L181–183
+ test_last_impl_commit_nonempty_when_impl_exists method method test_last_impl_commit_nonempty_when_impl_exists L199–204
+ test_last_impl_date_is_date_format method method test_last_impl_date_is_date_format L206–212
+ test_renames_is_int method method test_renames_is_int L190–193
+ test_sig_changes_gte_one method method test_sig_changes_gte_one L185–188
+ test_truncated_false_for_small_repo method method test_truncated_false_for_small_repo L195–197
+ TestJsonDurationMs class class TestJsonDurationMs L153–167
+ test_duration_ms_is_float_or_int method method test_duration_ms_is_float_or_int L164–167
+ test_duration_ms_is_positive method method test_duration_ms_is_positive L159–162
+ test_duration_ms_present_in_json method method test_duration_ms_present_in_json L154–157
+ TestJsonExitCode class class TestJsonExitCode L131–145
+ test_exit_code_is_int method method test_exit_code_is_int L142–145
+ test_exit_code_is_zero_on_success method method test_exit_code_is_zero_on_success L137–140
+ test_exit_code_present_in_json method method test_exit_code_present_in_json L132–135
+ TestJsonSingleLine class class TestJsonSingleLine L220–232
+ test_json_output_is_single_line method method test_json_output_is_single_line L221–224
+ test_json_output_parseable_without_strip method method test_json_output_parseable_without_strip L226–232
+ TestRelativeTo class class TestRelativeTo L465–506
+ _dt method method _dt L466–467
+ test_days_later method method test_days_later L480–485
+ test_months_later method method test_months_later L494–499
+ test_one_day_later method method test_one_day_later L474–478
+ test_same_day method method test_same_day L469–472
+ test_weeks_later method method test_weeks_later L487–492
+ test_years_later method method test_years_later L501–506
+ TestSanitiseMsg class class TestSanitiseMsg L328–355
+ test_null_byte_stripped method method test_null_byte_stripped L352–355
+ test_short_message_unchanged method method test_short_message_unchanged L342–345
+ test_strips_control_chars method method test_strips_control_chars L329–334
+ test_trailing_ellipsis_on_truncation method method test_trailing_ellipsis_on_truncation L347–350
+ test_truncates_at_72 method method test_truncates_at_72 L336–340
+ TestShowSourceWithJson class class TestShowSourceWithJson L590–599
+ test_show_source_json_combination_does_not_crash method method test_show_source_json_combination_does_not_crash L591–599
+ TestTypedDictExport class class TestTypedDictExport L240–266
+ test_event_record_typeddict_importable method method test_event_record_typeddict_importable L249–254
+ test_narrative_json_typeddict_importable method method test_narrative_json_typeddict_importable L241–247
+ test_narrative_json_typeddict_matches_output method method test_narrative_json_typeddict_matches_output L256–266
+ cli variable variable cli L34–34
+ CliRunner import import CliRunner L32–32
+ annotations import import annotations L24–24
+ datetime import import datetime L26–26
+ json import import json L27–27
+ pathlib import import pathlib L28–28
+ pytest import import pytest L31–31
+ textwrap import import textwrap L29–29
+ narrative_repo function function narrative_repo L58–94
+ repo function function repo L44–49
+ runner variable variable runner L35–35
~ tests/test_test_selection_speedup.py .py 29 symbols added
+ TestSelectTestsAcceptsCallgraphCache class class TestSelectTestsAcceptsCallgraphCache L90–120
+ test_accepts_callgraph_cache_instance method method test_accepts_callgraph_cache_instance L98–104
+ test_accepts_callgraph_cache_none method method test_accepts_callgraph_cache_none L91–96
+ test_result_unchanged_with_or_without_cache method method test_result_unchanged_with_or_without_cache L106–120
+ TestSelectTestsPersistsCallgraphCache class class TestSelectTestsPersistsCallgraphCache L128–166
+ test_callgraph_cache_file_created_after_run method method test_callgraph_cache_file_created_after_run L129–140
+ test_callgraph_cache_nonempty_after_run method method test_callgraph_cache_nonempty_after_run L142–152
+ test_explicit_cache_is_populated_after_run method method test_explicit_cache_is_populated_after_run L154–166
+ TestSelectTestsSharedSymbolCache class class TestSelectTestsSharedSymbolCache L209–245
+ test_load_symbol_cache_called_once_when_none method method test_load_symbol_cache_called_once_when_none L223–245
+ test_load_symbol_cache_not_called_when_cache_supplied method method test_load_symbol_cache_not_called_when_cache_supplied L210–221
+ TestSharedCacheAcrossBothCalls class class TestSharedCacheAcrossBothCalls L253–281
+ test_select_tests_with_prepopulated_cache method method test_select_tests_with_prepopulated_cache L268–281
+ test_shared_cache_produces_same_diff method method test_shared_cache_produces_same_diff L254–266
+ TestWarmCallgraphCacheSkipsParse class class TestWarmCallgraphCacheSkipsParse L174–201
+ test_second_call_skips_parse_symbols method method test_second_call_skips_parse_symbols L175–187
+ test_warm_cache_result_matches_cold method method test_warm_cache_result_matches_cold L189–201
+ _make_repo function function _make_repo L48–82
+ ChangedSymbol import import ChangedSymbol L36–36
+ Manifest import import Manifest L34–34
+ annotations import import annotations L27–27
+ blob_id import import blob_id L34–34
+ call import import call L30–30
+ changed_symbols_from_diff import import changed_symbols_from_diff L36–36
+ patch import import patch L30–30
+ pathlib import import pathlib L29–29
+ pytest import import pytest L32–32
+ select_tests import import select_tests L36–36
+ write_object import import write_object L35–35
~ muse/cli/commands/narrative.py .py 1 symbol added, 3 symbols modified
+ start_timer import import start_timer L155–155
~ run
~ muse/cli/commands/test_cmd.py .py 1 symbol added, 1 symbol modified
+ load_symbol_cache import import load_symbol_cache L115–115
~ run
~ muse/core/test_selection.py .py 2 symbols added, 1 symbol modified
+ CallGraphCache import import CallGraphCache L45–45
+ load_callgraph_cache import import load_callgraph_cache L45–45
~ tests/test_cmd_test.py .py 1 symbol modified
~ repo
← Older Oldest on task/supercharge-narrative-and-test-speedup
All commits
Newer → Latest on task/supercharge-narrative-and-test-speedup

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