Skip to content

feat(causality): sharpen bug_causality with git-blame (bo-8nmm)#36

Merged
scbrown merged 1 commit into
mainfrom
bo-8nmm-blame-causality
Jun 28, 2026
Merged

feat(causality): sharpen bug_causality with git-blame (bo-8nmm)#36
scbrown merged 1 commit into
mainfrom
bo-8nmm-blame-causality

Conversation

@scbrown

@scbrown scbrown commented Jun 28, 2026

Copy link
Copy Markdown
Owner

What

Follow-up to bo-s1kb. v1 inferred a bug's culprit commit by recency+overlap (the most-recent prior commit touching the fix's files). This adds SZZ-lite git-blame sharpening: blame the exact lines a fix removed against the fix's parent to pin the precise introducing commit, at higher confidence — falling back to recency+overlap where blame can't help.

Updates bug_causality.culprit_sha + .confidence.

How

src/index/git.rs

  • blame_lines_at_rev(rev, file, start, end) — blame a range as of a revision (not the worktree).
  • blame_fix_culprits(fix_sha, file)git show --unified=0 → reuse parse_unified_diff for the removed (old-side) line ranges → group_consecutive → blame each range at <fix_sha>^. Returns one BlameEntry per blamed line. Empty for pure-addition fixes, files newly created by the fix, or root commits (no parent).
  • group_consecutive(lines) range helper.

src/cli/bead.rs (reconstruct-causality)

  • For each fix commit + touched file, accumulate blame culprit shas.
  • merge_causality(fallback, blame_map): per file, blame's dominant culprit replaces the recency+overlap candidate where available; files without blame keep the fallback; blame-only files are added.
  • dominant_culprit (deterministic tie-break) + blame_confidence (floored 0.6, scales to 0.98 with blame concentration — above the overlap heuristic's 0.95 cap).
  • Blame culprits store the sha only (culprit_bead_id → None). Degrades gracefully when not a git repo.

Tests

  • Pure units: dominant_culprit (majority + ties), blame_confidence band, merge_causality (blame overrides fallback; blame-only files added), group_consecutive.
  • Integration on a known bug (temp git repo): a commit introduces a buggy line, a later fix changes it → blame_fix_culprits attributes the removed line to the introducing commit, not the fix. Plus a pure-addition → empty case.

cargo test --bin bobbin green for the touched modules; build + clippy clean.

AC

✅ blame-based causality where available ✅ falls back to recency+overlap ✅ tested on a known bug.

🤖 Generated with Claude Code

bo-s1kb v1 picked the most-recent prior commit touching a fix's files
(recency+overlap). This adds SZZ-lite blame sharpening: diff the fix against
its parent, blame the exact lines it removed at <fix>^, and take the dominant
introducing commit as the culprit — a precise sha at higher confidence.

git.rs:
- blame_lines_at_rev(): blame a range at a given revision.
- blame_fix_culprits(): show --unified=0 -> parse_unified_diff removed lines
  -> group into ranges -> blame at <fix>^. Empty for pure additions / new
  files / root commits (no parent).
- group_consecutive() range helper + unit test.

bead.rs reconstruct-causality:
- Per fix commit+file, accumulate blame culprit shas; merge_causality()
  replaces the recency+overlap candidate per file where blame found a
  dominant culprit, falls back otherwise, and adds blame-only files.
- blame_confidence(): floored 0.6, scales to 0.98 with blame concentration
  (exceeds the overlap heuristic's 0.95). Blame culprits store sha only
  (culprit_bead_id = None).
- Degrades gracefully when not a git repo.

Tests: dominant_culprit/blame_confidence/merge_causality pure units +
two temp-repo integration tests (known introduced-then-fixed bug, and
pure-addition -> empty). Build + clippy clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GuQ96t4m1vzFQ6v72btayV
@scbrown
scbrown force-pushed the bo-8nmm-blame-causality branch from d546873 to 375433a Compare June 28, 2026 02:58
@scbrown
scbrown merged commit ad813a4 into main Jun 28, 2026
2 checks passed
@scbrown
scbrown deleted the bo-8nmm-blame-causality branch June 28, 2026 03:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant