blame.md
markdown
sha256:b636f72dcba9e190afb980bece906fa5b717fbde014b76ef023df8cb96e01eb9
docs: expand cache plan with all seven testing tiers and do…
Sonnet 4.6
131 days ago
muse blame — line-level attribution for text files
muse blame shows which commit last modified each line of a text file tracked in state/. It is the universal, domain-agnostic attribution tool — the core VCS equivalent of git blame.
For domain-specific attribution, see:
muse midi note-blame— per-bar attribution in MIDI tracksmuse code blame— per-symbol attribution in code files
Usage
muse blame README.md
muse blame --ref v1.0.0 docs/design.md
muse blame --porcelain state/config.toml | jq '.commit_id'
muse blame --short 8 src/main.py
Options
| Flag | Default | Description |
|---|---|---|
--ref, -r |
HEAD | Commit or branch to blame from |
--porcelain, -p |
false | Emit JSON objects instead of human-readable output |
--short |
12 | Length of commit SHA prefix to display |
Output (human-readable)
cccccccc0000 (Test User 2026-03-19) 1 hello world
Columns:
- Commit SHA prefix (12 chars by default)
- Author name (padded)
- Date (
YYYY-MM-DD) - Line number (right-aligned)
- Line content
Output (--porcelain)
One JSON object per line:
{"lineno": 1, "commit_id": "cccccccc…", "author": "Test User", "committed_at": "2026-03-19T14:22:01+00:00", "message": "initial commit", "content": "hello world"}
How attribution works
The blame algorithm walks the commit graph backwards from the requested ref:
- Every line in the file at HEAD is initially attributed to HEAD.
- For each ancestor commit, a unified diff is computed between the ancestor's version and its child's.
- Lines that appear unchanged in both versions are re-attributed to the ancestor — the older commit that first introduced them.
- Lines that were added by a commit remain attributed to that commit.
This is equivalent to Git's blame algorithm for linear histories. For merge commits, the algorithm chooses the first parent to keep attribution clean.
Agent workflows
Find who introduced a bug
muse blame --porcelain src/parser.py \
| jq 'select(.content | test("legacy_mode")) | .commit_id' \
| sort -u
Audit a configuration file
muse blame config/production.toml
Annotate every line with its commit
muse blame --porcelain README.md > blame-report.jsonl
Limitations
- Only text files are supported. Binary files (images, MIDI, etc.) should use domain-specific blame commands.
- The walk follows the first-parent chain for merge commits. To attribute across both parents, use
muse midi note-blameormuse code blamewhich are domain-aware.
Exit codes
| Code | Meaning |
|---|---|
| 0 | Success |
| 1 | File not found at the specified ref, or ref not found |
File History
3 commits
sha256:b636f72dcba9e190afb980bece906fa5b717fbde014b76ef023df8cb96e01eb9
docs: expand cache plan with all seven testing tiers and do…
Sonnet 4.6
131 days ago
sha256:7f9e2ef5286aedad9c1e6011b4c46ca27f39dbdad6e3409357e36b26e46b3b7c
docs: docstring sprint for-each-ref→hotspots — idiomatic ru…
Sonnet 4.6
patch
137 days ago
sha256:a09b1b4f6838754495547f200aa0ce88e2f56ffc5b20b900f6f0cff2c3cdede9
fix(cursorignore): remove git-ism (.git/worktrees)
Human
minor
⚠
140 days ago