Standard / manifest · mandate · gateway · mcp · evals

Holon Caller Mandate — v0.1 (draft)

The manifest says what an agent offers. The mandate says what an agent is allowed to do: which agents it may call, how much it may spend, and what may happen to the data it passes on.

It is the piece that lets agents act without a human watching every call, while the human stays in control. More autonomy is granted by widening a mandate, not by removing it.

Machine-checkable definition: schema/holon-mandate.schema.json.

holon mandate check <mandate.yaml> <holon.yaml|dir>...   # may the grantee call these agents?
holon mandate attenuate <parent.yaml> <child.yaml>       # is the sub-mandate within its parent?
holon search [query] --mandate <mandate.yaml>            # rank only what the mandate permits

1. Model

alice (human)
  └─ root mandate ──────────► alice/assistant
                                 └─ sub-mandate ──────► holon-labs/invoice-pipeline
                                                           └─ calls ► acme/table-extract
  • A root mandate is issued by a human account to an agent (the grantee).
  • The grantee MAY issue sub-mandates to the agents it calls. A sub-mandate MUST be an attenuation of its parent: it can narrow everything and widen nothing.
  • The gateway checks every call against the caller's mandate before the call is made. Every call produces a receipt: which agent, under which mandate, the worst case, the actual cost, and the decision with its reasons.

This is the capability-token pattern (as in macaroons or UCAN) applied to spending and delegation between agents.

2. Fields

Field Rule
issuer / grantee Who grants, who acts. For a sub-mandate, issuer MUST be the parent's grantee.
valid.from / valid.until Mandates always expire.
budget.total, per_call, per_day Decimal strings. per_call bounds a single call's worst case.
budget.fx Rates into budget.currency. A call priced in a currency without a rate is refused. Conversion rounds up.
approval.above Calls whose worst case exceeds this are held for the issuer's approval instead of being refused.
allow.capabilities Class patterns: extraction.table, extraction.* (subtree) or *.
allow.agents / deny.agents namespace/name or namespace/*. Deny wins.
allow.published Hosted gateway: true lets capability calls be routed to agents published by other authors. Off by default; calling an agent by name is not affected.
require charge_on_success, runtimes, and measured thresholds: min_success_rate, max_latency_p95_s, min_runs_30d, min_eval_score (evaluations).
data max_retention, training_use: false, allow_egress: false.
delegation.max_depth How many more levels of agents may appear below the direct callee. Defaults to 0.

3. Admission: may this call happen?

For a caller holding mandate M and a callee with manifest A, the call is:

  • denied if any of the following fails:
    • M is valid now, and A is not matched by deny;
    • A matches allow by capability class or by agent;
    • if A declares calls: delegation.max_depth ≥ 1, and every declared downstream capability or agent is itself within allow;
    • A's pricing, runtime and data policy meet require and data;
    • A's measured record meets the thresholds. No record means the threshold is unmet: an unmeasured agent is not a trusted agent;
    • worst case ≤ per_call, and neither total nor per_day would be exceeded counting the worst case.
  • held for approval if it passes and the worst case exceeds approval.above.
  • allowed otherwise.

worst case = price ceiling (amount, or max for per-unit and quote) + downstream.cap for passthrough pricing, converted into the mandate's currency.

Budgets are charged at the worst case when a call starts, and the difference is released when it settles. Parallel calls therefore cannot overrun a budget together.

4. Attenuation

A sub-mandate C of parent P is valid only if:

  • C.parent = P.id and C.issuer = P.grantee;
  • C's validity window is inside P's;
  • same currency, and every budget ceiling in P exists in C and is not higher; the same applies to approval.above;
  • every allow pattern in C is covered by a pattern in P;
  • every deny pattern in P is kept in C;
  • every require and data condition in P is kept or tightened;
  • C.delegation.max_depth ≤ P.delegation.max_depth − 1. Each hop consumes one level, so delegation chains always terminate.

5. Ranking under a mandate

holon search --mandate removes the agents the mandate denies (each with its first reason) and ranks the rest by relevance, then by cost per successful run (worst case ÷ success rate), then by p95 latency. List price alone is a poor signal: a cheap agent that fails half the time costs double.

Cold start

An unmeasured agent is not trusted, so a mandate with measured thresholds refuses brand-new agents. Platform evaluations close the gap. They produce eval_score and feed success_rate without counting as usage. A mandate that requires min_eval_score (plus, if it wants, min_success_rate) accepts a new agent once it has been evaluated. min_runs_30d stays for mandates that also want a usage history.

6. Open questions

  • Signatures: mandates must be signed by the issuer and chained by hash. v0.1 specifies content only.
  • Revocation: a revocation list checked by the gateway, and what happens to calls in flight.
  • Spend state: spent.total and spent.today are gateway state. The reference CLI takes them as flags (--spent-total, --spent-today).
  • Data classes: tagging inputs (PII, health, secrets) and restricting which agents may see each class.