OpenWOP openwop.dev
FieldValue
RFC0040
TitleMulti-agent execution model Phase 3: cross-host causation linking + W3C tracecontext propagation across composition boundaries + cross-host run-ID resolution
StatusAccepted
Author(s)David Tufts (@davidscotttufts)
Created2026-05-22
Updated2026-05-24 (Active → Accepted: first non-steward host advertises version: 3 + the full crossHostCausation sub-block end-to-end. MyndHyve workflow-runtime advertises capabilities.multiAgent.executionModel.{version: 3, crossHostCausation: {supported: true, hostId: 'myndhyve', ancestryEndpointSupported: true}} live on https://api.myndhyve.ai/.well-known/openwop (verified 2026-05-24 via direct curl). MyndHyve commit f281549f (Cloud Run revision workflow-runtime-00198-q48) closes Sessions 5c+5d+5e: sqlite-reference-host MCP peer with distinct hostId: 'sqlite-reference' (closes the self-loop tautology that would otherwise have MyndHyve calling itself) + core.conformance.mcp-invoke conformance node + version: 3 discovery advertise + outbound traceparent injection on every outbound HTTP through ServerHttpClientAdapter.fetch (single injection point covers AI providers, webhook deliveries, conformance test seams, MCP outbound). The GET /v1/runs/{runId}/ancestry endpoint is registered and serving (returns JSON {"error":"Not found"} for unknown runIds — distinct from the bare 404 it would have returned if unregistered). cross-host-causation-shape.test.ts + cross-host-ancestry-endpoint.test.ts pass per MyndHyve's report. cross-host-traceparent-propagation.test.ts stays it.todo upstream — MyndHyve calling-side + sqlite-host receiving-side both ready, waiting on the cross-host harness driver landing on this side. Per the bootstrap-phase rule (advertisement + scenarios pass-modulo-honest-skip), graduates Active → Accepted. 2026-05-22 prior: Draft → Active same-day. The multi-agent execution model roadmap (Phases 1-4) now has Phases 1+2+3 Accepted end-to-end on a non-steward host; Phase 4 (RFC 0041) remains Active.)
Affectsspec/v1/multi-agent-execution.md (extends with §"Cross-host causation (Phase 3, normative)" + §"Agent memory lifecycle across sub-runs (RFC 0039 Phase 2, normative)") · schemas/run-event-payloads.schema.json (additive causationHostId field on all 10 causationId-bearing payload shapes per §A) · schemas/capabilities.schema.json (bumps multiAgent.executionModel.version ceiling effective range to include 3; adds optional crossHostCausation block) · schemas/run-ancestry-response.schema.json (new) · api/openapi.yaml (getRunAncestry operation) · 4 new conformance scenarios · CHANGELOG. Follow-up (deferred): spec/v1/observability.md §"Trust boundary + redaction" cross-host extension; spec/v1/mcp-integration.md + spec/v1/a2a-integration.md tracecontext propagation prose; INTEROP-MATRIX.md host-row updates; host-side wiring (ancestry endpoint impl + traceparent injection in the reference workflow-engine's MCP + A2A composition). The protocol-layer contract is complete; the follow-ups are documentation + impl, not new normative surface.
Compatibilityadditive
Supersedes
Superseded by

Summary

Closes 3 open spec gaps from RFC 0037 §"Open spec gaps":

  • MAE-4 (causationId cross-host scope): extends causationId to span hosts (currently single-host scope per spec/v1/replay.md §"Determinism with non-deterministic agents").
  • MAE-5 (W3C tracecontext across MCP/A2A): normates W3C tracecontext propagation across the MCP/A2A composition boundary (partial coverage exists in RFCS/0023-conformance-agent-event-emitters.md for OTel; this normates the cross-host case).
  • MAE-6 (cross-host run-ID resolution): defines the discoverable identifier chain when host A's run dispatches to host B (e.g., via MCP composition or A2A handoff).

Bumps multiAgent.executionModel.version from 2 (Phase 2, RFC 0039) to 3 (Phase 3, this RFC) when implemented. Phase 1 + Phase 2 hosts continue to advertise their existing version. Hosts that implement Phase 3 advertise version: 3 and conform to additional MUSTs.

Motivation

RFC 0037 Phase 1 normated the per-host execution loop. RFC 0039 Phase 2 normated confidence escalation + same-host memory lifecycle. Neither addresses what happens when a workflow crosses a host boundary:

  • A workflow on host A invokes an MCP tool whose implementation lives on host B; events host B's tool emits ought to chain back to host A's originating run — §A makes that wire-shape explicit.
  • An A2A peer on host B sends a message to host A's agent; the receiving agent needs a discoverable path to walk the causation chain back to the sender's originating event — §C's ancestry endpoint provides it.
  • A core.subWorkflow dispatch can target a workflow registered on a different host (per host-extensions.md §"Canonical prefixes" + a future cross-host dispatch contract).

Without normated cross-host causation:

  • OTel traces don't survive the composition boundary; debug-bundle exports lose causal context.
  • Replay-from-fork against a run that touched a cross-host call cannot deterministically reproduce the call's causation chain.
  • Cross-host workflow run-IDs are opaque; clients can't discover the parent run when given only a child run-ID from a different host.

The external standards-readiness review of 2026-05-21 finding (3) called out cross-host causality as part of the "multi-agent semantics not fully portable" gap. RFC 0037 Phase 1 closed the per-host half; RFC 0039 Phase 2 closed the same-host-memory half; this RFC closes the cross-host half.

Proposal — Phased

Like RFC 0037 + 0039, this RFC stages its surface so the comment window can converge.

§A — causationHostId field on cross-host event payloads (normative when Phase 3 advertised)

Add an optional causationHostId: string field to every event payload shape that carries causationId today. When the causationId points at an event on the SAME host, causationHostId is absent (existing semantics). When the causationId points at an event on a DIFFERENT host, causationHostId MUST be present and MUST equal the originating host's /.well-known/openwop advertisement's host.id (a new optional capability field also added by this RFC — see §D below).

Affected payload shapes: agent.reasoned, agent.toolCalled, agent.toolReturned, agent.handoff, agent.decided, runOrchestrator.decided, core.workflowChain.event, core.workflowChain.confidence-escalated, prompt.composed, agent.promptResolved. The field is additive on every shape; existing consumers that ignore unknown fields continue to work.

§B — W3C tracecontext across MCP + A2A composition (normative when Phase 3 advertised)

Extend spec/v1/mcp-integration.md §"Trust boundary" with: hosts that dispatch MCP tool calls AND advertise multiAgent.executionModel.version >= 3 MUST inject the parent run's W3C traceparent header into the outbound MCP request envelope. The MCP tool's host MUST honor the inbound traceparent as the parent trace for any spans it emits. The same rule applies symmetrically to a2a-integration.md: outbound A2A messages MUST carry the parent run's traceparent; inbound A2A handlers MUST adopt it as the trace parent.

This extends the per-host trace propagation already covered by RFC 0023 (otel-trace-propagation-subworkflow.test.ts) to cross-host composition.

§C — Cross-host run-ID resolution (normative when Phase 3 advertised)

Define a normative response shape for GET /v1/runs/{runId}/ancestry (NEW endpoint) returning the cross-host parent chain:

{
  "runId": "current-host-run-id",
  "hostId": "current-host-id",
  "parent": {
    "runId": "parent-host-run-id",
    "hostId": "parent-host-id",
    "wellKnownUrl": "https://parent.example.com/.well-known/openwop",
    "cause": "mcp-tool-call" | "a2a-message" | "core.subWorkflow"
  } | null
}

parent: null means the current run is a top-level run (not dispatched from another host). When the parent is on the same host, wellKnownUrl is absent (existing single-host case). When the parent is on a different host, wellKnownUrl MUST be set so a client can resolve the chain by walking the URLs.

§D — Capability advertisement

   "multiAgent": {
     "executionModel": {
       ...,
+      "crossHostCausation": {
+        "type": "object",
+        "additionalProperties": false,
+        "required": ["supported"],
+        "properties": {
+          "supported": { "type": "boolean" },
+          "hostId": {
+            "type": "string",
+            "minLength": 1,
+            "description": "Stable identifier for this host instance, used as the `causationHostId` value on cross-host events. SHOULD be a URL or DNS-style identifier (e.g., `myndhyve.ai/workflow-runtime`)."
+          },
+          "ancestryEndpointSupported": {
+            "type": "boolean",
+            "description": "Host serves the GET /v1/runs/{runId}/ancestry endpoint per §C."
+          }
+        }
+      }
     }
   }

Hosts advertising multiAgent.executionModel.version: 3 MUST also advertise crossHostCausation.supported: true and provide a stable hostId.

Compatibility

Additive. Hosts advertising version: 1 or version: 2 continue unchanged. Hosts upgrading to version: 3 add:

  • A new optional payload field (causationHostId) that pre-Phase-3 consumers ignore.
  • A new endpoint (GET /v1/runs/{runId}/ancestry) that pre-Phase-3 clients don't call.
  • A new capability sub-block (crossHostCausation) that pre-Phase-3 clients ignore.
  • New normative MUSTs on existing endpoints (MCP/A2A tracecontext propagation) — additive in that they only fire when the host dispatches via those surfaces AND advertises version: 3.

Conformance

3 new conformance scenarios:

  • cross-host-causation-traceparent.test.ts — capability-gated on multiAgent.executionModel.version >= 3 AND OPENWOP_TEST_MCP_REAL_SERVER_URL set. Drives an MCP tool call from the host and asserts the outbound request carries the parent run's traceparent.
  • cross-host-ancestry-endpoint.test.ts — capability-gated on crossHostCausation.ancestryEndpointSupported: true. Creates a run dispatched from a synthetic cross-host fixture; asserts GET /v1/runs/{runId}/ancestry returns the parent chain with wellKnownUrl set.
  • cross-host-causation-payload.test.ts — capability-gated. Asserts that when a cross-host event is emitted (e.g., an MCP tool reply), the host's event log entry includes causationHostId pointing at the originating host.

Alternatives considered

1. Skip causationHostId and rely on URL-namespaced causationId values (e.g., https://host-a.example.com/runs/.../events/123). Rejected — causationId is opaque-string per the existing event-log schema; clients shouldn't need to URL-parse to discover cross-host context. A sibling field is cleaner. 2. Define a separate cross-host RunEventType (run.crossHostCausation) instead of extending existing payload shapes. Rejected — would force consumers to learn a new event type AND walk through cross-host events to reconstruct chains. Extending the existing payload shapes is denser and preserves consumer code. 3. Defer to a separate "federation" RFC. Rejected — cross-host causation is the load-bearing piece of multi-agent portability; deferring it perpetuates the standards-readiness gap.

Unresolved questions

1. hostId format. SHOULD be URL-or-DNS-style but not strictly normated. A future clarification may tighten to a pattern matching ^[a-z0-9]+(\.[a-z0-9-]+)+/[a-z0-9-]+$. 2. Ancestry endpoint pagination. A run dispatched through 10 hosts has a 10-deep parent chain. Should GET /v1/runs/{runId}/ancestry return the full chain or just the immediate parent? Defer to comment-window discussion; current proposal returns immediate parent only. 3. Replay across the cross-host boundary. Phase 4 (RFCS/0041) covers replay-under-nondeterminism; the cross-host-replay-determinism intersection might warrant a dedicated note in the §C ancestry endpoint contract — defer to comment-window discussion.

Acceptance criteria

  • [x] Spec text merged (this file).
  • [x] spec/v1/multi-agent-execution.md extended with §"Cross-host causation (Phase 3, normative)" per §A + §B + §C.
  • [ ] spec/v1/mcp-integration.md + spec/v1/a2a-integration.md extended with §"Tracecontext propagation (RFC 0040)" per §B. (Follow-up — protocol-layer contract is in multi-agent-execution.md; the per-composition-doc cross-links are documentation strengthening, not normative gate-blockers.)
  • [x] schemas/capabilities.schema.json extends multiAgent.executionModel with the crossHostCausation block per §D.
  • [x] schemas/run-event-payloads.schema.json adds optional causationHostId to all listed payload shapes.
  • [x] api/openapi.yaml gains GET /v1/runs/{runId}/ancestry endpoint per §C; response schema in schemas/run-ancestry-response.schema.json (NEW).
  • [x] 3 new conformance scenarios per §Conformance — cross-host-causation-shape.test.ts, cross-host-ancestry-endpoint.test.ts, cross-host-traceparent-propagation.test.ts. Shipped in @openwop/openwop-conformance@1.5.0.
  • [x] At least one non-steward host advertises version: 3 + passes the scenarios — MyndHyve workflow-runtime advertises capabilities.multiAgent.executionModel.{version: 3, crossHostCausation: {supported: true, hostId: 'myndhyve', ancestryEndpointSupported: true}} on Cloud Run revision workflow-runtime-00198-q48 (commit f281549f). cross-host-causation-shape.test.ts + cross-host-ancestry-endpoint.test.ts PASS per MyndHyve's report. cross-host-traceparent-propagation.test.ts stays it.todo upstream — MyndHyve calling-side + sqlite-reference-host receiving-side both ready, waiting on the cross-host harness driver landing on this side. Per the bootstrap-phase rule (advertisement + scenarios pass-modulo-honest-skip), the bar is met.
  • [x] INTEROP-MATRIX.md updated — see §"Third-party host adoption — RFC 0040 (cross-host causation) external-validation gate (2026-05-24)" (lands in the commit promoting this RFC).
  • [x] CHANGELOG entry under [Unreleased].

Path to Active → Accepted: cross-host advertisement evidence per RFCs/0001-rfc-process.md §"Promotion to Accepted."

Landing log

2026-05-22 — Draft → Active. Phase 3 protocol-layer surface landed atomically following the RFC 0034/0037/0039 pattern (steward repo, bootstrap-phase exception). Files that shipped:

  • spec/v1/multi-agent-execution.md — §"Cross-host causation (RFC 0040 Phase 3, normative)" with §A causationHostId field contract, §B W3C tracecontext propagation across MCP + A2A composition, §C ancestry endpoint contract. Also §"Agent memory lifecycle across sub-runs (RFC 0039 Phase 2, normative)" — RFC 0039 prose landed in the same commit (the §B normative section for MAE-2 + MAE-3 had not previously been prosed).
  • schemas/capabilities.schema.jsonmultiAgent.executionModel.crossHostCausation.{supported, hostId, ancestryEndpointSupported} sub-block per §D.
  • schemas/run-event-payloads.schema.json — optional causationHostId field added to all 10 causationId-bearing payload shapes per §A: coreWorkflowChainEvent, coreWorkflowChainConfidenceEscalated, agentReasoned, agentToolCalled, agentToolReturned, agentHandoff, agentDecided, runOrchestratorDecided, promptComposed, agentPromptResolved.
  • schemas/run-ancestry-response.schema.json — NEW. §C endpoint response shape.
  • api/openapi.yamlgetRunAncestry operation at GET /v1/runs/{runId}/ancestry.
  • 4 conformance scenarios: cross-host-causation-shape.test.ts (advertisement-shape probe, always-on when discovery reachable), cross-host-ancestry-endpoint.test.ts (behavioral: top-level run + 404-on-non-advertise), cross-host-traceparent-propagation.test.ts (behavioral, gated on OPENWOP_MCP_REAL_SERVER_URL / OPENWOP_A2A_REAL_PEER_URL peer harness), multi-agent-memory-lifecycle.test.ts (RFC 0039 §B advertisement-shape + behavioral stubs).
  • CHANGELOG entry under [Unreleased].

Deferred to follow-up: host-side wiring (ancestry endpoint impl + traceparent injection in the reference workflow-engine's MCP + A2A composition), observability.md §"Trust boundary + redaction" cross-host case, mcp-integration.md + a2a-integration.md tracecontext propagation prose, INTEROP-MATRIX.md host-row update. The protocol-layer contract is complete; the deferred items are documentation rendering + implementation, not new normative surface.

References