Pre-authorized budgets with Mandate

Cap an autonomous agent's total spend before it starts. Server-side enforced — even a runaway loop can't drain the wallet.

The problem

Letting an autonomous agent invoke capabilities with infinite spend is unwise. A bug in the agent's loop, a confused planner, a malicious prompt — any could empty the wallet.

The solution

Attach a Mandate to invocations. The Hub enforces the cap atomically per call. Calls that would exceed the cap fail with INSUFFICIENT_BUDGET before the Provider is contacted.

const mandate = {
  budget_usdc: 1.00,                                  // hard cap across all calls
  expires_at: '2026-12-31T00:00:00Z',                 // mandate dies even if budget unspent
};

await jecp.invoke('a/b', 'action', input, { mandate });
await jecp.invoke('a/b', 'action', input, { mandate }); // accumulates
await jecp.invoke('a/b', 'action', input, { mandate });
// ...eventually:
// INSUFFICIENT_BUDGET — sum exceeded $1.00
Mandates are per-mandate, not per-call. Reusing the same mandate object across calls accumulates spend. Pass a fresh mandate each invocation if you want per-call caps.

Recovery

When a mandate is exhausted, the error includes next_action: { type: 'increase_mandate' }. Your code can decide to raise the budget and retry:

import { InsufficientBudgetError } from '@jecpdev/sdk';

let budget = 1.00;
async function invokeWithBudget(input: unknown) {
  try {
    return await jecp.invoke('a/b', 'c', input, {
      mandate: { budget_usdc: budget },
    });
  } catch (e) {
    if (e instanceof InsufficientBudgetError) {
      // Decide whether to raise the cap
      if (await operatorApprovesIncrease(budget * 2)) {
        budget *= 2;
        return invokeWithBudget(input);
      }
    }
    throw e;
  }
}

Mandate fields

From the CLI

jecp invoke a/b c --input '{"...":"..."}' --budget 1.00