Chapter 14

Generate a Minimal Coherent Patch

A minimal patch changes exactly the contract that explains the defect and adds enough evidence. It's not necessarily one line, but it has no incidental renames, formatting, or improvements beyond the goal. In the companion project the write is arranged so the preview requires exactly one match and the write itself is atomic.

TypeScript
export function previewReplacement(before: string, operation: TextReplacement): string {
  if (operation.expected.length === 0 || operation.expected === operation.replacement) {
    throw new Error("Replacement must change one non-empty fragment");
  }
  const matchCount = occurrences(before, operation.expected);
  if (matchCount !== 1) {
    throw new Error(`Expected exactly one match in ${operation.path}, found ${matchCount}`);
  }
  return before.replace(operation.expected, operation.replacement);
}

export async function applyTextReplacement(root: string, operation: TextReplacement): Promise<void> {
  resolveContained(root, operation.path);
  const path = await assertRegularContainedFile(root, operation.path);
  const before = await readFile(path, "utf8");
  const after = previewReplacement(before, operation);
  const temporaryPath = join(dirname(path), `.${randomUUID()}.agent-write`);
  await writeFile(temporaryPath, after, { encoding: "utf8", flag: "wx", mode: 0o600 });
  await rename(temporaryPath, path);
}

The order of the change enforces discipline: save a baseline, match every planned write against the allowed scope, form the patch and check that it changes the expected fragment, write atomically, build a snapshot again, and reject the result on unplanned changes.

Typical anti-patterns and a control for each are worth keeping in view.

Anti-pattern · Risk · Control

  • Rewrite the whole file - Hidden formatting diff and lost comments; Patch specific hunks
  • Replace all matches - Change other semantics; Expect an exact match count
  • Update dependencies along the way - New supply-chain and compatibility surface; A separate task and review
  • Fix the test instead of the code - Remove the defect signal; First show why the test is wrong
  • Format the whole repository - Hide the meaningful diff; Formatter only on the touched files

Two caveats clarify the word "minimal." The first is that coherent doesn't mean microscopic: if a change of public behavior requires an implementation, a regression test, and contract documentation, those three files can make up one minimal coherent patch. Deleting a test to cut line count doesn't improve the patch.

A patch doesn't confirm behavior. Even a perfect diff stays a hypothesis until a test, build, static analysis, or an observable UI check. Code review and execution verification are needed together, not separately.

The patch is ready. But to check it the agent runs commands - and it must run them as data, not as shell text.

Links