Skip to content

fix(tools): reject fuzzy edits with drifted content - #983

Open
PierrunoYT wants to merge 1 commit into
Gitlawb:mainfrom
PierrunoYT:fix/issue-963-fuzzy-edit-drift
Open

fix(tools): reject fuzzy edits with drifted content#983
PierrunoYT wants to merge 1 commit into
Gitlawb:mainfrom
PierrunoYT:fix/issue-963-fuzzy-edit-drift

Conversation

@PierrunoYT

@PierrunoYT PierrunoYT commented Aug 27, 2026

Copy link
Copy Markdown
Contributor

Summary

  • remove the similarity-based block-anchor fallback that could replace content differing from old_string
  • remove the later context-aware fallback with the same unsafe first/last-anchor behavior
  • retain normalization-only fuzzy matching for indentation, whitespace, escapes, and boundaries
  • add regression coverage for the reported y := 2 / y := 99 interior drift and verify the file remains unchanged

The regression test failed before the fix with Successfully edited target.txt (replaced 1 occurrence).

Linked issue

Fixes #963

Checklist

  • The linked issue already has the issue-approved label.
  • go build ./..., go vet ./..., and go test ./... pass locally.
  • Changed Go files are gofmt clean.
  • Tests added/updated for the change.
  • No UI changes.

Validation

  • go vet ./...
  • go test ./...
  • go test ./internal/tools -count=1
  • go run ./cmd/zero-release build
  • go run ./cmd/zero-release smoke
  • make lint-static — 0 issues
  • make vulncheck — no vulnerabilities
  • git diff HEAD --check

make fmt-check remains blocked on the current base by existing formatting findings under internal/perfbench/testdata/; this PR does not modify those fixtures.

Summary by CodeRabbit

  • Bug Fixes
    • Improved fuzzy file editing to avoid replacing content when interior lines differ from the requested text.
    • Ambiguous or potentially unsafe matches are now rejected instead of selecting a similar-looking block.
    • Files remain unchanged when an exact, safe match cannot be confirmed, helping prevent unintended edits.

@coderabbitai

coderabbitai Bot commented Aug 27, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 42adf2fe-703b-4626-89d1-7e0b9a2d35ce

📥 Commits

Reviewing files that changed from the base of the PR and between 27b319c and 58016a6.

📒 Files selected for processing (3)
  • internal/tools/edit_file.go
  • internal/tools/edit_replacers.go
  • internal/tools/edit_replacers_test.go

Included review availability: Your plan provides up to 4 included reviews per hour; 2 remain after this review.


Walkthrough

The fuzzy edit cascade removes anchor-based similarity matching. It now uses normalization-based replacers only. Tests verify that interior drift returns an exact-match error and leaves the file unchanged.

Changes

Fuzzy edit safety

Layer / File(s) Summary
Restrict fuzzy replacers
internal/tools/edit_replacers.go
Removes anchor-based replacers, the similarity threshold, Levenshtein matching, and related comments.
Validate drift rejection
internal/tools/edit_replacers_test.go, internal/tools/edit_file.go
Updates tests and documentation to require exact-match failure for drifted interiors and preserve the file contents.

Estimated code review effort: 2 (Simple) | ~10 minutes

Merge Risk: ⚪ Minimal · up to 58016

The change prevents drifted content from being replaced while retaining normalization-only matching, and the supplied validation is passing; no actionable merge-blocking risk remains.

Suggested reviewers: euxaristia, kevincodex1

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 35.71% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 14 functions across 3 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly describes the main change: fuzzy edits now reject drifted content.
Linked Issues check ✅ Passed The changes satisfy issue #963. Similarity-based and context-aware fallback matchers were removed, normalization-only matching remains, and regression tests verify that interior drift fails without mo…
Out of Scope Changes check ✅ Passed All changes support the linked issue. The comment update, matcher removal, and regression test updates are directly related to preventing replacement of drifted content.
Full details: Linked Issues check

Explanation

The changes satisfy issue #963. Similarity-based and context-aware fallback matchers were removed, normalization-only matching remains, and regression tests verify that interior drift fails without modifying the file.

  • Fix all pre-merge checks with AI
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands.

@Vasanthdev2004 Vasanthdev2004 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approving. Deleting 248 lines of matching fallback is the kind of change where the risk is over-deletion rather than the fix itself, so I measured it instead of reading the diff and hoping.

I ran the same eleven inputs through fuzzyEditMatch on main and on this head. Exactly one result changes, and it is the one you set out to change:

case main this PR
indent drift (spaces to tab) match match
trailing whitespace match match
leading blank line match match
collapsed inner spaces match match
escape normalization match match
CRLF content match match
interior drift, y := 2 against y := 99 match no match
interior extra line no match no match
first/last anchor only no match no match
blank-line drift inside no match no match

Every legitimate normalization still resolves to the same span. The last three are the interesting ones: they did not match on main either, so blockAnchorReplacer and contextAwareReplacer were much narrower in practice than 248 lines suggests. They effectively only fired on the drifted-interior case, which is why removing them costs nothing else.

The honest caveat is that eleven hand-written cases are a sample, not a proof. But they cover each retained normalization plus the shapes the deleted code was supposed to handle, and nothing in that set regressed.

Two other things I checked:

You replaced TestEditFuzzyBlockAnchorToleratesMiddleDrift with TestEditFuzzyRejectsInteriorDrift rather than deleting it. Inverting the assertion is the right way to record a deliberate behaviour change; a bare deletion would have hidden it.

This one is standalone. It shares no files with #892 to #895, so it does not inherit the ordering problem that series has.

go test ./internal/tools passes in full.

@jatmn jatmn left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

fix(tools): fuzzy edit can overwrite a block whose interior drifted

3 participants