mirror of
https://github.com/norandom/OpenUltraSAST.git
synced 2026-10-16 03:49:26 +00:00
push(snapshot): run-aware base/head line-correspondence (stop discarding intra-run anchors)
The correspondence mapped an equal-region base<->head line pair only when the line's content was GLOBALLY unique in the file, so common lines (`}`, blanks, imports) tripped `ambiguous_line_correspondence` and the finding's anchor was discarded -> the operation came back `unmapped` -> novelty `unknown` -> `comparison_unknown` -> the engine finding was suppressed (a direct cause of "near-blind to fixes"). Replace the global-uniqueness gate with run-aware positional anchoring: segment the equal-region pairs into contiguous runs (strictly +1/+1, as _equal_line_pairs emits), and map a pair when its content occupies exactly one old run and one new run. Duplicates WITHIN a contiguous run are positionally forced and now map; duplicates ACROSS runs split by an edit are aligned arbitrarily by git and stay withheld + flagged (soundness preserved -- the moved-repeated-operation guard still passes, so no false `new`/identity claims). Tests: update test_change_context_unknown_base_binary_and_ambiguous_lines_are_ unresolved (its two in-run sinks now anchor); keep the moved-operation soundness test; add intra-run-maps, cross-run-withheld, and distinctive-line-anchors cases. 163 push tests pass, ruff clean. Honest scope (design.md amendment): this removes one real cause but is necessary-not-sufficient -- live-testing a messy 14-file Java change showed coverage stays `incomplete` due to other, dominant blockers (capability_unavailable until Task 8.3; the engine produced no actionable defect; eligibility/projection gaps). Engine coverage on unseen diffs needs those too, not just correspondence. Co-Authored-By: Claude Opus 4.8 <[email protected]>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
c657c2219b
commit
abb2058a54
@@ -404,12 +404,31 @@ class SnapshotAdapter:
|
||||
spans.append(ChangedSpan(path_head.hex(), new_start, new_start + new_count - 1, "head"))
|
||||
old_cursor, new_cursor = old_index + old_count, new_index + new_count
|
||||
pairs.extend(_equal_line_pairs(old_lines, new_lines, old_cursor, len(old_lines), new_cursor, len(new_lines)))
|
||||
old_counts, new_counts = Counter(old_lines), Counter(new_lines)
|
||||
# Equal-region pairs are positionally 1:1 within a contiguous run
|
||||
# (strictly +1/+1 from _equal_line_pairs). A line's content is a
|
||||
# trustworthy positional anchor when it occupies exactly one old and
|
||||
# one new run; content repeated across runs split by an edit is aligned
|
||||
# arbitrarily by git and is withheld as ambiguous. Duplicates within one
|
||||
# run stay forced and safe.
|
||||
anchor_pairs = () if ambiguous_rename else pairs
|
||||
anchor_runs: list[list[tuple[int, int]]] = []
|
||||
for pair in anchor_pairs:
|
||||
last = anchor_runs[-1][-1] if anchor_runs else None
|
||||
if last is not None and pair[0] == last[0] + 1 and pair[1] == last[1] + 1:
|
||||
anchor_runs[-1].append(pair)
|
||||
else:
|
||||
anchor_runs.append([pair])
|
||||
old_runs: dict[bytes, set[int]] = {}
|
||||
new_runs: dict[bytes, set[int]] = {}
|
||||
for run_index, run in enumerate(anchor_runs):
|
||||
for old_index, new_index in run:
|
||||
old_runs.setdefault(old_lines[old_index], set()).add(run_index)
|
||||
new_runs.setdefault(new_lines[new_index], set()).add(run_index)
|
||||
ambiguous = False
|
||||
for old_index, new_index in () if ambiguous_rename else pairs:
|
||||
for old_index, new_index in anchor_pairs:
|
||||
_check_budget(budget, cancelled)
|
||||
content = old_lines[old_index]
|
||||
if old_counts[content] != 1 or new_counts[content] != 1:
|
||||
if len(old_runs.get(content, ())) != 1 or len(new_runs.get(content, ())) != 1:
|
||||
ambiguous = True
|
||||
continue
|
||||
mappings.append(LineCorrespondence(path_base.hex(), path_head.hex(), old_index + 1, old_index + 1, new_index + 1))
|
||||
|
||||
Reference in New Issue
Block a user