Boundary
Input and output schemas define the shape of the portable behavior.
In UMA, a descriptor is not just documentation beside a service. It is metadata the runtime can evaluate to understand the service boundary, validate inputs and outputs, check compatibility, and record why execution was allowed.
An active descriptor describes a capability in terms the runtime can use: schemas, emitted events, required inputs, allowed placements, version constraints, and the evidence expected from a run. It is active because it participates in execution decisions.
This does not mean the contract replaces service logic. The contract is an executable constraint model around the logic, while the service still owns the durable behavior.
A README beside a service is documentation for humans. An OpenAPI spec sitting in a repository is documentation for other developers. Neither of these is read by the runtime when it decides whether to approve an execution path. They exist to inform. They do not constrain.
An active descriptor is different. The runtime reads it during a real execution decision. It is a constraint model the system evaluates before approving a path, not a reference artifact a developer consults after something breaks. The word "active" is load-bearing: it means the descriptor has operational effect, not just informational value.
This distinction matters in practice because documentation drifts and constraint models do not. Or at least: when a constraint model drifts, the system knows about it. When a README drifts, the developer finds out at 2am during an incident.
The shape of a descriptor is specific enough for the runtime to reason with. A fully declared descriptor includes an input schema, an output schema, the events the capability emits, the events it requires, a version declaration, allowed placement targets, latency expectations, error expectations, and evidence expectations: the record of what a valid run is expected to produce.
Not every field is mandatory on every capability. A simple deterministic evaluator may have no event declarations. A capability that runs at the edge may have explicit latency expectations but relaxed evidence requirements. The descriptor is expressive enough to capture the full contract, and minimal enough that teams can adopt it incrementally.
What the descriptor does not contain is implementation detail. It does not describe how the capability works internally. It describes what the runtime needs to know to decide whether the capability can participate in a given execution context.
When a capability arrives with a descriptor, the runtime follows a specific decision sequence. First, it checks input schema compatibility: does the data flowing into this capability match what the descriptor declares? Second, it checks version constraints against other capabilities already participating in the workflow. Third, it checks placement rules: is this capability allowed to run in this execution environment? Fourth, it validates declared permissions against the trust model.
If all checks pass, the execution path is approved. The descriptor's evidence expectations then shape what gets recorded after the run: what the system will use to confirm that the capability behaved as declared, not just that it returned a value.
If any check fails, the path is rejected with a specific reason. The runtime does not proceed optimistically. It does not log a warning and continue. The descriptor is authoritative.
Silent interface drift: when a producer changes its output format but consumers are not updated, systems break at runtime rather than at contract validation. Descriptors make that drift visible before execution reaches production.
Undeclared dependency coupling: when a service assumes shared state or a side channel that is not in its contract, that assumption is invisible to the runtime and to any team consuming the capability. The descriptor forces every dependency to be declared.
Invisible permission escalation: when a service accesses a capability it never declared in its contract, the runtime has no way to enforce policy on that access. With descriptors, every permission claim is visible and every undeclared access is rejectable.
Input and output schemas define the shape of the portable behavior.
Version and event declarations help the runtime decide whether services can interact.
Latency, error, and evidence expectations make execution easier to inspect.
The runtime evaluates the descriptor before it treats a proposed path as approved.
The early examples prove the idea in small pieces: Chapter 4 uses a contract around deterministic flag evaluation, Chapter 6 uses a contract to compare native and WASI execution, and Chapter 7 lets contracts and events shape orchestration.
Chapter 4 is the simplest entry point: one input schema, one output schema, no event dependencies. It shows the minimum viable descriptor for a capability that has predictable behavior. Chapter 6 builds on that by proving the contract holds across two execution environments (native Rust and WASM) without changing the descriptor. Chapter 7 shows descriptors operating as first-class inputs to orchestration, with events shaping the workflow rather than code.
This page gives the preview. Chapters 4, 6, and 7 explain how descriptors become practical runtime inputs without turning the website into the full book.