Problem
detect_changes's "seed" set (the symbols it treats as directly changed, before
running the blast-radius traversal) is computed at whole-file granularity,
not at the diff-hunk/line level. A one-line, single-statement edit inside one
method reports every definition in that file as a seed symbol, then runs the
blast-radius traversal from all of them — producing an impact report an order
of magnitude larger than what actually changed.
This contradicts the stated intent in #1154 ("It now resolves the git diff
to those symbols and runs one multi-source BFS ... to the transitive
impact set") — the BFS traversal is real, but the input to it (seed_symbols)
is not scoped to the touched lines.
Reproduction
Tested on microsoft/qlib @ 3097dcc9 (any repo with more than one definition
per file should reproduce this; the two cases below were chosen for very
different file sizes to rule out coincidence).
codebase-memory-mcp cli index_repository --repo-path <qlib-checkout> --mode full --name repro
Case A — qlib/log.py (24 top-level/class-member definitions):
# single-line in-place edit inside TimeInspector.logt(), no line-count change
sed -i '' 's/ pass/ cls.timer_logger.debug("x")/' qlib/log.py
codebase-memory-mcp cli detect_changes --project repro --format json --depth 1
{"seed_symbols": 25, "impacted_total": 141, ...}
25 = 24 definitions + 1 module node. Only logt was edited; the other 23
definitions in the file are untouched.
Case B — qlib/backtest/decision.py (42 definitions), same methodology,
one line replaced with itself plus a trailing comment (no line-count change,
touches exactly one return statement in one method):
sed -i '' '96s/.*/ return self.amount * self.sign # bench-marker/' qlib/backtest/decision.py
codebase-memory-mcp cli detect_changes --project repro --format json --depth 1
{"seed_symbols": 43, "impacted_total": 68, ...}
43 = 42 definitions + 1 module node.
Both cases reproduce the same formula — seed_symbols == (definitions in changed file) + 1 — regardless of file size or which single line was
touched, which rules out this being an artifact of one file's structure.
Expected Behavior
seed_symbols should be the symbol(s) whose line range actually overlaps the
diff hunk (e.g. just logt for Case A, just the one method for Case B), not
every definition in the file.
Actual Behavior
Every definition in the changed file is treated as a seed, so the blast-radius
BFS runs from all of them. In Case A, the true direct callers of logt (6,
confirmed via oracle cross-check) were present in the output but diluted
across 141 total impacted entries pulled in by the other 23 unrelated seeds.
Impact
For any file with more than a handful of definitions, detect_changes on a
single-line change reports an impact set dominated by symbols the edit never
touched. This makes the tool unusable as a precision impact-review aid without
manual filtering — the caller has to guess which of the N seeds is the one
they actually meant.
Environment
- codebase-memory-mcp 0.9.1-rc.1
- macOS (Apple Silicon)
- Reproduced twice on two files of very different size (24 and 42 definitions)
with identical seed_symbols = defs_in_file + 1 in both
Suggested Fix
Scope seed identification to the definition(s) whose [start_line, end_line]
range intersects the diff hunk's changed line range, rather than every
definition record associated with the changed file path.
Problem
detect_changes's "seed" set (the symbols it treats as directly changed, beforerunning the blast-radius traversal) is computed at whole-file granularity,
not at the diff-hunk/line level. A one-line, single-statement edit inside one
method reports every definition in that file as a seed symbol, then runs the
blast-radius traversal from all of them — producing an impact report an order
of magnitude larger than what actually changed.
This contradicts the stated intent in #1154 ("It now resolves the git diff
to those symbols and runs one multi-source BFS ... to the transitive
impact set") — the BFS traversal is real, but the input to it (
seed_symbols)is not scoped to the touched lines.
Reproduction
Tested on
microsoft/qlib@3097dcc9(any repo with more than one definitionper file should reproduce this; the two cases below were chosen for very
different file sizes to rule out coincidence).
Case A —
qlib/log.py(24 top-level/class-member definitions):{"seed_symbols": 25, "impacted_total": 141, ...}25 = 24 definitions + 1 module node.Onlylogtwas edited; the other 23definitions in the file are untouched.
Case B —
qlib/backtest/decision.py(42 definitions), same methodology,one line replaced with itself plus a trailing comment (no line-count change,
touches exactly one
returnstatement in one method):{"seed_symbols": 43, "impacted_total": 68, ...}43 = 42 definitions + 1 module node.Both cases reproduce the same formula —
seed_symbols == (definitions in changed file) + 1— regardless of file size or which single line wastouched, which rules out this being an artifact of one file's structure.
Expected Behavior
seed_symbolsshould be the symbol(s) whose line range actually overlaps thediff hunk (e.g. just
logtfor Case A, just the one method for Case B), notevery definition in the file.
Actual Behavior
Every definition in the changed file is treated as a seed, so the blast-radius
BFS runs from all of them. In Case A, the true direct callers of
logt(6,confirmed via oracle cross-check) were present in the output but diluted
across 141 total
impactedentries pulled in by the other 23 unrelated seeds.Impact
For any file with more than a handful of definitions,
detect_changeson asingle-line change reports an impact set dominated by symbols the edit never
touched. This makes the tool unusable as a precision impact-review aid without
manual filtering — the caller has to guess which of the N seeds is the one
they actually meant.
Environment
with identical
seed_symbols = defs_in_file + 1in bothSuggested Fix
Scope seed identification to the definition(s) whose
[start_line, end_line]range intersects the diff hunk's changed line range, rather than every
definition record associated with the changed file path.