feat: muse#53 item 2 — muse code blame prefers symlog journal
`muse code blame ADDRESS` reconstructed authorship by BFS-walking the full commit graph and re-parsing each commit's structured_delta — O(commits) regardless of how many times the symbol actually changed. With symlogs already recording {commit_id, author, timestamp, operation} per change, blame can answer in O(entries for this symbol) instead.
New _events_from_symlog() in blame.py builds the same _BlameEvent objects the BFS path produces, reading via the (now-public, moved from symlog.py's CLI module) read_symlog_with_follow() — rename chains are followed exactly like `muse symlog --follow` already does, via born_from pointers. Returns None when no journal exists for the address, triggering the existing BFS path as a transparent fallback.
The journal's created/modified/deleted/renamed classification can't produce "moved" or "signature" events (categories only the richer per-commit structured_delta can distinguish), so a --kind filter requesting either forces the BFS fallback to stay correct. --from REF also forces BFS: the journal reflects all history unconditionally, with no way to slice it to "as reachable from an older ref" the way the BFS walk's starting commit boundary does.
read_symlog_with_follow() (building entries + a from_symbol origin map for rename-boundary annotation) was promoted from a private _read_with_follow() helper in muse/cli/commands/symlog.py to a public function in muse/core/symlog.py — it's pure symlog-reading logic with no CLI concerns, and blame.py now needs the same capability `muse symlog`'s own read path already had.
Covered by tests/test_blame_symlog_fast_path.py (7 cases, split deliberately into two groups after an initial TDD mistake: the first draft asserted only on final blame OUTPUT, which the pre-existing BFS path already produces correctly on its own — reverting the fix left all those tests passing, a false-negative RED that would have shipped an untested no-op. Rewritten to prove the MECHANISM instead: monkeypatching walk_commits_bfs to raise confirms the symlog path is used for the default case, confirms --from and --kind-signature queries still call through to BFS, plus 4 direct unit tests against _events_from_symlog() itself covering created/modified, deleted, and rename-chain address attribution). Confirmed genuine RED the second time by reverting all three changed files and re-running (5 of 7 failed — the two fallback-path tests passed incidentally, which is correct since the fallback path is pre-existing untouched behavior), then GREEN with the fix restored plus the full blame + symlog regression suite (329 + 145 tests across both areas, zero regressions). Live-verified via muse-dev against a disposable /tmp sandbox: default blame correctly reports created+modified via the fast path; --from HEAD~1 correctly reports only "created", confirming the fallback triggers as designed.
Co-Authored-By: Claude Sonnet 5 <[email protected]>
Semantic Changes
53 symbols
Files Changed
+1
~4
1240 in snapshot
0 comments
muse hub commit comment sha256:87e65c3a0f38438d20b4534feb442bd274da6a5a7f0f5f95e9c4e4dfefa86c42 --body "your comment"
No comments yet. Be the first to start the discussion.