Agent Scopes - Keeping AI Solutions Right-Sized

2026-03-09

aiagentsscope-managementdevelopment-workflowconstraints
Agent Scopes - Keeping AI Solutions Right-Sized

You send an AI agent off to add a feature. You come back to find it's rewritten half the codebase and overcomplicated the solution beyond recognition. How often has this happened to you?

The problem is scope creep without guardrails. Agents optimise for completion, not constraint. They add features, rewrite patterns, refactor code "for consistency" — all in service of the task, but none of it authorised. We need a way to define boundaries that agents understand and respect.

Borrowing from OAuth

OAuth scopes define boundaries — what an access token can do, which resources it can touch, what operations it can perform. The principle of least privilege keeps tokens constrained to what they need and nothing more.

What if we applied the same concept to AI agents?

In OAuth, authorisation is absolute. With AI agents, instructions aren't guarantees — there's no compiler preventing an agent from rewriting your database layer. But what if we established scopes anyway? Define expected changes. Set boundaries. Give the agent a framework for working within constraints and a mechanism for flagging when it hits a wall. Scopes might not enforce compliance, but they could signal intent. Once complete, they'd provide a baseline for evaluating whether the agent stayed roughly within bounds or wandered off on its own tangent.

Designed scope versus agent scope

Consider a to-do app API with PATCH /v1/tasks/{taskId} for updating task fields — title, dueDate, notes. You need to add the ability to mark tasks as complete. This is a genuine 50-50 decision:

  • Option A: Use existing endpoint with { "completed": true } (completion is just state)
  • Option B: Add POST /v1/tasks/{taskId}/complete (completion is an explicit action with side effects like setting completedAt)

Both are valid. The choice depends on your requirements.

Without scopes

Prompt: "Add the ability to mark tasks as complete"

Agent decides to add a new endpoint because "it's more RESTful". Creates POST /v1/tasks/{taskId}/complete. Adds route definitions, OpenAPI docs, controller logic. Updates client SDK to include the new endpoint. Implements similar endpoints for archive, snooze, and pin "for consistency".

You return to find four new action endpoints when a simple field update would have worked.

With scopes

Prompt: "Add the ability to mark tasks as complete. Granted: +edit:endpoint. Denied: -add:endpoint, -add:api-client"

Agent can modify existing endpoint logic but cannot create new endpoints or API client methods. Adds completed field handling to existing PATCH /v1/tasks/{taskId}.

You return to find exactly what you expected: one field added to the existing endpoint.

The scope constraint guided the agent towards the simpler solution and prevented architectural decisions you didn't authorise.

Surfacing hidden complexity

Now consider a scenario where complexity isn't a design choice but genuinely hidden: adding dark mode to an existing web application. Seems straightforward — just swap some colour variables, right?

Prompt: "Add dark mode to the application. Granted: edit:component, add:store. Denied: add:asset, edit:asset"

Agent implements CSS variable system for colours. Creates state store for theme management with localStorage and system preference detection. Updates component styles successfully.

Then hits a constraint:

I've implemented core dark mode theming with a toggle and persistent state. However, I found issues I cannot fix with current scopes:

  • Logo and icons need dark variants (requires add:asset or edit:asset)
  • Several images have white backgrounds that clash with dark mode (requires add:asset for alternatives)
  • Chart library colours are hardcoded and need configuration (might need add:component for wrapper)

Should I request additional scopes, or would you prefer to handle these separately?

You can now decide whether to expand the scope, phase the rollout, or keep dark mode as a CSS-only feature initially.

In this scenario, scopes would have surfaced the hidden complexity early — that you can't actually add dark mode without touching assets and hardcoded values. Whether that's a feature or a bug depends on your context. But at least you'd know what you're signing up for before the work sprawls.

A scope taxonomy

Examples of what scopes might look like across different layers:

API Layer

  • add:endpoint - Create new API endpoints
  • edit:endpoint - Modify existing endpoint logic
  • remove:endpoint - Delete API endpoints

Service Layer

  • add:service - Create new service classes or business logic
  • edit:service - Modify service methods and logic
  • remove:service - Remove unused services

Database Layer

  • add:migration - Create new database migrations
  • edit:migration - Modify pending migrations
  • remove:migration - Remove pending migrations

Routing

  • add:route - Add new application routes
  • edit:route - Modify route paths, guards, or metadata
  • remove:route - Remove routes from the application

Components

  • add:component - Create new UI components
  • edit:component - Modify component logic and styling
  • remove:component - Delete unused components

State Management

  • add:store - Create new state stores or slices
  • edit:store - Modify state logic, actions, or selectors
  • remove:store - Remove unused state management code

Assets

  • add:asset - Add new static assets
  • edit:asset - Replace or optimise existing assets
  • remove:asset - Remove unused assets

These are generic examples. In practice, we might augment these with custom scopes tailored to a project's architecture — edit:payment-service, add:notification-template, edit:analytics-event — whatever reflects your core components and boundaries.

How this differs from OAuth

With OAuth scopes, absence implies denial. Authorisation checks look for the presence of a scope.

With agent scopes, you have two options: explicitly grant or deny each permission upfront, or establish a contract where unmentioned scopes are implicitly denied. The latter initially sounds cleaner — define which scopes are granted, everything else is off limits. You need a clear definition of what each scope means, along with the complete scope taxonomy for the project — This could be included as part of an agent skill or project-level configuration. But agents will likely handle explicit denial better in practice — a clear "you cannot do X" in the prompt will like result in a better adherence to the concept.

Syntactic sugar with purpose

Agent scopes are really just syntactic sugar for checkboxes that ultimately end up in the prompt. Nothing technically prevents an agent from ignoring them. But they serve a purpose beyond enforcement: they act as a reminder to provide scoping in your initial prompt. A structured way to think about boundaries before you hit "run".

Beyond the prompt

Scopes could serve purposes beyond just constraining the agent itself. Merge requests could be checked against the declared scopes — did the agent stay within bounds? Scope violations could flag commits for prioritised human review. As the volume of AI-assisted code changes accelerates, we'll need triage mechanisms. Scope adherence is a natural filter: changes within declared bounds might bypass review queues, while scope violations trigger immediate attention.

Cost control

Scopes could impact the economics of AI-assisted development. Limiting scopes might reduce token usage by preventing agents from wandering into unnecessary context. Smaller scope could mean smaller search space, which could lead to more efficient execution. An agent constrained to edit:component might not need to load and reason about database schemas, API contracts, or migration files.

Increased autonomy

When you trust that an agent will stay within defined boundaries, you could grant it more autonomy. You might be more likely to let an agent run unsupervised overnight if you know it's constrained to edit:tests and edit:component rather than having free rein across the entire codebase. The paradox could be that more constraints enable more freedom.

Forcing incremental change

Scopes could force agents to be efficient with their changes rather than continuously reinventing large parts of the codebase. Without constraints, agents often lean towards ground-up rewrites — it's easier to build from scratch than to understand and modify existing patterns. By enforcing surgical, scoped changes, you might push the agent to work incrementally, to understand what's already there, and to make minimal modifications.

Better brownfield development

This constraint-driven approach might actually make AI more effective in brownfield projects. Without constraints, agents often default to rewriting large sections of well-proven codebases By limiting scope to specific capabilities like edit:component or add:endpoint, you force the agent to work within the established architecture rather than replacing it. The agent must learn to make surgical changes that fit the existing system instead of reimagining entire subsystems from scratch.

The result could be code that evolves deliberately rather than exploding unpredictably.

This is just an idea — one I'm still experimenting with and refining. But I think we're going to need something like it as we grant agents more autonomy. Scopes might not be perfect. But they might be better than the alternative: sending agents out with no guardrails and hoping they do what you had initially pictured.