{
  "schemaVersion": "1.0",
  "title": "Capabilities and contracts",
  "description": "An AIP capability describes a stable operation that a caller can discover and request. Its schemas describe data shape; its contract describes side effects, execution, retry, data, credential, approval, and recovery expectations. This page ",
  "canonical": "https://getaip.org/docs/concepts/capabilities",
  "route": "/docs/concepts/capabilities",
  "source": "docs/concepts/capabilities.md",
  "protocol": "Agent Interoperability Protocol",
  "protocolVersion": "1.0",
  "section": "Core Concepts",
  "documentType": "Concept",
  "language": "en",
  "revision": {
    "lastReviewedRevision": "97be86e9efedf07ecf1783b03800f683f107fb04",
    "documentationSourceRevision": "9192fef3695ad294994f2712f6d156241e5e92fb",
    "basis": "frontmatter"
  },
  "downloads": {
    "md": "/docs/download/concepts/capabilities.md",
    "txt": "/docs/download/concepts/capabilities.txt",
    "json": "/docs/download/concepts/capabilities.json",
    "pdf": "/docs/download/concepts/capabilities.pdf"
  },
  "content": {
    "format": "text/markdown",
    "markdown": "---\ntitle: Capabilities and contracts\ndescription: Understand what an AIP capability declares and what must still be enforced\nkind: explanation\naudience: developer\nappliesTo: \"1.x\"\nwritingStandard: \"aip-docs/1.0\"\nlastReviewedRevision: \"97be86e9efedf07ecf1783b03800f683f107fb04\"\n---\n\n# Capabilities and contracts\n\nAn AIP capability describes a stable operation that a caller can discover and\nrequest. Its schemas describe data shape; its contract describes side effects,\nexecution, retry, data, credential, approval, and recovery expectations. This\npage helps application and connector developers interpret those declarations\nwithout treating them as stronger evidence than they are.\n\nThe types and admission behavior on this page apply to AIP 1.0 and the Rust\nimplementation at source revision\n`97be86e9efedf07ecf1783b03800f683f107fb04`. A capability declaration is not\nby itself proof of provider behavior, conformance, qualification, or production\nreadiness.\n\n## An endpoint is not a capability contract\n\nAn API endpoint identifies where and how one system accepts a request. A\ncapability gives an AIP caller a stable semantic operation and enough declared\ncontext to decide whether that operation can be attempted safely.\n\nFor example, `POST /bookings` does not answer all of these questions:\n\n- Does the operation create state, send a notification, or call another system?\n- Which JSON input is valid, and what structured result can be expected?\n- Can the caller retry after a lost response?\n- Is an idempotency key required, and in which namespace is it unique?\n- Can the operation run asynchronously, stream, or be cancelled?\n- Which data and credential boundaries apply?\n- Does policy require human approval?\n- Can the operation be planned, committed, reconciled, or compensated?\n\nA connector can combine several provider requests behind one capability. One\nprovider endpoint can also become several capabilities when distinct use cases\nneed different inputs, risk, authorization, or recovery contracts. The AIP\ncapability remains the caller-facing unit of governance.\n\n## The capability mental model\n\nRead a capability as five linked declarations:\n\n1. **Identity:** `id`, `name`, and `kind` say which operation is being offered.\n2. **Shape:** `input_schema` and optional `output_schema` define the accepted and\n   completed data shapes.\n3. **Discovery:** description, risk, stability, cost, auth hints, and bindings\n   help a caller select and project the operation.\n4. **Behavior:** `CapabilityContract` describes safety and lifecycle semantics.\n5. **Evidence:** manifest admission and implementation claims establish what the\n   reviewed runtime is willing to publish; separate tests establish what an\n   artifact actually does.\n\nThe first four are data. The fifth determines how much confidence a deployment\ncan place in that data.\n\n## Capability fields\n\nThe `Capability` type has the following top-level fields at the reviewed\nrevision:\n\n| Field | Required | Meaning and boundary |\n|---|---:|---|\n| `id` | Yes | Operation identifier carried by `Action.capability_id`; external constructors should use the checked parser |\n| `name` | Yes | Human-readable operation name; manifest admission rejects an empty value |\n| `kind` | Yes | `agent`, `tool`, `workflow`, `channel`, `resource`, or `human_task` |\n| `input_schema` | Yes | Draft 2020-12 JSON Schema value for `Action.input` |\n| `output_schema` | No | Draft 2020-12 JSON Schema value checked for a completed result |\n| `description` | No | Human-readable purpose and limits |\n| `risk` | No | `low`, `medium`, `high`, or `critical` operational classification |\n| `stability` | No | `stable`, `experimental`, or `deprecated` lifecycle label |\n| `cost` | No | Profile- or deployment-defined pricing and metering metadata |\n| `auth` | No | Flexible discovery metadata about authentication or scopes |\n| `bindings` | No | Profile-specific projection metadata keyed by `ProfileId` |\n| `requires_human_approval` | No | Top-level approval flag still evaluated by runtime policy |\n| `contract` | No | Structured `CapabilityContract` for execution and governance semantics |\n\nThe Rust `CapabilityId` parser currently requires only a non-empty string. IDs\nsuch as `cap:calendar:booking:create` are a useful ownership convention, not an\nadditional parser-enforced wire rule. Once published, an ID should keep one\nsemantic meaning; changing an operation while reusing its ID makes action,\nidempotency, policy, and evidence records ambiguous.\n\nA capability whose `kind` is `resource` is discovery-only in the production\nhandler-admission path. Readable objects use the separate `Resource` model and\nresource query APIs. Other capability kinds are callable and require an\nimplementation claim when strict admission is enabled.\n\nThe flexible `auth` and `cost` fields are discovery hints. They do not replace\ntrusted transport authentication, resolved credential handles, capability\npolicy, or the structured credential contract.\n\n## Read the contract in safety order\n\nWhen `contract` is present, `idempotency`, `execution`, and `data` are required\nobjects. Side effects default to an empty list; credentials, approval, service\nlevel, transactions, and compensation are optional. Absence of a contract or\noptional section means that guarantee is not declared. It does not mean the\noperation is harmless.\n\n### Side effects and risk\n\n`side_effects` lists every consequence a caller should assume:\n\n| Value | Consequence |\n|---|---|\n| `read` | Reads data without an intended mutation |\n| `write` | Creates or changes state |\n| `delete` | Deletes or destroys state |\n| `send_message` | Produces a user-visible or external message |\n| `financial` | Moves money or changes a financial obligation or billing state |\n| `identity` | Changes identity, account, access, or credential state |\n| `medical` | Touches medical or health-related records |\n| `legal` | Touches legal, contractual, or compliance-sensitive records |\n| `external_network` | Calls an external network service |\n| `code_execution` | Executes code or scripts supplied at runtime |\n\nSide effects are cumulative. A booking creation can be both `write` and\n`external_network`; a refund can be `write` and `financial`. The separate\n`risk` field expresses operational severity. Runtime policy can require human\napproval when risk exceeds its automatic-approval threshold even if the legacy\napproval flag is absent.\n\n### Idempotency and retry\n\nThe idempotency contract has four decisions:\n\n| Field | Values | Question answered |\n|---|---|---|\n| `requirement` | `required`, `optional`, `unsupported` | May the runtime accept the action without a key? |\n| `collision_behavior` | `return_original_result`, `reject_conflict`, `revalidate_input_hash` | What happens when the scoped key already exists? |\n| `key_scope` | `action`, `capability`, `principal`, `tenant`, `external_account` | Within which trusted partition is the key unique? |\n| `ttl_ms` | Positive integer or absent | When may the retained key expire? |\n\n`ExecutionContract.retry_safety` is a separate classification:\n`safe`, `safe_with_idempotency_key`, `unsafe`, or `unknown`. The\n`supports_retry` flag says that retry behavior is implemented; it does not make\nan unsafe retry safe. A caller needs both the classification and the required\nidempotency context.\n\nThe reviewed runtime hashes the capability ID, business input, and transaction\nintent when it validates idempotent replay. A runtime-assigned transaction ID is\nexcluded from that fingerprint so the same business intent does not change\nidentity merely because correlation state was allocated.\n\n### Execution\n\n`ExecutionContract` declares five support flags:\n\n- `supports_sync`;\n- `supports_async`;\n- `supports_streaming`;\n- `supports_cancel`;\n- `supports_retry`.\n\nIt also declares `expected_completion` as `sync`, `async`, `streaming`, or\n`any`, plus the retry-safety classification above. Manifest admission rejects a\ncontract that supports none of the three completion modes. Runtime invocation\ndefaults an omitted action mode to `sync` and rejects a mode whose flag is\nfalse.\n\nCancellation support means the runtime can reach a handler cancellation path.\nIt does not establish that an external provider can reverse or stop work after\ncommit. Streaming support means the implementation can publish incremental\nchunks; it does not make every transport binding lossless or resumable without\nits own replay support.\n\n### Data and credentials\n\n`DataContract` requires a sensitivity value:\n`public`, `internal`, `confidential`, `restricted`, `regulated`, or `unknown`.\nIt also declares whether personally identifiable information may be present and\nwhether redaction is required. Optional residency rules list allowed and\nprohibited regions. Optional retention rules set minimum retention, maximum\ntime before deletion, and whether legal hold can override deletion.\n\n`CredentialPolicy` declares whether a resolved external credential is required,\nwhich issuers are accepted, which downstream scopes are required, and whether\nOAuth refresh may be used. It carries no raw secret. In the reviewed runtime,\nthe credential handle comes from trusted identity resolution; the runtime\nchecks presence, expiry, issuer, scopes, and tenant consistency before handler\nexecution.\n\n### Approval\n\n`ApprovalPolicy` can identify a principal, role, group, tenant policy, external\nsystem, or delegated authority. A composed `rule` supports `all`, `any`, and\nquorum expressions. The policy can also require distinct principals,\nseparation of requester, operator, and approver duties, evidence, expiration,\nand a stable policy version.\n\nThese values identify required authority. A role name or approval object inside\nan action does not prove membership. The runtime evaluates approval decisions\nagainst a trusted authority resolver and the immutable policy snapshot for the\ngoverned action.\n\n### Service level, transactions, and compensation\n\n`ServiceLevelContract` can declare expected latency, runtime timeout, whether\nasynchronous execution is expected, maximum queue delay, and a human-readable\navailability target. These are scheduling and operational expectations, not an\navailability guarantee.\n\n`TransactionContract` declares supported modes from `execute`, `dry_run`,\n`plan`, `commit`, `compensate`, `reconcile`, and\n`rollback_not_supported`. It also says whether commit requires a prior plan and\nlabels dry-run fidelity as `schema_only`, `policy_and_schema`,\n`downstream_validation`, or `full_simulation`.\n\n`CompensationContract` classifies reversal as `not_required`, `supported`,\n`best_effort`, or `rollback_not_supported`. Supported compensation identifies\nthe compensating capability; an optional window limits when it can be used, and\nthe contract states whether compensation itself needs approval.\n\nCompensation is a new governed action, not time travel. `best_effort` and\n`rollback_not_supported` must remain visible to callers deciding how to recover\nfrom a partially completed workflow.\n\n## Example capability\n\nThis illustrative capability is not part of a maintained connector catalog. It\nshows the minimum structured contract needed to describe a tenant-scoped,\nretry-sensitive write:\n\n```json\n{\n  \"id\": \"cap:calendar:booking:create\",\n  \"name\": \"Create booking\",\n  \"kind\": \"tool\",\n  \"input_schema\": {\n    \"type\": \"object\",\n    \"required\": [\"starts_at\"],\n    \"properties\": {\n      \"starts_at\": { \"type\": \"string\", \"format\": \"date-time\" }\n    },\n    \"additionalProperties\": false\n  },\n  \"output_schema\": {\n    \"type\": \"object\",\n    \"required\": [\"booking_id\"],\n    \"properties\": {\n      \"booking_id\": { \"type\": \"string\" }\n    },\n    \"additionalProperties\": false\n  },\n  \"risk\": \"medium\",\n  \"stability\": \"stable\",\n  \"contract\": {\n    \"side_effects\": [\"write\", \"external_network\"],\n    \"idempotency\": {\n      \"requirement\": \"required\",\n      \"collision_behavior\": \"revalidate_input_hash\",\n      \"key_scope\": \"tenant\",\n      \"ttl_ms\": 86400000\n    },\n    \"execution\": {\n      \"supports_sync\": true,\n      \"supports_async\": false,\n      \"supports_streaming\": false,\n      \"supports_cancel\": false,\n      \"supports_retry\": true,\n      \"expected_completion\": \"sync\",\n      \"retry_safety\": \"safe_with_idempotency_key\"\n    },\n    \"data\": {\n      \"sensitivity\": \"internal\",\n      \"contains_pii\": true,\n      \"redaction_required\": true\n    }\n  }\n}\n```\n\nA caller reading this contract can determine that the operation mutates an\nexternal system, requires a tenant-scoped idempotency key, supports only\nsynchronous execution, and permits retry only with that key. It cannot conclude\nthat the provider actually deduplicates correctly without implementation and\ntest evidence.\n\n## How an action uses the capability\n\n`Action.capability_id` selects the declaration and `Action.input` is validated\nagainst `input_schema`. The action may add a mode, idempotency key, trusted\nidentity projection, approval decision, or transaction context. The runtime\nthen applies the declared contract before selecting a handler.\n\nAt the reviewed revision, the runtime returns typed, non-retryable errors when\nrequired idempotency is absent or a mode is unsupported. It applies the same\nerror class when a plan is required, a transaction or compensation mode is not\ndeclared, or the resolved credential does not satisfy the contract.\n\nIt validates an `output_schema` only for a result whose status is `completed`;\na failure carries its own typed error instead of a successful output object.\n\nSchema validation bounds shape, not meaning. A schema can require an amount to\nbe a number; policy or connector logic must still decide whether that amount is\nauthorized and whether the provider accepted the intended currency and account.\n\n## Admission connects declaration to implementation\n\nThe reviewed discovery service checks a manifest before publication:\n\n- profile and capability IDs are unique within a manifest, and resource and\n  channel identifiers satisfy their own non-empty uniqueness checks;\n- each input and output schema compiles as Draft 2020-12;\n- non-fragment schema references are rejected by default;\n- a binding names a profile declared by the manifest and does not duplicate a\n  profile for the same capability;\n- projected profile names do not collide;\n- contract invariants such as positive TTLs, non-empty transaction modes,\n  valid approval rules, and compensation targets hold.\n\nWith strict implementation checking, every callable capability must also have\na `CapabilityImplementationSupport` record. Admission compares declared\ncancellation, streaming, retry, transaction, reconciliation, compensation,\napproval, and credential behavior with the handler's support flags. The local\nruntime then publishes the admitted manifest and exact handler set atomically.\n\nThis check prevents a handler from advertising a feature it does not claim to\nimplement. It still does not prove that the downstream provider behaves as\ndeclared. Connector tests, conformance checks, qualification runs, and live\nexternal evidence answer different questions and must retain exact artifact\nidentities.\n\n## Trust and data boundaries\n\n- The caller can select a capability, but the gateway supplies the authenticated\n  actor and trusted tenant context.\n- The manifest can declare credential requirements, but the deployment resolves\n  a protected credential handle and the connector owns raw provider secrets.\n- The contract can label side effects and retry safety, but the provider remains\n  the source of truth for external commits.\n- The runtime can validate schemas and declared support, but it cannot infer an\n  undeclared business invariant from JSON shape.\n- A compatibility binding can rename or project a capability, but the native ID\n  and contract remain the canonical operation identity.\n\n## Design trade-offs\n\nA small, coarse capability catalog is easier to discover but forces unrelated\nrisk and policy into one contract. A highly granular catalog gives policy and\nretry logic a more accurate unit, but it increases versioning, navigation, and\nqualification work. The right boundary is one stable business intent with one\ncoherent input, side-effect, authorization, and recovery model.\n\nRich contracts make conservative automation possible. They also create an\nobligation to track provider changes. When an upstream endpoint changes its\nside effects, idempotency, or result shape, the connector must update and\nrequalify the capability rather than preserving a stale declaration for\ncompatibility.\n\n## What a capability does not mean\n\n- `stable` does not mean a deployment is qualified or a provider is available.\n- `read` does not mean the result is non-sensitive or safe to disclose.\n- `supports_retry` does not mean retry is safe without checking\n  `retry_safety` and idempotency.\n- `supports_cancel` does not guarantee reversal after a provider commit.\n- `full_simulation` is a declared dry-run fidelity, not proof of provider parity.\n- An absent contract does not imply zero side effects or unrestricted use.\n- A profile binding does not replace the native capability ID or contract.\n\n## Related pages\n\n- [Actions and sessions](actions-and-sessions.md)\n- [Approvals and policy](approvals-and-policy.md)\n- [Transactions and compensation](transactions-and-compensation.md)\n- [Profiles, transports, and connectors](profiles-and-connectors.md)\n- [JSON Schemas](../spec/schemas.md)\n",
    "text": "Capabilities and contracts\n\nAn AIP capability describes a stable operation that a caller can discover and\nrequest. Its schemas describe data shape; its contract describes side effects,\nexecution, retry, data, credential, approval, and recovery expectations. This\npage helps application and connector developers interpret those declarations\nwithout treating them as stronger evidence than they are.\n\nThe types and admission behavior on this page apply to AIP 1.0 and the Rust\nimplementation at source revision\n97be86e9efedf07ecf1783b03800f683f107fb04. A capability declaration is not\nby itself proof of provider behavior, conformance, qualification, or production\nreadiness.\n\nAn endpoint is not a capability contract\n\nAn API endpoint identifies where and how one system accepts a request. A\ncapability gives an AIP caller a stable semantic operation and enough declared\ncontext to decide whether that operation can be attempted safely.\n\nFor example, POST /bookings does not answer all of these questions:\n• Does the operation create state, send a notification, or call another system?\n• Which JSON input is valid, and what structured result can be expected?\n• Can the caller retry after a lost response?\n• Is an idempotency key required, and in which namespace is it unique?\n• Can the operation run asynchronously, stream, or be cancelled?\n• Which data and credential boundaries apply?\n• Does policy require human approval?\n• Can the operation be planned, committed, reconciled, or compensated?\n\nA connector can combine several provider requests behind one capability. One\nprovider endpoint can also become several capabilities when distinct use cases\nneed different inputs, risk, authorization, or recovery contracts. The AIP\ncapability remains the caller-facing unit of governance.\n\nThe capability mental model\n\nRead a capability as five linked declarations:\n1. Identity: id, name, and kind say which operation is being offered.\n2. Shape: inputschema and optional outputschema define the accepted and\n   completed data shapes.\n3. Discovery: description, risk, stability, cost, auth hints, and bindings\n   help a caller select and project the operation.\n4. Behavior: CapabilityContract describes safety and lifecycle semantics.\n5. Evidence: manifest admission and implementation claims establish what the\n   reviewed runtime is willing to publish; separate tests establish what an\n   artifact actually does.\n\nThe first four are data. The fifth determines how much confidence a deployment\ncan place in that data.\n\nCapability fields\n\nThe Capability type has the following top-level fields at the reviewed\nrevision:\n\n| Field | Required | Meaning and boundary |\n\n| id | Yes | Operation identifier carried by Action.capabilityid; external constructors should use the checked parser |\n| name | Yes | Human-readable operation name; manifest admission rejects an empty value |\n| kind | Yes | agent, tool, workflow, channel, resource, or humantask |\n| inputschema | Yes | Draft 2020-12 JSON Schema value for Action.input |\n| outputschema | No | Draft 2020-12 JSON Schema value checked for a completed result |\n| description | No | Human-readable purpose and limits |\n| risk | No | low, medium, high, or critical operational classification |\n| stability | No | stable, experimental, or deprecated lifecycle label |\n| cost | No | Profile- or deployment-defined pricing and metering metadata |\n| auth | No | Flexible discovery metadata about authentication or scopes |\n| bindings | No | Profile-specific projection metadata keyed by ProfileId |\n| requireshumanapproval | No | Top-level approval flag still evaluated by runtime policy |\n| contract | No | Structured CapabilityContract for execution and governance semantics |\n\nThe Rust CapabilityId parser currently requires only a non-empty string. IDs\nsuch as cap:calendar:booking:create are a useful ownership convention, not an\nadditional parser-enforced wire rule. Once published, an ID should keep one\nsemantic meaning; changing an operation while reusing its ID makes action,\nidempotency, policy, and evidence records ambiguous.\n\nA capability whose kind is resource is discovery-only in the production\nhandler-admission path. Readable objects use the separate Resource model and\nresource query APIs. Other capability kinds are callable and require an\nimplementation claim when strict admission is enabled.\n\nThe flexible auth and cost fields are discovery hints. They do not replace\ntrusted transport authentication, resolved credential handles, capability\npolicy, or the structured credential contract.\n\nRead the contract in safety order\n\nWhen contract is present, idempotency, execution, and data are required\nobjects. Side effects default to an empty list; credentials, approval, service\nlevel, transactions, and compensation are optional. Absence of a contract or\noptional section means that guarantee is not declared. It does not mean the\noperation is harmless.\n\nSide effects and risk\n\nsideeffects lists every consequence a caller should assume:\n\n| Value | Consequence |\n\n| read | Reads data without an intended mutation |\n| write | Creates or changes state |\n| delete | Deletes or destroys state |\n| sendmessage | Produces a user-visible or external message |\n| financial | Moves money or changes a financial obligation or billing state |\n| identity | Changes identity, account, access, or credential state |\n| medical | Touches medical or health-related records |\n| legal | Touches legal, contractual, or compliance-sensitive records |\n| externalnetwork | Calls an external network service |\n| codeexecution | Executes code or scripts supplied at runtime |\n\nSide effects are cumulative. A booking creation can be both write and\nexternalnetwork; a refund can be write and financial. The separate\nrisk field expresses operational severity. Runtime policy can require human\napproval when risk exceeds its automatic-approval threshold even if the legacy\napproval flag is absent.\n\nIdempotency and retry\n\nThe idempotency contract has four decisions:\n\n| Field | Values | Question answered |\n\n| requirement | required, optional, unsupported | May the runtime accept the action without a key? |\n| collisionbehavior | returnoriginalresult, rejectconflict, revalidateinputhash | What happens when the scoped key already exists? |\n| keyscope | action, capability, principal, tenant, externalaccount | Within which trusted partition is the key unique? |\n| ttlms | Positive integer or absent | When may the retained key expire? |\n\nExecutionContract.retrysafety is a separate classification:\nsafe, safewithidempotencykey, unsafe, or unknown. The\nsupportsretry flag says that retry behavior is implemented; it does not make\nan unsafe retry safe. A caller needs both the classification and the required\nidempotency context.\n\nThe reviewed runtime hashes the capability ID, business input, and transaction\nintent when it validates idempotent replay. A runtime-assigned transaction ID is\nexcluded from that fingerprint so the same business intent does not change\nidentity merely because correlation state was allocated.\n\nExecution\n\nExecutionContract declares five support flags:\n• supportssync;\n• supportsasync;\n• supportsstreaming;\n• supportscancel;\n• supportsretry.\n\nIt also declares expectedcompletion as sync, async, streaming, or\nany, plus the retry-safety classification above. Manifest admission rejects a\ncontract that supports none of the three completion modes. Runtime invocation\ndefaults an omitted action mode to sync and rejects a mode whose flag is\nfalse.\n\nCancellation support means the runtime can reach a handler cancellation path.\nIt does not establish that an external provider can reverse or stop work after\ncommit. Streaming support means the implementation can publish incremental\nchunks; it does not make every transport binding lossless or resumable without\nits own replay support.\n\nData and credentials\n\nDataContract requires a sensitivity value:\npublic, internal, confidential, restricted, regulated, or unknown.\nIt also declares whether personally identifiable information may be present and\nwhether redaction is required. Optional residency rules list allowed and\nprohibited regions. Optional retention rules set minimum retention, maximum\ntime before deletion, and whether legal hold can override deletion.\n\nCredentialPolicy declares whether a resolved external credential is required,\nwhich issuers are accepted, which downstream scopes are required, and whether\nOAuth refresh may be used. It carries no raw secret. In the reviewed runtime,\nthe credential handle comes from trusted identity resolution; the runtime\nchecks presence, expiry, issuer, scopes, and tenant consistency before handler\nexecution.\n\nApproval\n\nApprovalPolicy can identify a principal, role, group, tenant policy, external\nsystem, or delegated authority. A composed rule supports all, any, and\nquorum expressions. The policy can also require distinct principals,\nseparation of requester, operator, and approver duties, evidence, expiration,\nand a stable policy version.\n\nThese values identify required authority. A role name or approval object inside\nan action does not prove membership. The runtime evaluates approval decisions\nagainst a trusted authority resolver and the immutable policy snapshot for the\ngoverned action.\n\nService level, transactions, and compensation\n\nServiceLevelContract can declare expected latency, runtime timeout, whether\nasynchronous execution is expected, maximum queue delay, and a human-readable\navailability target. These are scheduling and operational expectations, not an\navailability guarantee.\n\nTransactionContract declares supported modes from execute, dryrun,\nplan, commit, compensate, reconcile, and\nrollbacknotsupported. It also says whether commit requires a prior plan and\nlabels dry-run fidelity as schemaonly, policyandschema,\ndownstreamvalidation, or fullsimulation.\n\nCompensationContract classifies reversal as notrequired, supported,\nbesteffort, or rollbacknotsupported. Supported compensation identifies\nthe compensating capability; an optional window limits when it can be used, and\nthe contract states whether compensation itself needs approval.\n\nCompensation is a new governed action, not time travel. besteffort and\nrollbacknotsupported must remain visible to callers deciding how to recover\nfrom a partially completed workflow.\n\nExample capability\n\nThis illustrative capability is not part of a maintained connector catalog. It\nshows the minimum structured contract needed to describe a tenant-scoped,\nretry-sensitive write:\n\n{\n  \"id\": \"cap:calendar:booking:create\",\n  \"name\": \"Create booking\",\n  \"kind\": \"tool\",\n  \"inputschema\": {\n    \"type\": \"object\",\n    \"required\": [\"startsat\"],\n    \"properties\": {\n      \"startsat\": { \"type\": \"string\", \"format\": \"date-time\" }\n    },\n    \"additionalProperties\": false\n  },\n  \"outputschema\": {\n    \"type\": \"object\",\n    \"required\": [\"bookingid\"],\n    \"properties\": {\n      \"bookingid\": { \"type\": \"string\" }\n    },\n    \"additionalProperties\": false\n  },\n  \"risk\": \"medium\",\n  \"stability\": \"stable\",\n  \"contract\": {\n    \"sideeffects\": [\"write\", \"externalnetwork\"],\n    \"idempotency\": {\n      \"requirement\": \"required\",\n      \"collisionbehavior\": \"revalidateinputhash\",\n      \"keyscope\": \"tenant\",\n      \"ttlms\": 86400000\n    },\n    \"execution\": {\n      \"supportssync\": true,\n      \"supportsasync\": false,\n      \"supportsstreaming\": false,\n      \"supportscancel\": false,\n      \"supportsretry\": true,\n      \"expectedcompletion\": \"sync\",\n      \"retrysafety\": \"safewithidempotencykey\"\n    },\n    \"data\": {\n      \"sensitivity\": \"internal\",\n      \"containspii\": true,\n      \"redactionrequired\": true\n    }\n  }\n}\n\nA caller reading this contract can determine that the operation mutates an\nexternal system, requires a tenant-scoped idempotency key, supports only\nsynchronous execution, and permits retry only with that key. It cannot conclude\nthat the provider actually deduplicates correctly without implementation and\ntest evidence.\n\nHow an action uses the capability\n\nAction.capabilityid selects the declaration and Action.input is validated\nagainst inputschema. The action may add a mode, idempotency key, trusted\nidentity projection, approval decision, or transaction context. The runtime\nthen applies the declared contract before selecting a handler.\n\nAt the reviewed revision, the runtime returns typed, non-retryable errors when\nrequired idempotency is absent or a mode is unsupported. It applies the same\nerror class when a plan is required, a transaction or compensation mode is not\ndeclared, or the resolved credential does not satisfy the contract.\n\nIt validates an outputschema only for a result whose status is completed;\na failure carries its own typed error instead of a successful output object.\n\nSchema validation bounds shape, not meaning. A schema can require an amount to\nbe a number; policy or connector logic must still decide whether that amount is\nauthorized and whether the provider accepted the intended currency and account.\n\nAdmission connects declaration to implementation\n\nThe reviewed discovery service checks a manifest before publication:\n• profile and capability IDs are unique within a manifest, and resource and\n  channel identifiers satisfy their own non-empty uniqueness checks;\n• each input and output schema compiles as Draft 2020-12;\n• non-fragment schema references are rejected by default;\n• a binding names a profile declared by the manifest and does not duplicate a\n  profile for the same capability;\n• projected profile names do not collide;\n• contract invariants such as positive TTLs, non-empty transaction modes,\n  valid approval rules, and compensation targets hold.\n\nWith strict implementation checking, every callable capability must also have\na CapabilityImplementationSupport record. Admission compares declared\ncancellation, streaming, retry, transaction, reconciliation, compensation,\napproval, and credential behavior with the handler's support flags. The local\nruntime then publishes the admitted manifest and exact handler set atomically.\n\nThis check prevents a handler from advertising a feature it does not claim to\nimplement. It still does not prove that the downstream provider behaves as\ndeclared. Connector tests, conformance checks, qualification runs, and live\nexternal evidence answer different questions and must retain exact artifact\nidentities.\n\nTrust and data boundaries\n• The caller can select a capability, but the gateway supplies the authenticated\n  actor and trusted tenant context.\n• The manifest can declare credential requirements, but the deployment resolves\n  a protected credential handle and the connector owns raw provider secrets.\n• The contract can label side effects and retry safety, but the provider remains\n  the source of truth for external commits.\n• The runtime can validate schemas and declared support, but it cannot infer an\n  undeclared business invariant from JSON shape.\n• A compatibility binding can rename or project a capability, but the native ID\n  and contract remain the canonical operation identity.\n\nDesign trade-offs\n\nA small, coarse capability catalog is easier to discover but forces unrelated\nrisk and policy into one contract. A highly granular catalog gives policy and\nretry logic a more accurate unit, but it increases versioning, navigation, and\nqualification work. The right boundary is one stable business intent with one\ncoherent input, side-effect, authorization, and recovery model.\n\nRich contracts make conservative automation possible. They also create an\nobligation to track provider changes. When an upstream endpoint changes its\nside effects, idempotency, or result shape, the connector must update and\nrequalify the capability rather than preserving a stale declaration for\ncompatibility.\n\nWhat a capability does not mean\n• stable does not mean a deployment is qualified or a provider is available.\n• read does not mean the result is non-sensitive or safe to disclose.\n• supportsretry does not mean retry is safe without checking\n  retrysafety and idempotency.\n• supportscancel does not guarantee reversal after a provider commit.\n• fullsimulation is a declared dry-run fidelity, not proof of provider parity.\n• An absent contract does not imply zero side effects or unrestricted use.\n• A profile binding does not replace the native capability ID or contract.\n\nRelated pages\n• Actions and sessions (actions-and-sessions.md)\n• Approvals and policy (approvals-and-policy.md)\n• Transactions and compensation (transactions-and-compensation.md)\n• Profiles, transports, and connectors (profiles-and-connectors.md)\n• JSON Schemas (../spec/schemas.md)\n"
  },
  "integrity": {
    "algorithm": "sha256",
    "sourceDigest": "e4104385da37221fecedcd75a208cb9cd6e053c6dc962ebd77ce5c8ba75c50ad"
  }
}
