muse symlog — Follow-up Items
Background
Issue #51 delivered the full symlog foundation: per-symbol journaling at commit time,
muse symlog read CLI with filters, lifecycle management (expire/delete/GC), and
@{N} ref resolution for muse code cat, muse symlog resolve, and
muse symlog diff. All 55 test IDs (SL_01–SL_55) are green.
This issue captures the items explicitly deferred from #51 plus useful extensions that emerged during implementation.
Deferred from #51
1. Analytics commands — muse symlog coupling and muse symlog hotspots
The live symlog journal is a rich, already-written dataset. Two analytics commands can read it in O(1) per symbol without touching commit history:
muse symlog hotspots [--top N] [--file path] [--json]
— ranks symbols by churn (number of symbol-modified entries in the journal).
Complements muse code hotspots (which reads commit history) with a zero-scan
alternative that is always up to date.
muse symlog coupling [--file path] [--json]
— finds symbol pairs that share commit IDs across their logs (i.e. they always
change together). Surfaced purely from symlog data, no AST traversal needed.
2. muse blame integration
muse blame "file.py::Symbol" currently reconstructs authorship by scanning
commit history. With symlogs in place, the per-symbol change record already
contains author and commit ID at each index. blame should prefer the symlog
when available — O(1) per symbol instead of O(commits).
3. muse code narrative rewrite
muse code narrative "file.py::Symbol" generates a plain-English description of
a symbol's lifecycle. It currently works from AST diffs across commits. The symlog
journal is the canonical source of that history now — narrative should read from
symlog entries, gaining richer metadata (operation, author, born-from chains).
4. Remote symlog sharing
Symlogs are currently local-only — they are not pushed or pulled. For teams sharing a MuseHub remote, symlogs are silently missing on clones. The correct design:
muse pushbundles.muse/symlogs/alongside commits.muse pullmerges incoming symlog entries (append-only, no conflicts).muse bundle createincludes symlogs in the msgpack payload.
5. Symlog entries for non-code domains
The extractor returns {} for non-parseable files, so MIDI tracks, binary assets,
and schema files produce no symlog entries. For music repos this is the wrong
trade-off: a MIDI symbol (track::chorus) should produce a symlog entry when
the Harmony domain plugin identifies a change. Deferred until the domain plugin
API supports content-ID extraction for non-code artifacts.
6. Relative time syntax (@{1.day.ago}, @{yesterday})
@{N} addresses work by index. Git's reflog also supports relative time syntax
(HEAD@{1.hour.ago}). Symlog --since/--until cover the filtering use case,
but @{1.day.ago} as a direct ref specifier is more ergonomic in agent prompts.
New items from implementation
7. muse checkout-symbol "file.py::Symbol@{N}"
Restore a prior version of a single symbol to disk without touching any other
file. The natural extension of muse code cat "addr@{N}" — cat reads, checkout
restores. Critically useful for surgical recovery: "undo the change to this one
function without reverting the whole commit."
8. muse symlog grep PATTERN [--file path] [--json]
Search symbol bodies across their full symlog history. Answers: "when did this
symbol last contain the string deprecated?" or "which version of this function
called session.add?" Reads object store bodies via resolve_symbol_body for
each entry.
9. muse symlog show "file.py::Symbol@{N}"
Convenience alias for muse code cat "file.py::Symbol@{N}" with human-focused
output: operation, author, timestamp header, then the full symbol body. Useful for
interactive exploration ("show me what this function looked like two changes ago").
10. muse symlog stat [--file path] [--json]
Summary statistics for a symbol or file: total entries, operation breakdown (created/modified/deleted/renamed), most active author, first and last commit IDs, date range. Useful for code review context and agent decision-making.
11. Symlog entries for muse revert
muse revert records a reflog entry for the branch ref move, but writes no symlog
entries for the symbols it touches. A revert of a commit that modified compute_total
should produce a symbol-modified: revert <commit_id> entry in that symbol's log.
12. muse symlog prune-orphans [--dry-run] [--json]
Find symlog files whose symbol address no longer exists in the current snapshot
and remove them. Analogous to muse gc for unreachable objects — keeps the
.muse/symlogs/ tree clean after large-scale renames or file deletions.