The Ledger crate enforces budget limits with soft threshold warnings and hard limit enforcement. It tracks spend by agent, model, provider, and billing code with versioned CAS updates.
Overview
Purpose: Budget enforcement with real-time spend tracking
LOC: ~300
Functions: 4 (set_budget, check, spend, summary)
Endpoints: 4 REST + 1 PubSub
Source: crates/ledger/src/main.rs
Core Concepts
Budget Structure
struct Budget {
id : String , // "bgt-{uuid}"
realm_id : String ,
agent_id : Option < String >, // Per-agent or realm-wide (null)
monthly_cents : u64 , // Budget limit in cents
spent_cents : u64 , // Current spend
soft_threshold : f64 , // 0.0-1.0 (0.8 = 80% warning)
hard_limit : bool , // Enforce hard cutoff at 100%
billing_code : Option < String >,
version : u32 , // Optimistic concurrency
period_start : String , // Budget period start date
updated_at : String ,
}
Spend Event
struct SpendEvent {
id : String , // "spn-{uuid}"
realm_id : String ,
agent_id : String ,
cost_cents : u64 ,
provider : String , // "anthropic", "openai", etc.
model : String , // "claude-sonnet-4", "gpt-4o", etc.
input_tokens : u64 ,
output_tokens : u64 ,
mission_id : Option < String >,
billing_code : Option < String >,
timestamp : String ,
}
Budget Enforcement Flow
0% ─────────────── 80% ──────────── 100%
↓ ↓ ↓
Normal Soft Alert Hard Stop
(warning) (if enabled)
Functions
ledger::set_budget
Set or update budget for a realm or specific agent.
Agent identifier (null = realm-wide budget)
Monthly budget limit in cents
Warning threshold (0.0-1.0). 0.8 = alert at 80%
Enforce hard cutoff at 100%
Optional billing/project code
Example:
// Set realm-wide budget: $5,000/month
iii . trigger ( "ledger::set_budget" , json! ({
"realmId" : "r-1" ,
"monthlyCents" : 500_000 , // $5,000 = 500,000 cents
"softThreshold" : 0.8 , // Alert at $4,000 (80%)
"hardLimit" : true // Block at $5,000 (100%)
})) . await ? ;
// Set per-agent budget: $100/month
iii . trigger ( "ledger::set_budget" , json! ({
"realmId" : "r-1" ,
"agentId" : "agent-dev-1" ,
"monthlyCents" : 10_000 , // $100
"softThreshold" : 0.9 , // Alert at $90 (90%)
"hardLimit" : false // Warn but don't block
})) . await ? ;
REST Endpoint:
POST /api/ledger/budget
Content-Type: application/json
{
"realmId" : "r-1",
"monthlyCents" : 500000,
"softThreshold" : 0.8,
"hardLimit" : true
}
ledger::check
Check if agent is within budget.
Example:
let result = iii . trigger ( "ledger::check" , json! ({
"realmId" : "r-1" ,
"agentId" : "agent-dev-1"
})) . await ? ;
// Returns:
// {
// "allowed": true,
// "spentCents": 8500,
// "limitCents": 10000,
// "remainingCents": 1500,
// "utilizationPct": 85.0,
// "alert": "Warning" // null, "Warning", or "Critical"
// }
REST Endpoint:
GET /api/ledger/check/r-1/agent-dev-1
Budget Check Logic (ledger/src/main.rs:68-131):
let utilization = if budget . monthly_cents > 0 {
( budget . spent_cents as f64 / budget . monthly_cents as f64 ) * 100.0
} else {
0.0
};
let alert = if utilization >= 100.0 {
Some ( AlertSeverity :: Critical )
} else if utilization >= budget . soft_threshold * 100.0 {
Some ( AlertSeverity :: Warning )
} else {
None
};
let allowed = ! ( budget . hard_limit && utilization >= 100.0 );
let remaining = budget . monthly_cents . saturating_sub ( budget . spent_cents);
BudgetCheckResult {
allowed ,
spent_cents : budget . spent_cents,
limit_cents : budget . monthly_cents,
remaining_cents : remaining ,
utilization_pct : utilization ,
alert ,
}
ledger::spend
Record a spend event and enforce budget.
LLM provider (“anthropic”, “openai”, etc.)
Example:
// Record LLM API call spend
iii . trigger ( "ledger::spend" , json! ({
"realmId" : "r-1" ,
"agentId" : "agent-dev-1" ,
"costCents" : 15 , // $0.15
"provider" : "anthropic" ,
"model" : "claude-sonnet-4" ,
"inputTokens" : 1500 ,
"outputTokens" : 800 ,
"missionId" : "msn-xyz789" ,
"billingCode" : "PROJ-2024-Q1"
})) . await ? ;
// If budget exceeded with hardLimit=true:
// Error: "agent agent-dev-1 exceeded budget: 10015/10000"
REST Endpoint:
POST /api/ledger/spend
Content-Type: application/json
{
"realmId" : "r-1",
"agentId" : "agent-dev-1",
"costCents" : 15,
"provider" : "anthropic",
"model" : "claude-sonnet-4",
"inputTokens" : 1500,
"outputTokens" : 800
}
Spend Enforcement (ledger/src/main.rs:133-172):
let check_result : BudgetCheckResult = /* ... check budget ... */
if ! check_result . allowed {
// Publish alert
let _ = iii . trigger_void ( "publish" , json! ({
"topic" : "ledger.alert" ,
"data" : {
"type" : "hard_limit_reached" ,
"realmId" : req . realm_id,
"agentId" : req . agent_id,
"spentCents" : check_result . spent_cents,
"limitCents" : check_result . limit_cents,
},
}));
// Log to council audit trail
let _ = iii . trigger (
"council::activity" ,
json! ({
"realmId" : req . realm_id,
"actorKind" : "system" ,
"actorId" : "ledger" ,
"action" : "budget_exceeded" ,
"entityType" : "agent" ,
"entityId" : req . agent_id,
"details" : { "spentCents" : check_result . spent_cents, "limitCents" : check_result . limit_cents },
}),
) . await ;
return Err ( IIIError :: Handler ( format! (
"agent {} exceeded budget: {}/{}" ,
req . agent_id, check_result . spent_cents, check_result . limit_cents
)));
}
PubSub Trigger:
Ledger also listens to cost.incurred topic:
iii . register_trigger ( "subscribe" , "ledger::spend" ,
json! ({ "topic" : "cost.incurred" })) ? ;
Other workers can publish spend events:
iii . trigger_void ( "publish" , json! ({
"topic" : "cost.incurred" ,
"data" : { /* SpendEvent */ }
}));
ledger::summary
Get spend summary with breakdowns.
Group by: “agent” (default), “model”, “provider”, “billing_code”
Example:
// Summary by agent
let by_agent = iii . trigger ( "ledger::summary" , json! ({
"realmId" : "r-1" ,
"groupBy" : "agent"
})) . await ? ;
// Returns:
// {
// "totalCents": 125000,
// "totalInputTokens": 2500000,
// "totalOutputTokens": 1200000,
// "eventCount": 450,
// "breakdown": {
// "agent-dev-1": 45000,
// "agent-dev-2": 38000,
// "agent-reviewer": 22000,
// ...
// }
// }
// Summary by provider
let by_provider = iii . trigger ( "ledger::summary" , json! ({
"realmId" : "r-1" ,
"groupBy" : "provider"
})) . await ? ;
// Returns:
// {
// "totalCents": 125000,
// ...
// "breakdown": {
// "anthropic": 85000,
// "openai": 30000,
// "deepseek": 10000
// }
// }
REST Endpoint:
GET /api/ledger/summary/r-1?groupBy=agent
GET /api/ledger/summary/r-1?groupBy=provider
GET /api/ledger/summary/r-1?groupBy=billing_code
Storage Scopes
realm:{realmId}:budgets - Budget configurations
realm:{realmId}:spend - Individual spend events
Events
Ledger publishes to ledger.alert topic:
{
"type" : "soft_threshold" | "hard_limit_reached" ,
"realmId" : "r-1" ,
"agentId" : "agent-dev-1" ,
"spentCents" : 8500 ,
"limitCents" : 10000 ,
"utilizationPct" : 85.0
}
Use Cases
Cost Control Prevent runaway LLM costs with hard budget limits per agent or realm.
Budget Alerts Get notified when agents hit 80% budget usage before they hit the limit.
Spend Analytics Track spend by agent, model, provider, or billing code for cost optimization.
Multi-Tenant Billing Use billing_code to attribute costs to customers or projects.
Best Practices
Start with soft limits
Set hardLimit=false initially to gather data without blocking agents.
Use 80% threshold
Default softThreshold=0.8 gives good advance warning before budget exhaustion.
Set per-agent budgets
Isolate risk by setting individual agent budgets rather than just realm-wide.
Tag with billing codes
Always set billingCode on spend events for accurate cost attribution.
Review summaries weekly
Run ledger::summary grouped by model/provider to identify cost optimization opportunities.
Reset budgets monthly
Budgets are calendar-based. Archive old period and create new budgets each month.
Integration Example
Integrate ledger checks into your agent loop:
// Before LLM call
let check = iii . trigger ( "ledger::check" , json! ({
"realmId" : realm_id ,
"agentId" : agent_id
})) . await ? ;
if ! check [ "allowed" ] . as_bool () . unwrap_or ( false ) {
return Err ( "Budget exceeded" );
}
// Make LLM call
let response = llm_complete ( ... ) . await ? ;
// Record spend
iii . trigger ( "ledger::spend" , json! ({
"realmId" : realm_id ,
"agentId" : agent_id ,
"costCents" : calculate_cost ( response . usage),
"provider" : "anthropic" ,
"model" : "claude-sonnet-4" ,
"inputTokens" : response . usage . input_tokens,
"outputTokens" : response . usage . output_tokens,
"missionId" : current_mission_id
})) . await ? ;
Mission - Link spend to missions via missionId
Council - Budget violations logged to audit trail
Pulse - Pulse invocations skip agents over budget