Contracts

What are postconditions in a Traverse contract?

Postconditions are guarantees about the output of a capability. They are declared in the contract's [outputs] section and validated by the runtime after execution completes.

The output schema defines what fields will be present, what types they have, and any constraints on their values. If the WASM binary returns an output that does not match the postconditions, the runtime moves to error state. The caller receives a clear error, not malformed data.

# Postconditions declared in [outputs]
[outputs]
[[outputs.fields]]
name     = "approved"
type     = "boolean"

[[outputs.fields]]
name     = "approved_amount"
type     = "number"
min      = 0

[[outputs.fields]]
name     = "reason_code"
type     = "string"
allowed  = ["approved", "insufficient_credit", "policy_limit"]

What postconditions prevent

Without postconditions, a caller must inspect and validate every response. They have to defensive-code against missing fields, wrong types, or unexpected values. This is tedious and error-prone. It also means the implementation and the caller are loosely coupled in a bad way: a change to what the capability returns can silently break callers.

With postconditions:

  • The output is validated at the boundary, before it reaches the caller.
  • A capability that returns a negative approved_amount fails immediately at the runtime level.
  • A capability that returns an undeclared reason_code fails immediately.
  • The caller receives a well-typed, validated response every time — or a clear error.

How this differs from plain function definitions

A function signature tells you the return type. That is a hint, not a guarantee. Nothing enforces that the returned struct actually contains valid values at runtime. Postconditions go further. They are checked by the runtime after the binary returns, against the declared schema. The contract is the enforcement point, not just the description.

Why AI agents rely on postconditions

An AI agent calling a capability via MCP reads the contract and knows the output schema before calling. After the call, the agent receives a response that has already been validated against the schema. The agent does not need to write defensive parsing code. It can use the output directly. For regulated use cases, this also means the agent's decisions are based on validated, governed data — not raw unverified output from a WASM binary.