Every command submitted through the broker has a token cost. The RBAC guard enforces per-tick and daily quotas to prevent runaway resource consumption.
Token Costs¶
Each command type has a fixed token cost:
| Command Type | Token Cost | Description |
|---|---|---|
message |
3 | Agent-to-agent messaging |
despawn |
5 | Remove an entity |
remove_component |
5 | Remove a component from an entity |
remove_processor |
5 | Remove a processor |
query_world |
5 | Read state from a world |
update |
8 | Update entity state |
add_component |
8 | Add a component to an entity |
spawn |
10 | Create a new entity |
custom |
10 | User-defined command |
destroy_world |
10 | Tear down a child world |
add_processor |
15 | Hot-swap a processor |
create_world |
50 | Spawn a child world |
fork_world |
100 | Clone world state for branching |
run_rollout |
200 | Run N steps in a world |
run_episode |
500 | Full episode with sampled initial conditions |
Unknown command types default to a cost of 10.
Quotas¶
Two quotas are enforced per actor:
| Quota | Limit | Scope |
|---|---|---|
| Per-tick | 500 commands | Reset at start of each tick |
| Daily | 200,000 tokens | Reset at day boundary |
Per-Tick Limit¶
Each actor can submit at most 500 commands per tick, regardless of command type. The counter is shared across all command types and all worlds.
Daily Token Budget¶
Each actor has a daily budget of 200,000 tokens. Token costs accumulate across all commands submitted throughout the day. The budget is shared across all command types and all worlds.
What Happens When a Quota Is Exceeded¶
Both quota violations raise PermissionError, which the API layer returns as HTTP 403 Forbidden.
Per-tick violation:
PermissionError: Actor {id} exceeded per-tick quota (500 commands)
Daily token violation:
PermissionError: Actor {id} exceeded daily token budget (200000 tokens)
The command is rejected immediately and is not enqueued. No partial execution occurs.
Enforcement Flow¶
Quotas are checked during CommandBroker.enqueue(), before the command enters the priority queue:
CommandService.submit(world_id, cmd, ctx)
|
v
CommandBroker.enqueue(world_id, cmd, ctx)
|
v
guardrail_allow(cmd, ctx)
1. RBAC check -- does the actor's role permit this command type?
2. Per-tick quota -- has the actor hit 500 commands this tick?
3. Daily token budget -- would this command exceed 200k tokens?
|
v
[Enqueued] or [PermissionError raised]
Roles and Permissions¶
Quotas apply equally to all roles. However, roles determine which command types an actor can submit:
| Role | Permitted Commands |
|---|---|
viewer |
get_state, get_world, get_run, query_world |
coder |
add_component, remove_component, update |
operator |
spawn, despawn, update, get_state, get_world, get_run, query_world |
maintainer |
spawn, despawn, add_component, remove_component, add_processor, remove_processor, update |
player |
spawn, despawn, update, message, custom |
admin |
All commands (wildcard *) |
A viewer actor with 500 commands available still cannot spawn -- the RBAC check runs first.
Budget Planning¶
Use these costs to estimate whether a workload fits within the daily budget:
| Scenario | Commands | Tokens |
|---|---|---|
| Spawn 100 entities | 100 spawn | 1,000 |
| 50 ticks of messaging (10 msgs/tick) | 500 message | 1,500 |
| Fork + run 10-step rollout | 1 fork + 1 rollout | 300 |
| Full episode | 1 run_episode | 500 |
| Heavy day (1000 spawns + 5000 messages + 10 forks) | 6,010 commands | 26,000 |
At these rates, the 200k daily budget supports substantial workloads. The per-tick limit of 500 is the more common constraint for burst scenarios.
Source Reference¶
The quota system is defined in src/archetype/app/auth/guard.py:
ROLE_PERMS-- role-to-permission mapping_TOKEN_COSTS-- cost per command typeMAX_CMDS_PER_TICK-- per-tick limit (500)MAX_TOKENS_PER_DAY-- daily budget (200,000)guardrail_allow()-- the enforcement functionreset_tick_counters()-- called each tick by SimulationServicereset_daily_tokens()-- called at day boundary