The four-line task boundary that stops AI agent overreach
A six-line scope contract at the top of every agent prompt cuts review time in half. Diffs stay inside the lane you asked for. What goes in those lines matters more than the model.

A developer asks an AI agent for a one-line bug fix: in the email-sending function, swap the order of the to and bcc arguments. The agent comes back forty-five seconds later with a 31-file diff. The bug is fixed in line 14 of one file. The other thirty files are "consistency improvements" — renamed variables, lifted constants, a refactor of the logger, two unrelated test files updated to use a new helper the agent decided to write. The diff compiles. The tests pass. The reviewer now has to reason about thirty unsolicited changes to land the one that was asked for.
This is not a model failure. The agent did precisely what it was told. The instruction was "fix this bug." It read "fix this bug" as "improve this codebase." Without an explicit boundary, the agent treats the entire visible repo as in-scope, because it has no information that says otherwise.
The fix is upstream of every prompt-engineering trick. Before you describe what you want done, you describe where it is allowed to be done. A four-line preamble at the top of the prompt — call it a task boundary — is the difference between a one-line PR and a thirty-file rewrite. The boundary is short, mechanical, and easy to forget. Forgetting it is the load-bearing reason most "the agent did too much" complaints exist.
Why agents overreach by default
Three reasons reinforce each other. None of them are fixable by switching models.
The training distribution rewards "polish." Coding agents are post-trained on diffs from real engineers, who often improve adjacent code while fixing a bug. The reward signal does not distinguish "the engineer was asked to refactor and did" from "the engineer happened to refactor while fixing a bug." Out of the box, the agent has learned that a good fix is a fix-plus-some-cleanup. Without a boundary, that prior runs.
Reviewers are an invisible cost. The agent gets feedback when its PR fails tests or is rejected. It does not get feedback when a reviewer spends an extra forty minutes reading a diff three times the size of necessary. From the agent's perspective, the second-best diff (focused fix, no cleanup) and the larger one (focused fix, plus cleanups that compile) look indistinguishable. From the team's perspective they are not.
"Helpful by default" is an explicit design choice. Every modern coding agent is tuned toward proactivity, because the alternative — agents that ask before doing — gets bad reviews on first contact with a casual user. The proactivity is appropriate when the user has phrased a vague request. It is wildly inappropriate when the user has phrased a precise one. The boundary is how you flip the default for the case at hand.
Unbounded vs bounded, in one diff
Here is the same task, given two ways. Same model, same repo, same files in scope.
Unbounded prompt:
Fix the email function — to and bcc are swapped.
What comes back: 31 files, ~600 added lines, ~200 removed. The fix is in there. So is a renamed variable in mailer.ts, a new sendOptions type the agent extracted, a logger refactor, two test files updated to use a helper that didn't exist before, and an updated README example that now mentions the new type.
Bounded prompt:
SCOPE
Edit only: src/mail/sendEmail.ts (one file)
Read for context: src/mail/types.ts
Do not touch: anything else.
TASK
The to and bcc arguments to sendEmail are passed in the wrong order
at the call site on line 14. Swap them. Do not rename variables,
extract types, refactor adjacent code, or "improve" anything else.
REPORT
If you believe a change outside the allowed file is required to make
this work, stop and tell me. Do not edit it.
VERIFY
Run tests/mail/sendEmail.test.ts only. Do not run other suites.
What comes back: 1 file, 1 line changed, 1 test verified. The whole diff is the fix.
The two prompts differ by sixty seconds of typing. The diffs differ by thirty files. The math is one-sided enough to make this a default.
The four-line boundary template
Strip the bounded prompt above to its skeleton. Four sections, each one short, each one load-bearing.
1. Scope. The exact list of files (or directories, or modules) the agent may edit. Anything else is read-only or off-limits. Be ruthless: if you write src/, you have written nothing useful.
2. Prohibition. A short list of the things the agent is prone to do that you do not want. "Do not rename variables. Do not extract types. Do not write new helpers. Do not update unrelated tests." This list is task-specific. Tune it once, then reuse it across similar tasks.
3. Reporting protocol. What the agent should do when its boundary blocks a change it believes is necessary. The exact phrasing matters: "stop and tell me" beats "ask before doing" because the latter still rewards proactivity. Modern coding agents respect "stop and report" when it is stated as a hard constraint.
4. Test verification scope. Which test suites to run, and only those. Without this line, the agent runs the full suite, sees an unrelated failure in a flaky test, and "fixes" that too.
That is the entire technique. Four sections, ten lines, applied at the top of every prompt for tasks where a precise change is wanted.
A worked example: typo fix in a satellite microservice
A real prompt, real shape, redacted file paths.
SCOPE
Edit only: services/billing/src/handlers/refund.ts
Read for context: services/billing/src/types/refund.ts
Do not touch: anything in services/orders/, services/notifications/, or shared/.
TASK
The error message returned when a refund exceeds the original charge
amount currently reads "Refund amount over orginal charge." Fix the
typo to "Refund amount over original charge." Do not change phrasing,
punctuation, structure, or any other strings.
REPORT
If the typo also appears in tests or fixtures, do NOT fix those copies.
Tell me where they are; I will fix them in a separate PR.
VERIFY
Run only services/billing/test/handlers/refund.test.ts.
The agent edits one line, runs one test file, and reports two other files where the typo appears. Total review time, two minutes. Without the prompt, the same task tends to land as "fixed typo in error message and updated all 6 tests, plus added a BillingError.tsx enum to centralize error strings." Each of those changes is defensible in isolation. None of them is what was asked for.
Why prompts beat tool grants — and why you want both
Tool grants (Read(src/**), Edit(src/billing/**)) are the OS-level enforcement layer. They survive a prompt the agent ignores. They are also, by themselves, blunt: they will let the agent edit anything in the allowed paths, including the unsolicited cleanups.
The boundary prompt is the policy layer. It tells the agent what is allowed within the granted scope. Of the two, the prompt is what produces a small diff. The tool grant is what makes sure the agent cannot escape into adjacent code if it forgets the prompt.
Treat them as complementary. Tool grants are your floor; the boundary prompt is your ceiling. Without the floor, an inattentive agent edits adjacent code. Without the ceiling, an attentive agent over-improves the code you wanted edited.
The "stop and report" line
Of the four sections, the reporting protocol is the one that does the most work, and the one most often dropped.
The default agent behaviour, when it hits a constraint, is to find a way around the constraint. Modern coding agents are trained to be agentic — to make progress. If the prompt says "do not edit other files" but the agent decides another file genuinely needs editing to make the task work, it will edit that file and add a justification in the PR description.
The reporting line — "if you believe a change outside the allowed file is required to make this work, stop and tell me. Do not edit it." — flips this. It tells the agent that stopping is the success state when a boundary would be crossed. The agent now blocks on you instead of acting unilaterally. That blocking is the whole point: a boundary that the agent silently routes around is not a boundary, it is a suggestion.
A team that adopts the boundary template without the report line gets about half the benefit. The diffs get smaller, but the agent invents reasons to edit one more file. With the report line, you get the full effect: the diff matches the scope, exactly.
Failure modes and how to catch them
Three patterns show up when teams first adopt this.
Boundary too tight. "Edit only line 14 of mailer.ts" leaves no room for the agent to update an import or a type. The agent reports back "I cannot complete this task without editing the type at mailer.ts:7," and the right answer is to widen the scope by one line. The boundary should be tight enough to prevent overreach, loose enough to allow the obvious surrounding edits the change implies.
Boundary forgotten on follow-ups. The first prompt is bounded. The follow-up — "now write the changelog entry" — is not. The agent treats the follow-up as a fresh, unbounded turn and writes the changelog, plus updates four other docs that "should mention this change." Re-state the boundary on every turn, not just the first. It is two lines per follow-up. It is worth it.
Inconsistent prohibitions. "Do not rename anything" works. "Do not refactor unnecessarily" does not work, because unnecessarily is an opinion the agent will have. Prohibitions must name concrete actions: rename, extract, move, inline. Avoid evaluative words.
What this gives you back
The boundary prompt is a forcing function for a thing teams already wanted: small, focused, reviewable diffs. The same change that takes ten minutes of review without the boundary takes ninety seconds with it. Multiplied across a team's PR queue, that is the difference between merge-by-end-of-day and merge-by-end-of-week.
The deeper effect is not the speedup. It is that the agent's output starts to look like the kind of work a careful engineer ships: minimal, deliberate, easy to revert. That shape is what you wanted from the agent in the first place. The boundary is how you tell it which shape to make.
Four lines. The cheapest correctness lever in the modern coding workflow, and the one teams skip most.
Related in the StoicSoft network
If you work in AI-assisted coding, shared terminal sessions, or agent-driven shell workflows like the ones above, 1devtool is the StoicSoft network's tool for safer AI-assisted terminal work — shared sessions with auditing, preflight policy, and tiered model routing built in.