Inline Edit and Apply-Patch
Phase 11 · Document 04 · AI Coding Platforms Prev: 03 — Symbol Search and AST · Up: Phase 11 Index
Table of Contents
- Why This Matters
- Core Concept
- Mental Model
- Hitchhiker's Guide
- Warmup Readings
- Deep Readings and External References
- Key Terms
- Important Facts
- Observations from Real Systems
- Common Misconceptions
- Engineering Decision Framework
- Hands-On Lab
- Verification Questions
- Takeaways
- Artifact Checklist
1. Why This Matters
A coding assistant's value collapses at the last step if the edit won't land: a brilliant change that can't be applied to the file is worthless. Apply-patch — turning model output into reliable, reviewable edits — is therefore one of the most important (and underestimated) subsystems of a coding platform (00), and apply-rate (the fraction of proposed edits that apply cleanly) is a first-class product metric. This is the same apply problem from Phase 10.06, here taken to depth: the edit formats, why exact-match diffs fail, the dedicated apply model that Cursor pioneered, the inline-edit UX (diff preview + review), and the safety rule — never auto-apply without review.
2. Core Concept
Plain-English primer: deciding the change vs applying it
There are two distinct problems, and conflating them is the root of most apply failures:
- Decide the change — the (strong) model figures out what to edit. It's good at intent, weaker at reproducing exact surrounding text.
- Apply the change — turn that intent into a precise modification of the actual file bytes. This needs exactness, not intelligence.
How a platform expresses and lands an edit is the edit format, and the choices trade token cost, precision, and reliability:
| Format | What the model emits | Pros | Cons / failure mode |
|---|---|---|---|
| Whole-file rewrite | The entire new file | Simple; no matching | Expensive (re-emits all); risks unintended changes; slow on big files |
| Search/replace (diff) blocks | old_string → new_string | Token-efficient; targeted | Fails if old_string doesn't match exactly (whitespace/drift) |
| Unified diff / patch | A diff/patch hunk | Standard; line-precise | Models miscount line numbers; brittle hunks |
| Apply model | A sketch of the change → a 2nd fast model merges it | High apply-rate; cheap on the strong model | Extra model + latency; another component |
Why exact-match edits fail (and apply-rate matters)
Search/replace and unified diffs require the model to reproduce the original text exactly (or count lines correctly). Models drift on whitespace, comments, and long spans, so the old_string doesn't match → the edit silently fails to apply. This is why apply-rate is a tracked metric: an edit that doesn't apply is a failed task regardless of how good the change was. Mitigations: keep edits small/targeted, re-read the file right before editing (so the model sees current text), make matching whitespace-tolerant/fuzzy, and on a miss feed the error back so the model retries (Phase 10.01).
The apply model (Cursor's insight)
The key architectural idea: decouple "decide" from "apply." A strong, expensive model decides the change but emits a loose sketch ("change the loop to use enumerate; keep the rest") rather than exact text; then a small, fast, specialized "apply model" merges that sketch into the file precisely. Benefits:
- High apply-rate — the apply model is trained/tuned to land edits reliably (it handles the exact-text matching the big model is bad at).
- Cheaper + faster — the strong model emits less (a sketch, not the whole file), and the fast apply model is cheap.
- Speculative/fast apply — apply models can be very fast (some use speculative decoding, Phase 6.07) so edits land near-instantly.
This is a two-model edit pipeline and a major reason Cursor's edits feel reliable (06 on multi-model routing).
Inline-edit UX: diff preview and review
Applying is only half the UX — the user must see and approve the change:
- Diff preview — show the proposed change as an inline/side-by-side diff before writing (VS Code diff view /
WorkspaceEditpreview, 01). - Accept/reject (per-hunk) — let the user accept all, reject, or accept individual hunks.
- Inline edit (Cmd/Ctrl-K style) — select code, describe the change, see a diff in place, accept.
- Undo/rollback — edits are reversible (version control / editor undo) — never a one-way mutation.
This is the platform face of the agent-safety rule (Phase 10.05): review before commit; never auto-apply silently.
Multi-file edits and impact
Real changes span files (rename a function → update all call sites). Use the reference/call graph (03) to find every site, propose a multi-file diff, and let the user review the whole changeset. Verify with build/tests after applying (Phase 10.06) — apply-rate gets you a clean application; tests confirm it's correct.
3. Mental Model
TWO problems: DECIDE the change (strong model, intent) ≠ APPLY it (exactness, not IQ)
EDIT FORMATS (token/precision/reliability trade):
whole-file (simple, costly) · search-replace diff (efficient, exact-match FAILS) ·
unified diff (standard, line miscount) · APPLY MODEL (sketch → fast 2nd model merges → high apply-rate)
★ APPLY-RATE = fraction of edits that land cleanly = a first-class metric (great edit that won't apply = failed)
exact-match fails on whitespace/drift → small edits · RE-READ before editing · fuzzy match · feed errors back [10.01]
APPLY MODEL (Cursor): decouple decide/apply → high apply-rate + cheaper + fast (speculative [6.07])
UX: DIFF PREVIEW + accept/reject (per-hunk) + UNDO → review before commit (NEVER auto-apply) [10.05/01]
MULTI-FILE: reference graph [03] → multi-file diff → verify with tests [10.06]
Mnemonic: deciding the change ≠ applying it. Apply-rate is the metric; exact-match diffs fail on drift, so re-read + fuzzy-match or use a dedicated apply model (decide-sketch → fast merge). Always diff-preview + review; never auto-apply.
4. Hitchhiker's Guide
What to look for first: the edit format + apply-rate, and whether there's diff preview/review before write. Those determine whether edits reliably land and are safe.
What to ignore at first: building a custom apply model — start with search/replace + re-read-before-edit + fuzzy matching; add an apply model when apply-rate is the bottleneck.
What misleads beginners:
- Ignoring apply-rate. Optimizing the "decide" model while edits silently fail to apply (00).
- Exact-match diffs without re-read. The model's
old_stringdrifts from the real file → no match → failed edit; re-read right before editing. - Whole-file rewrites everywhere. Expensive, slow, and risk unintended changes on large files.
- Auto-applying without review. Violates the safety rule — diff-preview + accept/reject (Phase 10.05).
- Single-file thinking for cross-cutting edits. Use the reference graph for all call sites (03).
How experts reason: they decouple decide from apply, track apply-rate as a core metric, keep edits small + re-read before editing, use fuzzy/whitespace-tolerant matching or a dedicated apply model for reliability, always diff-preview + review, and verify with tests after applying (Phase 10.06). For refactors they drive multi-file edits off the reference graph (03).
What matters in production: apply-rate, edit latency (apply must feel instant), review UX (clear diffs, per-hunk accept), correctness post-apply (tests), and reversibility (undo/VC).
How to debug/verify: measure apply-rate; when edits fail, inspect whether old_string matched (drift → re-read/fuzzy/apply model); confirm a diff preview is shown and edits are undoable; check multi-file edits hit all call sites (03).
Questions to ask: what edit format + apply-rate? re-read before edit? fuzzy matching or an apply model? diff preview + per-hunk review? multi-file via the reference graph? tests after apply?
What silently gets expensive/unreliable: low apply-rate (silent failed edits), exact-match brittleness, expensive whole-file rewrites, auto-apply (unsafe), and incomplete multi-file refactors.
5. Warmup Readings
| Title | Why to read it | What to extract | Difficulty | Time |
|---|---|---|---|---|
| Phase 10.06 — Code-Editing Agents | The apply problem + apply-rate | edit→apply→verify | Beginner | 20 min |
| 03 — Symbol Search and AST | Multi-file edit impact | reference graph | Beginner | 20 min |
| 01 — VS Code Extension Architecture | WorkspaceEdit + diff view | apply + preview | Beginner | 20 min |
| Phase 10.05 — Sandbox and Approval | Review before commit | never auto-apply | Beginner | 20 min |
6. Deep Readings and External References
| Title | URL | Why it matters | Read first | Lab connection |
|---|---|---|---|---|
| Cursor — apply / fast edits | https://docs.cursor.com/ | The apply-model pattern | apply, instant edits | This lab |
| Aider — edit formats | https://aider.chat/docs/more/edit-formats.html | search-replace/diff/whole formats + apply-rate | format trade-offs | Format lab |
| VS Code WorkspaceEdit / diff | https://code.visualstudio.com/api/references/vscode-api#WorkspaceEdit | Applying + previewing | edit + preview | Apply UX |
| unified diff format | https://www.gnu.org/software/diffutils/manual/html_node/Unified-Format.html | The patch format | hunks, line counts | Diff format |
| Speculative decoding (fast apply) | https://arxiv.org/abs/2211.17192 | Why apply models are fast | accept/verify | Phase 6.07 |
7. Key Terms
| Term | Simple meaning | Technical meaning | Why it matters | Where it appears | How to use it |
|---|---|---|---|---|---|
| Apply-patch | Land the edit | Turn output into file changes | The last mile | platform | Track apply-rate |
| Apply-rate | % edits that land | Clean-apply fraction | First-class metric | edits | Measure + raise |
| Edit format | How a change is expressed | whole-file/search-replace/diff | Precision/cost | model output | Choose deliberately |
| Search/replace | old→new block | Find-and-replace edit | Token-efficient | format | Re-read before edit |
| Apply model | Edit-merger model | Fast 2nd model merges a sketch | High apply-rate | Cursor | Decouple decide/apply |
| Diff preview | Show before write | Inline/side-by-side diff | Review/safety | UX [01] | Always show |
| Per-hunk accept | Partial apply | Accept/reject each hunk | Control | UX | Granular review |
| Reference graph | All call sites | Symbol references [03] | Multi-file edits | refactor | Impact analysis |
8. Important Facts
- Deciding a change and applying it are different problems — apply needs exactness, not intelligence.
- Apply-rate (edits that land cleanly) is a first-class metric — an edit that won't apply is a failed task (00).
- Exact-match formats (search/replace, unified diff) fail on whitespace/drift/line-miscounts — mitigate with small edits, re-read-before-edit, fuzzy matching, error-feedback retry (Phase 10.01).
- The apply-model pattern decouples decide (strong model, sketch) from apply (fast specialized model) → high apply-rate, cheaper, fast (often speculative, Phase 6.07).
- Always diff-preview + review (per-hunk accept/reject) + undo — never auto-apply silently (Phase 10.05).
- Whole-file rewrite is simplest but expensive/slow and risks unintended changes — fine for small files only.
- Multi-file edits use the reference graph for all call sites (03); verify correctness with tests after apply (Phase 10.06).
- Edits must be reversible (VC/undo) — a one-way mutation is unsafe.
9. Observations from Real Systems
- Cursor's dedicated apply model (decouple decide/apply) is the canonical high-apply-rate, fast-edit design — a major reason its edits feel reliable (06).
- Aider documents multiple edit formats (whole, diff, search-replace) and measures which apply best per model — a great open reference on apply-rate.
- Claude Code's
Edittool uses exact search-replace with strict matching (and re-reads before editing) — the simple-but-disciplined approach (Phase 10.06). - The classic failure — "the assistant said it changed the code but nothing happened" — is an apply miss (exact-match failure) (00).
- Inline diff + accept/reject is the universal edit UX across Cursor/Copilot/Windsurf — review before commit (Phase 10.05).
10. Common Misconceptions
| Misconception | Reality |
|---|---|
| "A great edit is enough" | It must also apply cleanly — apply-rate matters |
| "Diffs always apply" | Exact-match fails on whitespace/drift; re-read/fuzzy/apply-model |
| "Use whole-file rewrites" | Expensive/slow; risks unintended changes on big files |
| "Auto-apply to save clicks" | Diff-preview + review; never silently mutate code |
| "Apply needs a smart model" | It needs exactness; a fast specialized apply model excels |
| "Refactors are single-file" | Use the reference graph for all call sites [03] |
11. Engineering Decision Framework
LAND EDITS RELIABLY:
1. DECOUPLE decide (strong model: intent/sketch) from APPLY (exactness).
2. EDIT FORMAT:
small targeted change → search/replace (RE-READ file first; fuzzy/whitespace-tolerant match)
high apply-rate needed / fast edits → dedicated APPLY MODEL (sketch → merge)
tiny file → whole-file rewrite (ok); big file → never whole-file
3. ON APPLY MISS: feed the error back → retry (bounded) [10.01]; track APPLY-RATE.
4. UX: DIFF PREVIEW + per-hunk accept/reject + UNDO — never auto-apply [10.05/01].
5. MULTI-FILE: reference graph → multi-file diff → review whole changeset [03].
6. VERIFY correctness with build/tests after apply [10.06].
| Situation | Choice |
|---|---|
| Small targeted edit | Search/replace + re-read + fuzzy match |
| Need reliability/speed | Dedicated apply model (decouple) |
| Tiny file | Whole-file rewrite (ok) |
| Refactor across files | Reference-graph multi-file diff [03] |
| Any edit | Diff preview + review + undo + tests |
12. Hands-On Lab
Goal
Build an apply pipeline, measure apply-rate, and show that re-read-before-edit (and/or an apply step) dramatically improves it — with diff preview before writing.
Prerequisites
- A Python file/repo; the assistant from 00;
pip install openai.
Steps
- Search/replace apply: prompt the model for an
ORIGINAL/UPDATED(search/replace) edit; apply by exact match; show a diff preview and require confirmation before writing (01). - Measure apply-rate: run 15 varied edit requests; count how many
old_stringblocks match and apply. Note failures (whitespace/drift). - Re-read before edit: change the flow to re-read the exact current file region right before constructing the edit; re-measure apply-rate — expect a clear jump.
- Fuzzy match: add whitespace-tolerant matching for the
old_string; re-measure (further improvement). - Apply-model sim: have the strong model emit a loose sketch ("replace the for-loop with enumerate; keep the rest") and a second cheap call merge it into the file precisely; compare apply-rate + latency to direct search/replace.
- Multi-file: for a rename, use a symbol/reference lookup (03) to find all call sites and produce a multi-file diff for review; run tests after applying (Phase 10.06).
Expected output
An apply pipeline with diff preview + confirmation, an apply-rate measurement that improves with re-read + fuzzy match (and/or apply-model), and a multi-file refactor with review + test verification.
Debugging tips
- Many failed applies →
old_stringdrift; re-read right before editing; add fuzzy match. - Apply-model worse → the sketch is too vague or the merge prompt weak; tighten the sketch format.
Extension task
Implement per-hunk accept/reject in the preview; add bounded retry-on-miss (feed the failure back, Phase 10.01).
Production extension
Wire apply through VS Code WorkspaceEdit + diff view (01); add a dedicated fast apply model (consider speculative decoding, Phase 6.07); track apply-rate in eval (08).
What to measure
Apply-rate (search/replace vs +re-read vs +fuzzy vs apply-model), edit latency, multi-file completeness (all call sites), post-apply test-pass.
Deliverables
- An apply pipeline with diff preview + confirmation.
- An apply-rate comparison (re-read / fuzzy / apply-model).
- A multi-file refactor (reference graph → diff → tests).
13. Verification Questions
Basic
- Why are "deciding a change" and "applying it" different problems?
- What is apply-rate, and why is it a first-class metric?
- Why do exact-match diffs fail, and three mitigations?
Applied 4. Explain the apply-model pattern and its three benefits. 5. When is whole-file rewrite acceptable vs harmful?
Debugging 6. "The assistant said it edited the file but nothing changed." Cause and fix. 7. A rename left some call sites unchanged. What was missing?
System design 8. Design a reliable, reviewable edit pipeline: format, apply-rate, preview/review, multi-file, verification.
Startup / product 9. Why does apply-rate (not just model quality) materially affect a coding product's perceived reliability?
14. Takeaways
- Deciding ≠ applying — apply needs exactness; apply-rate is a first-class metric (a great edit that won't land is a failed task).
- Exact-match diffs fail on drift — mitigate with small edits, re-read-before-edit, fuzzy matching, and error-feedback retry.
- The apply-model pattern (decide-sketch → fast merge) gives high apply-rate, lower cost, and fast edits (06).
- Always diff-preview + per-hunk review + undo — never auto-apply silently (Phase 10.05).
- Multi-file edits use the reference graph (03); verify correctness with tests after applying (Phase 10.06).
15. Artifact Checklist
- An apply pipeline with diff preview + confirmation.
- An apply-rate measurement (re-read / fuzzy / apply-model variants).
- A multi-file refactor via the reference graph + review.
- Tests after apply confirming correctness.
- (Optional) per-hunk accept/reject + retry-on-miss.
Up: Phase 11 Index · Next: 05 — Autocomplete Models