Documentation menu

Execution payload encoding

This binding defines event payloads and execution/accounting semantics. The schemas are the canonical wire grammar. Common envelope fields are id, URI source, type, timestamp time, and harness: {name, version}. trigger names the session/turn initiation cause; source remains event identity. Wire timestamps use RFC 3339 syntax and calendar constraints; source uses RFC 3986 absolute-URI grammar. Compact ISO timestamps, whitespace, invalid escapes and bad IP literals are invalid. Format validation is not endpoint authorization. Integer-valued JSON numbers such as 1.0 count as integers under Draft 2020-12. Removed names are not additional standard events: tool.error (use tool.after.outcome), prompt.submitted, agent.stop, notification, permission.request, compact.pre, compact.post, file.edited, and other. MCP inventory discovery is not required.

Required event-specific payloads

An empty envelope is not a valid execution event. Additional optional fields and conditional constraints are defined in the corresponding schema.

Event Required fields beyond the common envelope
session.start session, trigger, permissionMode, manifest, items
session.end session, outcome, reason
tool.before call, tool, path
tool.after outcome, execution, call, tool, path, items
turn.start turn, trigger, items
turn.finish.before turn, outcome, continuationCount, items
turn.end turn, outcome, continuationCount, items
turn.progress turn, item, delta, final
model.request.before model, attempt, params, items
model.response.after model, attempt, execution, items, finishReason
model.error model, attempt, execution, error
model.switch.before current, proposed, reason
model.switch.after previous, current, reason
tool.permission.request call, tool, path, suggestions, sandboxBypass
tool.permission.resolved call, tool, path, decision, decidedBy
tool.progress call, tool, path, partialOutput, backgrounded
tool.batch.after batch, calls
context.compact.before trigger, items
context.compact.after summary, removed, execution

Execution, calls, and model attempts

call: {id} identifies a tool invocation. tool requires verbatim name, parsed object input, and origin: native|mcp; behavioral kind is optional. MCP origin requires its self-contained mcp descriptor; native origin forbids it. MCP connection transport is HTTP/SSE or stdio. Unavailable URL/command/args/cwd fields use explicit field-path gaps rather than invented values. Descriptors never carry credentials. Runtime validation must additionally sanitize addresses and arguments. path identifies the covered tool path. batch: {id, callIds} lists unique sibling call IDs. Correlation, batch membership, and one-completion guarantees are runtime duties, not conclusions derived from validating individual messages.

Execution is either {status: "executed"}, or skipped with a reason. reason: "supplied_result" identifies a supplied result without exposing the harness-local subscription; other reasons are policy, cancelled, timeout, and other (optional detail). This is the only supplied result spelling. Tool outcomes are ok, error, denied, cancelled, timeout. Denial requires skipped/policy. Successful and failed supplied results retain ordinary outcomes; neither establishes original execution. Error objects require class and message, with optional code/status/native details. A supplied model response or compaction summary does not fabricate provider usage or latency.

Models use {id, provider}. Provider attempts use {id, number} with a positive attempt number. Provider-native request params, tool input, and native permission suggestions remain intentionally opaque objects, not portable AHP languages. Optional model-switch pricing has ISO-style uppercase three-letter currency and nonnegative inputPerMillionTokens / outputPerMillionTokens; absent rates are unknown. Pricing is not billed cost.

Content and accounting

At tool.after, modify(output) maps to items, not a native JSON result property. Replace requires a canonical message list; merge appends canonical messages in order and preserves duplicates. Objects, bare part lists, strings, and other primitive values MUST be rejected atomically. Structured application results are serialized into ordinary text parts; no dedicated JSON part or optional native output field is defined. Native tool input remains an object and its advertised merge remains shallow.

Model-visible items are ordered canonical messages with canonical roles and ordered parts, as defined in content selection. Generic items remain part lists. turn.progress.delta and tool.progress.partialOutput are singular canonical messages using the shared modelVisibleItem definition, not bare parts; their message role establishes ownership of their ordered parts. Compaction summaries use text-part lists. Ordinary text is inline in text; only non-text, non-JSON media attachments use immutable upload references. Provider-native prompt/message JSON MUST NOT replace this canonical representation. Common lists may be empty for legitimately absent or omitted content; adapters MUST NOT use emptiness to conceal known authorized content. Selection applies equally to inline text and attachments.

Usage carries kind: amount|total, scope: attempt|turn, completeness complete|partial|unknown, and provenance provider|estimate|mixed. Attempt usage is an amount with provider/estimate provenance; turn usage is an aggregate total and may be mixed. Nonnegative input/output/cache-read/cache-write token counts are optional: missing is unknown, not zero. Optional cost requires nonnegative amount, three-letter currency, and basis billed|reported|estimated.

Publish at most one finalized amount per provider attempt. Deduplicate delivery retries and subscription views. Never add a turn total to its constituent amounts. Failed attempts can have usage without a fabricated success. A model error is observation, not a retry instruction. Retry/fallback scheduling remains host-owned.

Enforcement limits

JSON Schema validates individual wire objects, not actual execution, final settlement, upload authorization, content completeness, cross-message ID equality, acyclic ancestry, aggregate accounting, native effect support, or delivery order. The static manifest and per-request capabilities MUST describe actual enforceable coverage. Generated codecs preserve JSON and are not canonical validators.

Identity and native boundary duties

Event identity is source-scoped. Optional sessions on ordinary tool and catalogue events do not justify fabricated sessions or turns for detached work. Session resumption retains identity; fork/clear origins use known links. Calls retain identity across before, permission, progress and completion; delegated calls have their own IDs. Event, session, turn, call, task, attempt/batch and content identities accept a boolean synthesized marker: synthesized identities carry true and stay stable for the entity’s lifetime. Parentage follows the lineage binding.

Retries preserve the exact subscription payload and identities; they are not new logical occurrences or provider attempts. Subscription-side-effect deduplication is distinct from logical occurrence identity. Separate explicit observe and intercept subscriptions on one backend are not duplicate deliveries. New provider attempts have distinct identities. No retry rule promises replay or durability.

Modified text parts retain logical identity and carry changed text inline; changed attachment bytes require a new immutable reference at their producing boundary, not an edit through a modification effect; new injections and newly created summaries receive new item identities. Startup instructions belong to session.start; expanded prompts and attachments belong to turn.start. Explicit skills and file reads use ordinary tools; implicit loads belong to the responsible lifecycle boundary. Report actual reads without reading additional files merely to report them. Reasoning stays attached to its owning assistant message and distinguishable from answers and summaries; provider-private reasoning, full transcripts and streaming are not required. Injection requests do not prove admission, sending or model consumption.

tool.before precedes invocation side effects and the permission stage. One tool.after represents a resolved call, whether executed, denied or supplied; error outcomes require event-level error and other outcomes exclude it. Output and error cannot coexist. tool.batch.after is one aggregate boundary after its calls resolve, not generic multi-event framing. Background launch completion and later delegated work are distinct. turn.finish.before is not turn.end; a turn ends only on real completion. Continuation into a new turn links the known requesting parent. Selected-model switches are not every per-call model choice; refusing a switch does not guarantee the previous model remains usable.

Tool kind is descriptive, not origin or authority; absent or unfamiliar kinds must not block processing or authorization. MCP descriptors preserve exact tool and server identity and runtime-selected destinations, not inferred name prefixes, gateway upstreams or cached inventories. Remove credentials, URL userinfo, headers/cookies and secret environment/argument values with honest gaps. Any retargeting requires effective-destination reauthorization.

Turn accounting includes known retries without double-counting. Supplied/skipped provider work does not fabricate usage, latency or file side effects. Errors do not promise another attempt. These are producer duties, not facts a receiver can infer from well-formed telemetry.