feat(runtime): thread real emitted events through LocalExecutor, retire output-JSON convention - #1053
Closed
enricopiovesan wants to merge 1 commit into
Closed
feat(runtime): thread real emitted events through LocalExecutor, retire output-JSON convention#1053enricopiovesan wants to merge 1 commit into
enricopiovesan wants to merge 1 commit into
Conversation
…re output-JSON convention
LocalExecutor::execute now returns LocalExecutionOutput { value, emitted_events }
instead of a bare Value, so both BoundLocalExecutor (PlacementRouter path) and
ArtifactRouter (workflow-internal node execution) carry real WASM-sourced
events instead of discarding them. Native-emitted events are validated against
the capability's `emits` list and Subscribable service_type before use.
workflows.rs now publishes to EventBroker and reads emitted events from the
structured field, removing the old JSON "emitted_events" key convention.
Migrates all ~21 LocalExecutor implementors across traverse-runtime,
traverse-mcp, and traverse-cli to the new return type.
Governing spec: 101-local-executor-event-emission (ADR-0037)
Closes #996
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Collaborator
Author
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
LocalExecutor::executereturned a bareValue, discarding any events anative or WASM-backed capability emitted during workflow-internal node
execution (
ArtifactRouter, used directly byworkflows.rs) and hardcodingemitted_events: Vec::new()on the livePlacementRouterpath(
BoundLocalExecutor).workflows.rsalso read a JSON"emitted_events"convention key out of the node output, rather than a structured field.
This PR extends
LocalExecutor::executeto returnLocalExecutionOutput { value, emitted_events: Vec<TraverseEvent> }, threadsreal WASM-sourced events through both call paths, validates natively-emitted
events against the capability's
emitsdeclaration andSubscribableservice_type before they're used for anything (mirroring
PlacementRouterStep 5's WASM-boundary validation), and publishesworkflow-node events to
EventBrokerforSubscribablecapabilities(best-effort — a publish failure does not fail the workflow step). The old
JSON
"emitted_events"convention key is removed. All ~21LocalExecutorimplementors across
traverse-runtime,traverse-mcp, andtraverse-cliare migrated to the new return type.
Governing Spec
101-local-executor-event-emission518-durable-local-datastore006-runtime-request-execution001-foundation-v0-1101-local-executor-event-emission(ADR-0037) is the primary spec; itgoverns
crates/traverse-runtime/src/{lib,artifact_router,workflows}.rs.518-durable-local-datastorecoverscrates/traverse-runtime/tests/.006-runtime-request-executioncoverscrates/traverse-runtime/examples/load_workspace_app_state.rs.001-foundation-v0-1coverscrates/traverse-cli/andcrates/traverse-mcp/(mechanicalLocalExecutorreturn-type migrationonly; no behavioral change to those crates).
Changes
LocalExecutionOutput { value, emitted_events }replaces the bareValuereturn type on
LocalExecutor::execute.BoundLocalExecutor(nativePlacementRouterpath) validates nativelyemitted events against
emits/Subscribablebefore returning them inExecutorOutput, soPlacementRouterStep 5 publishes real events insteadof the previous hardcoded empty vec.
ArtifactRouter::executereturns the realemitted_eventsfromWasmExecutor(already ABI-validated) instead of discarding them. It doesnot hold an
EventBrokeror publish internally — it's used both directlyby
workflows.rsand, viaBoundLocalExecutor, byPlacementRouter, sopublishing there would double-publish on the live
Runtime::execute()path.
workflows.rs'straverse_workflowvalidates natively-emitted events thesame way, publishes to
EventBrokerforSubscribablecapabilities(best-effort), and reads emitted events from
LocalExecutionOutput.emitted_eventsinstead of parsing a JSON"emitted_events"key out of the node output. The JSON-convention parserfunction is deleted.
LocalExecutorimplementors (production and test doubles) across theworkspace updated to the new return type.
Validation
cargo test --workspace— all suites green (traverse-runtime lib: 293tests, including 3 new
BoundLocalExecutor/PlacementRoutertests fordeclared/undeclared/non-Subscribable native events, 2 new
workflow-node →
EventBrokerpublish tests, and a newArtifactRouterreal-WASM-success test)
cargo clippy --workspace --all-targets -- -D warnings— cleancargo fmt --all --check— cleanbash scripts/ci/coverage_gate.sh— passed;traverse-runtime: 100.00% (19510/19510 lines),traverse-contracts: 100.00%,traverse-embedder: 100.00%,traverse-mcp: 98.89%,traverse-cli-rs: 87.16%,traverse-swift-host: 84.03%(all at or above their configured floor)BASE_SHA=origin/main bash scripts/ci/local_preflight.sh— pending