Control Claude Code with clear boundaries

Contents

TL;DR: Set opusplan as your default model, then phrase every task as five things — what you want, what must be preserved, what must not be touched, how to approach it, and what “done” means. You don’t need enormous prompts. You need clear boundaries and a clear definition of done.

Best practices for Claude Code documentation

Anthropic’s Best practices for Claude Code guide.

Steps

  1. Default to opusplan. Opus thinks and plans, Sonnet writes the code. It’s the single easiest optimisation for larger coding tasks.

    /model opusplan
    

    Or in your settings file:

    {
      "model": "opusplan"
    }
    
  2. Phrase tasks with five parts. Instead of Add authentication., give it WHAT, WHERE, RULES, HOW, and DONE WHEN:

    Add rate limiting to the login endpoint.
    
    Use the existing Redis client.
    
    Do not add new dependencies.
    Do not change the API response format.
    
    First inspect how the existing login flow works.
    Then plan the change before implementing it.
    
    You are done when:
    - the feature works
    - existing tests pass
    - new tests cover the rate limit
    - typecheck passes
    
  3. Make it investigate before it edits. Especially in unfamiliar code:

    Investigate this first. Do not make any changes yet.
    
    Find the relevant files, understand how the current implementation works,
    and tell me what you think is causing the problem.
    
  4. Make it plan before it codes. Plan Mode is read-only until you approve the plan, so this is free to ask for:

    Plan this first.
    
    Inspect the existing implementation and propose the smallest clean solution.
    
    Do not write code yet.
    

    Then, once you’ve read it: Looks good. Implement the plan.

  5. Give it a stopping condition. The most useful sentence in the whole workflow is “Do not stop after making the code changes.”

    You are done only when:
    
    - tests pass
    - lint passes
    - typecheck passes
    - the requested behaviour is verified
    
    If any check fails, investigate and fix it.
    Continue until all checks pass.
    
  6. Have it review its own work with fresh eyes. Not Check your code. — the same context will just agree with itself:

    Now review the implementation critically.
    
    Use a fresh subagent so the review is independent.
    
    Look specifically for:
    - incorrect assumptions
    - edge cases
    - security issues
    - missing tests
    - unnecessary complexity
    
    Fix any valid findings.
    

Fixing a bug

Don’t say Fix this error. Give it the reproduction command and ask for the root cause:

Investigate and fix this error:

[paste error]

You can reproduce it with:

  pnpm test

Find the root cause rather than patching the symptom.
Make the smallest reasonable fix.
Rerun the command until it passes.

Adding a feature

Implement [feature].

First inspect how similar features are implemented in this repository.
Follow those patterns instead of inventing a new architecture.

Requirements:
- ...

Do not:
- add unnecessary dependencies
- change unrelated code
- change existing behaviour

Run the relevant tests when complete.

The load-bearing phrase is “Follow those patterns instead of inventing a new architecture.” It matters most in established projects.

Refactoring

Refactor [component].

Preserve behaviour exactly.
Keep the refactor focused on [reason].

Do not change public APIs.
Do not introduce new dependencies.
Do not clean up unrelated code even if you notice other problems.

Make the changes in small steps and run tests afterwards.

Using subagents

Subagents run in separate contexts, so they’re ideal for large searches that would otherwise flood the main context. You rarely need custom agent definitions — just ask:

Use separate subagents to investigate:

1. the backend implementation
2. existing tests
3. the frontend integration

Have them report their findings back to you before making changes.

Keep the expensive coordinating model out of the file-grep business:

Delegate codebase exploration to a Sonnet subagent.

Have it find the relevant files and return a concise summary.
You should reason from its findings.

And for larger features:

Break this into independent tasks — backend, frontend, tests.
Fan out independent work to Sonnet subagents.
Coordinate their work and integrate everything afterwards.

Do not parallelise tasks that depend heavily on each other's unfinished changes.

With opusplan that gives you roughly:

                OPUS
         understand + plan
        ┌────────┴────────┐
        ↓                 ↓
  Sonnet subagent   Sonnet subagent
     research          research
        └────────┬────────┘
              SONNET
           implementation
         independent review
               tests

Keeping the change small

Negative instructions work well. Be explicit:

Do not:
- refactor unrelated code
- rename unrelated files
- add dependencies
- change public interfaces
- modify the database schema
- disable tests
- weaken validation

Plus the catch-all: “Make the smallest change that correctly solves the problem.”

When it’s going the wrong way

Stop implementing.

Re-evaluate your assumptions.

Inspect the relevant code again and explain why the current approach is wrong
before making any further changes.

If the context itself has gone stale or messy, run /clear and restate the task cleanly. That’s usually faster than arguing with a confused context.

Make it prove the work

Instead of asking Done?:

Before finishing, show me:

1. what you changed
2. why you changed it
3. what tests you ran
4. whether they passed
5. anything that remains uncertain

Or just: “Verify this works. Don’t just tell me it works.”

A default feature prompt

For most coding tasks this is enough on its own:

Implement [FEATURE].

First inspect the existing code and understand how similar functionality works.
Plan the change before implementing it.

Follow existing repository patterns.
Keep the implementation simple and focused.
Do not refactor unrelated code.
Do not introduce dependencies unless necessary.

Use subagents for large codebase exploration or independent tasks.

When finished:
- review your changes
- run relevant tests
- run typecheck/lint if applicable
- fix any failures

Do not stop until the checks pass.

Short phrases worth remembering

Investigate first. Don't edit yet.
Plan this before implementing it.
Follow existing patterns.
Make the smallest correct change.
Do not expand scope.
Do not modify unrelated code.
Use subagents to investigate this.
Fan out independent work to Sonnet subagents.
Use a fresh subagent to review the implementation.
Find the root cause, not just the symptom.
Run the relevant tests and fix failures.
Do not stop until all checks pass.
Verify it works. Don't just tell me it works.

The formula

If you only remember one thing:

OPUSPLAN

Investigate → Plan → Implement → Review → Test

And phrase every instruction around:

What I want
+ What you must preserve
+ What you must not touch
+ How to approach it
+ What "done" means