Skip to content

astmap.changed_symbols treats diff hunk context lines as changed symbols #10

Description

@KumamuKuma

Summary

astmap.changed_symbols() can treat normal unified-diff context lines as changed lines. As a result, a proposal may claim that an untouched neighboring function or class was modified.

The false symbols are written into candidate intent and code_slices, so approved capsules can persist incorrect provenance and later graph edges can be built from the wrong (file, symbol) data.

How I tested

I tested isolated clones of several real GitHub projects, including:

  • pypa/sampleproject
  • python-humanize/humanize
  • pypa/packaging
  • theskumar/python-dotenv

For each Python repo I ran:

  1. rgit init
  2. append one tiny new top-level probe function
  3. rgit run -- python -c "print('accuracy=...')"
  4. inspect rgit pending --json

Evidence

In python-humanize/humanize, I only appended this new function to src/humanize/filesize.py:

def rgit_probe_humanize():
    return "humanize"

But the generated candidate said:

Changes to naturalsize, rgit_probe_humanize in src/humanize/filesize.py

naturalsize was only present as diff context and was not changed.

In pypa/packaging, I only appended:

def rgit_probe_packaging():
    return "packaging"

But the generated candidate said:

Changes to TimeMarkerSuite, rgit_probe_packaging, time_evaluate in benchmarks/markers.py

TimeMarkerSuite and time_evaluate were also only diff context.

Minimal reproduction

Start with m.py:

def old_context():
    return 1


def untouched_neighbor():
    return 2

Commit it, then append only:

def new_feature():
    return 3

The diff contains untouched_neighbor() as context:

@@ -4,3 +4,7 @@ def old_context():
 
 def untouched_neighbor():
     return 2
+
+
+def new_feature():
+    return 3

Actual changed_symbols(diff, repo) result:

[
  {"file": "m.py", "symbol": "new_feature"},
  {"file": "m.py", "symbol": "untouched_neighbor"}
]

Expected result:

[
  {"file": "m.py", "symbol": "new_feature"}
]

Likely cause

_changed_line_ranges() in src/rgit/astmap.py uses the full new-side hunk range from the hunk header:

result[current].append((start, start + max(length, 1) - 1))

But that range includes unchanged context lines. changed_symbols() should derive touched ranges from the actual diff body lines instead of treating the whole hunk as changed.

Impact

  • proposals can mention symbols that were not changed
  • capsule code_slices can contain false symbols
  • graph relationships such as overlaps can be created from incorrect symbol data
  • recall/compose can later use misleading capsule context

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions