gabriel / muse public
feat BREAKING symlog task/symlog-phase1 #2 / 3
AI Agent gabriel · 19 days ago · Jun 28, 2026 · Diff

feat(symlog): Phase 2 — commit integration and symbol diff engine

- Wire _write_symlogs into muse commit after append_reflog; non-fatal - Add SymbolDiff dataclass and compute_symbol_diff with rename detection - extract_symbols: add file_path param (required by parse_symbols for correct keys) - _extract_body_hashes: body_hash-based rename matching (name-invariant) - compute_symbol_diff accepts optional rename key dicts for body-hash matching - 25 new tests (SL_13–SL_22): extract_symbols, compute_symbol_diff, created/ modified/deleted/renamed entries, initial commit, two-commit sequence, follow

sha256:930e8215a3d1d19f85e786bcb4d2bba8166bcac9a765b2adae1ae62d76063c7d sha
+62 ~2 symbols
sha256:b9aba323c99ccb5bb568011f5685b0cd8e7447d3fae44ab3e5d6cf07687a03a7 snapshot
+62
symbols added
~2
symbols modified
0
dead code introduced
Semantic Changes 64 symbols
~ tests/test_cmd_commit_symlog.py .py 56 symbols added
+ TestComputeSymbolDiff class class TestComputeSymbolDiff L140–222
+ test_created_symbols method method test_created_symbols L145–152
+ test_deleted_symbols method method test_deleted_symbols L154–160
+ test_mixed_operations method method test_mixed_operations L199–214
+ test_modified_symbols method method test_modified_symbols L162–168
+ test_rename_detection method method test_rename_detection L179–189
+ test_rename_with_content_change_is_not_a_rename method method test_rename_with_content_change_is_not_a_rename L191–197
+ test_returns_symbol_diff_dataclass class method test_returns_symbol_diff_dataclass L216–222
+ test_unchanged_symbols_not_in_diff method method test_unchanged_symbols_not_in_diff L170–177
+ TestExtractSymbols class class TestExtractSymbols L79–132
+ test_multiple_symbols method method test_multiple_symbols L111–132
+ test_returns_empty_for_non_code_file method method test_returns_empty_for_non_code_file L94–104
+ test_returns_empty_for_unknown_object_id method method test_returns_empty_for_unknown_object_id L106–109
+ test_returns_symbol_name_to_content_id_map method method test_returns_symbol_name_to_content_id_map L80–92
+ TestIntegrationRenameFollow class class TestIntegrationRenameFollow L486–516
+ test_rename_follow_traverses_chain method method test_rename_follow_traverses_chain L487–516
+ TestIntegrationTwoCommitSequence class class TestIntegrationTwoCommitSequence L419–478
+ test_create_modify_delete_sequence method method test_create_modify_delete_sequence L420–478
+ TestSymlogCreated class class TestSymlogCreated L249–284
+ test_all_new_symbols_get_created_entries method method test_all_new_symbols_get_created_entries L270–284
+ test_created_entry_has_correct_author method method test_created_entry_has_correct_author L262–268
+ test_new_symbol_gets_created_entry method method test_new_symbol_gets_created_entry L250–260
+ TestSymlogDeleted class class TestSymlogDeleted L335–354
+ test_deleted_symbol_gets_deleted_entry method method test_deleted_symbol_gets_deleted_entry L336–354
+ TestSymlogInitialCommit class class TestSymlogInitialCommit L395–411
+ test_initial_commit_all_symbols_created method method test_initial_commit_all_symbols_created L396–411
+ TestSymlogModified class class TestSymlogModified L292–327
+ test_modified_entry_contains_commit_message method method test_modified_entry_contains_commit_message L307–316
+ test_modified_entry_has_correct_commit_id method method test_modified_entry_has_correct_commit_id L318–327
+ test_modified_symbol_gets_modified_entry method method test_modified_symbol_gets_modified_entry L293–305
+ TestSymlogRenamed class class TestSymlogRenamed L362–387
+ test_rename_writes_two_entries method method test_rename_writes_two_entries L363–387
+ TestWriteSymlogsNonFatal class class TestWriteSymlogsNonFatal L230–241
+ test_commit_returns_commit_id method method test_commit_returns_commit_id L237–241
+ test_commit_succeeds_even_with_no_code_files method method test_commit_succeeds_even_with_no_code_files L231–235
+ _commit function function _commit L55–66
+ _init_repo function function _init_repo L44–46
+ _invoke function function _invoke L35–41
+ _make_repo function function _make_repo L69–71
+ _write_file function function _write_file L49–52
+ CliRunner import import CliRunner L15–15
+ NULL_CONTENT_ID import import NULL_CONTENT_ID L18–18
+ SymbolDiff import import SymbolDiff L18–18
+ annotations import import annotations L6–6
+ compute_symbol_diff import import compute_symbol_diff L18–18
+ extract_symbols import import extract_symbols L18–18
+ hash_blob import import hash_blob L17–17
+ is_null_content_id import import is_null_content_id L18–18
+ json import import json L8–8
+ list_symlog_symbols_for_file import import list_symlog_symbols_for_file L18–18
+ os import import os L9–9
+ pathlib import import pathlib L10–10
+ pytest import import pytest L13–13
+ read_symlog import import read_symlog L18–18
+ textwrap import import textwrap L11–11
+ runner variable variable runner L28–28
~ muse/cli/commands/commit.py .py 1 symbol added, 1 symbol modified
+ _write_symlogs import import _write_symlogs L50–50
~ run
~ muse/core/symlog.py .py 5 symbols added, 1 symbol modified
+ SymbolDiff class class SymbolDiff L596–608
+ _extract_body_hashes function function _extract_body_hashes L714–742
+ _write_symlogs function function _write_symlogs L745–864
+ compute_symbol_diff function function compute_symbol_diff L611–672
+ extract_symbols function function extract_symbols L675–711

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