gabriel / muse public
feat patch feat/53-narrative-symlog-integration #1 / 1
AI Agent gabriel · 5 hours ago · Oct 22, 2026 · Diff

feat: muse#53 item 3 — muse code narrative uses symlog as commit index

`muse code narrative ADDRESS` reconstructed a symbol's biography by BFS-walking the full commit DAG and re-parsing every commit's structured_delta — O(commits) regardless of how many times the symbol actually changed.

Not a literal "read narrative data from symlog entries" swap: the journal's created/modified/deleted/renamed classification is coarser than the impl-vs-signature distinction this command's storytelling depends on (separate body-rewrite/signature-change counts, breaking-change detection via SemVer bump, detailed summary text) — none of which the journal carries. Instead the journal is used as an INDEX narrowing down which commits actually touched the symbol, replacing the full BFS walk; each relevant commit's real structured_delta is still read for full fidelity via a new _process_commit_for_address() helper, extracted from _collect_history's inner loop so both the original BFS path and the new _collect_history_via_symlog() path share identical event-classification logic — zero duplicated business logic between the two strategies.

--since has no equivalent against the flat journal (no "stop at an older commit" concept), so it forces the original full-history fallback — same gating muse code blame's --from already established (item 2).

Incidentally fixes a real latent bug, not just a performance win: the original BFS walk tracked one FIXED symbol address for the entire scan, so a renamed symbol's history silently stopped at the rename boundary (the rename op is recorded under the OLD address, which a fixed-address scan of the NEW address never matches). The journal's born_from chain crosses that boundary natively via the same mechanism `muse symlog --follow` already uses, so a renamed symbol's narrative now includes its pre-rename history for the first time.

Covered by tests/test_narrative_symlog_fast_path.py (5 cases, same mechanism-proving pattern as blame's equivalent after that file's own TDD correction: monkeypatching walk_commits_bfs to raise confirms the symlog path is used by default; confirms --since still calls through to BFS; 3 direct unit tests against _collect_history_via_symlog() covering no-journal fallback, impl-vs-sig fidelity preservation, and the rename-boundary fix itself). Confirmed genuine RED by reverting the fix file and re-running (4 of 5 failed; the --since fallback test passed incidentally since that's pre-existing untouched behavior), then GREEN with the fix restored plus the full narrative + blame + symlog regression suite (73 + 183 tests, zero regressions). Live-verified via muse-dev against a disposable /tmp sandbox: a two-commit rename case went from commits_analysed=1 (pre-fix, would have silently missed the creation event) to commits_analysed=2 with the creation event correctly surfaced under the pre-rename address.

Co-Authored-By: Claude Sonnet 5 <[email protected]>

sha256:2e1a0661bf0d9f094a07af068f630fed10499f58d69f969b689d9171112ab680 sha
+26 ~5 −1 symbols
3 changed · 1241 in snapshot files
sha256:ce39f482c513c2bd01c0fc150879a8d070de0028c96517da13ebae1d4700b283 snapshot
+26
symbols added
~5
symbols modified
−1
symbol removed
3
files changed
1241
files in snapshot
0
dead code introduced
Semantic Changes 32 symbols
+ CMD variable variable CMD L48–48
+ TestCollectHistoryViaSymlogDirect class class TestCollectHistoryViaSymlogDirect L100–145
+ test_impl_and_sig_classification_preserved class method test_impl_and_sig_classification_preserved L110–127
+ test_rename_boundary_crossed_via_born_from method method test_rename_boundary_crossed_via_born_from L129–145
+ test_returns_none_when_no_journal_exists method method test_returns_none_when_no_journal_exists L101–108
+ TestSymlogFastPathIsActuallyUsed class class TestSymlogFastPathIsActuallyUsed L51–97
+ test_narrative_still_works_when_bfs_walk_is_broken method method test_narrative_still_works_when_bfs_walk_is_broken L52–70
+ test_since_flag_falls_back_to_bfs_walk method method test_since_flag_falls_back_to_bfs_walk L72–97
+ _commit function function _commit L41–45
+ _write function function _write L37–38
+ cli variable variable cli L24–24
+ CliRunner import import CliRunner L22–22
+ annotations import import annotations L14–14
+ json import import json L16–16
+ pathlib import import pathlib L17–17
+ pytest import import pytest L20–20
+ textwrap import import textwrap L18–18
+ repo function function repo L29–34
+ runner variable variable runner L25–25
~ docs/issues/symlog-followup.md .md 1 symbol added, 1 symbol removed, 2 symbols modified
− muse code narrative rewrite section 3. muse code narrative rewrite L48–54
+ muse code narrative rewrite ✅ IMPLEMENTED section 3. muse code narrative rewrite ✅ IMPLEMENTED L48–77
~ muse/cli/commands/narrative.py .py 6 symbols added, 3 symbols modified
+ _collect_history_via_symlog function function _collect_history_via_symlog L571–627
+ _process_commit_for_address function function _process_commit_for_address L494–568
+ CommitRecord import import CommitRecord L148–148
+ read_commit import import read_commit L148–148
+ read_symlog_with_follow import import read_symlog_with_follow L150–150
+ symlog_path import import symlog_path L150–150
~ run
Files Changed
+1 ~2
1241 in snapshot
← Older Oldest on feat/53-narrative-symlog-integration
All commits
Newer → Latest on feat/53-narrative-symlog-integration

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