gabriel / muse public
feat patch symlog task/symlog-phase4 #3 / 5
AI Agent gabriel · 19 days ago · Jun 28, 2026 · Diff

feat(symlog): @{N} ref resolution — Phase 5 (SL_46–SL_55)

- Add SymlogResolution frozen dataclass + _SYMLOG_REF_RE to muse/core/symlog.py - Add resolve_symlog_addr() — resolves addr@{N} specs; raises IndexError(idx,total) on OOB - Add resolve_symbol_body() — reconstructs symbol body from commit object store - Add muse symlog resolve addr@{N} [--follow] [--json] subcommand - Add muse symlog diff addr@{N} addr@{M}|HEAD [--json] subcommand - Add @{N} support to muse code cat — same JSON shape as normal code cat - 35 new integration tests (test_cmd_symlog_refs.py) all passing

sha256:f0818e35b4547bd44c4b14b7eee8f485fb24cc1daca9cab785b3b93439b3b95d sha
+98 ~11 symbols
sha256:a5551e29c9a41e015fa32f94f92d7531190de13ec951bc6ad3814668d9a7d76a snapshot
+98
symbols added
~11
symbols modified
0
dead code introduced
Semantic Changes 109 symbols
~ tests/test_cmd_symlog_refs.py .py 83 symbols added
+ TestSL46ResolveSymlogAddr class class TestSL46ResolveSymlogAddr L158–240
+ test_raises_file_not_found_for_missing_log method method test_raises_file_not_found_for_missing_log L218–223
+ test_raises_index_error_for_out_of_range method method test_raises_index_error_for_out_of_range L225–240
+ test_raises_value_error_for_addr_without_separator method method test_raises_value_error_for_addr_without_separator L166–172
+ test_returns_correct_index_1_entry method method test_returns_correct_index_1_entry L198–216
+ test_returns_none_for_non_at_spec method method test_returns_none_for_non_at_spec L159–164
+ test_returns_resolution_for_valid_spec method method test_returns_resolution_for_valid_spec L174–196
+ TestSL47SymlogResolveCmd class class TestSL47SymlogResolveCmd L248–337
+ _setup_log method method _setup_log L251–260
+ test_human_text_output method method test_human_text_output L282–294
+ test_json_all_fields_present method method test_json_all_fields_present L262–280
+ test_missing_log_exits_user_error method method test_missing_log_exits_user_error L296–306
+ test_out_of_range_error_mentions_range method method test_out_of_range_error_mentions_range L323–337
+ test_out_of_range_exits_user_error method method test_out_of_range_exits_user_error L308–321
+ TestSL48CodeCatAtN class class TestSL48CodeCatAtN L345–408
+ test_at0_returns_newest_body method method test_at0_returns_newest_body L387–396
+ test_at1_returns_older_body method method test_at1_returns_older_body L398–408
+ test_json_shape_identical_to_normal_code_cat method method test_json_shape_identical_to_normal_code_cat L369–385
+ two_commit_repo method method two_commit_repo L360–367
+ TestSL49CodeCatAt0EqualsHead class class TestSL49CodeCatAt0EqualsHead L411–439
+ one_commit_repo method method one_commit_repo L422–426
+ test_at0_source_equals_head_source method method test_at0_source_equals_head_source L428–439
+ TestSL50SymlogDiff class class TestSL50SymlogDiff L447–526
+ test_diff_counts_reflect_changes method method test_diff_counts_reflect_changes L494–507
+ test_diff_json_schema method method test_diff_json_schema L471–492
+ test_diff_lines_are_unified_diff method method test_diff_lines_are_unified_diff L509–526
+ two_commit_repo method method two_commit_repo L463–469
+ TestSL51SymlogDiffHead class class TestSL51SymlogDiffHead L529–584
+ test_diff_at0_vs_head_is_empty method method test_diff_at0_vs_head_is_empty L568–584
+ test_diff_at1_vs_head_shows_changes method method test_diff_at1_vs_head_shows_changes L552–566
+ two_commit_repo method method two_commit_repo L544–550
+ TestSL52OutOfRange class class TestSL52OutOfRange L592–652
+ _write_one_entry method method _write_one_entry L595–600
+ test_code_cat_out_of_range_user_error method method test_code_cat_out_of_range_user_error L629–638
+ test_diff_out_of_range_user_error method method test_diff_out_of_range_user_error L640–652
+ test_resolve_error_message_contains_valid_range method method test_resolve_error_message_contains_valid_range L615–627
+ test_resolve_out_of_range_user_error method method test_resolve_out_of_range_user_error L602–613
+ TestSL53Follow class class TestSL53Follow L660–734
+ _write_rename_chain method method _write_rename_chain L664–678
+ test_follow_populates_followed_from method method test_follow_populates_followed_from L680–703
+ test_no_follow_does_not_cross_boundary method method test_no_follow_does_not_cross_boundary L705–717
+ test_own_entry_has_no_followed_from method method test_own_entry_has_no_followed_from L719–734
+ TestSL54ThreeCommitHistory class class TestSL54ThreeCommitHistory L742–821
+ test_code_cat_at0_returns_commit_c_body method method test_code_cat_at0_returns_commit_c_body L793–802
+ test_code_cat_at2_returns_commit_a_body method method test_code_cat_at2_returns_commit_a_body L779–791
+ test_diff_at2_at0_shows_changes method method test_diff_at2_at0_shows_changes L804–821
+ test_symlog_has_three_entries method method test_symlog_has_three_entries L771–777
+ three_commit_repo method method three_commit_repo L761–769
+ TestSL55RenameFollow class class TestSL55RenameFollow L829–920
+ rename_repo method method rename_repo L844–851
+ test_bar_at0_returns_rename_commit_content method method test_bar_at0_returns_rename_commit_content L853–869
+ test_bar_at2_follow_returns_commit_a_content method method test_bar_at2_follow_returns_commit_a_content L884–901
+ test_bar_follow_chain_index_1_is_renamed_to method method test_bar_follow_chain_index_1_is_renamed_to L903–920
+ test_follow_chain_has_correct_length method method test_follow_chain_has_correct_length L871–882
+ _FAKE_CID_A variable variable _FAKE_CID_A L105–105
+ _FAKE_CID_B variable variable _FAKE_CID_B L106–106
+ _FAKE_CID_C variable variable _FAKE_CID_C L107–107
+ _FAKE_COMMIT_A variable variable _FAKE_COMMIT_A L108–108
+ _FAKE_COMMIT_B variable variable _FAKE_COMMIT_B L109–109
+ _FAKE_COMMIT_C variable variable _FAKE_COMMIT_C L110–110
+ _commit function function _commit L81–92
+ _init_repo function function _init_repo L70–72
+ _invoke function function _invoke L61–67
+ _invoke_symlog function function _invoke_symlog L135–150
+ _make_real_repo function function _make_real_repo L95–97
+ _write_file function function _write_file L75–78
+ _write_symlog_entries function function _write_symlog_entries L113–132
+ CliRunner import import CliRunner L38–38
+ ExitCode import import ExitCode L31–31
+ NULL_CONTENT_ID import import NULL_CONTENT_ID L32–32
+ annotations import import annotations L20–20
+ append_symlog import import append_symlog L32–32
+ argparse import import argparse L22–22
+ json import import json L23–23
+ os import import os L24–24
+ pathlib import import pathlib L25–25
+ pytest import import pytest L29–29
+ read_symlog import import read_symlog L32–32
+ symlog_path import import symlog_path L32–32
+ textwrap import import textwrap L26–26
+ time import import time L27–27
+ repo function function repo L48–53
+ runner variable variable runner L40–40
~ muse/cli/commands/cat.py .py 2 symbols added, 1 symbol modified
+ _SYMLOG_AT_RE variable variable _SYMLOG_AT_RE L62–62
+ re import import re L43–43
~ run
~ muse/cli/commands/symlog.py .py 9 symbols added, 10 symbols modified
+ _DiffJson class class _DiffJson L164–171
+ _ResolveJson class class _ResolveJson L155–161
+ _SYMLOG_REF_RE variable variable _SYMLOG_REF_RE L523–523
+ _get_symbol_body_from_workdir function function _get_symbol_body_from_workdir L886–927
+ SymlogResolution import import SymlogResolution L79–79
+ resolve_symbol_body import import resolve_symbol_body L79–79
+ resolve_symlog_addr import import resolve_symlog_addr L79–79
+ run_diff function function run_diff L930–1101
+ run_resolve function function run_resolve L781–878
~ run
~ muse/core/symlog.py .py 4 symbols added
+ SymlogResolution class class SymlogResolution L876–890
+ _SYMLOG_REF_RE variable variable _SYMLOG_REF_RE L872–872
+ resolve_symbol_body function function resolve_symbol_body L966–1038
+ resolve_symlog_addr function function resolve_symlog_addr L893–963

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