The Command Succeeded. The Scope Changed.

The agent inspects a small diff and runs the required command.
The command succeeds. A hook also regenerates a contract file from a newer source, and the resulting commit contains a change nobody asked for.
That is not a runaway agent. It is fairly normal repository automation doing what it was configured to do. The workflow still needs to decide whether the output belongs in this task.
I have used this kind of scope drift to refine the checks around delegated work. Reviewing an initial diff is useful; reviewing the artifact after automation is also necessary. They are not always the same artifact.
The example is deliberately synthetic
Consider this illustrative composite, not a file tree from an actual company repository.
A task updates one client dependency. Before the commit, the changes are:
package.json package-lock.json
A repository hook refreshes generated API code. The commit now also contains:
src/generated/catalog-api.ts src/generated/catalog-schema.json
The generator may be correct about the source it read. The new contract may be a legitimate change. Neither fact says it belongs in a dependency-only PR.
It could need another owner, another compatibility check, another release sequence, or simply a separate explanation. A successful generator run does not provide those decisions.
There are several versions of the change
A Git operation has more than one relevant state: working tree, index, commit tree, and the remote branch used by review.
An agent can inspect the working tree, stage a subset, and then assume the commit contains that subset. A hook can change files or restage content between those steps. Later, a push hook or generated build output can leave additional local changes that are not committed at all.
The useful question is "which artifact did we verify?"
These generic inspection commands address different artifacts:
git diff --name-status git diff --cached --name-status git show --format= --stat HEAD git show --format= HEAD git status --short
The first two compare working and staged changes. The next two inspect the actual commit. The final status shows what remains outside it. None, by itself, establishes whether the whole task is correctly scoped.
I would inspect the post-hook commit before treating it as ready for review or push. If the repository runs consequential automation during push, inspect its effects too rather than assuming the operation left no new state.
Capture the starting state
Scope checks are less useful if the agent does not know which changes existed before it started.
A working tree can already contain another person's edits. A generated file may have been dirty before the task. A script may update it again, mixing pre-existing content with the agent's output.
Record the branch, base revision, and clean or dirty status before implementation. For relevant dirty files, understand the existing changes instead of treating everything outside the task as disposable.
This is especially important when recovering from generated drift. "Remove unrelated files" is not permission to overwrite a colleague's uncommitted work.
The safe recovery depends on provenance: which change was introduced by this operation, which was already present, and which now conflicts with the authorized work. If that cannot be established cheaply, stop and ask rather than manufacture a clean tree.
A file allowlist helps, but it is not the contract
For a bounded task, an expected file set can reveal surprises:
Expected: dependency manifest and lockfile Observed: manifest, lockfile and generated service contract Decision needed: does the contract change belong to this task?
Sometimes the right implementation legitimately needs another file. A test, a call site, or an adapter may be required to satisfy the original behavior. A strict allowlist should expose that question, not force an incomplete fix.
The reverse is also true: changes inside an expected file can be unrelated. A lockfile may contain several package updates. One generated module can include multiple contract changes with different owners.
Review semantics as well as filenames. The requested scope is an engineering constraint, not a glob pattern.
Generated does not mean low risk
Generated artifacts can encode public APIs, schemas, route tables, database clients, or configuration. A small mechanical change there can affect more consumers than a large handwritten component edit.
A tool may regenerate against a remote source whose revision is not recorded. Run it twice and it can produce two different outputs from the same local commit. The task has acquired an external input even though nobody edited an external file by hand.
Where practical, pin and record the generator version and input revision, or preserve the relevant source snapshot. Keep generated output reproducible enough to explain a future diff.
If a live input is intentional, review the new output with that knowledge. Do not present it as a consequence of the dependency change when it came from unrelated source drift.
Do not bypass the gate just to avoid its output
The tempting response is to disable the hook and finish the small PR.
That may discard a required repository control. It also avoids the useful question of why this hook introduces changes unrelated to the task.
Follow the repository's supported procedure. It may allow a separate generated update, a pinned input, a check-only mode, or an explicitly approved exception. The agent should not invent an exemption because the hook is inconvenient.
After separating unrelated drift, run the checks that matter for the retained change and inspect the final artifact again. A repaired scope still needs verification; the earlier green result may have observed a different set of files.
Tool success is not scope approval
An exit code tells us whether the tool considers its operation successful. It does not certify that the operation had the intended inputs or that every resulting change was authorized.
This applies beyond Git hooks. A formatter can touch unrelated documents. A package manager can alter registry URLs or transitive versions. A code migration can rewrite more call sites than the agreed rollout intended.
The agent's explanation should identify those effects, not compress them into "all commands passed."
The command's success belongs to the command. Approval of the resulting scope belongs to the task.
That distinction allows useful automation without pretending tools understand the whole purpose of a change.
Make the check repeatable, not the incident immortal
After a scope problem, I would refine the workflow around the failure condition: record the starting state, inspect after mutating automation, and verify the artifact that will actually be reviewed.
I would not add a permanent paragraph describing every generated file from that one incident. Those details age quickly. The principle remains useful across different generators and repositories.
The rule also needs proportion. A read-only test command does not need the same artifact accounting as a commit hook that regenerates contracts. Use the checks where state can change, and keep the explanation local enough that the agent can apply it.
The final diff should be unsurprising for the right reason
An agent can produce a neat initial patch and still need help with the effects of the surrounding toolchain. That is not a contradiction. The repository is part of the execution environment, and it can change the result.
I want a reviewer to find the final scope unsurprising because the task explains every meaningful change, not because generated files were hidden from the description.
The next article, A Review Belongs to a Commit, follows that reviewed artifact as it changes again. A later commit can make yesterday's finding or decision stale.
If a tool in your repository can change the artifact after its last inspection, where is the next inspection scheduled? That small gap is worth closing before adding more autonomy.
About the author
Maksym Kuzmitskyi is a Senior Software Developer focused on React and TypeScript. His work includes enterprise applications, shared frontend components, Node.js integration, testing and accessibility. Alongside frontend work, he designs AI-assisted delivery workflows and has developed personal review tooling.
More than a blog post
I share frontend news and the reasoning behind it throughout the day. Pick the language that feels natural to you.