Scope Policy
The scope policy category enforces blast-radius limits — it controls the maximum impact a single agent execution can have on data, files, transactions, and external systems.
Use it when agents perform write operations (database updates, file modifications, financial transactions, external API calls) and you need guardrails to prevent runaway executions from causing disproportionate damage.
Rules
| Rule | Type | Default | Description |
|---|---|---|---|
max_records_modified | integer | 100 | Maximum number of records that can be modified in a single execution |
max_records_deleted | integer | 0 | Maximum number of records that can be deleted (default 0 means deletions require explicit allowance) |
max_files_changed | integer | 10 | Maximum number of files that can be created or modified |
max_transaction_amount | number | 1000.00 | Maximum total dollar amount of financial transactions |
max_api_writes | integer | 50 | Maximum number of external API write calls (POST, PUT, PATCH, DELETE) |
require_rollback_capability | boolean | false | Warn if the agent context does not declare rollback support |
dry_run_first | boolean | false | When true, sets context._dry_run_mode = true at before_workflow |
action_on_violation | string | "block" | "block" raises PolicyViolationError; "warn" logs and continues |
How It Works
The scope handler runs at all three enforcement phases:
before_workflow
Stores the scope rules into context._scope_rules for mid-execution access. Optionally enables dry-run mode (context._dry_run_mode = true) and warns if rollback capability is required but not declared.
mid_execution
Reads the running totals from the context and checks each limit:
context.records_modifiedvsmax_records_modifiedcontext.records_deletedvsmax_records_deletedcontext.files_changedvsmax_files_changedcontext.transaction_totalvsmax_transaction_amountcontext.api_writesvsmax_api_writes
The first exceeded limit produces an immediate result (BLOCK or WARN based on action_on_violation). Limits are checked in this order — only one violation is reported per mid_execution check.
after_workflow
Audits all limits again against the final totals. Collects all violations (not just the first) and returns them as a warning list in the metadata, regardless of action_on_violation. This is an audit record — the after_workflow phase does not block on scope.
When mid_execution Fires
mid_execution runs every time the agent calls ctx.record_scope_impact(). This means violations are caught as soon as the agent reports impact, not just at the end of execution. The agent is blocked before additional writes can occur.
SDK Integration
Recording Scope Impact
import waxell_observe as waxell
from waxell_observe.errors import PolicyViolationError
async with waxell.WaxellContext(
agent_name="data-agent",
enforce_policy=True,
) as ctx:
# Perform your data operation
result = await update_database(query)
# Report the blast radius — triggers mid_execution governance check
ctx.record_scope_impact(
records_modified=result.rows_updated,
records_deleted=result.rows_deleted,
files_changed=result.files_written,
transaction_total=result.payment_amount,
api_writes=result.external_calls,
)
Additive Totals
record_scope_impact() is additive — each call increments the running totals. Call it once per operation to build up an accurate picture of cumulative impact:
async with waxell.WaxellContext(...) as ctx:
# First batch operation
ctx.record_scope_impact(records_modified=30, api_writes=5)
# Second batch operation — totals are now 80 records, 12 writes
ctx.record_scope_impact(records_modified=50, api_writes=7)
# Third batch — totals now 105 records, 12 writes
# If max_records_modified=100, this call triggers a mid_execution BLOCK
ctx.record_scope_impact(records_modified=25)
Handling Violations
try:
async with waxell.WaxellContext(
agent_name="data-agent",
enforce_policy=True,
) as ctx:
result = await process_records(batch)
ctx.record_scope_impact(
records_modified=len(result.modified),
records_deleted=len(result.deleted),
transaction_total=result.total_amount,
)
ctx.set_result(result)
except PolicyViolationError as e:
# e.g. "Records modified (250) exceeds limit (100)"
print(f"Scope limit exceeded: {e}")
await notify_operator(str(e))
Example Policies
Conservative Data Agent
Strict limits for agents with broad database access:
{
"max_records_modified": 100,
"max_records_deleted": 0,
"max_files_changed": 10,
"max_transaction_amount": 1000.00,
"max_api_writes": 50,
"require_rollback_capability": false,
"action_on_violation": "block"
}
Financial Operations
Zero tolerance for large transactions; allow more record modifications:
{
"max_records_modified": 500,
"max_records_deleted": 10,
"max_files_changed": 20,
"max_transaction_amount": 5000.00,
"max_api_writes": 100,
"require_rollback_capability": true,
"action_on_violation": "block"
}
Bulk ETL Pipeline
High limits for intentional bulk operations — use warn mode to audit without blocking:
{
"max_records_modified": 10000,
"max_records_deleted": 1000,
"max_files_changed": 50,
"max_transaction_amount": 0,
"max_api_writes": 0,
"action_on_violation": "warn"
}
Read-Only Enforcement
Prevent any writes — useful for analytics agents that should only read:
{
"max_records_modified": 0,
"max_records_deleted": 0,
"max_files_changed": 0,
"max_transaction_amount": 0,
"max_api_writes": 0,
"action_on_violation": "block"
}
Enforcement Flow
Agent starts (WaxellContext.__aenter__)
│
└── before_workflow governance runs
├── Stores scope rules into context._scope_rules
├── require_rollback_capability? → WARN if context.supports_rollback is False
└── dry_run_first? → sets context._dry_run_mode = True
Agent runs — calls ctx.record_scope_impact(...)
│
└── mid_execution governance runs (each call)
├── records_modified > max_records_modified? → BLOCK/WARN
├── records_deleted > max_records_deleted? → BLOCK/WARN
├── files_changed > max_files_changed? → BLOCK/WARN
├── transaction_total > max_transaction_amount? → BLOCK/WARN
├── api_writes > max_api_writes? → BLOCK/WARN
└── All within limits → ALLOW
Agent completes (WaxellContext.__aexit__)
│
└── after_workflow governance runs
├── Re-checks all limits against final totals
├── Collects all violations (not just first)
├── Violations → WARN with impact_summary metadata
└── No violations → ALLOW with impact_summary metadata
Creating via Dashboard
- Navigate to Governance > Policies
- Click New Policy
- Select category Scope
- Set your limit values
- Set
action_on_violationtoblockorwarn - Set scope to target specific agents (e.g.,
data-agent) - Enable
Creating via API
curl -X POST \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
https://acme.waxell.dev/waxell/v1/policies/ \
-d '{
"name": "Conservative Data Agent Limits",
"category": "scope",
"rules": {
"max_records_modified": 100,
"max_records_deleted": 0,
"max_files_changed": 10,
"max_transaction_amount": 1000.00,
"max_api_writes": 50,
"action_on_violation": "block"
},
"scope": {
"agents": ["data-agent"]
},
"enabled": true
}'
Observability
Governance Tab
Scope evaluations appear at each enforcement phase:
before_workflow (always ALLOW unless rollback required):
| Field | Example |
|---|---|
| Policy name | Conservative Data Agent Limits |
| Action | allow |
| Phase | before_workflow |
| Reason | "Scope limits stored for enforcement" |
mid_execution (per record_scope_impact call):
| Field | Example |
|---|---|
| Action | block |
| Phase | mid_execution |
| Reason | "Records modified (250) exceeds limit (100)" |
| Metadata | {"records_modified": 250, "limit": 100} |
after_workflow (final audit):
| Field | Example |
|---|---|
| Action | allow |
| Phase | after_workflow |
| Reason | "Scope audit passed (modified=8, deleted=0, files=2, tx=$450.00)" |
| Metadata | {"impact_summary": {"records_modified": 8, "records_deleted": 0, ...}} |
Impact Summary Metadata
Every after_workflow evaluation includes a full impact_summary:
{
"impact_summary": {
"records_modified": 8,
"records_deleted": 0,
"files_changed": 2,
"transaction_total": 450.0,
"api_writes": 3
}
}
This is available even on successful runs, making it useful for auditing the actual impact of every execution.
Common Gotchas
-
max_records_deleteddefaults to0. This means the default policy blocks any record deletion. If your agent deletes records legitimately, set an explicitmax_records_deletedvalue. -
record_scope_impact()is additive, not absolute. Each call adds to the running total. If you call it three times withrecords_modified=50each, the total is 150 — not 50. -
mid_executiononly reports the first violation. If records_modified and transaction_total both exceed limits in the same call, only the first exceeded limit (by check order) is reported. The after_workflow phase reports all violations. -
after_workflowalways warns, never blocks. Even ifaction_on_violation=block, the after_workflow phase issues warnings in its result metadata. Use mid_execution for blocking enforcement. -
Rollback checks always warn, never block. Setting
require_rollback_capability=truewhen the context does not support rollback produces a WARN at before_workflow, not a BLOCK. The agent still runs. -
Zero values are valid limits.
max_transaction_amount=0blocks any financial transaction.max_api_writes=0blocks all external API writes. Use this for read-only enforcement. -
Limits are per-execution, not per-day. The scope policy resets with each new
WaxellContext. For rate-limiting across executions, use therate-limitpolicy category.
Combining with Other Policies
- cost: Use
costto limit LLM spend per execution; usescopeto limit data impact. They operate on different dimensions. - audit: Enable
auditalongsidescopeto get a permanent record of every impact summary. Theafter_workflowmetadata from scope is captured in the audit trail. - approval: Combine
scopewithapprovalto require human sign-off before executions that would approach scope limits. - operations: Use
operationsto limit execution time and retries; usescopeto limit data blast radius. Both protect against runaway executions in complementary ways.
Next Steps
- Policy & Governance -- How policy enforcement works
- Grounding Policy -- Govern factual accuracy of agent outputs
- Audit Policy -- Permanent record of agent impact
- Approval Policy -- Human-in-the-loop for high-impact operations
- Policy Categories & Templates -- All 26 categories