#FLOW Run/0
Status: prerelease specification candidate.
Run/0 is the finite executable boundary for a FLOW package. It deliberately does not expose a host's durable records, resolver, authority evidence, graph model, provider identities, or application ontology.
Invocation and cancellation use:
These are component entry and dependency invocation, respectively. They are
not separate top-level and child execution models: every launched component
receives flow/run, including a component selected through flow/call.
The caller supplies the dependency's input. The host constructs the selected
implementation's complete execution context under its local authority.
The channel extension adds component-to-host channel/create,
channel/subscribe, channel/send, channel/next, channel/close, and channel/release.
Channels carry bounded JSON values during work. They do not start work,
authorize control operations, or replace invocation results.
flow/run supplies the complete context to an already selected component.
flow/call asks the host to invoke one declared, admitted slot. The selected
implementation may be an ordinary Flow or a trusted native implementation.
These operations have distinct parameter shapes. Neither method names nor
interface equality grant authority. The host enforces the caller's actual
invocation authority before effects.
The end-to-end operation is Flow A running Flow B through the host:
A child is an invocation relationship, not a different kind of Flow package.
Every component receives the same flow/run entry request. Native
implementations need not create a Flow process. They retain the same call-level
input/result, authority, failure and owned-work obligations.
#1. Process and framing
One component process handles exactly one root flow/run request. The channel
is full-duplex JSON-RPC 2.0 over stdio. Here "root" means the owner request on
this component's channel, including when the host launched it as a child:
Each stdin or stdout frame is one JSON object encoded as UTF-8 and terminated
by one LF byte. The LF is not part of the frame payload. A frame has at most
16,777,216 bytes before LF. Empty frames, JSON-RPC batches, a BOM, invalid
UTF-8, duplicate object members, lone Unicode surrogates, and values outside
FLOW JSON/0 are invalid. EOF after nonempty bytes without LF
is an incomplete frame.
Both peers keep their reader active while awaiting responses. Writes are
serialized and flushed. A component may have at most 64 component-originated
requests awaiting responses at once. An SDK may queue additional calls rather
than put them on the wire. A host sends exactly one flow/run request.
Request IDs are 1–128 byte ASCII tokens matching:
Each sender chooses its own ID namespace and never reuses an ID during one
channel incarnation, including after the request settles. Opposite directions
may coincidentally use the same spelling. IDs correlate wire messages only.
They are not durable Run or operation identities. Numeric and null request
IDs are invalid in Run/0.
Each sender may originate at most 65,536 request-form messages during one channel incarnation. Settled and cancelled requests still consume this lifetime budget. Responses and notifications do not. A request with a fresh, structurally valid ID consumes the budget before method dispatch. This includes requests with unknown methods or invalid method params.
A conforming SDK rejects an attempted 65,537th outbound request locally with
RESOURCE_EXHAUSTED and emits no frame, so its root handler may recover. A
receiver which observes a 65,537th request records a fatal PROTOCOL_ERROR and
closes without relying on another response. This fixed lifetime bound is
separate from the limit of 64 unresolved component requests on the wire.
Channel implementations reserve at least one simultaneous request slot and enough remaining request IDs to close/release already allocated endpoints and pending allocations. Ordinary admission stops before consuming these reserves. Repeated failed settlement attempts cannot consume unlimited reserved capacity. Cancellation, host revocation and fencing never depend on a free ordinary slot.
Whenever a request or notification includes params, that member must be a
JSON object or array. null and scalar params make the complete JSON-RPC
envelope invalid. They are not method-level invalid parameters.
An unknown well-formed request method receives JSON-RPC -32601. A recognized
request with invalid params receives -32602. Unknown notifications are
ignored. The direction restrictions in this specification are part of method
validity.
A complete, bounded, LF-terminated, valid-UTF-8 frame may fail JSON/0.
For such a frame, a peer should best-effort send -32700 with id: null,
flush, and close. This
includes JSON syntax errors, a BOM, duplicate members, lone surrogates, and
out-of-domain JSON/0 numbers or value bounds. For a parsed batch, non-object,
or invalid JSON-RPC envelope, the peer should best-effort send an error, then close.
That error is -32600 with id: null or an unambiguous valid ID.
The following conditions close the channel without relying on another frame:
- Invalid UTF-8.
- An oversized or incomplete frame.
- An unknown/duplicate response.
- Reuse of a request ID.
- A failed write.
Every fatal close stops admission, cancels owned work, and fails local pending calls under this exact split:
PROTOCOL_ERRORmeans a detected framing, JSON/0, envelope, correlation, or protocol-state violation by the peer.CHANNEL_LOSTmeans EOF, read/write failure, or transport loss without a detected peer-protocol violation.
A valid standard JSON-RPC error received in response to a correctly emitted
Run/0 request proves that the peers disagree about the fixed protocol. It is a
fatal PROTOCOL_ERROR, not a per-call OperationError. A peer must never rely
on a best-effort error frame arriving over a corrupted channel.
State-dependent request handling is fixed as follows:
After sending its root terminal response, a component may immediately stop reading and exit. A host which sends later traffic is itself nonconforming and cannot require a response.
#2. Shared names and values
slot, channel names and Run outcome use the Package/0 LocalName grammar:
Their length is 1–64 ASCII characters. Whether an outcome is done or one of
the invocation contract's declared custom outcomes is checked against that contract,
not inferred from this wire grammar.
operationId uses the request-ID token grammar and limit. It is stable
semantic identity chosen by component code, not a transport ID generated by an
SDK.
All input, output, settings and operational error details are bounded
JSON/0 values. settings is always an object. Output is required, including
for a declared domain refusal. Use null when no more meaningful value exists.
deadlineUnixMs is a nonnegative JSON/0 safe integer containing the
host-authoritative UTC Unix epoch deadline in milliseconds. It is advisory to
component cleanup. The host remains responsible for cancellation and enforced
termination. Calls inherit the remaining root deadline
and cannot supply or widen one.
#3. flow/run
The host's only request is:
params has these required fields and optional channels:
channels, when present, maps at most 256 LocalName entries to distinct
host-granted endpoints defined below. Absence means an empty map.
Each attachment has required path and access, and an optional readonly
artifact reference as defined in section 4.1:
path is a nonempty runtime-native path inside the already prepared sandbox.
access is exactly read or read-write. The outer execution envelope, not
an SDK path helper, enforces the view. One Run has at most 256 named
attachments.
There is no Run ID, parent ID, trigger field, correlation field, provider
identity, slot inventory, enforcement receipt, or negotiated limit
object in Run/0. The initial profile accepts no operation selector. A triggering
fact belongs in input. Lifecycle and authority
evidence remain host-side.
A successful component result has required outcome and output, and only
optional artifactResults (section 4.1):
Protocol, execution, cancellation, deadline, provider, or uncertainty failures are JSON-RPC failures. They never masquerade as package outcomes.
#4. flow/call
While its root request is pending, the component may invoke a declared slot:
Params have exactly the required operationId, slot and input, plus
optional intent, channels and attachments. slot names one dependency declared by
Package/0 metadata's uses map. A host supplies its exact Flow or native
implementation. A slot is not a package address, implementation URI or request
for catalogue discovery. A named dependency must match the selected
Invocation Contract/0 and its complete channel closure.
intent is an optional 1–16,384 Unicode-scalar advisory string. It never becomes
application input, Agent instructions, provider arguments or authority. Exact
host routes may treat it as inert. Any host use must stay within the already
authorized slot meaning, without changing or forwarding the actual application
input or widening authority. Instructions belong in input.
Optional channels maps at most 256 callee-declared LocalNames to held
endpoint-reference strings. Omission and an explicit empty map remain distinct
operation content. Validate selected-operation requirements and actual grants
before atomic transfer or dispatch. Optional attachments supplies finite
immutable reads or fresh operation-owned outputs as defined below. There is no
method selector or operation selector in this initial profile.
A normal reply is directly the complete host CallResult:
Declared domain refusal is also a normal complete result, such as
{"outcome":"not-found","output":{"key":"missing"}} under an interface declaring
that outcome. No success-value wrapper, named-error envelope, unwrapping or
exception conversion exists. Operational failures use the existing JSON-RPC
error envelope.
Each call supplies bounded JSON/0 input and explicit channel rights, and returns a separately validated complete result. Interface identity cannot select trusted native control or retention capacity, or turn caller-manufactured data into host evidence. Every lifecycle owner uses the same admitted implementation and configuration, with no fallback after an explicit unsupported selection.
Ordinary Flow invocation is finite work under its own context. It does not merge
graphs or implicitly inherit settings, attachments or authority. Native routes
retain their own qualified execution and cleanup owners. Hosts may impose smaller
concurrency, depth, resources or retained-result budgets and report
RESOURCE_EXHAUSTED. The Run/0 identity, replay, cancellation and lifetime rules
still apply.
#4.1 Finite artifacts
An artifact is an immutable finite tree whose backing and rights are owned by
the host. An opaque reference is a request-token string (wireId: 1–128 ASCII
bytes). It is scoped to a live participant. Knowing or copying a spelling grants
no authority. References contain no portable path, ticket, storage policy or
host lifecycle identifier.
attachments, when present on flow/call, is a closed map of at most 256
callee-declared LocalName ports. Each value is exactly one of:
read borrows an immutable tree held by the caller into a declared read port.
create requests a fresh empty output at a declared read-write port for this
operation. Unknown ports, wrong modes, malformed values, released references
and references not held by the caller reject before effects. The host validates
all required ports and route permissions.
A static read and a supplied create may cover disjoint ports. Two sources for the same port are ambiguous and reject. No mutable output becomes a read grant while its writer is live.
The host CallResult contains required outcome and output, plus optional
artifacts, a map of at most 256 LocalNames to opaque references. Writable
port names identify sealed outputs. Declared result names identify explicitly
forwarded immutable outputs.
A usable grant is exposed only after domain result validation, immutable capture
and confirmed execution cleanup. A normal custom
outcome follows the same rules as done. An empty tree is valid. Operational
failure creates no newly usable grant.
The component's flow/run success has required outcome and output, plus
optional artifactResults, a map from declared result names to held references.
It cannot send host artifacts. Each selected name must occur in the invoked
contract's artifactResults array. Selection may be a subset, including empty.
The host validates participant rights, unreleased identity and declared names,
then forwards the same immutable tree without copying, resealing or granting
arbitrary rights. A result name must not collide with a writable output port.
Invocation result schemas validate only {outcome, output}. Host and handler
artifact envelopes are separately validated, never domain data.
Initial flow/run readonly attachments may additionally contain artifact,
an opaque scoped read reference. The SDK exposes it as a held object for onward
delegation. Writable attachments cannot contain artifact. The existing path
is only the prepared sandbox-local attachment view, not an artifact field or
portable reference. Hosts supporting artifact delegation supply a reference for
each initial readonly attachment.
Exact duplicate calls join before fresh output allocation and return the original complete outcome, output and artifact references. Changed mappings, including absent versus empty, conflict. Released references never regain initiation rights through replay: an exact settled duplicate may replay its original references, but cannot recreate grants or backing.
The optional advanced request flow/artifact/release has exactly
{operationId, artifact} and returns {}. It uses the same token grammar,
participant-scoped operation identity, join/conflict and cancellation settlement
rules as calls. Method is part of identity, so a call and release cannot reuse
one operation ID.
Releasing ends that participant's right to initiate new readers or forward the artifact. Readers already accepted, including siblings, retain their independent borrowed rights through settlement. Exact release duplicates return the original result. Release of an unheld reference rejects. An unsupported host returns method-not-found, never pretends to release.
Ordinary callers need no manual release. Root completion or cancellation automatically retires live rights after owned readers settle. A host may retain selected final bytes under its own result policy, but retention is not detached execution or a live participant grant. Cancelled call waiters retain wire settlement: late replies must still validate and any late artifact backing remains owned until automatic root cleanup. Neither an SDK cancellation nor a released caller right revokes an accepted sibling's read.
#5. Channels
This extension supports finite, single-writer JSON/0 sequences. A direct source has one receiver. A broadcast source has independently bounded subscriptions. Arbitrary byte transports, persistent streams and continuing Agent control are not part of this extension.
An endpoint grant is a closed object:
Endpoint possession grants only the indicated communication right. It is not
portable JSON authority: a string copied into ordinary input grants nothing.
The creating Run owns the source's lifetime. An unused endpoint may transfer
through an exact flow/call. Its cleanup owner does not change.
First local use claims a right. Inspecting metadata does not claim it.
Broadcast creation also grants subscription authority to the creating invocation only. Its opaque source reference uses the endpoint token grammar but is not an endpoint and cannot be transferred in a call map. Moving a writer does not move subscription authority.
Each successful subscription allocates a distinct reader starting at the next accepted sequence. Late subscriptions receive no history. Preallocated readers may lag even before their first read. Source sealing or failure prevents new subscriptions. All allocations count over the owner's lifetime. Releasing one does not replenish that allowance.
Before dispatch, the host atomically validates all mapped rights, declaration requirements, contracts, provider support, delivery, queued-prefix constraints and capacity. Within that atomic action, it then moves the rights and constructs the callee's grants. Rejected admission changes no rights.
Exact operation joins precede moved-right rejection. Changed mappings conflict. An SDK offer or failed final result does not establish whether rights moved. The host retains authoritative ownership. No cross-root connection, ambient lookup or late injection into an ungranted running participant is implied.
Disposing a receiver does not revoke its peer's unused send right. While the
source owner remains live and the source is neither failed nor sealed, that
sender remains transferable under those checks, even after receiver
disposal. For direct delivery, its sends and close still fail DISCONNECTED.
Transfer cannot revive delivery. Broadcast delivery continues for other readers
and permits later subscriptions while the source remains open.
A disposed receiver is not transferable. Required ports require a grant, not a guarantee that the peer remains available. This keeps observation disposal independent of whether producer admission wins or loses that race.
Creation defaults to direct delivery and generic JSON/0. Schemas use Schema/0.
contract is either a package-local ./path.json string or the closed object
{slot: LocalName, channel: LocalName}. The latter selects the named agreement
on that channel port in the invoking package's declared dependency contract.
Both names are at most 64 characters. Resolution MUST use the caller's captured
declaration and its offline closure, never a selected provider's files or a URL.
Missing declarations, missing ports or ports without a named agreement fail before allocation. Resolution neither invokes the slot nor grants endpoint or execution rights. Ordinary delivery and transfer checks still apply. Named references resolve only against the invoking package. Unsupported valid requests fail operationally before allocation or dispatch. Invalid RPC shapes retain the ordinary incompatibility rules.
The host assigns accepted sequences starting at one. Receivers validate a
contiguous interval from their immutable startSequence. A clean end equals
the last delivered sequence (startSequence - 1 for an empty interval).
There is one outstanding read and no SDK prefetch. Direct full queues exert
bounded sender pressure. Receiver disposal rejects pending and future sends
with DISCONNECTED.
Broadcast acceptance does not wait for readers. A reader exceeding its capacity
fails with sticky LAGGED, independently of the writer and other readers. A
reader-schema failure likewise affects only that subscription. With no readers,
accepted values advance sequence and source byte budget but are not retained.
Source-invalid or oversized values instead fail the entire source before
acceptance.
Source/writer constraints apply before per-reader validation. Adding a reader never adds its validator to a broadcast source. Connection admission still rejects known conflicting nontrivial writer/reader schemas in either binding order, including all staged mappings and existing live subscribers. The host bounds queues, retained/in-flight payload, pending sends, parser/writer buffers and lifetime allocations. A committed but unread response consumes receiver capacity until the next read releases its credit.
Clean writer close rejects while sends remain unaccepted. Otherwise it seals without waiting for the receiver or execution result. Accepted data can drain while the source owner lives. Failure before sealing aborts the source. Previously explicitly sealed intervals remain sealed despite subsequent producer failure. Neither sealing nor receiver EOF establishes execution success.
An owned writer may instead close with error:"LAGGED" to declare incomplete
delivery. This optional cause is a closed enumeration, not an arbitrary error
message or execution status. The host checks writer authority before changing
the source, records its sticky abnormal end, rejects pending sends and wakes
all still-active receivers with LAGGED. This abnormal close is allowed while
sends remain pending. Their operations still settle separately. Repeating the
same abnormal close joins that end.
An earlier explicit clean seal cannot be rewritten into a failure:
such a later abnormal close rejects INVALID_INPUT.
A prior source failure stays authoritative. Receiver disposal and committed
read responses keep their ordinary ordering rules.
The producer's declaration establishes only incomplete observation. It does not cancel producer execution or supply host-authenticated process, authority, or cleanup evidence. Ordinary calls and language-level failure recovery are unchanged.
Failure discards only uncommitted queued values. A committed read response may still arrive. The next read or release reports the sticky cause. Revocation and clean-end commitment are atomically ordered by the host. Local read cancellation may win before SDK end exposure. Root cancellation independently prevents execution success.
Cancelling an active read disposes its receiver. The SDK retains and drains the original read response and disposal response. It cannot restart iteration after silently skipping a committed item. Cancelling a send retracts only an unaccepted pending value, never an accepted value or permission to replay it. Cancelling a close/release wait retains its settlement action.
Cancelling a creation or subscription wait does not prove that no allocation occurred. The SDK retains the wire response and disposes any late grants before completion. It cannot lose or replay an uncertain allocation. A newly allocated broadcast receiver is active owned work even if never read. Its holder must finish or dispose it. Finalization cannot silently turn abandonment into success.
Uncancelled receiver disposal waits for its response and all prior reads. It exposes a previously unexposed terminal failure even if a read waiter was cancelled before that failure arrived. An internally known cause is not exposed until a public operation rejects/raises with it. Repeated disposal joins the same action and does not rethrow an already exposed cause. Disposal that wins before an earlier source failure means deliberate incomplete delivery, not a new failure. Observation cancellation does not cancel producer execution.
Independent readers/writers must remain serviced while operations are pending. A blocked transport cannot prevent other participants' progress or host fencing. Control has priority only between complete frames. No delivery is promised over a broken or persistently blocked pipe.
#6. Operation identity
operationId belongs to the authenticated invoking participant, not the whole
root tree. Siblings reusing one spelling never share an operation. A supplied
caller/session ID is ordinary data and cannot choose that identity scope.
Canonical equality compares this exact byte sequence:
The separator is one NUL byte. Remove only operationId. Preserve all other
members and optional-key presence.
Slot, actual input, advisory intent and channel and attachment mappings retain
distinct meaning. Omitted channels and channels:{}
conflict under one identity. There is no empty-map or schema-default
normalization. Transport request IDs and wait timing are not semantic input.
The operation remains bound to its authenticated caller and the exact admitted implementation, configuration and grants selected for it. A duplicate must not re-resolve that selection. An authenticated exact duplicate can join without transferring already moved endpoints again. It cannot resurrect revoked rights or join another caller. Changing the slot conflicts even when both slots resolve to the same package or interface. New operations validate all actual rights, resources, support and endpoint requirements before atomic transfer and dispatch.
The host chooses persistence. Run/0 defines no ledger schema, public call hash, global registry, internal activation ID or recovery database.
Each transport request is one waiter even when several requests join the same
operation. Cancelling one request settles or removes only that waiter. It does
not cancel another waiter. The receiver may request cancellation of shared
underlying work only after no live waiter remains. A terminal operation result
which won the receiver's atomic race may still settle a concurrent
cancellation. Otherwise the cancelled waiter receives CANCELLED while other
waiters remain attached.
An operation is never automatically replayed after unprovable dispatch.
Uncertain completion is returned as UNCERTAIN. A deliberate new attempt uses
a new operationId.
#7. Errors
Run/0 uses standard JSON-RPC -32700, -32600, -32601, -32602, and
-32603 with their standard meanings. Operational failures use numeric code
-32000 and this exact data shape:
details is optional bounded JSON/0 diagnostic data. message is required by
JSON-RPC, contains 1–1,024 Unicode scalar values, and is non-normative human
text. The closed wire-visible code set is:
JSON-RPC -32602 means the Run/0 method params themselves are invalid.
INVALID_INPUT is downstream application validation. JSON-RPC -32603 means
the peer failed while processing the protocol. EXECUTION_FAILED means the
admitted application work failed.
Every request has one atomic terminal decision. A committed result or error
wins a later cancellation or deadline observation. Otherwise the first
recorded cancellation/deadline terminal condition determines CANCELLED or
DEADLINE_EXCEEDED. No peer sends two terminal responses.
That decision fixes the request-level result or error. Overall Run acceptance also requires the clean process completion described in Section 9.
Host-internal distinctions such as which host binding, provider, runtime selection, or execution envelope was unavailable belong in durable host diagnostics, not the portable error taxonomy. Activation failures which occur before a channel exists are not Run/0 errors.
PROTOCOL_ERROR and CHANNEL_LOST are local terminal classifications, not
-32000 values sent over a channel which can no longer be trusted. The
machine-readable registry is
run-0-errors.json.
#8. Cancellation
The originator of a pending request may send this notification:
It has no id and receives no response. A valid target must have been
originated by the notifier on this channel. Duplicate, stale, already-terminal,
unknown, and opposite-direction targets are harmless no-ops because response
and cancellation may race. A malformed cancellation notification is fatal:
the sender cannot safely assume it requested cancellation.
Cancellation closes new work for that request and asks the receiver to stop. It does not prove that dispatched external work was undone. The original request still receives at most one eventual result or error if the channel survives.
Root cancellation applies to the complete component-owned subtree. An SDK must propagate it to the handler and cancel its pending outbound waits. The host enforces the deadline and terminates an uncooperative process after its private grace policy.
#9. Completion and exit
The component admits outbound calls only while flow/run is pending. It must
settle every outbound request before returning the root result or error. Calls
cannot be detached, reparented, or transferred. A normal root response with
outstanding owned work cannot become success.
Recoverable settled failures use ordinary language recovery. There is no error acknowledgement or global settled-failure ledger. An ignored, already-settled recoverable failure may escape detection. Fatal loss of this invocation's transport, root cancellation, unresolved ownership or failed cleanup still prevent success. A child that is conclusively fenced and cleaned may instead return a recoverable parent-local operational error. Fatality follows the affected owner, not a word in an error message.
Before implicit writer sealing, account for handler error or invalid result, fatal/cancellation state, abandoned live work and active unfinished receivers. Capture abandonment at handler settlement. Cleanup does not erase it. Resolve retained cancellation/disposal accounting and recheck eligibility. The host, which knows actual endpoint transfers and source state, seals only healthy held writers after eligibility. A known disqualifier aborts unsealed sources.
A wholly unused unconnected pair can be released automatically. An activated receiver must reach end, terminal failure or explicit disposal. Recheck fatal and cancellation state before accepting the execution terminal.
The host must keep the component's stdin open while the root request is pending. After receiving and validating the complete root terminal response, it may close that sending half immediately. The component must tolerate this causally later half-close.
Component stdin and stdout are independent byte streams. Run/0 infers no physical wall-clock ordering between them. The component locally linearizes a terminal response by claiming publication immediately before its serialized transport write begins.
An stdin EOF, framing failure, or fatal protocol condition can prevent the root response. It does so only when the component's protocol state machine atomically claims it before that publication claim.
Once publication has started, later stdin state cannot overturn it: the complete write and
runtime-buffer flush wins, while a write failure is CHANNEL_LOST. Flush is
not fsync, a peer acknowledgement, or proof that the host received the
frame.
Kernel or runtime buffering does not establish cross-pipe order. Bytes merely read or queued by the transport have no priority. After publication starts, the component may stop reading. Unread or subsequently observed host input has no response guarantee.
After receiving a root response, the host continues draining component stdout and awaits process termination. It accepts the Run only when all these conditions hold:
- The response is valid and correlated.
- No component-originated request remains pending.
- Stdout ends on a frame boundary with no trailing bytes or frames.
- The process exits zero.
The supervising host classifies premature termination deterministically:
- a host-enforced kill after a recorded cancellation or deadline is
CANCELLEDorDEADLINE_EXCEEDEDrespectively, unless a terminal response had already won. - a detected peer-protocol violation is
PROTOCOL_ERROR. - a nonzero process exit without either condition is
EXECUTION_FAILED. - component-stdout EOF, transport loss, or a zero exit before a complete
response is
CHANNEL_LOST.
A response fixes the request decision but does not by itself satisfy those
acceptance conditions. A nonzero exit, pending owned work, invalid output,
trailing component bytes or frames, or a post-response shutdown kill prevents
overall success. A post-response shutdown kill is an EXECUTION_FAILED
lifecycle failure rather than a later cancellation or request deadline winning
the already-fixed request decision. Cleanup failure must surface through
process exit. There is no hidden cleanup-acknowledgement protocol.
#10. Machine interface and SDK projection
The closed message schema is
run-0.json. Direction and response
correlation remain protocol state and cannot be proven by a context-free JSON
Schema document. Framing and JSON/0 validation happen before schema validation.
The TypeScript package @jigging/flow and Python distribution/import
jiggy-flow/jiggy.flow expose the same semantic surface:
They do not expose JSON-RPC envelopes, transport IDs, pending tables,
resolution, host bindings, providers, schema loading, sandboxes,
administration controls, Services, Agents, or graph types. operationId
remains caller-supplied.
The exact language projections and their cancellation/error behavior are
closed in Run SDK/0.
The corpus under conformance/run-0/ provides executable evidence for this
candidate through separately implemented TypeScript and Python participants.
Passing that repository corpus is not a certification of a third-party
implementation.