Getting started
Quickstart
- Build the current runtime and inspect a governed bundle. This path works with Traverse v0.16.1 and Rust 1.95 or later.
+ Build the current runtime and inspect a governed bundle. This path works with Traverse v0.16.2 and Rust 1.95 or later.
git clone https://github.com/traverse-framework/traverse.git
cd traverse
cargo build
diff --git a/src/pages/index.astro b/src/pages/index.astro
index b6c7e04..185e9d0 100644
--- a/src/pages/index.astro
+++ b/src/pages/index.astro
@@ -1,8 +1,8 @@
---
import BaseLayout from '@layouts/BaseLayout.astro';
-const _body = "\n\n \n \n
\n \n v0.16.1 · Apache 2.0 · Open source\n
\n
\n Governed capability runtime.\n
\n
Discover, execute, trace.
\n
\n Write business logic once as WASM and run it on every host. Agents propose, the runtime decides.\n
\n
\n
\n\n\n\n\n \n
\n \n
\n
\n \n
\n
[capability]\nname = \"calculate-price\"\nversion = \"1.2.0\"\nwasm = \"pricing.wasm\"\n\n[governing_spec]\ntitle = \"Pricing Policy v3\"\nsource = \"docs/pricing-policy.md\"\n\n[input]\ntype = \"object\"\nproperties.sku = \"string\"\nproperties.quantity = \"integer\"\nproperties.region = \"string\"\nrequired = [\"sku\", \"quantity\"]\n\n[output]\ntype = \"object\"\nproperties.total = \"number\"\nproperties.currency = \"string\"\nrequired = [\"total\", \"currency\"]
\n
\n
\n
\n
\n \n
\n
$traverse run pricing --input '{\"sku\":\"PRO\",\"quantity\":5}'
\n
✓ Contract validated
\n
✓ WASM executed (2.1ms)
\n
→ {\"total\": 249.95, \"currency\": \"USD\"}
\n
\n
\n
\n
\n\n \n
\n
How Traverse works
\n
\n Write a contract.
Ship a capability.\n
\n
\n Three steps from idea to portable, contract-governed business logic on the hosts that have shipped.\n
\n
\n
\n
01
\n
\n
Define the contract
\n
Write a TOML file with your capability name, the WASM binary path, and JSON Schema definitions for inputs and outputs. Link it to the governing spec document your team actually works from.
\n
\n
\n
\n
02
\n
\n
Author the capability
\n
Skill-first, so you don’t have to write Rust. Usual path: describe it in plain English and the Claude skill traverse-capability-author drafts the contract, builds the WASM, and opens a human-reviewed PR. The manual path is still Rust compiled to wasm32-wasip1. Same artifact on every embedder.
\n
\n
\n
\n
03
\n
\n
Register and run
\n
Add the capability to the registry with traverse add. Call it from the CLI, from an AI agent via MCP, or from your app directly. Every call is validated and traced.
\n
\n
\n
\n
\n
\n
\n\n\n\n\n \n \n
\n
\n
\n
Contract-first validation
\n
Every capability call validates inputs against a JSON Schema precondition before execution. Postconditions validate the output. Bad data never reaches your logic.
\n
\n
\n
\n
WASM sandbox isolation
\n
Each capability runs in its own Wasmtime WASM instance with linear memory isolation. A capability cannot access host resources it was not explicitly granted.
\n
\n
\n
\n
AI agent integration
\n
Expose your entire capability registry to AI agents via the MCP stdio server. Claude, GPT-4, and any MCP-compatible agent can discover and call capabilities safely.
\n
\n
\n
\n
Honest host surface
\n
Shipped today: native (Linux/macOS/Windows) and browser via traverse-embedder-web. Swift, Kotlin, and .NET packages are published, pre-1.0, and not Certified. Edge is planned; cloud placement is an explicit non-goal for v0.1. See Platforms.
\n
\n
\n
\n
Trace artifacts
\n
Every execution produces a trace artifact: the input, the output, the contract version, and a timestamp. Audit any past run without re-executing anything.
\n
\n
\n
\n
Policy paper trail
\n
Every contract can link to the policy document it implements. Specs are honesty hygiene for the codebase, not the product pitch, and not a count to advertise.
\n
\n
\n
\n\n\n\n\n \n
Watch a workflow get composed, live.
\n
Your browser fetches the real capability registry, and a client-side heuristic (not a hosted AI model) chains matching capabilities into a workflow. No fixtures, no precomputed data.
\n
Watch the live demo\n
\n\n\n\n\n \n \n
\n
\n
1
\n
Shared
runtime.wasm orchestrator. Embedders are clients. Shipped targets are on
Platforms.
\n
\n
\n
0
\n
Logic rewrites between shipped hosts. Same contract, same binary, same behavior. (Not a claim about mobile packages, edge, or cloud.)
\n
\n
\n
2ms
\n
Typical contract execution time on the local target. WASM startup is fast. Contract validation adds negligible overhead.
\n
\n
\n
\n\n\n\n\n \n \n
\n
\n
\n
Pricing and discount logic
\n
Encode complex pricing rules as a contract with a link to your pricing policy document. The same capability runs via the published Web embedder, native/CLI hosts, and MCP agents with identical results: where those surfaces are shipped.
\n
Learn more\n
\n
\n
\n
Eligibility and access rules
\n
Run eligibility logic as a sandboxed WASM capability so an AI agent can check a user's eligibility for a product, service, or feature without risk of hallucinating the answer.
\n
Learn more\n
\n
\n
\n
Compliance and audit logic
\n
Capture regulatory and compliance rules in versioned contracts with governing spec links. Every execution is traced. Auditors can replay any historical decision from the trace artifact.
\n
Learn more\n
\n
\n
\n
AI agent guardrails
\n
Give your AI agents a set of contract-governed capabilities to call. The agent cannot exceed the contract's boundaries. Postcondition checks block invalid outputs before they propagate.
\n
Learn more\n
\n
\n
\n\n\n\n\n
\n
\n
Start building with Traverse
\n
Install the CLI, write your first contract, and run it in under five minutes.
\n
\n
\n
\n\n";
-const _jsonLd = "{\"@context\":\"https://schema.org\",\"@type\":\"SoftwareApplication\",\"name\":\"Traverse\",\"description\":\"A governed capability runtime: discover → execute → trace. Skill-first authoring via traverse-capability-author; one shared runtime.wasm; shipped clients are browser, native desktop, CLI, and MCP. The agent proposes; the runtime decides.\",\"url\":\"https://traverse-framework.com\",\"author\":{\"@type\":\"Person\",\"name\":\"Enrico Piovesan\"},\"license\":\"https://www.apache.org/licenses/LICENSE-2.0\",\"applicationCategory\":\"DeveloperApplication\",\"softwareVersion\":\"0.16.1\",\"codeRepository\":\"https://github.com/traverse-framework/traverse\"}";
+const _body = "\n\n \n \n
\n \n v0.16.2 · Apache 2.0 · Open source\n
\n
\n Governed capability runtime.\n
\n
Discover, execute, trace.
\n
\n Write business logic once as WASM and run it on every host. Agents propose, the runtime decides.\n
\n
\n
\n\n\n\n\n \n
\n \n
\n
\n \n
\n
[capability]\nname = \"calculate-price\"\nversion = \"1.2.0\"\nwasm = \"pricing.wasm\"\n\n[governing_spec]\ntitle = \"Pricing Policy v3\"\nsource = \"docs/pricing-policy.md\"\n\n[input]\ntype = \"object\"\nproperties.sku = \"string\"\nproperties.quantity = \"integer\"\nproperties.region = \"string\"\nrequired = [\"sku\", \"quantity\"]\n\n[output]\ntype = \"object\"\nproperties.total = \"number\"\nproperties.currency = \"string\"\nrequired = [\"total\", \"currency\"]
\n
\n
\n
\n
\n \n
\n
$traverse run pricing --input '{\"sku\":\"PRO\",\"quantity\":5}'
\n
✓ Contract validated
\n
✓ WASM executed (2.1ms)
\n
→ {\"total\": 249.95, \"currency\": \"USD\"}
\n
\n
\n
\n
\n\n \n
\n
How Traverse works
\n
\n Write a contract.
Ship a capability.\n
\n
\n Three steps from idea to portable, contract-governed business logic on the hosts that have shipped.\n
\n
\n
\n
01
\n
\n
Define the contract
\n
Write a TOML file with your capability name, the WASM binary path, and JSON Schema definitions for inputs and outputs. Link it to the governing spec document your team actually works from.
\n
\n
\n
\n
02
\n
\n
Author the capability
\n
Skill-first, so you don’t have to write Rust. Usual path: describe it in plain English and the Claude skill traverse-capability-author drafts the contract, builds the WASM, and opens a human-reviewed PR. The manual path is still Rust compiled to wasm32-wasip1. Same artifact on every embedder.
\n
\n
\n
\n
03
\n
\n
Register and run
\n
Add the capability to the registry with traverse add. Call it from the CLI, from an AI agent via MCP, or from your app directly. Every call is validated and traced.
\n
\n
\n
\n
\n
\n
\n\n\n\n\n \n \n
\n
\n
\n
Contract-first validation
\n
Every capability call validates inputs against a JSON Schema precondition before execution. Postconditions validate the output. Bad data never reaches your logic.
\n
\n
\n
\n
WASM sandbox isolation
\n
Each capability runs in its own Wasmtime WASM instance with linear memory isolation. A capability cannot access host resources it was not explicitly granted.
\n
\n
\n
\n
AI agent integration
\n
Expose your entire capability registry to AI agents via the MCP stdio server. Claude, GPT-4, and any MCP-compatible agent can discover and call capabilities safely.
\n
\n
\n
\n
Honest host surface
\n
Shipped today: native (Linux/macOS/Windows) and browser via traverse-embedder-web. Swift, Kotlin, and .NET packages are published, pre-1.0, and not Certified. Edge is planned; cloud placement is an explicit non-goal for v0.1. See Platforms.
\n
\n
\n
\n
Trace artifacts
\n
Every execution produces a trace artifact: the input, the output, the contract version, and a timestamp. Audit any past run without re-executing anything.
\n
\n
\n
\n
Policy paper trail
\n
Every contract can link to the policy document it implements. Specs are honesty hygiene for the codebase, not the product pitch, and not a count to advertise.
\n
\n
\n
\n\n\n\n\n \n
Watch a workflow get composed, live.
\n
Your browser fetches the real capability registry, and a client-side heuristic (not a hosted AI model) chains matching capabilities into a workflow. No fixtures, no precomputed data.
\n
Watch the live demo\n
\n\n\n\n\n \n \n
\n
\n
1
\n
Shared
runtime.wasm orchestrator. Embedders are clients. Shipped targets are on
Platforms.
\n
\n
\n
0
\n
Logic rewrites between shipped hosts. Same contract, same binary, same behavior. (Not a claim about mobile packages, edge, or cloud.)
\n
\n
\n
2ms
\n
Typical contract execution time on the local target. WASM startup is fast. Contract validation adds negligible overhead.
\n
\n
\n
\n\n\n\n\n \n \n
\n
\n
\n
Pricing and discount logic
\n
Encode complex pricing rules as a contract with a link to your pricing policy document. The same capability runs via the published Web embedder, native/CLI hosts, and MCP agents with identical results: where those surfaces are shipped.
\n
Learn more\n
\n
\n
\n
Eligibility and access rules
\n
Run eligibility logic as a sandboxed WASM capability so an AI agent can check a user's eligibility for a product, service, or feature without risk of hallucinating the answer.
\n
Learn more\n
\n
\n
\n
Compliance and audit logic
\n
Capture regulatory and compliance rules in versioned contracts with governing spec links. Every execution is traced. Auditors can replay any historical decision from the trace artifact.
\n
Learn more\n
\n
\n
\n
AI agent guardrails
\n
Give your AI agents a set of contract-governed capabilities to call. The agent cannot exceed the contract's boundaries. Postcondition checks block invalid outputs before they propagate.
\n
Learn more\n
\n
\n
\n\n\n\n\n
\n
\n
Start building with Traverse
\n
Install the CLI, write your first contract, and run it in under five minutes.
\n
\n
\n
\n\n";
+const _jsonLd = "{\"@context\":\"https://schema.org\",\"@type\":\"SoftwareApplication\",\"name\":\"Traverse\",\"description\":\"A governed capability runtime: discover → execute → trace. Skill-first authoring via traverse-capability-author; one shared runtime.wasm; shipped clients are browser, native desktop, CLI, and MCP. The agent proposes; the runtime decides.\",\"url\":\"https://traverse-framework.com\",\"author\":{\"@type\":\"Person\",\"name\":\"Enrico Piovesan\"},\"license\":\"https://www.apache.org/licenses/LICENSE-2.0\",\"applicationCategory\":\"DeveloperApplication\",\"softwareVersion\":\"0.16.2\",\"codeRepository\":\"https://github.com/traverse-framework/traverse\"}";
---
Swift / iOS
In progress
- The engine blocker recorded here as of July 19, 2026 is resolved. The wasmi feasibility spike below was adopted the next day: ADR-0014 selected the wasmi Apple runtime profile, ADR-0015 governed a production Swift wasmi C ABI, and Spec 074 (Approved) now defines the resource-control certification conditions. packages/swift/TraverseEmbedder ships a production WasmiHostBridgeClient backed by TraverseSwiftHost, a released XCFramework wrapping the wasmi interpreter behind a narrow C ABI, that enforces host-owned artifact-size, memory, fuel-per-invocation, and I/O limits on every call. The earlier WasmKit path, which never exposed those controls, has been removed from the package entirely (Decision 96, #1469); WasmKit is not supported. The xcframework ships as versioned swift-host-v* GitHub release assets. The current asset is swift-host-v0.16.1, released with Traverse v0.16.1 on November 3, 2026. The v0.16.1 tag's Package.swift pins swift-host-v0.16.0 (#1769); main moved the pin to swift-host-v0.16.1 after the tag (#1780). The v0.16.0 tag's Package.swift pinned the older rebuild swift-host-v0.15.0-1. The v0.15.0 asset was swift-host-v0.15.0. That published xcframework includes ExactModelHost for signed exact-ref execute (GitHub Release + SPM binary target). Apple hosts can opt in to a package's signed Core ML variant under the same policy, tolerance, and evidence rules; the default placement stays wasm-cpu. Evidence so far is macOS cargo test plus the Decision 113 iPhone spike. Governed-path iPhone evidence shipped in v0.16.0 (traverse#1630): BirdNET on one iPhone 14 Pro Max at p95 141 ms per 3 s clip under [coreml, wasm-cpu], relying on schema 2.3.0 (new in v0.16.0) score_transform (details).
+ The engine blocker recorded here as of July 19, 2026 is resolved. The wasmi feasibility spike below was adopted the next day: ADR-0014 selected the wasmi Apple runtime profile, ADR-0015 governed a production Swift wasmi C ABI, and Spec 074 (Approved) now defines the resource-control certification conditions. packages/swift/TraverseEmbedder ships a production WasmiHostBridgeClient backed by TraverseSwiftHost, a released XCFramework wrapping the wasmi interpreter behind a narrow C ABI, that enforces host-owned artifact-size, memory, fuel-per-invocation, and I/O limits on every call. The earlier WasmKit path, which never exposed those controls, has been removed from the package entirely (Decision 96, #1469); WasmKit is not supported. The xcframework ships as versioned swift-host-v* GitHub release assets. The current asset is swift-host-v0.16.2, released with Traverse v0.16.2 on November 4, 2026. The v0.16.2 tag's Package.swift pins swift-host-v0.16.1; main moved the pin to swift-host-v0.16.2 after the tag (#1798). The v0.16.1 tag's Package.swift pinned swift-host-v0.16.0 (#1769). The v0.16.0 tag's Package.swift pinned the older rebuild swift-host-v0.15.0-1. The v0.15.0 asset was swift-host-v0.15.0. That published xcframework includes ExactModelHost for signed exact-ref execute (GitHub Release + SPM binary target). Apple hosts can opt in to a package's signed Core ML variant under the same policy, tolerance, and evidence rules; the default placement stays wasm-cpu. Evidence so far is macOS cargo test plus the Decision 113 iPhone spike. Governed-path iPhone evidence shipped in v0.16.0 (traverse#1630): BirdNET on one iPhone 14 Pro Max at p95 141 ms per 3 s clip under [coreml, wasm-cpu], relying on schema 2.3.0 (new in v0.16.0) score_transform (details).
Read the wasmi feasibility write-up →
diff --git a/src/pages/questions/can-a-traverse-application-manifest-invoke-a-host-connector.astro b/src/pages/questions/can-a-traverse-application-manifest-invoke-a-host-connector.astro
new file mode 100644
index 0000000..51c2531
--- /dev/null
+++ b/src/pages/questions/can-a-traverse-application-manifest-invoke-a-host-connector.astro
@@ -0,0 +1,77 @@
+---
+import QuestionLayout from '@layouts/QuestionLayout.astro';
+
+const jsonLd = JSON.stringify({
+ '@context': 'https://schema.org',
+ '@type': 'FAQPage',
+ mainEntity: [{
+ '@type': 'Question',
+ name: 'Can a Traverse application manifest invoke a host connector?',
+ acceptedAnswer: {
+ '@type': 'Answer',
+ text: 'Yes, since Traverse v0.16.2 (November 4, 2026). A state in an application state machine invokes exactly one of two things: a capability ({"capability_id": "...", "input_from": "..."}) or a host connector ({"host_connector": "audio.permission.request"}). traverse-cli app validate, activation and registration accept both (Spec 1773, traverse#1772). Neither, both, an empty value or an unknown invoke field fails closed with a stable diagnostic. The connector command must be declared by the app and resolves through Specs 104 and 137. A host-connector state must route all four terminal events: host_connector_succeeded, host_connector_failed, host_connector_timeout and host_connector_cancelled. Existing capability-only manifests behave as before. Limit: traverse-cli app activate only registers its built-in reference connector catalog, and traverse.audio-input is not in it yet (traverse#1791).',
+ },
+ }],
+});
+
+const capabilityInvoke = `{
+ "invoke": {
+ "capability_id": "com.example.transcribe",
+ "input_from": "host_connector_result.artifact_ref"
+ }
+}`;
+
+const connectorInvoke = `{
+ "id": "requesting_permission",
+ "invoke": { "host_connector": "audio.permission.request" },
+ "transitions": [
+ { "on": "host_connector_succeeded", "to": "ready" },
+ { "on": "host_connector_failed", "to": "error" },
+ { "on": "host_connector_cancelled", "to": "error" },
+ { "on": "host_connector_timeout", "to": "error" }
+ ]
+}`;
+
+const relatedLinks = [
+ { href: '/questions/how-do-i-upgrade-to-traverse-v0-16-0.html', label: 'How do I upgrade to Traverse v0.16.x?' },
+ { href: '/questions/what-is-the-traverse-cli.html', label: 'What is the Traverse CLI?' },
+ { href: '/questions/does-catalog-model-execute-run-on-published-traverse-packages.html', label: 'Does catalog model.execute run on published Traverse packages?' },
+ { href: '/changelog.html', label: 'Changelog' },
+];
+---
+
+ Short answer: yes, since Traverse v0.16.2 (November 4, 2026). A state in your app's state machine can ask the host to do something, like request microphone permission, instead of running a capability. traverse-cli app validate, activation and registration all accept it (#1772, Spec 1773).
+
+ The two shapes
+ Every state that has invoke names exactly one target. A capability:
+ {capabilityInvoke}
+ Or a host connector. This state comes from the audio-analysis example app in the traverse repo at the v0.16.2 tag:
+ {connectorInvoke}
+ The host connector runs, and its result can feed a later capability through input_from: "host_connector_result.…". The business logic still lives in the capability. The host only does the I/O.
+
+ What fails closed
+
+ - An invoke with neither field, both fields, an empty value or an unknown field is rejected at validation, before activation. A host connector is never quietly treated as a capability.
+ - A host-connector state that doesn't route all four terminal events (
host_connector_succeeded, host_connector_failed, host_connector_timeout, host_connector_cancelled) fails with app_state_machine_missing_unhappy_routes.
+ - The connector command has to be declared by the app and resolve through Specs 104 and 137. An undeclared command, an incompatible version or a binding the host never activated fails closed.
+
+ Existing capability-only manifests validate and serialize as before. v0.16.2 changes no host, guest or bridge ABI.
+
+ Try it
+ cargo install traverse-cli-rs --version =0.16.2 --locked
+traverse-cli app validate path/to/app.manifest.json
+ The crate is traverse-cli-rs; the binary is traverse-cli. It needs Rust 1.95 or later.
+
+ What isn't there yet
+
+ traverse-cli app activate only registers its built-in reference connector catalog. traverse.audio-input isn't in it yet, so the audio example can't activate from the CLI yet (#1791, open).
+ - The v0.16.2 release notes scope this to
traverse-cli workspace applications. Check your host's README before you rely on a host-connector invoke there.
+
+
diff --git a/src/pages/questions/can-i-run-traverse-capabilities-in-nodejs.astro b/src/pages/questions/can-i-run-traverse-capabilities-in-nodejs.astro
index 2597a30..783f0ae 100644
--- a/src/pages/questions/can-i-run-traverse-capabilities-in-nodejs.astro
+++ b/src/pages/questions/can-i-run-traverse-capabilities-in-nodejs.astro
@@ -9,7 +9,7 @@ const jsonLd = JSON.stringify({
name: 'Can I run Traverse capabilities in Node.js?',
acceptedAnswer: {
'@type': 'Answer',
- text: 'Yes, through the same npm package the browser uses. traverse-embedder-web@0.15.0 exports NodeFsBundleLoader, which reads your application bundle from disk instead of fetching it. The embedder loads the bundle\'s own runtime/runtime.wasm, checks its sha256 digest, and runs each capability through it, so a Node process discovers, executes, and traces against the same runtime.wasm a browser tab loads. Node is a host, not a separate Traverse runtime. Workflows are limited to linear direct-triggered pipelines today, and Node is not listed as its own target on the Platforms page.',
+ text: 'Yes, through the same npm package the browser uses. traverse-embedder-web@0.16.2 (and since 0.15.0) exports NodeFsBundleLoader, which reads your application bundle from disk instead of fetching it. The embedder loads the bundle\'s own runtime/runtime.wasm, checks its sha256 digest, and runs each capability through it, so a Node process discovers, executes, and traces against the same runtime.wasm a browser tab loads. Node is a host, not a separate Traverse runtime. Workflows are limited to linear direct-triggered pipelines today, and Node is not listed as its own target on the Platforms page.',
},
}],
});
@@ -47,11 +47,11 @@ const relatedLinks = [
>
Yes. There's no separate Node package. You use traverse-embedder-web, the same npm package a browser app uses, and give it a different bundle loader.
-
In the browser, FetchBundleLoader pulls the app bundle over HTTP. In Node, NodeFsBundleLoader reads the same files from disk. Both are exported from the published 0.15.0 package. Everything after loading is the same: the embedder loads the bundle's runtime/runtime.wasm, checks it against runtime/runtime.wasm.sha256, and runs your capabilities through it. So a Node script discovers, executes, and traces against the same runtime.wasm a browser tab would. Node is just another host.
+
In the browser, FetchBundleLoader pulls the app bundle over HTTP. In Node, NodeFsBundleLoader reads the same files from disk. Both are exported from the published 0.16.2 package. Everything after loading is the same: the embedder loads the bundle's runtime/runtime.wasm, checks it against runtime/runtime.wasm.sha256, and runs your capabilities through it. So a Node script discovers, executes, and traces against the same runtime.wasm a browser tab would. Node is just another host.
{nodeExample}
-
We ran this shape on Node 20 with traverse-embedder-web@0.15.0 from npm and the traverse-starter bundle checked into the traverse repo. The submit came back accepted, the subscriber saw capability_invoked then capability_result, and traceList returned one completed trace for traverse-starter.process. No traverse-cli serve sidecar was running.
+
As of v0.15.0, we ran this shape on Node 20 with traverse-embedder-web@0.15.0 from npm and the traverse-starter bundle checked into the traverse repo. The submit came back accepted, the subscriber saw capability_invoked then capability_result, and traceList returned one completed trace for traverse-starter.process. No traverse-cli serve sidecar was running.
Where this is useful
@@ -70,5 +70,5 @@ const relatedLinks = [
- Python isn't covered by this. There's no Python SDK. From Python, shell out to
traverse-cli capability-package execute.
-
If you need a Rust process instead, the Rust embedder is traverse-embedder@0.15.0 on crates.io. For agents, use traverse-mcp. All of them are clients of the same capability contracts. Nobody reimplements the rule.
+
If you need a Rust process instead, the Rust embedder is traverse-embedder@0.16.2 on crates.io. For agents, use traverse-mcp. All of them are clients of the same capability contracts. Nobody reimplements the rule.
diff --git a/src/pages/questions/does-catalog-model-execute-run-on-published-traverse-packages.astro b/src/pages/questions/does-catalog-model-execute-run-on-published-traverse-packages.astro
index 98f83c9..b2b2c4e 100644
--- a/src/pages/questions/does-catalog-model-execute-run-on-published-traverse-packages.astro
+++ b/src/pages/questions/does-catalog-model-execute-run-on-published-traverse-packages.astro
@@ -9,7 +9,7 @@ const jsonLd = JSON.stringify({
name: 'Does catalog model.execute run on published Traverse packages?',
acceptedAnswer: {
'@type': 'Answer',
- text: 'Yes on native Rust, Node and the browser, since Traverse v0.16.1 (November 3, 2026). The published model.execute@1.0.0 guest ran unchanged over the signed traverse.digits-onnx@1.0.0 package on native (crates.io traverse-runtime 0.16.1, wasmtime), Node and Chromium (npm traverse-embedder-web@0.16.1). The success output, the 56-byte output frame and six fail-closed cases (connector_unavailable, usage_undeclared, key_untrusted, pin_mismatch, digest_mismatch, package_revoked) matched on all three; native also adds placement_evidence. A CI job on a fresh GitHub-hosted runner reinstalls only published packages and gets the same result. Limits: runtime.wasm and the test-signed package come from the v0.16.1 git tag, not a package or release (traverse#1784); on native, activate_exact_model_runtime does not let you read the output frame back (traverse#1785); Swift, Android and .NET cannot activate the connector yet; registry spec 027 is still a draft; no host is Certified under Spec 529.',
+ text: 'Yes on native Rust, Node and the browser, since Traverse v0.16.1 (November 3, 2026). The published model.execute@1.0.0 guest ran unchanged over the signed traverse.digits-onnx@1.0.0 package on native (crates.io traverse-runtime 0.16.1, wasmtime), Node and Chromium (npm traverse-embedder-web@0.16.1). The success output, the 56-byte output frame and six fail-closed cases (connector_unavailable, usage_undeclared, key_untrusted, pin_mismatch, digest_mismatch, package_revoked) matched on all three; native also adds placement_evidence. A CI job on a fresh GitHub-hosted runner reinstalls only published packages and gets the same result. Limits: the test-signed package comes from the v0.16.1 git tag, and runtime.wasm came from the tag too (since November 4 it is also on the runtime-wasm-v0.16.1 release; traverse#1784 closed); on native, activate_exact_model_runtime does not let you read the output frame back (traverse#1785); Swift, Android and .NET cannot activate the connector yet; registry spec 027 is still a draft; no host is Certified under Spec 529.',
},
}],
});
@@ -56,7 +56,7 @@ const relatedLinks = [
What isn't true yet
- runtime.wasm isn't in a package or release. The demo fetched it from the v0.16.1 git tag and checked its digest. See Where does BundleEmbedder get runtime.wasm? (traverse#1784).
+ runtime.wasm isn't in the npm package. The demo fetched it from the v0.16.1 git tag and checked its digest. Since November 4 the same file is also on the runtime-wasm-v0.16.1 release (traverse#1784, closed). See Where does BundleEmbedder get runtime.wasm?
- Native output frames need a workaround.
activate_exact_model_runtime takes the host by value, so a caller can't read the output frame back through it. The demo builds the activation by hand around ExactModelMediatedConnector instead (traverse#1785).
- Swift, Android and .NET have no activation API for this connector yet.
- The model is test-signed.
traverse.digits-onnx@1.0.0 is signed with the test-only key (traverse#1567).
diff --git a/src/pages/questions/does-the-website-use-the-latest-traverse-embedder.astro b/src/pages/questions/does-the-website-use-the-latest-traverse-embedder.astro
index 61142b6..463aa63 100644
--- a/src/pages/questions/does-the-website-use-the-latest-traverse-embedder.astro
+++ b/src/pages/questions/does-the-website-use-the-latest-traverse-embedder.astro
@@ -9,7 +9,7 @@ const jsonLd = JSON.stringify({
name: 'Does the Traverse website use the latest traverse-embedder-web?',
acceptedAnswer: {
'@type': 'Answer',
- text: 'Today, yes: the website pins traverse-embedder-web at ^0.15.0, the same line npm publishes with Traverse v0.15.0, and the /discover generate panel admits its demo fixture through registerPackage(manifestBytes, wasm, signatureBytes) and passes modelUsage, which v0.15.0 requires. The demo fixture is signed with Traverse\'s published test-only key, which it trusts only for that demo. The site can still lag a future release, so treat published npm/crates versions and what-is-real-today as the product line, not the website pin.',
+ text: 'Mostly. As of November 5, 2026 the website pins traverse-embedder-web at ^0.16.2, the line npm publishes with Traverse v0.16.2, and the /discover generate panel admits its demo fixture through registerPackage(manifestBytes, wasm, signatureBytes, policy) and passes modelUsage. One part lags: the /discover execute panel ships its own runtime.wasm copy pinned to the v0.13.0 digest. The demo fixture is signed with Traverse\'s published test-only key, which it trusts only for that demo. The site can still lag a future release, so treat published npm/crates versions and what-is-real-today as the product line, not the website pin.',
},
}],
});
@@ -24,22 +24,22 @@ const relatedLinks = [
---
- Short answer: today, yes, but it can lag. The marketing site follows the published package line after each release. That is honesty, not a secret second runtime.
+ Short answer: mostly, and it can lag. The marketing site follows the published package line after each release. That is honesty, not a secret second runtime.
What is pinned today
- On traverse-framework/website, package.json depends on traverse-embedder-web at ^0.15.0. npm’s current published line for that package is also 0.15.0, lockstep with Traverse v0.15.0 crates. Cite what ships today for the consumer list apps should build against.
+ On traverse-framework/website, package.json depends on traverse-embedder-web at ^0.16.2 (updated November 5, 2026). npm’s current published line for that package is also 0.16.2, lockstep with Traverse v0.16.2 crates. The lag: the /discover execute panel loads its own copy of runtime.wasm from /runtime/runtime.wasm, pinned to the v0.13.0 digest (a254c161…). Current releases ship theirs on runtime-wasm-v0.16.2 (details). Cite what ships today for the consumer list apps should build against.
How /discover admits its demo model
- The public /discover generate panel (discover-generate.js) constructs an ExactModelBrowserHost and admits the fixture.responder@1.0.0 conformance fixture through registerPackage(manifestBytes, wasm, signatureBytes). v0.15.0 also requires modelUsage whenever pins exist; the demo passes non_commercial. The Ed25519 signature over the exact model.manifest.json bytes, the pin digest, and the WASM digest are all verified before execute. The fixture is signed with Traverse's published test-only key, which the demo trusts only for that fixture. Product hosts configure their own trust roots. The 0.13 pin used insertVerified, which 0.14 removed.
+ The public /discover generate panel (discover-generate.js) constructs an ExactModelBrowserHost and admits the fixture.responder@1.0.0 conformance fixture through registerPackage(manifestBytes, wasm, signatureBytes, policy). Since v0.16.0 registration takes the execution policy (Decision 120), and since v0.15.0 hosts require modelUsage whenever pins exist; the demo passes non_commercial. The Ed25519 signature over the exact model.manifest.json bytes, the pin digest, and the WASM digest are all verified before execute. The fixture is signed with Traverse's published test-only key, which the demo trusts only for that fixture. Product hosts configure their own trust roots. The 0.13 pin used insertVerified, which 0.14 removed.
What you should pin
- If you are building a product host, depend on the published npm / crates.io versions (today traverse-embedder-web@0.15.0 / traverse-embedder@0.15.0), not on whatever the website happens to ship in its demo bundle. The site is a citeable demo surface; it is not the version authority for your app.
+ If you are building a product host, depend on the published npm / crates.io versions (today traverse-embedder-web@0.16.2 / traverse-embedder@0.16.2), not on whatever the website happens to ship in its demo bundle. The site is a citeable demo surface; it is not the version authority for your app.
Related
What the page is for: What does the /discover page do?. Signed exact-ref surface: What is exact-ref model execution?. Embedder delta notes: v0.14.0: what changed for embedders.
diff --git a/src/pages/questions/how-do-i-package-an-onnx-model-for-traverse.astro b/src/pages/questions/how-do-i-package-an-onnx-model-for-traverse.astro
index 8ee510c..a4582b2 100644
--- a/src/pages/questions/how-do-i-package-an-onnx-model-for-traverse.astro
+++ b/src/pages/questions/how-do-i-package-an-onnx-model-for-traverse.astro
@@ -9,7 +9,7 @@ const jsonLd = JSON.stringify({
name: 'How do I package my own ONNX model for Traverse?',
acceptedAnswer: {
'@type': 'Answer',
- text: 'Install the CLI with cargo install traverse-cli-rs --version =0.15.0 --locked (Rust 1.94 or newer; crates.io traverse-cli is an unrelated tool). Download the audited runner.wasm from the onnx-runner-v0.15.0 GitHub release and check its sha256, then run traverse-cli model package-onnx runner.wasm model.onnx model.package.json out/dir. Sign the manifest with a key kept outside the repo, verify, generate and check a conformance vector, and pin. The app then declares the pin and model_usage, and the host runs it under discover → execute → trace. In 0.15.0 the packager supports one input and one output tensor. Traverse v0.16.0 (November 2, 2026) adds multi-input, multi-output packaging for Hugging Face-style text encoders (traverse#1661), model verify --model-usage, and a new audited runner on onnx-runner-v0.16.0 that only the 0.16.0 CLI accepts; building 0.16.0 needs Rust 1.95.',
+ text: 'Install the CLI with cargo install traverse-cli-rs --version =0.15.0 --locked (Rust 1.94 or newer; crates.io traverse-cli is an unrelated tool). Download the audited runner.wasm from the onnx-runner-v0.15.0 GitHub release and check its sha256, then run traverse-cli model package-onnx runner.wasm model.onnx model.package.json out/dir. Sign the manifest with a key kept outside the repo, verify, generate and check a conformance vector, and pin. The app then declares the pin and model_usage, and the host runs it under discover → execute → trace. In 0.15.0 the packager supports one input and one output tensor. Traverse v0.16.0 (November 2, 2026) adds multi-input, multi-output packaging for Hugging Face-style text encoders (traverse#1661), model verify --model-usage, and a new audited runner on onnx-runner-v0.16.0 that only the 0.16.x CLI accepts; building 0.16.x needs Rust 1.95. v0.16.1 and v0.16.2 republish the same runner bytes on onnx-runner-v0.16.1 and onnx-runner-v0.16.2. The current CLI is traverse-cli-rs 0.16.2.',
},
}],
});
@@ -31,7 +31,7 @@ const relatedLinks = [
relatedLinks={relatedLinks}
jsonLd={jsonLd}
>
- Update, November 2, 2026: Traverse v0.16.0 adds named multi-input, multi-output packaging (traverse#1661), model verify --model-usage (traverse#1686), and a new audited runner on onnx-runner-v0.16.0 (sha256 ac5591fac5f37435667169e969f9117cc6f81dc66b73cd74d1aef9000f5d3a0a, on tract-onnx 0.23.9). model package-onnx from 0.16.0 accepts only that runner; the 0.15.0 CLI pairs with onnx-runner-v0.15.0. Building 0.16.0 needs Rust 1.95. traverse-cli-rs 0.16.0 is on crates.io (cargo install traverse-cli-rs --version =0.16.0 --locked, then the onnx-runner-v0.16.0 runner). The steps below were written for 0.15.0; swap both version pins to use 0.16.0.
+ Update, November 2, 2026: Traverse v0.16.0 adds named multi-input, multi-output packaging (traverse#1661), model verify --model-usage (traverse#1686), and a new audited runner on onnx-runner-v0.16.0 (sha256 ac5591fac5f37435667169e969f9117cc6f81dc66b73cd74d1aef9000f5d3a0a, on tract-onnx 0.23.9). model package-onnx from 0.16.x accepts only that runner; the 0.15.0 CLI pairs with onnx-runner-v0.15.0. Building 0.16.x needs Rust 1.95. The current CLI is traverse-cli-rs 0.16.2 (cargo install traverse-cli-rs --version =0.16.2 --locked). The runner releases onnx-runner-v0.16.1 and onnx-runner-v0.16.2 carry the same runner.wasm bytes (same sha256), so any of the three works with a 0.16.x CLI. The steps below were written for 0.15.0; swap both version pins to use 0.16.2.
Short answer: since Traverse v0.15.0, traverse-cli model package-onnx turns an ONNX file into a Spec 138 exact-ref package without writing a guest. It copies an audited, import-free runner guest (built on tract) byte for byte and appends your model as data. You then sign, verify, generate a conformance vector, and pin. The app declares that pin and its model_usage, and every host runs it under discover → execute → trace.
diff --git a/src/pages/questions/how-do-i-unit-test-app-code-that-calls-traverse.astro b/src/pages/questions/how-do-i-unit-test-app-code-that-calls-traverse.astro
index 92c8724..348a170 100644
--- a/src/pages/questions/how-do-i-unit-test-app-code-that-calls-traverse.astro
+++ b/src/pages/questions/how-do-i-unit-test-app-code-that-calls-traverse.astro
@@ -9,7 +9,7 @@ const jsonLd = JSON.stringify({
name: 'How do I unit-test app code that calls Traverse without running WASM?',
acceptedAnswer: {
'@type': 'Answer',
- text: 'Swap the real embedder for the deterministic test double that ships in the same package. traverse-embedder-web and the Rust traverse-embedder crate (both 0.15.0) export EmbedderTestDouble, which implements the same embedder API: you script an output or an error per target id, and it emits the same event envelope with deterministic ids (sess-*, req-*, evt-*), rejects unknown targets with target_not_found, and rejects calls after shutdown with runtime_stopped. Swift, Kotlin, and .NET ship a smaller InMemoryTraverseEmbedder harness. A test double never loads WASM, so it tests your host code, not the capability.',
+ text: 'Swap the real embedder for the deterministic test double that ships in the same package. traverse-embedder-web and the Rust traverse-embedder crate (both 0.16.2, and since 0.15.0) export EmbedderTestDouble, which implements the same embedder API: you script an output or an error per target id, and it emits the same event envelope with deterministic ids (sess-*, req-*, evt-*), rejects unknown targets with target_not_found, and rejects calls after shutdown with runtime_stopped. Swift, Kotlin, and .NET ship a smaller InMemoryTraverseEmbedder harness. A test double never loads WASM, so it tests your host code, not the capability.',
},
}],
});
@@ -58,7 +58,7 @@ const relatedLinks = [
Swap the real embedder for the test double that ships in the same package. Your screen, handler, or job talks to the embedder API: submit, subscribe, shutdown. The double implements that same API without loading a bundle or any WASM. You tell it what each target should return, and your test checks how your code reacts.
JS/TS and Rust: EmbedderTestDouble
- Both traverse-embedder-web@0.15.0 and the Rust traverse-embedder@0.15.0 crate export EmbedderTestDouble. For each target id you can script a success with an output, or a failure with a runtime-shaped error code and message.
+ Both traverse-embedder-web@0.16.2 and the Rust traverse-embedder@0.16.2 crate export EmbedderTestDouble. For each target id you can script a success with an output, or a failure with a runtime-shaped error code and message.
{tsExample}
@@ -83,5 +83,5 @@ const relatedLinks = [
- One real integration test per host that loads your actual bundle with
BundleEmbedder and runs discover, execute, and trace end to end. The web package's own suite does this with the checked-in traverse-starter bundle.
-
In traverse-embedder-web@0.14.0, releaseEvidence().package.version reported 0.9.0 because the version was hard-coded (#1654). The published 0.15.0 package sets that constant to 0.15.0.
+
In traverse-embedder-web@0.14.0, releaseEvidence().package.version reported 0.9.0 because the version was hard-coded (#1654). The published 0.15.0 package sets that constant to 0.15.0, and 0.16.2 reports 0.16.2.
diff --git a/src/pages/questions/how-do-i-upgrade-to-traverse-v0-16-0.astro b/src/pages/questions/how-do-i-upgrade-to-traverse-v0-16-0.astro
index e617d5c..b72555a 100644
--- a/src/pages/questions/how-do-i-upgrade-to-traverse-v0-16-0.astro
+++ b/src/pages/questions/how-do-i-upgrade-to-traverse-v0-16-0.astro
@@ -9,7 +9,7 @@ const jsonLd = JSON.stringify({
name: 'How do I upgrade to Traverse v0.16.0?',
acceptedAnswer: {
'@type': 'Answer',
- text: 'Traverse v0.16.0 (November 2, 2026) is a minor lockstep release with four breaking changes. 1) Exact-ref model registration takes the execution policy (Spec 138 0.16.0, Decision 120): pass policy_ref, placements and require_fuel_metering when you register, register every policy_ref you call, expect slower registration and faster first calls, and stop passing placements on calls. 2) Every host gives guests RFC 8785 (JCS) canonical JSON input (Decision 118); input JCS cannot represent fails with input_not_canonicalizable, and Rust ExecutorError gains InputNotCanonicalizable. 3) Hosts enforce the contract inputs.schema before the artifact runs (#1658): unknown fields under additionalProperties: false and strings over maxLength fail with invalid_input / RequestInvalid. 4) Registry rights fail closed (Spec 045 1.1.0, #1728): ranges skip revoked versions, an exact pin to a revoked version fails closed with the revocation record, and conditional model rights need an explicit host opt-in. Building from source needs Rust 1.95. Use the onnx-runner-v0.16.0 runner. traverse-mcp Mode A now ships prebuilt binaries, so no Rust toolchain is needed. v0.16.0 also carries the wasmtime 48.0.7 security fix. crates.io, npm, Maven Central, nuget.org and SwiftPM are all at 0.16.0 (the crates landed on the afternoon of November 2). Discover → execute → trace is unchanged on one shared runtime.wasm.',
+ text: 'Traverse v0.16.0 (November 2, 2026) is a minor lockstep release with four breaking changes. 1) Exact-ref model registration takes the execution policy (Spec 138 0.16.0, Decision 120): pass policy_ref, placements and require_fuel_metering when you register, register every policy_ref you call, expect slower registration and faster first calls, and stop passing placements on calls. 2) Every host gives guests RFC 8785 (JCS) canonical JSON input (Decision 118); input JCS cannot represent fails with input_not_canonicalizable, and Rust ExecutorError gains InputNotCanonicalizable. 3) Hosts enforce the contract inputs.schema before the artifact runs (#1658): unknown fields under additionalProperties: false and strings over maxLength fail with invalid_input / RequestInvalid. 4) Registry rights fail closed (Spec 045 1.1.0, #1728): ranges skip revoked versions, an exact pin to a revoked version fails closed with the revocation record, and conditional model rights need an explicit host opt-in. Building from source needs Rust 1.95. Use the onnx-runner-v0.16.0 runner. traverse-mcp Mode A now ships prebuilt binaries, so no Rust toolchain is needed. v0.16.0 also carries the wasmtime 48.0.7 security fix. crates.io, npm, Maven Central, nuget.org and SwiftPM are all at 0.16.0 (the crates landed on the afternoon of November 2). Discover → execute → trace is unchanged on one shared runtime.wasm. v0.16.1 (November 3) and v0.16.2 (November 4) are additive patches: bump every pin to 0.16.2 with no extra migration. v0.16.2 adds host-connector invokes in traverse-cli workspace application manifests (Spec 1773) and moves to traverse-registry 0.31.0.',
},
}],
});
@@ -24,7 +24,7 @@ const relatedLinks = [
---
New: Browser and Node can run the catalog model.execute@1.0.0 capability with BundleEmbedder.activateMediatedConnector and exactModelMediatedConnector. Use submitAsync; sync submit fails these targets with async_submit_required (published-package run).
Fix on every host: the output filter no longer refuses a signed model_evidence because it contains public URLs. Before, a real package failed with connector_unavailable.
Swift: the v0.16.1 tag's Package.swift pins swift-host-v0.16.0 (#1769), which fixes the stale v0.16.0 pin; main points at swift-host-v0.16.1 (#1780).
- v0.16.1 stays on the 0.16.x line because published traverse-registry 0.29.0 accepts traverse-contracts below 0.17.0. traverse-registry 0.31.0 (published November 4, 2026) widens that to below 0.18.0 (registry#649); Traverse main moved to it in #1788, not yet in a Traverse release.
+ v0.16.1 stays on the 0.16.x line because published traverse-registry 0.29.0 accepts traverse-contracts below 0.17.0. traverse-registry 0.31.0 (published November 4, 2026) widens that to below 0.18.0 (registry#649); Traverse moved to it in #1788, which shipped in v0.16.2.
+
+
+ Then take v0.16.2: no extra migration
+ Traverse v0.16.2 (November 4, 2026) is another additive patch. No host ABI, guest ABI or bridge ABI change, and existing capability-target manifests behave as before. Bump every pin to 0.16.2: npm, Maven Central, nuget.org and all six crates are at 0.16.2, Swift is on swift-host-v0.16.2, and Mode A binaries are on traverse-mcp-v0.16.2.
+
+ - New: a
traverse-cli workspace application state can invoke a host connector instead of a capability (#1772, Spec 1773). Empty, ambiguous and malformed invokes still fail closed (example).
+ - Registry: v0.16.2 consumes
traverse-registry 0.31.0.
+ runtime.wasm: take it from runtime-wasm-v0.16.2 (sha256 b313b5c5…). That release, and runtime-wasm-v0.16.1, were published on November 4 (#1797).
+ - Swift: the v0.16.2 tag's
Package.swift pins swift-host-v0.16.1; main points at swift-host-v0.16.2 (#1798). So a SwiftPM dependency on the v0.16.2 tag still downloads the v0.16.1 xcframework.
+ - ONNX runner:
onnx-runner-v0.16.1 and onnx-runner-v0.16.2 carry the same runner.wasm as onnx-runner-v0.16.0, so nothing changes for packaging.
Package versions (v0.16.0)
@@ -84,7 +94,7 @@ const relatedLinks = [
- Rust 1.95.
wasmtime 48.0.7 needs it (#1744). Building or installing this release from source needs rustc 1.95 or later.
- Security.
wasmtime 48.0.7 fixes GHSA-mghf-wjfp-p5xm, an aarch64 Cranelift sandbox escape, and the ONNX runner guest moves to tract-onnx 0.23.9 (#1735). If you run native Rust hosts on v0.15.0, plan the upgrade.
- - ONNX runner. Download
onnx-runner-v0.16.0 (sha256 ac5591fac5f37435667169e969f9117cc6f81dc66b73cd74d1aef9000f5d3a0a). Its digest changed, and model package-onnx from this release accepts only that runner. See How do I package my own ONNX model?
+ - ONNX runner. Download
onnx-runner-v0.16.0 (sha256 ac5591fac5f37435667169e969f9117cc6f81dc66b73cd74d1aef9000f5d3a0a). Its digest changed, and model package-onnx from the 0.16.x line accepts only that runner. onnx-runner-v0.16.1 and onnx-runner-v0.16.2 carry the same bytes. See How do I package my own ONNX model?
traverse-mcp Mode A. Prebuilt, checksum-pinned binaries for Linux x64, Linux arm64, macOS arm64 and Windows x64 are on traverse-mcp-v0.16.0 (#1653, Decision 121). No Rust toolchain needed:
curl -L https://github.com/traverse-framework/traverse/releases/download/traverse-mcp-v0.16.0/traverse-mcp-aarch64-apple-darwin.tar.gz | tar -xz
./traverse-mcp sync --out synced-state.json
diff --git a/src/pages/questions/index.astro b/src/pages/questions/index.astro
index be787a0..8fe092b 100644
--- a/src/pages/questions/index.astro
+++ b/src/pages/questions/index.astro
@@ -7,7 +7,7 @@ const groups = [
items: [
['how-do-i-install-traverse.html', 'How do I install Traverse?'],
['how-do-i-start-with-traverse-as-an-agent.html', 'How do I start with Traverse as an agent?'],
- ['how-do-i-upgrade-to-traverse-v0-16-0.html', 'How do I upgrade to Traverse v0.16.0 (and v0.16.1)?'],
+ ['how-do-i-upgrade-to-traverse-v0-16-0.html', 'How do I upgrade to Traverse v0.16.0 (and v0.16.2)?'],
['what-does-traverse-not-claim-yet.html', 'What does Traverse not claim yet?'],
['do-i-need-rust.html', 'Do I need to know Rust to use Traverse?'],
['how-do-i-author-a-capability-in-plain-english.html', 'How do I author a Traverse capability in plain English?'],
@@ -57,6 +57,7 @@ const groups = [
items: [
['does-catalog-model-execute-run-on-published-traverse-packages.html', 'Does catalog model.execute run on published Traverse packages?'],
['where-does-bundleembedder-get-runtime-wasm.html', 'Where does BundleEmbedder get runtime.wasm?'],
+ ['can-a-traverse-application-manifest-invoke-a-host-connector.html', 'Can a Traverse application manifest invoke a host connector?'],
['what-does-discover-execute-trace-mean.html', 'What does discover → execute → trace mean in Traverse?'],
['what-is-one-shared-runtime-wasm.html', 'What is one shared runtime.wasm in Traverse?'],
['does-the-rust-embedder-use-the-same-runtime-wasm.html', 'Does the Rust embedder use the same runtime.wasm?'],
diff --git a/src/pages/questions/what-is-exact-model-host.astro b/src/pages/questions/what-is-exact-model-host.astro
index 1e7c80a..a904fd4 100644
--- a/src/pages/questions/what-is-exact-model-host.astro
+++ b/src/pages/questions/what-is-exact-model-host.astro
@@ -9,7 +9,7 @@ const jsonLd = JSON.stringify({
name: 'What is ExactModelHost?',
acceptedAnswer: {
'@type': 'Answer',
- text: 'ExactModelHost is the host-side connector for governed exact-ref model packages (Spec 138). A host registers a signed package under host-owned trust roots, then executes it under discover → execute → trace. It is not a second Traverse runtime. In Traverse v0.15.0 it is published on native Rust, web ExactModelBrowserHost, Swift swift-host-v0.15.0, Maven Central traverse-embedder 0.15.0, and nuget.org TraverseEmbedder 0.15.0. model_usage is required. digits-mlp-1.0.0 uses a test-only key; production signing custody is #1567. This is not catalog model.execute, and it is not a Hugging Face integration.',
+ text: 'ExactModelHost is the host-side connector for governed exact-ref model packages (Spec 138). A host registers a signed package under host-owned trust roots, then executes it under discover → execute → trace. It is not a second Traverse runtime. It first shipped on every host in Traverse v0.15.0. As of v0.16.2 it is published on native Rust (crates 0.16.2), web ExactModelBrowserHost in traverse-embedder-web 0.16.2, Swift swift-host-v0.16.2, Maven Central traverse-embedder 0.16.2, and nuget.org TraverseEmbedder 0.16.2. model_usage is required. digits-mlp-1.0.0 uses a test-only key; production signing custody is #1567. This is not catalog model.execute, and it is not a Hugging Face integration.',
},
}],
});
@@ -25,7 +25,7 @@ const relatedLinks = [
---
Short answer: ExactModelHost is the host-side connector for governed exact-ref model packages (Spec 138). The host registers a signed package under trust roots the host owns, then executes that package under discover → execute → trace. It is a connector on the host. It is not a second Traverse runtime.
What the host actually does
- The app names a package by digest and signature. The connector checks that pin against a key the host already trusts, caches the package, and runs it. Apps do not add trust roots. A naked URL is not the name of the model that ran. The same loop applies on every host that has shipped the connector: discover the pinned package, execute it, leave a trace. v0.15.0 requires model_usage on that path.
+ The app names a package by digest and signature. The connector checks that pin against a key the host already trusts, caches the package, and runs it. Apps do not add trust roots. A naked URL is not the name of the model that ran. The same loop applies on every host that has shipped the connector: discover the pinned package, execute it, leave a trace. Since v0.15.0, model_usage is required on that path.
What is published
- - Native: the connector ships in the Traverse v0.15.0 crates (
ExactModelHostConnector).
- - Web: published
traverse-embedder-web@0.15.0 includes ExactModelBrowserHost.
- - Swift:
ExactModelHost is on the published xcframework swift-host-v0.15.0. It can opt in to a signed Core ML variant. The default placement stays wasm-cpu.
- - Kotlin and .NET:
ExactModelHost is in Maven Central com.traverse-framework:traverse-embedder 0.15.0 and nuget.org TraverseEmbedder 0.15.0 (#1651, closed). The 0.14.0 packages did not include it.
+ - Native: the connector ships in
traverse-runtime (ExactModelHostConnector; 0.16.2 today, since 0.15.0).
+ - Web: published
traverse-embedder-web@0.16.2 includes ExactModelBrowserHost.
+ - Swift:
ExactModelHost is on the published xcframework swift-host-v0.16.2 (first in swift-host-v0.15.0). It can opt in to a signed Core ML variant. The default placement stays wasm-cpu.
+ - Kotlin and .NET:
ExactModelHost is in Maven Central com.traverse-framework:traverse-embedder 0.16.2 and nuget.org TraverseEmbedder 0.16.2 (since 0.15.0; #1651, closed). The 0.14.0 packages did not include it.
Swift, Kotlin, and .NET embedders are published, pre-1.0, and not Certified under Spec 529. Check Platforms before treating a host as Certified.
diff --git a/src/pages/questions/what-is-the-traverse-cli.astro b/src/pages/questions/what-is-the-traverse-cli.astro
index 51c071f..fce0690 100644
--- a/src/pages/questions/what-is-the-traverse-cli.astro
+++ b/src/pages/questions/what-is-the-traverse-cli.astro
@@ -2,7 +2,7 @@
import QuestionLayout from '@layouts/QuestionLayout.astro';
const relatedLinks = [];
-const _body = "The Traverse CLI is the traverse command-line tool you use to compile contracts, register capabilities, execute them locally, and inspect results. It is published on crates.io as traverse-cli-rs (the installed binary is traverse-cli) and wraps the full runtime in a developer-friendly interface.
\n\n What you can do with it
\n \n - Compile a contract TOML file into a validated contract artifact
\n - Register a capability (contract + WASM binary) into the local registry
\n - Run a capability with a JSON input and see the output and trace
\n - List all registered capabilities and their versions
\n - Start the MCP stdio server for AI agent integration
\n - Inspect trace artifacts from previous executions
\n
\n\n Basic usage
\n # Scaffold a new capability package\ntraverse-cli capability new pricing.calculate-total\n\n# After you build the wasm32-wasip1 binary, register a bundle's\n# capabilities, events, and workflows\ntraverse-cli bundle register examples/expedition/registry-bundle/manifest.json\n\n# Execute a capability package against a runtime request\ntraverse-cli capability-package execute capabilities/pricing.calculate-total/manifest.json request.json\n\n# List registered capabilities\ntraverse-cli registry list
\n\n Starting the MCP server
\n The MCP stdio server ships as its own binary, separate from the CLI:
\n traverse-mcp stdio
\n This makes your local registry available to any MCP-compatible client, including Claude Desktop. See how the MCP server works for details.
\n\n Installation
\n Install from crates.io with Cargo:
\n cargo install traverse-cli-rs --version =0.16.1 --locked
\n Traverse v0.16.x needs Rust 1.95; traverse-cli-rs 0.16.1 (November 3, 2026) is on crates.io. On Rust 1.94, pin =0.15.0 instead. See How do I upgrade to Traverse v0.16.0?
\n Watch the crate name: traverse-cli on crates.io is an unrelated project (a Solidity analysis tool) that installs a binary with the same name, so cargo install traverse-cli gets you the wrong tool. You need Rust 1.95 or newer for 0.16.x (for example rustup toolchain install 1.95.0, then cargo +1.95.0 install traverse-cli-rs --locked) and the wasm32-wasip1 target installed. model package-onnx also needs the audited ONNX runner guest, which the crate doesn't bundle: download runner.wasm from the onnx-runner-v0.16.0 release and check its sha256 (ac5591fac5f37435667169e969f9117cc6f81dc66b73cd74d1aef9000f5d3a0a) before you use it; the 0.15.0 CLI pairs with onnx-runner-v0.15.0 (f3902703…) (#1687). Walk-through: how do I package an ONNX model? See the CLI reference for a full command listing.
";
+const _body = "The Traverse CLI is the traverse command-line tool you use to compile contracts, register capabilities, execute them locally, and inspect results. It is published on crates.io as traverse-cli-rs (the installed binary is traverse-cli) and wraps the full runtime in a developer-friendly interface.
\n\n What you can do with it
\n \n - Compile a contract TOML file into a validated contract artifact
\n - Register a capability (contract + WASM binary) into the local registry
\n - Run a capability with a JSON input and see the output and trace
\n - List all registered capabilities and their versions
\n - Start the MCP stdio server for AI agent integration
\n - Inspect trace artifacts from previous executions
\n
\n\n Basic usage
\n # Scaffold a new capability package\ntraverse-cli capability new pricing.calculate-total\n\n# After you build the wasm32-wasip1 binary, register a bundle's\n# capabilities, events, and workflows\ntraverse-cli bundle register examples/expedition/registry-bundle/manifest.json\n\n# Execute a capability package against a runtime request\ntraverse-cli capability-package execute capabilities/pricing.calculate-total/manifest.json request.json\n\n# List registered capabilities\ntraverse-cli registry list
\n\n Starting the MCP server
\n The MCP stdio server ships as its own binary, separate from the CLI:
\n traverse-mcp stdio
\n This makes your local registry available to any MCP-compatible client, including Claude Desktop. See how the MCP server works for details.
\n\n Installation
\n Install from crates.io with Cargo:
\n cargo install traverse-cli-rs --version =0.16.2 --locked
\n Traverse v0.16.x needs Rust 1.95; traverse-cli-rs 0.16.2 (November 4, 2026) is on crates.io. On Rust 1.94, pin =0.15.0 instead. See How do I upgrade to Traverse v0.16.0?
\n Watch the crate name: traverse-cli on crates.io is an unrelated project (a Solidity analysis tool) that installs a binary with the same name, so cargo install traverse-cli gets you the wrong tool. You need Rust 1.95 or newer for 0.16.x (for example rustup toolchain install 1.95.0, then cargo +1.95.0 install traverse-cli-rs --locked) and the wasm32-wasip1 target installed. model package-onnx also needs the audited ONNX runner guest, which the crate doesn't bundle: download runner.wasm from the onnx-runner-v0.16.2 release and check its sha256 (ac5591fac5f37435667169e969f9117cc6f81dc66b73cd74d1aef9000f5d3a0a, the same bytes as onnx-runner-v0.16.0 and v0.16.1) before you use it; the 0.15.0 CLI pairs with onnx-runner-v0.15.0 (f3902703…) (#1687). Walk-through: how do I package an ONNX model? See the CLI reference for a full command listing.
";
const _jsonLd = "{\"@context\":\"https://schema.org\",\"@type\":\"FAQPage\",\"mainEntity\":[{\"@type\":\"Question\",\"name\":\"What is the Traverse CLI?\",\"acceptedAnswer\":{\"@type\":\"Answer\",\"text\":\"The Traverse CLI (crate traverse-cli-rs, binary traverse-cli) is the command-line tool for compiling contracts, registering capabilities, running them locally, and inspecting trace artifacts. It is the primary interface for developing with Traverse outside of an IDE.\"}}]}";
---
- Short answer: from your app bundle. BundleEmbedder loads runtime/runtime.wasm and runtime/runtime.wasm.sha256 from the bundle you give it, checks the digest, and fails closed at init if the file isn't there. The catch is where you get the file in the first place: today it comes from the git tag, not from a package or a release.
+ Short answer: from your app bundle. BundleEmbedder loads runtime/runtime.wasm and runtime/runtime.wasm.sha256 from the bundle you give it, checks the digest, and fails closed at init if the file isn't there. To get the file, download it from the runtime-wasm release that matches your traverse-embedder-web version.
- What ships where (v0.16.1)
+ What ships where (v0.16.2)
- npm
traverse-embedder-web doesn't include runtime.wasm. Its README says so: the orchestrator belongs to the app bundle.
- - The v0.16.1 GitHub Release is notes only.
- - The last
runtime-wasm-v* release is runtime-wasm-v0.11.0 (September 16, 2026). That's far too old for a v0.16.x embedder.
- - The tag has it.
runtime/runtime.wasm and runtime/runtime-release.json are committed at each release tag.
+ runtime-wasm-v0.16.2 and runtime-wasm-v0.16.1 are artifact-only GitHub releases, published November 4, 2026. Each has runtime.wasm, runtime.wasm.sha256 and runtime-release.json. They are never marked Latest.
+ - The tag still has it.
runtime/runtime.wasm and runtime/runtime-release.json are committed at each release tag, with the same bytes.
+ - Before November 4 the last
runtime-wasm-v* release was runtime-wasm-v0.11.0, so v0.16.0 has no matching release. Take v0.16.0 from its tag.
- What to do today
- Take runtime/runtime.wasm from the tag that matches your traverse-embedder-web version, and check it against runtime/runtime-release.json from the same tag before you put it in your bundle. For v0.16.1:
- curl -fsSLO https://raw.githubusercontent.com/traverse-framework/traverse/v0.16.1/runtime/runtime.wasm
+ What to do
+ Download the three files for your version and check the digest before you put the file in your bundle. For v0.16.2:
+ BASE=https://github.com/traverse-framework/traverse/releases/download/runtime-wasm-v0.16.2
+curl -fsSLO $BASE/runtime.wasm
+curl -fsSLO $BASE/runtime.wasm.sha256
+curl -fsSLO $BASE/runtime-release.json
sha256sum runtime.wasm
-# expect 7a322a17e3fd58f8bd26e915dd81bad68732500dc981499bd280a6d2e6507d52
- runtime-release.json at v0.16.1 reads runtime_version 0.16.1, bridge_version 1.1.0, bridge_abi_version 10100, and the same sha256. Then write sha256:<hex> into runtime/runtime.wasm.sha256 in your bundle. The published-package proof for catalog model.execute does exactly this, and its clean-runner CI checks the digest every run.
+# expect b313b5c5c11291d9e9669125a0a9a77aa42a911b15d431a73e86b17c874e298c
+ runtime-release.json for v0.16.2 reads runtime_version 0.16.2, bridge_version 1.1.0, bridge_abi_version 10100, and the same sha256. runtime.wasm.sha256 already holds sha256:<hex>, the form the bundle expects, so it can go straight into runtime/. For v0.16.1 use runtime-wasm-v0.16.1 and expect 7a322a17e3fd58f8bd26e915dd81bad68732500dc981499bd280a6d2e6507d52. We downloaded the v0.16.2 file on November 5 and the digest matched.
Or build it yourself from the tagged source with Rust 1.95 or later. Either way you end up with one shared runtime.wasm that every web and Node host loads; native Rust hosts link traverse-runtime directly and don't need the file.
- What's still open
- traverse#1784 asks for a decision: publish a runtime-wasm-vX.Y.Z release with every product release (the release process still lists that type, but no workflow creates it), ship the file in the npm package, or document the tag as the supported source. Until that lands, treat the tag as the source and always check the digest.
+ What changed
+ traverse#1784 asked how apps should get the file. traverse#1797 closed it: every product tag now publishes runtime-wasm-vX.Y.Z, and the product GitHub Release waits for it (Spec 048 1.5.0, Decision 123). That wiring is on main; the v0.16.1 and v0.16.2 releases were backfilled from their tags, and the first automatic run will be the next product tag. npm still doesn't ship the file.
diff --git a/src/pages/questions/which-hosts-run-signed-exact-ref-models.astro b/src/pages/questions/which-hosts-run-signed-exact-ref-models.astro
index de90bda..7b0ec2e 100644
--- a/src/pages/questions/which-hosts-run-signed-exact-ref-models.astro
+++ b/src/pages/questions/which-hosts-run-signed-exact-ref-models.astro
@@ -9,7 +9,7 @@ const jsonLd = JSON.stringify({
name: 'Which hosts run signed exact-ref models in Traverse?',
acceptedAnswer: {
'@type': 'Answer',
- text: 'Discover → execute → trace. One shared runtime.wasm; embedders are clients. As of Traverse v0.15.0, published exact-ref execute is native Rust, traverse-embedder-web@0.15.0, Swift ExactModelHost on swift-host-v0.15.0, Kotlin ExactModelHost in Maven Central com.traverse-framework:traverse-embedder 0.15.0, and .NET ExactModelHost in nuget.org TraverseEmbedder 0.15.0. Every host enforces model_usage. Apple hosts can opt in to a signed Core ML variant; default placement stays wasm-cpu. Governed-path iPhone evidence shipped in v0.16.0 (traverse#1630): BirdNET on one iPhone 14 Pro Max ran at p95 141 ms per 3 s clip under the policy [coreml, wasm-cpu]. It relies on manifest schema 2.3.0 (new in v0.16.0) score_transform, so v0.15.0 alone does not reproduce it. digits-mlp-1.0.0 uses a test-only key; production custody is #1567. No host is Certified.',
+ text: 'Discover → execute → trace. One shared runtime.wasm; embedders are clients. Published exact-ref execute first shipped on all five hosts in Traverse v0.15.0. As of v0.16.2 (November 4, 2026) it is native Rust (crates 0.16.2), traverse-embedder-web@0.16.2, Swift ExactModelHost on swift-host-v0.16.2, Kotlin ExactModelHost in Maven Central com.traverse-framework:traverse-embedder 0.16.2, and .NET ExactModelHost in nuget.org TraverseEmbedder 0.16.2. Since v0.16.0 the execution policy is set at registration. Every host enforces model_usage. Apple hosts can opt in to a signed Core ML variant; default placement stays wasm-cpu. Governed-path iPhone evidence shipped in v0.16.0 (traverse#1630): BirdNET on one iPhone 14 Pro Max ran at p95 141 ms per 3 s clip under the policy [coreml, wasm-cpu]. It relies on manifest schema 2.3.0 (new in v0.16.0) score_transform, so v0.15.0 alone does not reproduce it. digits-mlp-1.0.0 uses a test-only key; production custody is #1567. No host is Certified.',
},
}],
});
@@ -28,21 +28,21 @@ const relatedLinks = [
---
- Short answer: discover → execute → trace, on one shared runtime.wasm. As of v0.15.0, published exact-ref execute is native Rust, the web embedder, Swift, Kotlin, and .NET. Pin by digest and signature. A naked URL is not identity. No host is Certified under Spec 529.
+ Short answer: discover → execute → trace, on one shared runtime.wasm. Since v0.15.0, published exact-ref execute is native Rust, the web embedder, Swift, Kotlin, and .NET. The current release is v0.16.2. Pin by digest and signature. A naked URL is not identity. No host is Certified under Spec 529.
Honest matrix (checked 14 October 2026)
- - Native Rust:
ExactModelHostConnector in the v0.15.0 crates. model_usage is required.
- - Web: published
traverse-embedder-web@0.15.0 executes exact-ref (ExactModelBrowserHost). Pass modelUsage whenever pins exist.
- - Swift:
ExactModelHost is in the published xcframework swift-host-v0.15.0. Package.swift at the v0.15.0 line pinned its rebuild swift-host-v0.15.0-1 (Traverse v0.16.0 ships swift-host-v0.16.0; main pins it since #1769), which adds the Spec 138 guest reject codes (#1695). The v0.15.0 tag's Package.swift still pointed at swift-host-v0.14.0-4. Distribution is GitHub Release + SPM binary target.
- - Kotlin: Maven Central
com.traverse-framework:traverse-embedder 0.15.0 includes ExactModelHost (#1580, #1651 closed). The 0.14.0 AAR did not.
- - .NET: nuget.org
TraverseEmbedder 0.15.0 includes ExactModelHost (#1602, #1651 closed). The 0.14.0 package did not. Native engine RIDs in the release: win-x64, win-arm64, linux-x64.
+ - Native Rust:
ExactModelHostConnector in traverse-runtime (0.16.2 today, since 0.15.0). model_usage is required.
+ - Web: published
traverse-embedder-web@0.16.2 executes exact-ref (ExactModelBrowserHost). Pass modelUsage whenever pins exist.
+ - Swift:
ExactModelHost is in the published xcframework swift-host-v0.16.2 (the v0.16.2 tag's Package.swift pins swift-host-v0.16.1; main pins v0.16.2 since #1798). It first shipped on swift-host-v0.15.0. Package.swift at the v0.15.0 line pinned its rebuild swift-host-v0.15.0-1 (Traverse v0.16.0 ships swift-host-v0.16.0; main pins it since #1769), which adds the Spec 138 guest reject codes (#1695). The v0.15.0 tag's Package.swift still pointed at swift-host-v0.14.0-4. Distribution is GitHub Release + SPM binary target.
+ - Kotlin: Maven Central
com.traverse-framework:traverse-embedder 0.16.2 includes ExactModelHost (since 0.15.0 ; #1580, #1651 closed). The 0.14.0 AAR did not.
+ - .NET: nuget.org
TraverseEmbedder 0.16.2 includes ExactModelHost (since 0.15.0; #1602, #1651 closed). The 0.14.0 package did not. Native engine RIDs in the release: win-x64, win-arm64, linux-x64.
Rights, ONNX, and Core ML
diff --git a/src/pages/questions/why-does-bundleembedder-fail-with-cannot-find-definition-for-import-connector-invoke.astro b/src/pages/questions/why-does-bundleembedder-fail-with-cannot-find-definition-for-import-connector-invoke.astro
index a0a9da6..356d4ef 100644
--- a/src/pages/questions/why-does-bundleembedder-fail-with-cannot-find-definition-for-import-connector-invoke.astro
+++ b/src/pages/questions/why-does-bundleembedder-fail-with-cannot-find-definition-for-import-connector-invoke.astro
@@ -31,7 +31,7 @@ const relatedLinks = [
relatedLinks={relatedLinks}
jsonLd={jsonLd}
>
- Short answer: your capability calls a host connector through the traverse_host.connector_invoke import, and the published browser and Node runtime.wasm doesn't provide that import yet. It's a known gap in v0.15.0. v0.16.0 links the import, and v0.16.1 adds the Browser and Node activation API, so upgrade to traverse-embedder-web@0.16.1 (tracked in traverse#1719, now closed). It isn't a problem with your bundle or its digest.
+ Short answer: your capability calls a host connector through the traverse_host.connector_invoke import, and the published browser and Node runtime.wasm doesn't provide that import yet. It's a known gap in v0.15.0. v0.16.0 links the import, and v0.16.1 adds the Browser and Node activation API, so upgrade to traverse-embedder-web@0.16.1 or later (current: 0.16.2) (tracked in traverse#1719, now closed). It isn't a problem with your bundle or its digest.
Update, November 2, 2026: partly fixed in v0.16.0
traverse#1755 is in Traverse v0.16.0, released November 2, 2026 (traverse-embedder-web@0.16.0 on npm). The Browser and Node part came in v0.16.1 (below). Upgrading? See How do I upgrade to Traverse v0.16.0?
@@ -48,7 +48,7 @@ const relatedLinks = [
- Suspend and resume. A guest calling a connector the host answers asynchronously suspends at
connector_invoke and resumes on the next submit, through the same Spec 104 checks. No exported symbol or bridge ABI version changed, so a host that doesn't opt in sees no difference.
- Output filter fix. The host-private filter no longer rejects the public URLs inside a signed rights record in the top-level
model_evidence of traverse.model-runtime, on native and nested.
- Run on published packages. The published
model.execute@1.0.0 guest ran unchanged on native, Node and Chromium from the v0.16.1 packages, with identical output and six identical fail-closed reasons (details, #1782).
- - Still open: Swift, Android and .NET activation APIs aren't shipped.
runtime.wasm still comes from the release tag, not a package (#1784).
+ - Still open: Swift, Android and .NET activation APIs aren't shipped.
runtime.wasm isn't in the npm package; download it from the matching runtime-wasm-vX.Y.Z release, such as runtime-wasm-v0.16.2 (details).
The rest of this page describes the 0.15.0 packages, where the import is missing entirely.
diff --git a/src/pages/what-is-real-today.astro b/src/pages/what-is-real-today.astro
index f452fbb..91116da 100644
--- a/src/pages/what-is-real-today.astro
+++ b/src/pages/what-is-real-today.astro
@@ -8,7 +8,7 @@ const _body = `
What ships today.
A citeable snapshot for humans and agents. Not a pitch deck. Not a roadmap dressed as shipped. If it is not on this page, do not invent it.
- v0.16.1
+ v0.16.2
pre-1.0
Apache 2.0
@@ -110,7 +110,7 @@ const _body = `
No Python SDK. Shell out to traverse-cli capability-package execute (stdlib subprocess). See Python →
- Native Swift, Kotlin, and .NET embedders are published and pre-1.0: Swift ships a wasmi xcframework on swift-host-v0.16.1 (the v0.16.1 tag's Package.swift pins swift-host-v0.16.0; main moved to swift-host-v0.16.1 after the tag in #1780), Kotlin is com.traverse-framework:traverse-embedder 0.16.1 on Maven Central, and .NET is TraverseEmbedder 0.16.1 on nuget.org. They are marked In progress. No host is Certified under Spec 529. Signed exact-ref models run on those hosts as well as native Rust and the browser. Check Platforms before assuming a target is shipped.
+ Native Swift, Kotlin, and .NET embedders are published and pre-1.0: Swift ships a wasmi xcframework on swift-host-v0.16.2 (the v0.16.2 tag's Package.swift pins swift-host-v0.16.1; main moved to swift-host-v0.16.2 after the tag in #1798), Kotlin is com.traverse-framework:traverse-embedder 0.16.2 on Maven Central, and .NET is TraverseEmbedder 0.16.2 on nuget.org. They are marked In progress. No host is Certified under Spec 529. Signed exact-ref models run on those hosts as well as native Rust and the browser. Known issue in 0.16.2 and earlier: their RuntimeTraverseEmbedder hands a capability the whole {"{target_id, input}"} submit envelope instead of just input. The fix is on main, not released (#1800). Check Platforms before assuming a target is shipped.