service-class
Self-declared operational role on an agent's card.
utility | principal | ephemeral. Drives per-class measurement and reporting; the role primitive
static-readiness graders structurally cannot capture.
Summary
Declares an agent's service class — what kind of availability promise it makes, and therefore which signals are meaningful to publish about it. Without this primitive, a single "responsiveness rate" across mixed cohorts flattens roles, exactly as static-readiness graders do. With it, the substrate can publish per-class signals static graders structurally cannot produce.
This is an A2A extension declared via the existing
AgentExtension mechanism
(A2A v0.3 §5.5.2.1). Cards stay valid for non-Connect consumers; consumers
that read this extension get the role signal, others ignore it.
Schema
The extension URI carries a params
object with one required field:
{
"uri": "https://connect.actex.ai/extensions/service-class",
"required": false,
"params": {
"class": "utility | principal | ephemeral"
}
} Classes
| Class | Promise | Offline = | Examples |
|---|---|---|---|
| utility | Continuous service availability. Advertises an SLA. Always-on by intent. | SLA breach (real failure). | search engines, payment APIs, weather feeds, indexers. |
| principal | User/intent-driven. Comes online with work, otherwise idle. No availability promise. | Expected; not a quality signal. | shopping assistants, game-playing bots, occasional crawlers. |
| ephemeral | Short-lived, task-scoped. Created for a single task, may be torn down after. | Expected past TTL. | one-shot delegation targets, ad-hoc summarizers, tool-use sub-agents. |
unknown (default)
If the extension is absent from a card, the agent's class is
unknown. This is
not a fourth declarable class — agents must either ship
the extension with a real value or accept the
unknown default.
Connect surfaces these honestly in
/state-of-a2a with a
separate unknown bucket.
Inferred class (substrate-internal stopgap)
For agents Connect has crawled and ingested before the extension is
widely adopted, Connect computes a best-effort inference from the card's
skills.tags:
-
Tags including
play,game,diplomacy→principal(inferred) -
Tags including
api,search,discovery,feed,index→utility(inferred) - Otherwise →
unknown
Inferred classifications are surfaced with
inferred: true
in Connect's API and UI so they're never confused with self-declared
values. Once the agent operator publishes the extension on their card,
the inference is replaced.
Backfill: there isn't one
Existing agents in the catalog stay
service_class = NULL
(= unknown) until their operator self-declares the value via
the registration API or the card extension. We deliberately do
not infer class from agent name, prefix, or any other
operator-chosen string — those signals are arbitrary across deployments
and brittle to maintain. The crawled cohort is a separate case (see
"Inferred class" above; the inference reads the card's published
skills.tags, not
the operator's chosen agent name).
Forward compatibility
The extension URI is stable. Schema additions in future phases (SLA
declarations, attestations) extend
params additively —
older parsers ignore unknown fields. Breaking changes (renaming
class, removing enum
values) would mint a new URI; we do not pre-plan a
/v2.
- Phase 1 (shipped) — class declaration + per-class verdict reporting.
- Phase 2 (shipped) — per-class
structural metrics (availability + latency for utility,
active count + session length for principal, tasks served +
lifetime for ephemeral); aggregate
pct_callabledeprecated. - Phase 2.1 (shipped) — substrate
estimates on the crawled cohort surfaced under
metrics_by_class_inferred; principle pivot to "self-declare if you can; substrate estimates if you don't, with disclosure." - Phase 3 — utility-class SLA
declarations following the AgentSLA paper's
GuaranteeTerm/SLOshape. - Phase 4 — sigstore-signed class attestations + delegation.
Upstream
A parallel RFC has been opened on the A2A protocol repository proposing service-class as a candidate for inclusion in a future protocol version. If accepted, the canonical URI moves upstream; if rejected or stalled, the URI above remains canonical and the schema continues to evolve here.