The Agent Descriptor
The operator's standing description of one agent, and the primary location for its metadata.
This page renders Section 6 of the Common Agent Specification 0.26.0-draft. Where the two differ, the full specification governs. Section numbers are the specification's own, so a reference such as Section 4.1 is in the full text. Rendered 2026-10-17 from SPEC.md in the Common Agent Standards repository, tag common-agent-v0.26.0-draft, commit 9423e81d.
The declaration surface is the Agent Descriptor: the operator's standing description of one agent, and the primary location for its metadata. What it does, what each offering takes and returns, who drives it, what it refuses, and where it runs, in one document, signed once bound, versioned by replacement, referenced at a digest. This chapter is the Descriptor's normative definition; the page at https://commonagent.net/descriptor.html is a rendering of it.
6.1 Primary, and others bind#
An agent's facts end up spelled in several places: a description on a card, offerings on a registration, inputs in a contract, a model name in a config. Two spellings of one fact drift, and then a reader cannot tell which one the operator means. The Descriptor exists to end that: it is the one place the operator writes, and everything else derives from it or points into it.
A fact about the agent appears in the Descriptor once. A card or a manifest MAY carry a copy of a Descriptor fact, but only as a projection: derived from the Descriptor, never edited independently. A signed document that wants to make a Descriptor fact binding references it at a digest (Section 6.5) rather than restating it. A document that spells a Descriptor fact a second time, in its own words, does not conform to this section.
What the Descriptor is not: it is not a card, because it carries no endpoint and no authentication, which are connection facts, and the Descriptor holds shapes only (Section 6.4). It is not a contract: nothing in it binds anyone until a signed proposal references it. And it is not evidence: nothing issued by a third party after something happened is a member of it. Verdicts, records, and reputation check the Descriptor from outside.
6.2 The document#
A Descriptor is a JSON object. Three members are required in every Descriptor, draft or bound:
| Member | Holds |
|---|---|
format |
Which version of the Agent Descriptor format this document follows. For this specification it MUST be "agent-descriptor-v1". |
agent_version |
Which version of the agent this describes, in the operator's own scheme. Two Descriptors for the same subject are ordered by it. |
does |
One sentence on what the agent does. |
The subject, draft and bound. The subject member holds the agent's key and handle: { "id": <public key>, "handle": <handle> }. A draft leaves subject absent, because a builder describes agents that do not exist yet; the subject is filled at deployment, when the agent receives its identity. Nothing binds to a draft: a signed proposal MUST NOT reference a Descriptor without a subject, and a registry MUST NOT store one as an agent's Descriptor. Once bound, a Descriptor's subject MUST NOT change. A new agent gets a new Descriptor, not an edited one.
Offerings. offerings[] carries one entry per hireable thing. Each entry has an id, a name, one sentence of description, and its inputs and outputs:
inputs[]: each input'sname, itskind(Section 6.3), whether it isrequired, andexternal: truewhen it is reached rather than furnished. An input that is a grant rather than a thing sent MAY carryvia, one or more values from Agent SoW's grant-mechanism vocabulary, naming the mechanisms the operator accepts for making the grant. A caller reads it before deciding whether to engage, which is the point of stating it here. An input MAY carryone_of, a group name: at least one input of the offering naming that group MUST arrive, and no member of the group isrequiredon its own, so an agent that reads any one of five kinds of source says so once instead of marking all five optional and leaving the caller to read an agent that needs nothing. A consumer that does not know the member reads each as optional, the weaker claim, which is the safe direction to fail in. An input MAY carrymax_bytes, the most of it the agent takes: a caller, and anything that hands work on, checks it before sending and, over it, says so and sends nothing, because an agent handed part of an input does part of the work without knowing it. An agent that works inside a process MAY declare an input of kindapplication/vnd.agentmesh.run-context+json, namedrun-context, withfieldsnaming what it reads (for examplefocusandaudience): the run context, the answers the run was started with, which a process runner hands to every step whatever its place in the process. A consumer that does not know either member loses nothing by ignoring it.outputs[]: each deliverable'sname, itskind, andwhen:per_taskfor a deliverable each task produces,standingfor one maintained across tasks. An output MAY carryworking: truewhen it is the agent's working out, filed so a reader can check the deliverable against where it came from, rather than the deliverable itself; a renderer lists the deliverables first and MUST NOT drop the working pieces, because a caller still receives them.
Revisions. An offering MAY carry revisions, what a change to its delivered work costs (Section 5.7): included, with a count and a window_days after the first delivery, and either steps[], each a step id from the offering's own steps[] (Section 12.3) with a price in the price declaration's shape, or flat, one price for any revision. An offering without revisions does not offer them, and a request that names a prior task is refused as Section 5.7 says. The member is a declaration in the sense of Section 6.10: what it promises is enforced at the responder's node, and a document that promises what its node does not apply is not conformant.
The line between an input and a system: something furnished or named per task is an input, and something bound once at deployment and used across tasks is a system (systems[], below).
Interaction and refusals. interaction is "interactive" when a person attends the agent and "service" when nobody is in the loop; the caller-side semantics are Section 6.7's. refusals is prose: what the agent will not do, in the operator's own words. Refusals gain force elsewhere, as SoW clauses and role contracts; here they are the operator's plain statement.
Extensions. Every member beyond the core is optional, and an absent one means not stated (Section 6.4):
| Member | Holds |
|---|---|
role |
The standard role held, by offering name. The contract stays at the roles registry. |
interfaces[] |
The interfaces implemented, by name. The definitions stay at the registry. |
shape |
harness, model, steps (fixed or chosen), memory (keeps or starts_clean), tools_runtime (fixed or discovered), fleet, true when several processes answer as one identity, and kind, one value of Section 9.5.1's vocabulary. An assembled view computes kind from a record wherever one establishes it, and carries the operator's word only where no record can, which is how an agent behind a bridge says what it is made of at all. Where a record and the operator's word disagree, the computed value is carried and the disagreement is reported. That is the shape of the rule Section 6.8 gives a projection rather than an instance of it: this member is the operator's own declaration, and what overrides it is a record of what was deployed. |
hosted_in[] |
The jurisdictions or regions the runtime sits in. A region, never an address. Distinct from where content is processed and where answers apply, which keep their own documents. |
systems[] |
Standing systems the work is bound to: a name, an access level (read, write, trigger), and needs, what the access is for. The assembled view carries this as its reaches section (Section 9). |
limits |
Per-caller ceilings: requests_per_hour, model_budget_per_day, and past_them, what happens beyond them. |
handling_ref, price_ref, samples_ref |
Pointers to the data-use declaration, the price, and the samples document (Section 7.7), which keep their existing homes. The Descriptor points at them rather than restating them. |
run_config |
What a job may set: the declared settings, the models the author tested, and the author's named run configs (below, and Section 5.8). |
The member that names a system is name, and role is its alias for one revision. A reader MUST treat systems[].role and systems[].name as the same member, and MUST prefer name where a document carries both. A writer SHOULD emit name, and the alias is removed at the next revision. The rename is because role already names the standard job an agent holds, the first member in the table above, whose contract is an entry at the roles registry: one word for the job an agent takes on and for the name of a database it reaches makes a document nobody can read without being told which was meant.
Run configs. run_config declares what a run config may set for this agent (Section 5.8). Only a setting declared here can be set, at any layer.
"run_config": {
"settings": [
{ "name": "model", "kind": "rule", "default": "example/model-a",
"allowed": ["example/model-a", "example/model-b"], "job_may_set": false },
{ "name": "speaker", "kind": "preference", "default": "the deck's author",
"allowed": ["the deck's author", "a narrator"], "job_may_set": true }
],
"tested_models": ["example/model-a"],
"named": [ { "name": "Deck explainer, Oct 6", "settings": { "speaker": "the deck's author" }, "digest": "sha256:…" } ]
}
Each entry in settings[] has a name, unique in the block; a kind, preference or rule, whose resolution Section 5.8 gives; a default; allowed; and job_may_set. allowed lists the values the agent can use. A rule whose values are words MUST carry it, because it is the list a closer layer narrows. A rule whose default is a number is a ceiling, and its default is the highest value any layer may set. A rule whose default is true or false needs no list. On a preference allowed is OPTIONAL, and where it is absent any value of the default's type may be sent, which the agent still uses exactly or refuses. job_may_set is true when a sender who does not own the agent may set the setting for a job, and an absent job_may_set is read as false.
A setting named model is the AI model the agent's work calls, so an organization's rule about which models may be used narrows that setting's allowed. tested_models lists the models the author has tested the agent with. It SHOULD be a subset of the model setting's allowed, and a model that is allowed and not listed is permitted and untested, which a reader is told (Section 9.5). named lists the author's named run configs. Each has a name, unique in the block; settings, giving values only to declared settings, each inside its setting's allowed or under its ceiling; and digest, computed as Section 5.8 says over the entry without digest. replay, OPTIONAL, is true when the agent can replay a saved run's step without calling a model, so a pin move can be checked by comparing outputs (Section 5.8, Moving a pin); absent means it cannot.
A declared setting is a choice made for each job, so it MUST NOT be a credential, a key, an address or an account identifier. What an install binds is an install setting, named in the install file (Section 12.4), and is never declared here. A run config that an owner, an organization or a person saves is kept with them and is never added to the Descriptor, which differs from its package's draft only as Section 12.6 rule 6 allows. An agent whose Descriptor has no run_config member takes no settings.
A consumer that meets a member it does not recognise MUST ignore it rather than fail: an unknown extension is somebody else's business.
6.3 Kinds#
An input or output kind is a media type where the thing is a file: application/pdf, application/gzip, text/csv. Not every input is a file, so four value kinds sit beside the media types:
| Kind | Means |
|---|---|
text |
A string a person or program supplies inline. |
identifier |
A name for a thing: an agent handle, a record id, a subject key. |
url |
An address to be used as an address. |
document |
A fetchable file whose media type is not fixed. |
A non-file input MUST use a value kind. Forcing an agent handle into a media type misdescribes it, and a consumer checking inputs would check the wrong thing.
6.4 The rules#
- Every fact has one authored spelling. A fact appears in the Descriptor once. Any other document carries a projection or a reference (Sections 6.1 and 6.8).
- An absent member means not stated. A consumer MUST treat an absent member as something the operator has not said, never as a default. An unreadable member is treated as absent, never as the safe-sounding value.
- It carries shapes only. Media types, region names, and system names belong in a Descriptor. Addresses, credentials, endpoints, and account identifiers MUST NOT appear in one. A document violating this does not conform, whoever wrote it.
- Evidence stays outside it. Nothing issued by a third party after something happened is a Descriptor member. A Descriptor states; records and verdicts check.
6.5 Versioning and the digest#
A Descriptor is standing: true until its operator changes it. It is versioned by replacement. There is no partial edit; a new version is a whole new document.
The digest is over the exact bytes served, with no canonicalization. The digest of a Descriptor is the SHA-256 of the byte sequence a consumer fetched, exactly as fetched. This matches how an Agent SoW contract forms on bytes: a reference names an artifact, and the artifact is the bytes.
A reference to a Descriptor carries its digest, and MAY carry a location. A signed proposal that elevates Descriptor members references the Descriptor at its digest, which is why an operator's later edit cannot move what an existing signature meant.
agent_version orders versions of the agent, not edits of the document. Two Descriptors with different digests and the same agent_version are two spellings of the same agent version, and only the digest tells them apart. A Descriptor describing a changed agent MUST carry a new agent_version.
6.6 The signature#
A bound Descriptor SHOULD carry the operator's signature, made with the subject's identity key, so a copy stays checkable wherever it travels. A bound Descriptor without one is trusted only as far as the place it was fetched from.
The signature follows the family convention (Section 8.1). The tag defined here:
descriptor-statement-v1: the operator's statement that this is the subject's standing description.byMUST be the subject's own key, the same key assubject.id.
The digest (Section 6.5) is over the served bytes including signatures: a reference names the exact artifact, signature and all. The signature is over the canonical form without itself: a statement survives reserialization, an artifact does not, and the two jobs are different on purpose.
A draft has no subject and therefore no subject key, so a draft carries no descriptor-statement-v1 signature. Whoever passes a draft around vouches for it themselves.
6.7 Serving and discovery#
The addresses. A subject reachable at a domain SHOULD serve its current Descriptor at https://<domain>/.well-known/agent-descriptor.json, beside the A2A card and the AgentDoc. Most agents are not reachable at a domain, so the general case is a pointer: the subject's registration SHOULD carry the location of its current Descriptor and that version's digest. A consumer who has found the agent has found its Descriptor.
The registry. At registration the subject SHOULD hand the registry the Descriptor itself, not only a pointer. A registry that stores Descriptors MUST serve the current one for a subject, MUST retain and serve every version it has stored by digest, and becomes the reliable place to fetch from when the operator's own serving goes away. Where a registry's stored copy and the operator's served copy disagree, a consumer MUST NOT merge them: the disagreement is reported, the same rule the assembled view follows for drifted projections.
Asking the agent. A subject SHOULD answer a request for its own current Descriptor, before any agreement exists, answering with the document bytes and their digest. This is entryway exchange 2 (Section 4.4); a consumer on the same network as the agent then needs no other serving at all.
History. A signed reference is only checkable while the version it names can still be fetched. Whoever serves Descriptors for a subject MUST keep serving each version they have served, by digest, for as long as they serve the subject at all. The registry's stored history is the backstop; an operator SHOULD keep their own. A countersigner is well advised to keep their own copy besides, since their signature is the reason the version matters.
Hosted agents. Where a platform hosts the agent, the platform serves the Descriptor on the operator's behalf, and that hosted copy is the authoritative home: the pointer in the registration points at it, and its bytes are the ones a digest names.
Knowing it changed. Replacing a Descriptor SHOULD be announced as an event where the subject is registered, so a consumer who cares can subscribe rather than poll. A consumer without the event compares digests on refetch. Staleness is detectable either way; the event only makes it cheap.
6.8 Projections and consumers#
Four documents consume the Descriptor, each in its own way, and none of them edits its copy:
- The A2A card is generated from it:
doesbecomes the description, offerings become skills, and kinds coarsen to input and output modes. The serving machinery adds the endpoint and authentication, which are connection facts the Descriptor never holds. - The registration manifest carries the pointer and digest and projects
interactionand the shape members it has fields for. - An Agent SoW standing proposal elevates by reference: it signs Descriptor members at the Descriptor's digest, which is what turns a described input or price into a binding one. It does not restate them.
- An AgentDoc lists the Descriptor as a source, prefers it over any projection of it, records its digest, and reports rather than merges when a projection has drifted (Section 9.4).
A projection that disagrees with its Descriptor is a defect, and every consumer that can see the disagreement MUST report it rather than pick a side silently.
Checking a Descriptor is mechanical: the three required members are present, format names this specification, every kind is a media type or a defined value kind, no member carries an address, credential, or endpoint, a bound document's signature verifies against subject.id, and a draft carries no subject and no subject signature. An agent's behavior against its Descriptor's claims is a separate question, answered by an evaluator's signed record (Section 8.4), and never by this document about itself.
6.9 The wider declaration set#
The declarations below are what a well-described agent states about itself beyond the Descriptor's core members. Each is carried by the Descriptor, by a document it points to, or by the binding's registration projection; each is the operator's word, presented as such.
Standing. One defined value: guest. A guest is an agent a platform provisions and operates on trial terms: temporary tenure, at the platform's expense, for a principal who runs nothing of their own yet. The declaration exists so a counterparty knows what it is dealing with before agreeing to anything, so a platform that hosts guests MUST declare it on every guest it provisions; an agent that is not a guest declares nothing here, and absent means not stated, never resident. Four obligations follow from the declaration, wherever it appears. A guest MUST run under an allowance (Section 7.5) at all times, and every cost the guest incurs is metered against it, including the guest's own model spend where the platform runs the model. A guest buys and never sells: it MUST NOT declare a price or hold offerings, and a registry MUST refuse both from a declared guest. A commitment a guest enters MUST fit inside its remaining allowance at signing, so no counterparty is ever owed money by a party built to expire. And a guest past its tenure refuses mechanically (Sections 4.6 and 4.7), stating that it has lapsed, rather than going silent. The tenure itself, how a guest is funded, how long it lasts, how many one principal may hold, is the platform's policy, stated where the platform binds this specification, never here.
Interaction, the caller's side. service means sending disturbs nobody, and a reply does not wait on human attention; interactive means delivery lands in a live session a human is using, sending may interrupt someone, and a reply arrives when they get to it. Absent means unknown, and a careful caller SHOULD treat unknown as interactive, the cautious reading. This is a statement of fact about how the agent currently runs, not a security boundary: an agent that misdeclares inconveniences callers rather than gaining privilege, and implementations SHOULD derive it from how they actually run rather than asking an operator to assert it.
Modes. The media types an offering accepts and produces, with agent-level defaults as fallback where an offering does not say. Resolution is the offering's own modes, then the agent's defaults, then nothing; and nothing means the agent has not said, which a caller reads as text and MUST NOT read as a refusal of other types. Agents that handle anything beyond text SHOULD declare, because a caller has no other way to learn it before sending: an agent that accepts PDFs and says nothing is indistinguishable from one that does not, and consumers faced with that silence have historically invented an answer on the agent's behalf.
Needs and delivers. What must be in hand before work can start, and what the caller gets. A need is a shared resource with an access level, a file by media type, a credential (a sign-in to a named third-party service the agent does not control, with the narrowest true scope stated), or prose. Delivers states the final deliverable, whether interim checkpoints arrive as task updates, and whether the deliverable lands in a caller-provided resource rather than travelling back. Both are declarations, deliberately loose: the reader at discovery time is usually a model deciding whom to hire, so they must read well to a model, not validate well in a parser. The honesty doctrine applies: an agent that needs a repository and says nothing is indistinguishable from one that needs nothing. A credential need is neither a permission nor a promise about handling, and nothing in the declaration transports a credential; a renderer SHOULD present a credential need more prominently than the other kinds, because it is the one entry a reader can be harmed by missing.
Reporting level. An offering MAY declare the progress-reporting level it offers, on an ordinal vocabulary compared meets-or-exceeds. It is an advertisement, not a clause, it is self-declared and MUST be shown as such, and an unreadable value is dropped at registration, because a declaration that cannot be read declares nothing and MUST NOT be presented as if it did.
Sealing posture. A declared encryption key says an agent can be sealed to; the sealing posture says whether anyone should, and what happens to a request that arrives in the clear. required means the agent will not read a cleartext request: a sender MUST seal, and the receiver MUST refuse an unsealed request with a typed sealing-required refusal. preferred means a sender SHOULD seal when it can, and the agent reads both. Absent means the agent has not said, and a sender MUST NOT infer a posture from silence, and MUST NOT seal to an agent that has not asked to be sealed to. A posture REQUIRES the encryption key, and a registry MUST refuse a declaration stating one without the other: a posture is a promise about reading, and an agent with no key cannot keep it. The sealed unit is the request's input and the terminal response's output: the caller's material and the deliverable. Routing, status, errors, and timing stay readable, so a sealing posture protects content, never the fact of the conversation, and an implementation MUST NOT describe it as anonymity or traffic confidentiality.
Data use. What happens to content a buyer hands the agent, declared once, at agent level, deliberately: the pipeline is the operator's, shared by every offering, and a per-offering split posture is a gaming surface. Promises carry only the promises made (no_training, no_third_party_sharing, no_human_reading), each spelled true: false is spelled by omission, because a promise left out is a promise not made, and a reader MUST NOT infer one. Retention states the ceiling in days the operator is prepared to bind. Processors name the services content passes through, which is what lets an agent built on an upstream model API make the no-third-party-sharing promise honestly instead of staying silent or lying; an empty processor list is a statement, an omitted one states nothing. Jurisdictions name where content may be processed and stored, as a set tested by subset against a buyer's allowed list; an operator that cannot truthfully pin a jurisdiction declares nothing, and an absent declaration fails any jurisdiction requirement, which is the correct fate for "we don't know where it runs" when the buyer asked. Confident fiction is the failure mode this declaration must not invite. Everything here is self-declared, MUST be shown as such, and an unreadable data-use declaration is dropped whole rather than served in part, because a partially readable privacy claim misleads more than none at all. What binds is the signed engagement's confidentiality clause; where the declaration and the signed document disagree, the signed document wins.
Compliance. The postures an operator claims (SOC 2, ISO 27001, GDPR, HIPAA, PCI-DSS, an open vocabulary of lowercase tokens compared by exact equality), each with a scope in words and an attestation pointer: an auditor's name, a URL a reader can follow, an expiry after which the claim is stale on its face. Everything here is self-declared, including the pointer; nothing fetches the URL, verifies the auditor, or checks the expiry against anything but the calendar. Directories MAY index and filter on the tokens under the same presentation rule: a filter over self-declared claims is a filter over claims, and labeling it otherwise is the platform lying on the operator's behalf.
Access. How a caller presents identity, and who gets in, and they are different questions: the scheme is the lock, the policy is whose key was cut. The admission policy is a closed vocabulary of four values: open (anyone who satisfies a scheme is admitted), allowlist (only parties the operator already added), screened (a knock is evaluated, by policy or a person, and may be refused on grounds the operator does not have to publish), negotiated (admission is arranged out of band before any knock is meaningful). The vocabulary is closed because it feeds a decision, whether it is worth knocking, and an unrecognized value MUST be treated as unstated rather than as open. A scheme over the http transport is also the one statement that an agent on a mesh can be reached from outside it: a platform that brokers outside callers to its agents through a gateway MAY define a scheme for that gateway (a key the caller presents there), and an agent whose registration carries it has been opened to outside callers by its operator, while an agent without it is reachable on its mesh only and its projections (Section 6.8) MUST name no outside endpoint. The choice is the operator's, is made where the agent's door is enforced, and is projected into the declaration rather than typed into it. The membership of an access list is never published: publishing it turns a storefront into a customer roster, and the one reader guaranteed to find it useful is the one probing for accounts to impersonate. Schemes are alternatives, never a conjunction: a caller satisfies any one. Three states, and silence is one of them: schemes declared, schemes declared empty (a real answer: nothing to present), and nothing said, and a reader MUST NOT collapse the third into the second, because an agent that never described its door is not an agent with an open one. Schemes are shapes, never bindings: a member whose value would differ from one caller to the next is a binding and does not belong. An access declaration MUST NOT carry a credential, token, key, secret, account or tenant identifier, or per-caller URL, and a registry that detects one MUST drop the block whole rather than serve it, for a sharper reason than usual: a secret served on a pre-admission page has already leaked by the time anyone notices it was a validation error. Declaring a scheme grants nothing: nothing here issues a credential or promises admission, and what a caller must furnish to do the work once admitted is the offering's needs declaration.
6.10 The declaration doctrine#
Three rules bind every consumer of any declaration:
- Absent means not stated. Never a default, never the flattering value, and printed by name in any assembled view. A requirement stated against a declaration treats silence as not meeting it: fail closed.
- Shapes, never bindings. Declarations carry media types, roles, vocabularies, and regions; never credentials, endpoints, addresses, or account identifiers.
- Declared is a strength, not a verdict. An authored claim enters every view at declared strength and moves only on attestation (Section 8). No consumer may render a self-declaration as verified or enforced.
The AgentDoc is assembled from an agent's Descriptor and the records others sign about it. It is Section 9 of the specification and has a site of its own at agentdoc.net.