A repository change has a shape
A multi-file edit often starts with one visible symptom but crosses a contract boundary. Renaming a function may affect its implementation, callers, tests, documentation and generated types. Changing an API response may involve server code, client parsing and error handling. An agent can apply patches quickly, yet speed does not remove the need to map those dependencies. A change is complete when the relevant contract and its consumers agree.
Start by writing the behavioral goal in one sentence. Then list the files or subsystems likely to own that behavior. This is a hypothesis, not a command to edit everything listed. Search actual references and tests before applying a patch. An unexpectedly small or large set of references can reveal that the initial mental model was wrong.
Read before writing
Inspect the current interface and representative callers. Look for generated code, fixtures and compatibility wrappers. A repository may contain several similarly named functions, only one of which serves the active path. Ask the agent to cite the specific call chain it believes matters. A good explanation names paths and symbols that you can inspect yourself.
Branch state matters. If another process changes files while the agent works, its earlier reads become stale. Before patching a busy codebase, re-open the target files and check Git status. This small pause is cheaper than silently overwriting another contributor's edit. It also helps distinguish the agent's changes from unrelated work when reviewing the final diff.
Keep the patch coherent
The smallest useful patch is not always one file. It is the smallest set of changes that preserves the intended contract. If a type changes, updating every real caller may be necessary. Conversely, broad reformatting and opportunistic cleanup make it harder to tell whether the agent solved the requested problem. Ask for a focused diff and separate unrelated improvements into another task.
Apply edits in a reviewable order. Change the contract, update the dependent code and adjust tests that encode the old behavior. Avoid changing an assertion merely to silence a failure; first understand why the old expectation no longer holds. When the patch contains several independent behaviors, split it so each has a clear explanation and verification step.
Verification should follow dependencies
Run the most relevant test first to get fast feedback. Then run typechecking or a broader package test if the change affects shared interfaces. A passing narrow test demonstrates one path; it does not show that all consumers remain valid. The agent should report the exact commands, exit codes and scope of the checks rather than summarizing them as everything passed.
A failing test is new evidence. Read its assertion, stack and affected file before editing again. Some failures are caused by environment setup, while others expose a missing caller or overlooked behavior. Randomly applying another patch can make the change larger without improving the explanation. Keep the cause-and-effect chain visible.
Review every file for different risks
Implementation files, lockfiles, configuration and tests carry different risks. A lockfile change may indicate an unintended dependency installation. A configuration change can alter behavior outside the feature. A test deletion can make a regression invisible. A new file may be unused. Review the diff file by file, not only the agent's narrative of what it intended.
Look especially for removed validation, weakened authorization and widened error catches. These are common ways a patch can appear to fix a test while changing the safety properties of the product. If a file is surprising, ask the agent to justify its role with a reference to the task. Revert unnecessary changes before committing.
Reversibility improves experimentation
A clean Git checkpoint lets you recover when an agent goes off course. Worktrees or branches help isolate parallel tasks. Before an automated edit, note existing uncommitted changes so they are not mistaken for new output. Afterward, inspect Git status and diff. A snapshot is valuable, but it does not replace review; it simply makes a bad experiment cheaper to undo.
If several agents operate in parallel, give each a separate checkout or clearly disjoint file scope. Shared mutable files create conflicts and stale reads. Integrate only after each change has its own evidence and tests. The combined branch needs verification again because independently passing patches can interact.
A concrete migration example
Suppose an application changes a user identifier from a number to a string. The agent should locate the type definition, serialization boundary, database mapping, clients and fixtures. It may discover that public URLs still use the numeric identifier for compatibility. The right patch might preserve a conversion layer rather than replacing every number in the repository. Only code inspection can settle that.
After editing, run a targeted serialization test and a client typecheck. Review any migration or database change separately because it may be irreversible. The final explanation should say which boundary changed, which remained compatible and which checks ran. That is a multi-file edit as engineering work, not a directory-wide search-and-replace.
The agent's output is a proposed change until the repository checks and human review support it.
Sources & further reading
References support the concepts and product descriptions discussed above. Features, prices and account eligibility can change; check the live documentation. Inclusion here is not a hands-on test or vendor endorsement.