Repository navigation
Traverse v0.16.0
Released 2026-11-02.
Traverse v0.16.0 is a minor lockstep crate and npm release. It carries
breaking changes, and following this repo's 0.x convention those use a
minor bump. See the upgrade guide.
Highlights
- Model placement is prepared at registration (
#1706, Decision 120,
Spec 138 0.16.0). Breaking: every host's registration call takes the
execution policy, and no call pays the one-time preparation. - Guests receive canonical JSON input on every host (
#1722, Decision
118). Breaking: the same WASM given the same logical input now produces the
same output on every host. - Contract inputs are enforced by the host (
#1658). Breaking: unknown
fields fail before the artifact runs. - Registry rights fail closed (
#1727,#1728,#1729). Breaking:- the runtime rejects revoked Registry versions, and conditional model
rights need an explicit host opt-in; traverse-cli registry inspectshows lifecycle status, revocation and
model-rights records, andregistry listandregistry searchcan filter
on them;- Registry contract signatures are verified over their exact source bytes.
- the runtime rejects revoked Registry versions, and conditional model
traverse-mcpMode A without a Rust toolchain (#1653,#1751,
#1752,#1753,#1754, Decision 121). Checksum-pinned binaries for four
targets, asynccommand and a three-command quickstart.- Security.
wasmtime48.0.7 with Rust 1.95 (#1744), and the ONNX runner
guest ontract-onnx0.23.9 (#1735).
This release includes the CLI and runtime support for declared model rights.
It does not establish live Registry coverage or production compliance.
traverse-registry moves to 0.29.0.
All changes
Docs: three-command Mode A quickstart (#1754, Decision 121)
- The README gains a Mode A quickstart that needs no Rust toolchain:
download thetraverse-mcprelease binary,traverse-mcp sync, then
traverse-mcp prepare-cache. It was checked with the macOS binary from a
mcp-server-publish.ymldry run on a shell with no Rust toolchain. docs/mcp-mode-a-release-evidence.mdadds the sync step, the four
targets, a troubleshooting note for therecord/fielderror details,
and the weekly demo on the release binary.
Breaking: model registration takes the execution policy and prepares its placement (#1706, Decision 120, Spec 138 0.16.0)
-
Registration now does the one-time placement work, which first calls used
to do inside their own deadline. It takes the policy calls will name,
{policy_ref, placements, require_fuel_metering}, plus an optional
preparation_budget_ms, and fixes one placement per (package,
policy_ref). The Core ML compile and device self-check, orwasm-cpu's
model_prepare, run there. On the iPhone, acpu_onlyfirst call no
longer pays them inside its 60 s deadline. -
Breaking for every host. The registration call needs the policy:
- Rust
register_package/register_package_with_variantstake a
PlacementPolicy; - Swift
registerPackage(..., policy:), Kotlin
registerPackage(..., policy)and .NETRegisterPackageAsync(..., policy)take anExactModelPlacementPolicy; - web
registerPackage(..., policy, options?)takes an
ExactModelPlacementPolicy; - the framed protocol's
registertakespolicy.
registerPackageWithPreparation(Swift, Kotlin) and
RegisterPackageWithPreparationAsync(.NET) also return the fixed
placement and the preparation time. - Rust
-
A call naming a
policy_refthe package was not registered under fails
withmodel_unavailable/placement_unavailable. The call's
placements/require_fuel_meteringare now optional and deprecated:
when present they must equal the registered policy. They are removed in
the next major version. -
Each listed placement gets the budget, capped by the new host limit
max_preparation_ms(default five minutes). A placement over it is
skipped. Registration is cancellable, and a failed or cancelled
registration keeps nothing. A failingmodel_preparenow fails
registration withexecution_failedinstead of failing the first call. -
No call is charged for one-time preparation. The re-prepare after a
snapshot eviction is the only exception.
traverse-mcp sync and a shared registry-sync crate (#1751, Decision 121)
- New
traverse-mcp sync --out <path> [--release index-vN] [--source-repo <owner/repo>] [--json]. It writes the Spec 055 synced-state file that
prepare-cache --synced-statereads, so Mode A no longer needs a
hand-written state file ortraverse-cli. - The write is atomic: on failure no partial file is left and an existing
file is kept. The output records theindex-vNtag it used. - Registry sync moves into the new
traverse-registry-synccrate, used by
bothtraverse-cli registry sync(unchanged behavior and output) and
traverse-mcp sync. - When GitHub reports a
sha256:digest for theindex.jsonasset, sync
now checks it and fails withregistry_index_digest_mismatchon a
mismatch.
traverse-mcp names the invalid metadata binding (#1752, Decision 121)
prepare-cacheand server startup now run one shared verification-binding
validator. A synced state thatprepare-cacheaccepts is one the server
starts on. Before, an emptyservice_typeorlifecyclepassed
prepare-cacheand then stopped the server.- The error code stays
registry_metadata_cache_invalid. The--json
envelope addsrecord(namespace/id@version) andfield, and the
message names both. prepare-cachevalidates before it writes, so a failure keeps any
existing cache.traverse-embedderaddsvalidate_public_metadataand
RegistryCacheError::details.
traverse-mcp binaries for four targets (#1753, Decision 121)
- The
traverse-mcp-vX.Y.Zrelease now carries Linux arm64
(aarch64-unknown-linux-gnu) and Windows x64 (x86_64-pc-windows-msvc,
.zip) next to Linux x64 and macOS arm64. - Every target has a SHA-256 checksum and build provenance, and is
smoke-run (--version) before upload. The release notes list each
asset's SHA-256. workflow_dispatchtakesdry_run: trueto build, smoke-run, and
checksum all four targets without attesting or releasing.
Security: wasmtime 48.0.7 and Rust 1.95 (#1744, Decision 119)
wasmtime/wasmtime-wasimove from 45.0.3 to 48.0.7 (LTS). This fixes
critical GHSA-mghf-wjfp-p5xm: on aarch64, Cranelift could compile a large
br_tableto a wrong branch target, letting a guest escape the sandbox.
No API, contract, limit, or trace change.- Breaking for source builds: the toolchain and MSRV move from 1.94 to
1.95 (wasmtime 48 needs it). Building orcargo installing this release
needs rustc ≥ 1.95. - Committed wasm rebuilt on 1.95.0:
runtime.wasm, the ONNX runner guest
and the digits-mlp guest. Model fixtures are re-packaged and re-signed;
conformance outputs are unchanged.runtime.wasmsha2565ab8057fed81d3aa1e3c04dd803dc93d2d367a5f8c18c30928f2225fac512ab9.- Audited ONNX runner sha256
ac5591fac5f37435667169e969f9117cc6f81dc66b73cd74d1aef9000f5d3a0a,
replacing the#1735digest above;model package-onnxfrom this
source accepts only this runner.
Security: ONNX runner guest on tract-onnx 0.23.9 (#1735)
- The runner guest moves from
tract-onnx0.21 to 0.23.9. This drops the
vulnerabletimecrate (Dependabot alert #20) andgetrandom0.2. The
guest still imports nothing;getrandom0.3 uses theunsupportedbackend. - New audited runner sha256
7a20f87befcb8792b2f321a488145954ca9f1e000442d5984f1c03c8163353b8
(Linux CI build, 15.7 MB, was 11.5 MB).model package-onnxfrom this
source accepts only this runner; theonnx-runner-v0.15.0release runner
pairs with the 0.15.0 CLI until the nextonnx-runner-v*release. - Supported ONNX operators grow from 160 to 180 (strict superset).
digits-onnx,digits-onnx-coremlandhf-text-encoder-toyare
re-packaged and re-signed. All conformance output frames are byte-identical
to the 0.21 runner.
Security: wasmtime / wasmtime-wasi 44 → 45.0.3 (#1734)
- Fixes the wasmtime-wasi advisory where WASI hard links bypass
FilePerms
for the destination path. Affects the defaultwasmtime-executorfeature
oftraverse-runtime. No API, contract, limit, or trace change.
Perf / API: model path routing + async cancellable submit (#1657)
- ADR-0083 / Decision 117: model-backed Browser/Node work uses Spec 138
ExactModelBrowserHost(directWebAssembly), not nested wasmi. Nested
runtime.wasmstays for non-model capabilities. Perf report:
docs/perf/nested-vs-direct-wasm-1657.md; harness
scripts/perf/direct-wasm-model-bench.mjs(lightweight fixtures by
default; HF packages viaTRAVERSE_PERF_FULL=1). traverse-embedder-web:submitAsynconBundleEmbedder,
EmbedderTestDouble, andTraverseEmbedderApiwith optional
AbortSignal. Cancel returnsstatus: "cancelled"and Trace API
phase/outcomecancelled. Syncsubmitunchanged for small work.- README: async API, Worker guidance, Spec 138 routing for model math.
Feature: multi-IO ONNX packaging (#1661)
model package-onnxpackages Hugging Face–style multi-input/multi-output
ONNX graphs (and keeps legacy single-IOpackage.json). Token-id inputs
useelement: "i64". I/O is a Spec 138 frame bundle.- Spec 138 → 0.15.1 (FR-073 on top of 0.15.0). Reference package
fixtures/models/hf-text-encoder-toy-1.0.0with signed cross-host
conformance; digits-onnx packages rebuilt on the new runner. - Web
concatGuestFrames, nativeconcat_guest_frames, and Swift/Kotlin/.NET
GuestFramehelpers for app-side bundle assembly; hosts still stage opaque bytes.
Evidence: BirdNET in real time on iPhone on the governed path (#1630)
- iPhone 14 Pro Max, Release build, policy
[coreml, wasm-cpu], default
compute units: p95 is 141 ms per 3 s clip (bar 1.5 s). Top-5 is
identical and |Δ sigmoid| ≤ 4.8×10⁻³ againstwasm-cpu.wasm-cpu
alone takes about 10 s per clip. See
docs/evidence/birdnet-iphone-governed-2026-10-15.md. - New harness
tools/model-evidence/iosreproduces it. No weights or audio
are committed.
Logit outputs compared on their scores: tolerance.score_transform (Spec 138 0.15.0, Decision 116, #1630)
- A variant's tolerance may declare
score_transform: sigmoid(default
identity). Declaredf32outputs are mapped through it before
max_abs_diff/top_k, so classifiers that output logits meet
Decision 106's score bar. Converted BirdNET differs by up to 3.4×10⁻² in
raw logits but only 4.8×10⁻³ in sigmoid scores. - New manifest schema
2.3.0, a superset of2.2.0, carries it. A
non-identity transform in2.2.0ismanifest_invalid.
traverse-cli model add-variant --score-transform sigmoidwrites
2.3.0; without the flag it stays on2.2.0. - Native, web, Swift, Kotlin and .NET hosts accept
2.3.0. Hosts at or
below 0.15.0 reject it.
Fix: web embedder accepts variants that declare f32_dtypes (#1703)
traverse-embedder-web@0.15.0rejected every package whose accelerator
variant declarestolerance.f32_dtypes, including the signed
digits-onnx-coreml-1.0.0fixture, withmanifest_invalid. Native hosts
accept the same bytes. The web host now accepts the optional field
(unique integer dtype codes 0–255), matching native.
Docs/packaging: CLI install path + ONNX runner distribution (#1687)
- README and
docs/model-packaging-guide.mddocumentcargo install traverse-cli-rs(rustc ≥ 1.94), and warn that crates.iotraverse-cliis
an unrelated Solidity tool. - Audited ONNX runner guest ships on
onnx-runner-v*artifact releases with
sha256bd95db176d9268f04b06b42c4bd9a380e568a9bfb4b6abeaa8c07c3d79763622(matchesfixtures/onnx/runner.wasm). model package-onnxfails closed when the given runner digest is not the
audited guest. CI installs the CLI from a packaged.crateand runs the
digits-onnx package → verify → conformance path.
Fix: reject invalid web modelUsage (#1685)
ExactModelBrowserHostand the framed native create path only accept
commercial|non_commercial. Any other value fails closed with
usage_invalidand structureddetail(field: model_usage).- Spec 138 0.14.2; shared rights suite scenario 11.
Perf: framed host output length without clone (#1697)
executereportsusage.output_bytesviaModelIoStore::output_len(no buffer copy).
Feature: packaged traverse-mcp Mode A binaries (#1653)
- Product tags publish
traverse-mcp-vX.Y.Zwith Linux x86_64 + macOS arm64
archives,SHA256SUMS, and build-provenance attestations (never Latest). traverse-mcp --versionreports workspace version and the tagged commit.
Fix: model verify --model-usage and JSON usage errors (#1686)
traverse-cli model verify(andconformance generate|check) accept
--model-usage commercial|non_commercialand optional
--require-model-usage.- Without
--model-usage, verification still uses a non-commercial default
but the JSON report setsrights_record.effective_usagetonulland
keepsverification_usageexplicit (no false app declaration). --model-usage commercialon acommercial_use: prohibitedpackage fails
withrights_policy_denied; invalid values fail closed.- When
--jsonis present, argument/usage errors (malformed keys, unknown
flags, bad--model-usage) emit a JSON error envelope on stdout with
error.code: "usage_error"and a non-zero exit.
Fix: host-configurable nested limits for runtime.wasm (#1656)
- Nested capability fuel / memory inside
runtime.wasmstay defaulted to
10M / 32 MiB, but hosts can raise them viatraverse_initlimitsand
BundleEmbedder.init({ limits: { fuel, maxMemoryBytes } }). - Bundle load / native registration fail closed with
resource_requirements_exceed_hostwhen a capability's declared
execution.resourcesor WASM initial memory exceeds the host ceiling. - Spec 1402 FR-012 amended to 1.5.0; contract
execution.resourcesis
optional and backwards-compatible.
Device self-check records its worst case (#1708, Spec 138 FR-062)
- A device self-check now runs every conformance case and records what it found:
passed,cases,failed_cases,worst_abs_diff(afterscore_transform),worst_case,top_k_mismatchesandother_failures. - The evidence rides on each registration attempt's
self_checkand on SwiftExactModelRegistration.attempts. - The iPhone harness writes it as
placement_attempts.
Nested wasmi links Spec 104 connector_invoke (#1719)
- Nested wasmi
runtime.wasmlinks Spec 104traverse_host.connector_invokewith the same fail-closed mediation order as native wasmtime (declared → activated → semver → 64 KiB → host-private filter → evidence). - Native ships
ExactModelMediatedConnector/activate_exact_model_runtimefortraverse.model-runtime. - Swift / Android / .NET / Web READMEs document Spec 104 guest binding as not yet (web notes the sync-ABI vs async-execute gap). Follow-on: host activation + cross-host conformance.
Fix: reproducible runtime.wasm build + digest CI (#1659)
scripts/build-runtime-wasm.shrebuildsruntime.wasmfrom
traverse-runtime-wasmviatraverse-native-bridgewith path-stable
RUSTFLAGSand writesruntime-release.jsonfrom the workspace version.scripts/ci/runtime_wasm_reproducibility_check.shfails CI when a rebuild
digest drifts fromruntime/runtime.wasm.sha256(or any bundled copy).- Committed
runtime/runtime-release.jsonnow reports workspace0.15.0
(was stale0.12.0) and a freshly rebuilt digest.
Breaking: host-side contract input schema enforcement (#1658)
- Capability inputs are validated against the contract
inputs.schemabefore
the artifact runs (native runtime path and webBundleEmbedderwhen a
component declarescontract_path). additionalProperties: falseis enforced; unknown fields fail with
invalid_input/RequestInvalidand JSON Pointer violation paths
(e.g./skip_redaction).maxLengthon strings is enforced. RawWasmExecutor::run_bytesstill
does not validate — callers must validate or use the governed runtime /
embedder path.
Links
- Changelog
- Upgrade guide
- Release process
- Spec 138
- Range:
v0.15.0..v0.16.0