Writing · 2026
Problem. A standard diff includes headers such as @@ -80,2 +80,2 @@. The model has to get the code right and calculate line positions and lengths. Aider found that this bookkeeping caused avoidable failures. (Aider)
Solution. In December 2023, Aider described a simplified unified diff that drops the numbers and uses surrounding code to locate the edit: (Aider)
--- retry.py+++ retry.py@@ ... @@ def retry_download(status):- return status == 500+ return status in {429, 500, 503}The applier reconstructs two pieces of text from this patch:
# Context lines + removed linessearch = """def retry_download(status): return status == 500"""# Context lines + added linesreplacement = """def retry_download(status): return status in {429, 500, 503}"""It then searches for the first and substitutes the second. If a hunk does not match, Aider can adjust relative indentation, split it into smaller hunks, or vary the surrounding context. Those fallbacks were already present in its 2023 design. (Aider)
Problem. A chat response often describes a change without producing something a text editor can directly apply:
class Client: # ... existing methods ... def retry_download(self, status): return status in {429, 500, 503}Replacing the original class with this snippet would delete its other methods. Appending it would create another class definition. Someone still has to merge the suggestion into the file.
Solution. Cursor’s May 2024 Editing Files at 1000 Tokens per Second described a separate, trained apply model. It receives the original file, conversation, and suggested code, then generates a complete updated file. (Cursor)
class Client:
retry_upload(...)
retry_download(...)class Client:
# ... existing methods ...
retry_download(...) # new bodyclass Client:
retry_upload(...) # preserved
retry_download(...) # replacedFull-file generation creates a second problem: latency. Cursor addressed that with speculative edits, using existing code to supply likely continuation tokens instead of generating every unchanged token from scratch. It still produces a full file; the optimization makes reproducing unchanged sections cheaper. (Cursor)
Problem. A small replacement may appear in several places—even under the same method name:
class UploadClient: def should_retry(self, status): return status == 500class DownloadClient: def should_retry(self, status): return status == 500Searching for return status == 500 is ambiguous. Including def should_retry still does not distinguish the two.
Solution. The apply_patch format allows explicit file operations and additional text anchors. Here, the class header directs the search toward the download implementation: (OpenAI Developers)
*** Begin Patch*** Update File: retry.py@@ class DownloadClient: def should_retry(self, status):- return status == 500+ return status in {429, 500, 503}*** End PatchThe tool searches past class DownloadClient:, then locates the method and old return statement. The anchor helps locate the edit without becoming part of the replacement. This is text matching, not an AST lookup. (OpenAI Developers)
OpenAI also addressed the generation side: its April 2025 GPT-4.1 guide states that the model had been extensively trained on the recommended format. The protocol was something the model had practiced producing, rather than an unfamiliar schema introduced only in a prompt. (OpenAI Developers)
Problem. The model copies the right line but leaves out its trailing spaces:
old = " return status == 500\n"actual = " return status == 500 \n"assert old != actualA strict search fails even though the intended location is clear.
Solution. Pi’s January 2026 fuzzy-edit change tries exact matching first, then a normalized comparison that handles trailing whitespace and selected Unicode differences. It does not simply strip all leading indentation. (GitHub)
For the whitespace case, the idea reduces to:
# Illustration of the trailing-whitespace rule, not the full implementation.def matching_view(text): return "\n".join(line.rstrip() for line in text.split("\n"))assert matching_view(old) == matching_view(actual)The comparison can now find the target. Duplicate detection still matters: normalization must not turn two possible locations into permission to choose one arbitrarily. Pi’s change includes duplicate checks after normalization. (GitHub)
Leading indentation is treated differently because these two blocks do different things:
if failed: retry() notify() # Only on failure.if failed: retry()notify() # Always.Problem. Trimming line endings is not enough when the mismatch is inside a line:
// The model's oldString:"return status === 500;"// The actual file text:"return status === 500;"Solution. OpenCode’s edit path runs candidate-generating matchers in order. For this one-line example, the relevant path is:
The important detail is what the matcher returns: the actual substring from the file, not the model’s imperfect copy. The replacement engine can then replace that substring. Unless replaceAll is requested, it checks that the returned substring occurs only once.
Other fallbacks are broader. The block matcher uses first and last lines as anchors, then compares the interior for similarity. That can recover more edits, but matching similar text does not establish whether the differences are safe to overwrite.
Problem. Sometimes the model copied the old code perfectly. The file changed afterward.
# What the model read:def retry_download(status): return status == 500# What a developer subsequently saved:def retry_download(status): audit(status) return status == 500A permissive whole-function replacement could accept the old block as “close enough” and remove audit(status).
Solution. DeepSeek Harness offers an optional fs-observation-policy. It records which file version the session observed and supplies that version as a condition for later edits. A stale version produces FS_STALE_VERSION, with instructions to read again.
This check is separate from locating the replacement text. The old return statement may still match exactly; the policy nevertheless requires the agent to observe the changed file before editing it. The protection applies when the policy is installed.
After re-reading, the intended change can preserve the new logging call:
def retry_download(status): audit(status)- return status == 500+ return status in {429, 500, 503}