The Problem
Agentic invocations are fundamentally different from traditional API calls. A single request may trigger multi-step LLM reasoning, tool chains, sub-agent calls, and iterative loops — compounding token usage unpredictably and without an upper bound visible to the consumer at request time.
In a federated ecosystem where agents from one enterprise's registry are invoked by consumers in another, this creates a cost governance gap:
-
Unbounded cost exposure for publishers — A publishing enterprise exposes agents to federated partners. Without quota governance, the partner's workload can impose uncapped inference cost on the publisher's infrastructure.
-
No feedback loop for consumers — Consuming registries have no protocol-level mechanism to know they're approaching a usage limit, or that their access will be degraded, until invocations start failing.
-
Hard failures break workflows — Without a degradation model, quota exhaustion results in rejected requests. The consumer's orchestration chain breaks mid-execution with no recovery path.
-
Rate limiting is insufficient — Traditional rate limits (requests/second) don't capture the real cost driver: token consumption. A simple query and a complex multi-step reasoning task may both be one request, but differ by 100x in token cost.
These gaps become acute in B2B federation where usage patterns are unpredictable, SLAs are contractual, and both parties need governed visibility into consumption.
Dependencies
This proposal depends on and extends:
Relationship to #53 (Federation Interoperability)
The federation lifecycle is: DISCOVER → AGREE → ENFORCE.
usagePolicy operates across two of these phases:
| Phase |
usagePolicy Role |
| DISCOVER |
Agent Card declares executionContract.hasQuotaGovernance: true — consumers see quota terms exist before federating |
| AGREE |
Full usagePolicy object is negotiated as part of the execution contract during the mutual trust handshake |
| ENFORCE |
Publisher's policy gate tracks token consumption per consumer identity at the trust boundary; triggers thresholds and degradation |
The usagePolicy object lives in the execution contract — the set of operational terms agreed during federation and enforced at runtime. It is referenced from the Agent Card in the discovery layer:
{
"identifier": "urn:air:acme.com:finance:invoice-processor",
"name": "Invoice Processor",
"cardProvenance": { "..." },
"contentIntegrity": { "..." },
"executionContract": {
"usagePolicyRef": "https://registry.acme.com/contracts/invoice-agent/usage",
"hasQuotaGovernance": true,
"degradationModes": ["informational-only", "block"]
}
}
The executionContract block in the Agent Card is a pointer — it signals that usage terms exist and where to retrieve the full policy. The full usagePolicy object is resolved during the AGREE phase and becomes the runtime enforcement reference.
Proposal
Usage Policy Object (usagePolicy)
Add an optional usagePolicy object to the execution contract that defines consumption limits, threshold notifications, and degradation behavior:
"usagePolicy": {
"tokenQuota": {
"limit": 100000,
"period": "PT24H",
"scope": "per-consumer"
},
"thresholds": [
{ "percent": 50, "action": "notify", "channel": "webhook" },
{ "percent": 80, "action": "notify", "channel": "webhook" },
{ "percent": 100, "action": "degrade", "mode": "informational-only" }
],
"degradedMode": {
"informational-only": {
"description": "Agent responds with cached/static information only. No LLM reasoning or tool execution.",
"responseHeaders": {
"X-Quota-Status": "degraded",
"X-Quota-Resets": "<ISO8601>",
"X-Quota-Remaining": "0"
}
},
"block": {
"description": "Requests are rejected with 429 status. Consumer must wait for quota reset or negotiate upgrade.",
"responseHeaders": {
"X-Quota-Status": "exhausted",
"X-Quota-Resets": "<ISO8601>",
"Retry-After": "<seconds>"
}
}
},
"notificationEndpoint": "https://consumer-registry.com/webhooks/quota",
"quotaResetPolicy": "period-end",
"upgradeEndpoint": "https://registry.acme.com/contracts/upgrade"
}
Field Definitions
| Field |
Type |
Description |
tokenQuota.limit |
integer |
Maximum tokens consumable per period |
tokenQuota.period |
duration (ISO 8601) |
Quota reset interval (e.g., PT24H, P30D) |
tokenQuota.scope |
enum |
Quota applies per-consumer (per federated registry) or per-agent (per individual agent invoked) |
thresholds |
array |
Ordered list of threshold actions triggered at consumption percentages |
thresholds[].percent |
integer |
Consumption percentage that triggers this action |
thresholds[].action |
enum |
notify (alert consumer), degrade (reduce capability), block (reject requests) |
thresholds[].channel |
string |
Notification delivery method (webhook, header, email) |
thresholds[].mode |
string |
For degrade action: which degradation mode to activate |
degradedMode |
object |
Named degradation behaviors — defines what the agent still provides when quota is constrained |
notificationEndpoint |
URI |
Consumer-provided webhook for threshold alerts |
quotaResetPolicy |
enum |
period-end (resets at period boundary) or rolling (sliding window) |
upgradeEndpoint |
URI (optional) |
Where the consumer can request quota increases |
Enforcement Semantics
Who enforces:
Threshold behavior:
notify — Advisory. Consumer receives a webhook notification but invocations continue normally
degrade — Active. Agent switches to the named degradation mode. Invocations still succeed but with reduced capability
block — Terminal. Requests are rejected until quota resets or is upgraded
Degradation model:
informational-only — Agent responds without invoking its LLM or executing tools. Returns documentation, capability descriptions, cached responses, or FAQ-style answers. The consumer's workflow receives a response (no hard failure) with headers indicating degraded status.
- Custom modes MAY be defined by publishers for domain-specific degradation (e.g.,
read-only, summary-only, cached-24h)
Response headers:
- All responses SHOULD include
X-Quota-Remaining and X-Quota-Resets headers regardless of quota status — enabling consumers to implement client-side awareness without waiting for threshold notifications.
Consumer-Side Pre-Check (Optional)
Publishers MAY expose a quota status endpoint:
GET /federation/quota/status?consumer=registry.partner.com
Response:
{
"consumer": "registry.partner.com",
"tokenQuota": { "limit": 100000, "used": 72000, "remaining": 28000 },
"currentPeriod": { "start": "2026-07-08T00:00:00Z", "end": "2026-07-09T00:00:00Z" },
"status": "active",
"nextThreshold": { "percent": 80, "action": "notify", "tokensUntil": 8000 }
}
This enables consumers to:
- Check remaining quota before initiating expensive multi-agent workflows
- Implement client-side backoff without waiting for rejection
- Display quota dashboards in their own registry UI
Relationship to Trust State
Usage exhaustion is NOT a trust event — it does not affect mutualTrust.state (defined in #53). A consumer at quota is still trusted; they are simply rate-governed. The trust state machine and usage policy are independent axes:
| Trust State |
Quota Status |
Outcome |
mutual |
OK |
✅ Full access |
mutual |
Degraded |
⚠️ Informational responses only |
mutual |
Exhausted (block) |
🚫 Rejected until reset |
revoked |
Any |
❌ No access regardless of quota |
Trust governs whether you can call. Quota governs how much you can call.
Composability
Discovery Signaling
The Agent Card in ai-catalog.json signals quota governance at discovery time so consumers know terms exist before they federate:
{
"identifier": "urn:air:acme.com:finance:invoice-processor",
"executionContract": {
"hasQuotaGovernance": true,
"quotaSummary": {
"defaultLimit": 100000,
"defaultPeriod": "PT24H",
"degradationModes": ["informational-only", "block"],
"supportsPreCheck": true
},
"usagePolicyRef": "https://registry.acme.com/contracts/invoice-agent/usage"
}
}
This is intentionally a summary — not the full policy. The full usagePolicy object is negotiated during the AGREE phase, where terms may be customized per consumer (e.g., premium partners get higher quotas).
Discussion Questions
- Should
usagePolicy quota enforcement be publisher-side only, or should the spec define a normative consumer-side pre-check endpoint (GET /federation/quota/status)?
- Should quota be denominated in tokens only, or should the spec support alternative cost units (requests, compute-seconds, monetary value)?
- Should there be a standard escalation protocol — e.g., consumer can programmatically request quota increase via
upgradeEndpoint, with the publisher's approval flowing through the same mutual trust mechanism?
- Should degraded responses carry a machine-readable capability delta (e.g., "these specific capabilities are unavailable in degraded mode") to help consumer LLMs adapt their planning?
- How should quota interact with multi-agent chains? If Agent A calls Agent B which calls Agent C across federation boundaries — whose quota is consumed?
Reference Implementation
The MCP Gateway and Registry (Apache 2.0, #40) could implement usagePolicy enforcement at its gateway layer — the gateway already intercepts cross-registry invocations and is the natural policy enforcement point for token accounting.
The Problem
Agentic invocations are fundamentally different from traditional API calls. A single request may trigger multi-step LLM reasoning, tool chains, sub-agent calls, and iterative loops — compounding token usage unpredictably and without an upper bound visible to the consumer at request time.
In a federated ecosystem where agents from one enterprise's registry are invoked by consumers in another, this creates a cost governance gap:
Unbounded cost exposure for publishers — A publishing enterprise exposes agents to federated partners. Without quota governance, the partner's workload can impose uncapped inference cost on the publisher's infrastructure.
No feedback loop for consumers — Consuming registries have no protocol-level mechanism to know they're approaching a usage limit, or that their access will be degraded, until invocations start failing.
Hard failures break workflows — Without a degradation model, quota exhaustion results in rejected requests. The consumer's orchestration chain breaks mid-execution with no recovery path.
Rate limiting is insufficient — Traditional rate limits (requests/second) don't capture the real cost driver: token consumption. A simple query and a complex multi-step reasoning task may both be one request, but differ by 100x in token cost.
These gaps become acute in B2B federation where usage patterns are unpredictable, SLAs are contractual, and both parties need governed visibility into consumption.
Dependencies
This proposal depends on and extends:
Spec Proposal: Registry Federation Interoperability — Mutual Trust & Cross-Registry Provenance #53 — Registry Federation Interoperability: Identifies the catalog metadata fields that federation governance depends on, including
mutualTrustandexecutionContract.usagePolicyis part of the execution contract — its terms are signaled at DISCOVER (Agent Card field), negotiated at AGREE (bilateral handshake), and enforced at ENFORCE (runtime policy gate). AGREE and ENFORCE are open protocol extensions defined in Spec Proposal: Registry Federation Interoperability — Mutual Trust & Cross-Registry Provenance #53 for registry implementations to adopt — they are outside ARD's scope.Spec Proposal: Agent Release Policy — Version Availability, Migration Windows & Pre-Release Signaling #55 — Release Policy: Version-level governance complements usage governance. A consumer may have different quota allocations per agent version (e.g., higher quota for stable, limited for preview).
Relationship to #53 (Federation Interoperability)
The federation lifecycle is: DISCOVER → AGREE → ENFORCE.
usagePolicyoperates across two of these phases:executionContract.hasQuotaGovernance: true— consumers see quota terms exist before federatingusagePolicyobject is negotiated as part of the execution contract during the mutual trust handshakeThe
usagePolicyobject lives in the execution contract — the set of operational terms agreed during federation and enforced at runtime. It is referenced from the Agent Card in the discovery layer:{ "identifier": "urn:air:acme.com:finance:invoice-processor", "name": "Invoice Processor", "cardProvenance": { "..." }, "contentIntegrity": { "..." }, "executionContract": { "usagePolicyRef": "https://registry.acme.com/contracts/invoice-agent/usage", "hasQuotaGovernance": true, "degradationModes": ["informational-only", "block"] } }The
executionContractblock in the Agent Card is a pointer — it signals that usage terms exist and where to retrieve the full policy. The fullusagePolicyobject is resolved during the AGREE phase and becomes the runtime enforcement reference.Proposal
Usage Policy Object (
usagePolicy)Add an optional
usagePolicyobject to the execution contract that defines consumption limits, threshold notifications, and degradation behavior:Field Definitions
tokenQuota.limittokenQuota.periodPT24H,P30D)tokenQuota.scopeper-consumer(per federated registry) orper-agent(per individual agent invoked)thresholdsthresholds[].percentthresholds[].actionnotify(alert consumer),degrade(reduce capability),block(reject requests)thresholds[].channelwebhook,header,email)thresholds[].modedegradeaction: which degradation mode to activatedegradedModenotificationEndpointquotaResetPolicyperiod-end(resets at period boundary) orrolling(sliding window)upgradeEndpointEnforcement Semantics
Who enforces:
Threshold behavior:
notify— Advisory. Consumer receives a webhook notification but invocations continue normallydegrade— Active. Agent switches to the named degradation mode. Invocations still succeed but with reduced capabilityblock— Terminal. Requests are rejected until quota resets or is upgradedDegradation model:
informational-only— Agent responds without invoking its LLM or executing tools. Returns documentation, capability descriptions, cached responses, or FAQ-style answers. The consumer's workflow receives a response (no hard failure) with headers indicating degraded status.read-only,summary-only,cached-24h)Response headers:
X-Quota-RemainingandX-Quota-Resetsheaders regardless of quota status — enabling consumers to implement client-side awareness without waiting for threshold notifications.Consumer-Side Pre-Check (Optional)
Publishers MAY expose a quota status endpoint:
This enables consumers to:
Relationship to Trust State
Usage exhaustion is NOT a trust event — it does not affect
mutualTrust.state(defined in #53). A consumer at quota is still trusted; they are simply rate-governed. The trust state machine and usage policy are independent axes:mutualmutualmutualrevokedTrust governs whether you can call. Quota governs how much you can call.
Composability
usagePolicyis negotiated during the mutual trust handshake and becomes part of the execution contract. Both parties agree to terms before federation is active.localAnnotations(Part 2c of Spec Proposal: Registry Federation Interoperability — Mutual Trust & Cross-Registry Provenance #53): A consuming registry MAY annotate federated agent cards with local quota status (e.g.,"quotaRemaining": 28000) inlocalAnnotationsfor its own consumers' visibility — without modifying the canonical card.Discovery Signaling
The Agent Card in
ai-catalog.jsonsignals quota governance at discovery time so consumers know terms exist before they federate:{ "identifier": "urn:air:acme.com:finance:invoice-processor", "executionContract": { "hasQuotaGovernance": true, "quotaSummary": { "defaultLimit": 100000, "defaultPeriod": "PT24H", "degradationModes": ["informational-only", "block"], "supportsPreCheck": true }, "usagePolicyRef": "https://registry.acme.com/contracts/invoice-agent/usage" } }This is intentionally a summary — not the full policy. The full
usagePolicyobject is negotiated during the AGREE phase, where terms may be customized per consumer (e.g., premium partners get higher quotas).Discussion Questions
usagePolicyquota enforcement be publisher-side only, or should the spec define a normative consumer-side pre-check endpoint (GET /federation/quota/status)?upgradeEndpoint, with the publisher's approval flowing through the same mutual trust mechanism?Reference Implementation
The MCP Gateway and Registry (Apache 2.0, #40) could implement
usagePolicyenforcement at its gateway layer — the gateway already intercepts cross-registry invocations and is the natural policy enforcement point for token accounting.