fix(patch): catch silent persistence failures and escape-drift in tool-call transport (#12669)

Two hardening layers in the patch tool, triggered by a real silent failure
in the previous session:

(1) Post-write verification in patch_replace — after write_file succeeds,
re-read the file and confirm the bytes on disk match the intended write.
If not, return an error instead of the current success-with-diff. Catches
silent persistence failures from any cause (backend FS oddities, stdin
pipe truncation, concurrent task races, mount drift).

(2) Escape-drift guard in fuzzy_find_and_replace — when a non-exact
strategy matches and both old_string and new_string contain literal
\' or \" sequences but the matched file region does not, reject the
patch with a clear error pointing at the likely cause (tool-call
serialization adding a spurious backslash around apostrophes/quotes).
Exact matches bypass the guard, and legitimate edits that add or
preserve escape sequences in files that already have them still work.

Why: in a prior tool call, old_string was sent with \' where the file
has ' (tool-call transport drift). The fuzzy matcher's block_anchor
strategy matched anyway and produced a diff the tool reported as
successful — but the file was never modified on disk. The agent moved
on believing the edit landed when it hadn't.

Tests: added TestPatchReplacePostWriteVerification (3 cases) and
TestEscapeDriftGuard (6 cases). All pass, existing fuzzy match and
file_operations tests unaffected.
This commit is contained in:
Teknium 2026-04-19 12:27:34 -07:00 committed by GitHub
parent db60c98276
commit d2c2e34469
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 254 additions and 2 deletions

View file

@ -794,7 +794,24 @@ class ShellFileOperations(FileOperations):
write_result = self.write_file(path, new_content)
if write_result.error:
return PatchResult(error=f"Failed to write changes: {write_result.error}")
# Post-write verification — re-read the file and confirm the bytes we
# intended to write actually landed. Catches silent persistence
# failures (backend FS oddities, race with another task, truncated
# pipe, etc.) that would otherwise return success-with-diff while the
# file is unchanged on disk.
verify_cmd = f"cat {self._escape_shell_arg(path)} 2>/dev/null"
verify_result = self._exec(verify_cmd)
if verify_result.exit_code != 0:
return PatchResult(error=f"Post-write verification failed: could not re-read {path}")
if verify_result.stdout != new_content:
return PatchResult(error=(
f"Post-write verification failed for {path}: on-disk content "
f"differs from intended write "
f"(wrote {len(new_content)} chars, read back {len(verify_result.stdout)}). "
"The patch did not persist. Re-read the file and try again."
))
# Generate diff
diff = self._unified_diff(content, new_content, path)