Coding agents usually do not drift because they are incapable. They drift because the task leaves too much room for interpretation.
A request like “clean up authentication” sounds clear to a human who already knows the codebase. To an agent, it can mean anything from renaming one helper to replacing the entire authentication stack.
The fix is not a longer prompt. It is a brief with four explicit parts:
- Outcome
- Context
- Guardrails
- Definition of Done
Below is the exact structure I use.
1. State the outcome as an observable change
Describe what should be different for the user or system when the work is complete.
Weak:
Fix the login bug.
Better:
When a user submits an expired magic link, show the existing “Link expired” message and offer a button that requests a new link without leaving the page.
The better version gives the agent a destination. It does not prescribe the implementation, but it makes success testable.
2. Give only the context that changes the decision
Context is useful when it removes ambiguity. It becomes noise when it is a tour of the whole repository.
Useful context often includes:
- The relevant entry point or route
- The existing component or service that should be reused
- A similar implementation elsewhere in the codebase
- The command used to run the relevant tests
- A known constraint, such as backwards compatibility
Example:
The page is implemented in
app/auth/verify/page.tsx. ReuserequestMagicLink()fromlib/auth/client.ts. The existing error-message styles live incomponents/auth/AuthNotice.tsx.
That is enough to start investigating without pretending we already know the final patch.
3. Add guardrails that define the change boundary
Guardrails prevent a small task from becoming an accidental rewrite.
A useful set might be:
- Do not change the public API.
- Do not add dependencies.
- Keep the current visual design.
- Do not edit generated files.
- Limit changes to the authentication flow and its tests.
- If a database migration appears necessary, stop and explain why before creating one.
Notice that the last guardrail gives the agent an escalation rule. “Stop and explain” is much safer than letting an uncertain assumption become a migration.
4. Make the Definition of Done evidence-based
“Works correctly” is not a Definition of Done. Ask for evidence that you can inspect.
For the magic-link example:
- An expired link shows the existing error message.
- Clicking “Request a new link” calls the existing client method once.
- The success and failure states are both covered by tests.
- The relevant test suite passes.
- The final response lists changed files and the verification commands run.
This turns the end of the task into a small acceptance test.
Copyable task-brief template
# Outcome
[Describe the observable behavior that should exist when complete.]
# Context
- Entry point:
- Existing code to reuse:
- Similar implementation:
- Verification command:
# Guardrails
- Do not:
- Preserve:
- Scope limit:
- Stop and ask if:
# Definition of Done
- [ ] Observable behavior is implemented.
- [ ] Important success and failure paths are tested.
- [ ] Relevant checks pass.
- [ ] Final response includes changed files and verification evidence.
Enter fullscreen mode Exit fullscreen mode
A complete bug-fix brief
# Outcome
When an expired magic link is submitted, show the existing “Link expired”
message and let the user request a replacement without leaving the page.
# Context
- Page: app/auth/verify/page.tsx
- Reuse: requestMagicLink() from lib/auth/client.ts
- Reuse styles: components/auth/AuthNotice.tsx
- Tests: npm test -- auth-verify
# Guardrails
- Do not add dependencies.
- Do not change the public auth API.
- Preserve the current layout and copy.
- Limit changes to this flow and its tests.
- If a server/API change seems necessary, stop and explain why first.
# Definition of Done
- [ ] Expired links show the existing message.
- [ ] The replacement-link action is available on the same page.
- [ ] Loading, success, and failure states are covered.
- [ ] npm test -- auth-verify passes.
- [ ] Final response lists files changed and checks run.
Enter fullscreen mode Exit fullscreen mode
Add one quality gate before accepting the patch
A good brief controls the start of the work. A quality gate controls the end.
Before accepting the result, ask:
- Did the patch solve the stated outcome?
- Did it stay inside the guardrails?
- Is there test or command output supporting the claim?
- Did the agent disclose assumptions and unverified areas?
- Is the diff smaller than a reasonable alternative?
That last question is especially useful. A correct result can still create unnecessary maintenance work.
Free resources and the kit I built
I published a free starter repository with brief templates and a small browser-based builder:
I also packaged the expanded version, AgentBrief Pro, with 43 reusable assets: 18 task briefs, 12 task recipes, 8 recovery playbooks, and 5 quality gates. It is a paid download ($29): view AgentBrief Pro on Payhip.
The important idea is free to use: make the outcome observable, provide decision-changing context, set boundaries, and demand evidence.
0 Comments
Log in to join the conversation.No comments yet. Be the first to share your thoughts.