Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
},
"dependencies": {
"astro": "7.3.4",
"traverse-embedder-web": "^0.13.0"
"traverse-embedder-web": "^0.14.0"
},
"devDependencies": {
"@playwright/test": "^1.63.0"
Expand Down
2 changes: 1 addition & 1 deletion public/llms.txt
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ Current packages: crates.io at 0.14.0 (pin `traverse-registry` at `=0.25.0` if y
- [How do hosts trust signed models?](https://traverse-framework.com/questions/how-do-hosts-trust-signed-models.html): host-owned trust roots gate `register_package`; pin by digest + `model.sig.json`; test-only digits-mlp key; exact-ref execute native+web+Swift ExactModelHost; Kotlin/.NET not yet — no claimed ONNX generic runner.
- [Which hosts run signed exact-ref models?](https://traverse-framework.com/questions/which-hosts-run-signed-exact-ref-models.html) · [Is production model signing ready?](https://traverse-framework.com/questions/is-production-model-signing-ready.html) · [Can Kotlin or .NET run exact-ref yet?](https://traverse-framework.com/questions/can-kotlin-or-dotnet-embedders-run-exact-ref-yet.html): honest matrix (native+web+Swift ExactModelHost; Kotlin/.NET #1580/#1602); test-only key ≠ prod (#1567).
- [What is digits-mlp?](https://traverse-framework.com/questions/what-is-digits-mlp.html): first trained exact-ref package in v0.14.0 (UCI digits MLP, 96.10% held-out, bit-identical); test-only signing; not a general LLM.
- [Does the website use the latest traverse-embedder-web?](https://traverse-framework.com/questions/does-the-website-use-the-latest-traverse-embedder.html): site currently pins `^0.13.0` while npm ships `0.14.0`; `/discover` still uses `insertVerified`; product apps pin published packages, not the website demo.
- [Does the website use the latest traverse-embedder-web?](https://traverse-framework.com/questions/does-the-website-use-the-latest-traverse-embedder.html): site pins `^0.14.0` (matching npm) and `/discover` admits its signed demo fixture through `registerPackage`; the site can lag future releases, so product apps pin published packages, not the website demo.
- [How does Traverse complement Hugging Face?](https://traverse-framework.com/questions/how-does-traverse-complement-hugging-face.html): Hub = provenance; Traverse = pinned signed client-first capability; not Transformers.js/Hub replacement; no defer promise until a second executor exists.

## Optional
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ const jsonLd = JSON.stringify({
name: 'Does the Traverse website use the latest traverse-embedder-web?',
acceptedAnswer: {
'@type': 'Answer',
text: 'Not always. The public website currently pins traverse-embedder-web at ^0.13.0 while npm publishes 0.14.0 with Traverse v0.14.0. The /discover generate panel still calls ExactModelBrowserHost.insertVerified (the 0.13 API); 0.14 replaced that with registerPackage(manifestBytes, wasm, signatureBytes) for signed Spec 138 packages. Treat published npm/crates versions and what-is-real-today as the product line — do not assume the website pin equals the latest shipped embedder.',
text: 'Today, yes: the website pins traverse-embedder-web at ^0.14.0, the same line npm publishes with Traverse v0.14.0, and the /discover generate panel admits its demo fixture through registerPackage(manifestBytes, wasm, signatureBytes), the 0.14 signed Spec 138 path. 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.',
},
}],
});
Expand All @@ -24,19 +24,19 @@ const relatedLinks = [
---
<QuestionLayout
title="Does the Traverse website use the latest traverse-embedder-web?"
description="Not always — the site currently pins ^0.13.0 while npm ships 0.14.0. /discover still uses insertVerified; 0.14 uses registerPackage. Pin published packages, not the website demo."
description="Today the site pins ^0.14.0, matching npm, and /discover admits its signed demo fixture through registerPackage. The site can lag future releases: pin published packages, not the website demo."
canonical="https://traverse-framework.com/questions/does-the-website-use-the-latest-traverse-embedder.html"
category="Runtime and architecture"
relatedLinks={relatedLinks}
jsonLd={jsonLd}
>
<p><strong>Short answer:</strong> <strong>not always.</strong> The marketing site can lag the published package line. That is honesty, not a secret second runtime.</p>
<p><strong>Short answer:</strong> <strong>today, yes</strong>, but it can lag. The marketing site follows the published package line after each release. That is honesty, not a secret second runtime.</p>

<h2>What is pinned today</h2>
<p>On <code>traverse-framework/website</code> main, <code>package.json</code> depends on <code>traverse-embedder-web</code> at <code>^0.13.0</code>. npm’s current published line for that package is <strong>0.14.0</strong>, lockstep with <a href="https://github.com/traverse-framework/traverse/releases/tag/v0.14.0">Traverse v0.14.0</a> crates. Cite <a href="/what-is-real-today.html">what is real today</a> for the consumer list apps should build against.</p>
<p>On <code>traverse-framework/website</code> main, <code>package.json</code> depends on <code>traverse-embedder-web</code> at <code>^0.14.0</code>. npm’s current published line for that package is also <strong>0.14.0</strong>, lockstep with <a href="https://github.com/traverse-framework/traverse/releases/tag/v0.14.0">Traverse v0.14.0</a> crates. Cite <a href="/what-is-real-today.html">what is real today</a> for the consumer list apps should build against.</p>

<h2>Why /discover can lag</h2>
<p>The public <a href="/discover.html">/discover</a> generate panel (<code>discover-generate.js</code>) still constructs an <code>ExactModelBrowserHost</code> and calls <strong><code>insertVerified(...)</code></strong> — the <strong>0.13</strong> admission path. In <strong>0.14</strong>, that host admits packages through <strong><code>registerPackage(manifestBytes, wasm, signatureBytes)</code></strong> so signed Spec 138 manifests and <code>model.sig.json</code> are verified before execute. Migrating the demo is separate eng work; until it lands, the site pin stays on 0.13 so the demo keeps working.</p>
<h2>How /discover admits its demo model</h2>
<p>The public <a href="/discover.html">/discover</a> generate panel (<code>discover-generate.js</code>) constructs an <code>ExactModelBrowserHost</code> and admits the <code>fixture.responder@1.0.0</code> conformance fixture through <strong><code>registerPackage(manifestBytes, wasm, signatureBytes)</code></strong>, the 0.14 path. The Ed25519 signature over the exact <code>model.manifest.json</code> bytes, the pin digest, and the WASM digest are all verified before execute. The fixture is signed with Traverse's published <strong>test-only</strong> key, which the demo trusts only for that fixture. Product hosts configure their own trust roots. Earlier, the 0.13 pin used <code>insertVerified</code>, which 0.14 removed.</p>

<h2>What you should pin</h2>
<p>If you are building a product host, depend on the <strong>published</strong> npm / crates.io versions (today <code>traverse-embedder-web@0.14.0</code> / <code>traverse-embedder@0.14.0</code>), 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.</p>
Expand Down
49 changes: 30 additions & 19 deletions src/scripts/discover-generate.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,17 @@ import {
// Small enough to embed and audit directly rather than fetch.
const FIXTURE_WASM_B64 = 'AGFzbQEAAAABCQFgBH9/f38BfwMCAQAFAwEAAgcaAgZtZW1vcnkCAA1tb2RlbF9leGVjdXRlAAAK9AEB8QEBB38gAUEMSQRAQX8PCyAAKAIIIQQgAEEMaiEFQQwgBGogAUsEQEF/DwtBACEIQQAhBgJAA0AgBkECaiAESw0BIAUgBmotAABB6ABGIAUgBkEBamotAABB6QBGcQRAQQEhCAwCCyAGQQFqIQYMAAsLIAhBAUYEQEHKuAIhCUEIIQoFQd64AiEJQQMhCgtBDCAKaiADSwRAQX8PCyACQQE7AQAgAkEEOgACIAJBAToAAyACIAo2AgQgAiAKNgIIQQAhBwJAA0AgByAKTw0BIAJBDGogB2ogCSAHai0AADoAACAHQQFqIQcMAAsLQQwgCmoLCyMDAEHAuAILAmhpAEHKuAILCGhpIHRoZXJlAEHeuAILA2htbQCUAQRuYW1lAmIBAAsABmluX3B0cgEGaW5fbGVuAgdvdXRfcHRyAwdvdXRfY2FwBAtwYXlsb2FkX2xlbgULcGF5bG9hZF9wdHIGAWkHAWoIB21hdGNoZWQJCHJlc3BfcHRyCghyZXNwX2xlbgMpAQAEAgtzZWFyY2hfZG9uZQMGc2VhcmNoBwljb3B5X2RvbmUIBGNvcHk=';

// The same fixture's signed Spec 138 package files (traverse-embedder-web
// 0.14 admits packages only through registerPackage): the exact bytes of
// fixtures/models/fixture-responder-1.0.0/model.manifest.json (its SHA-256
// is the pin digest) and its detached Ed25519 model.sig.json.
const FIXTURE_MANIFEST_B64 = 'ewogICJzY2hlbWFfdmVyc2lvbiI6ICIyLjAuMCIsCiAgIm1vZGVsX2lkIjogImZpeHR1cmUucmVzcG9uZGVyIiwKICAidmVyc2lvbiI6ICIxLjAuMCIsCiAgIndhc21fZGlnZXN0IjogImJmMDQ3NjBiMTkzN2MyZjJiODEzYjZlMjhmMmZkYzZlMzM0ODMzYzJkZmFkYzFmN2M4NzJmM2YyOGMzNDEyOTQiLAogICJyZWdpc3RyeV9yZWYiOiAicmVnaXN0cnk6Zml4dHVyZS5yZXNwb25kZXJAMS4wLjAiLAogICJleGVjdXRhYmxlX2Zvcm1hdCI6ICJ0cmF2ZXJzZS1tb2RlbC13YXNtIiwKICAiYWJpX3ZlcnNpb24iOiAxLAogICJpbnB1dF9zY2hlbWFfcmVmIjogInNjaGVtYTpicmlkZ2VkLWdlbmVyYXRlLWluIiwKICAiaW5wdXRfc2NoZW1hX3ZlcnNpb24iOiAiMS4wLjAiLAogICJvdXRwdXRfc2NoZW1hX3JlZiI6ICJzY2hlbWE6YnJpZGdlZC1nZW5lcmF0ZS1vdXQiLAogICJvdXRwdXRfc2NoZW1hX3ZlcnNpb24iOiAiMS4wLjAiLAogICJyaWdodHMiOiB7CiAgICAibGljZW5zZV9pZCI6ICJBcGFjaGUtMi4wIiwKICAgICJhdHRyaWJ1dGlvbiI6ICJUcmF2ZXJzZSBTcGVjIDA0NS8xMzggYnJpZGdlIGNvbmZvcm1hbmNlIGZpeHR1cmUiLAogICAgInJlZGlzdHJpYnV0aW9uIjogInRlc3Qtb25seTsgbm90IGZvciBwcm9kdWN0aW9uIHJlZGlzdHJpYnV0aW9uIGNsYWltcyIsCiAgICAiY29tbWVyY2lhbF91c2UiOiAiYWxsb3dlZCIsCiAgICAic291cmNlX3VybCI6ICJodHRwczovL2dpdGh1Yi5jb20vdHJhdmVyc2UtZnJhbWV3b3JrL1RyYXZlcnNlL3RyZWUvbWFpbi9maXh0dXJlcy9tb2RlbHMvZml4dHVyZS1yZXNwb25kZXItMS4wLjAiCiAgfSwKICAic3VwcG9ydGVkX3Byb2ZpbGVzIjogWwogICAgIndhc20tY3B1IgogIF0sCiAgIm1heF9tZW1vcnlfYnl0ZXMiOiAxMzEwNzIsCiAgIm1heF9mdWVsIjogMTAwMDAwMCwKICAibWF4X2lucHV0X2J5dGVzIjogNDA5NiwKICAibWF4X291dHB1dF9ieXRlcyI6IDQwOTYsCiAgIm1heF9leGVjdXRpb25fbXMiOiA1MDAwLAogICJvZmZsaW5lX2FsbG93ZWQiOiB0cnVlCn0K';
const FIXTURE_SIGNATURE_B64 = 'ewogICJhbGciOiAiZWQyNTUxOSIsCiAgImtleV9pZCI6ICJlZDI1NTE5OjQ1NWRmZmIwOTMxNjNkODQzOWI1NDRjYzRmMGVhNzllMzNhMDdiMjA1OTRjNDczOWE4YmJiNGMwODE5ZDJkNjciLAogICJzaWduYXR1cmUiOiAiOTkzZDA0M2QzZTM5NmE5OTkxMjUzZmY1NWZiZDgwNjU4MWZlYjU5MTYxNDRjNTc5ZTAzMTMxZGZjOTVmMmNlOTBlZTE2ODQ1ZGE0YjY5ZmIzZWNkMzc2YjYzNmVhZTBjYTQzM2RlNTA1OWY1MmNkNWMzNjQ4Yjc0YmY2NThkMDQiCn0K';
// TEST-ONLY public key (fixtures/models/test-signing-key.json in
// traverse-framework/traverse) that signed the conformance fixtures. It is
// trusted here only to run this demo fixture; production hosts never trust it.
const FIXTURE_TEST_KEY_HEX = '97002eba1e28b582a739eb48750a5f0822b2bbcb61e6bcedd2fada36b51af355';

const MODEL_ID = 'fixture.responder';
const MODEL_VERSION = '1.0.0';
const GUEST_TEXT_DTYPE = 4; // matches the fixture's own conformance test (Spec 138 guest ABI v1)
Expand All @@ -54,22 +65,22 @@ async function sha256Hex(bytes) {
the WASM guest decides, and this function only reports what it did. */
export async function runResponderDemo(promptText) {
const wasm = b64ToBytes(FIXTURE_WASM_B64);
const digest = await sha256Hex(wasm);
const host = new ExactModelBrowserHost([
{ model_id: MODEL_ID, version: MODEL_VERSION, digest, offline_allowed: true },
]);
await host.insertVerified(
{
model_id: MODEL_ID, version: MODEL_VERSION,
wasm_digest: digest, package_digest: digest,
input_schema_ref: 'schema:bridged-generate-in', input_schema_version: '1.0.0',
max_memory_bytes: 131072, max_fuel: 1_000_000,
max_input_bytes: MAX_BYTES, max_output_bytes: MAX_BYTES,
offline_allowed: true, supported_profiles: [PLACEMENT_WASM_CPU],
license_id: 'Apache-2.0', abi_version: 1,
},
wasm,
const manifestBytes = b64ToBytes(FIXTURE_MANIFEST_B64);
const wasmDigest = await sha256Hex(wasm);
// Spec 138: the pin digest is the SHA-256 of the exact signed manifest
// bytes, which pin wasm_digest in turn.
const digest = await sha256Hex(manifestBytes);
const host = new ExactModelBrowserHost(
[{
model_id: MODEL_ID, version: MODEL_VERSION, digest, offline_allowed: true,
target: PLACEMENT_WASM_CPU, rights: { license_id: 'Apache-2.0', commercial_use: 'allowed' },
}],
{ trustedPublicKeysHex: [FIXTURE_TEST_KEY_HEX] },
);
// Real verification: Ed25519 signature by a trusted key over the exact
// manifest bytes, pin digest, WASM digest, rights, target, and limits.
// Any mismatch throws; nothing here can fabricate an admitted package.
await host.registerPackage(manifestBytes, wasm, b64ToBytes(FIXTURE_SIGNATURE_B64));

const promptBytes = new TextEncoder().encode(promptText);
const frame = encodeGuestFrame(GUEST_TEXT_DTYPE, [promptBytes.length], promptBytes);
Expand Down Expand Up @@ -97,7 +108,7 @@ export async function runResponderDemo(promptText) {
output_ref: result.output_ref,
});

return { digest, response, placement: result.placement, evidence };
return { digest, wasmDigest, response, placement: result.placement, evidence };
}

function el(id) { return document.getElementById(id); }
Expand All @@ -121,11 +132,11 @@ async function runDemo() {
log.innerHTML = '';
if (out) out.hidden = true;
btn.disabled = true;
logLine(log, '$ sha256(model.wasm) — verify against the fixture.responder@1.0.0 pin', 'cmd');
logLine(log, '$ registerPackage — verify the Ed25519 signature (test-only fixture key), manifest pin, and sha256(model.wasm)', 'cmd');

try {
const { digest, response, placement, evidence } = await runResponderDemo(promptText);
logLine(log, '✓ digest verified: sha256:' + digest.slice(0, 23) + '…', 'ok');
const { digest, wasmDigest, response, placement, evidence } = await runResponderDemo(promptText);
logLine(log, '✓ signed package verified: pin sha256:' + digest.slice(0, 16) + '…, wasm sha256:' + wasmDigest.slice(0, 16) + '…', 'ok');
logLine(log, '$ encode prompt as a Spec 138 guest frame (ABI v1) and stage it', 'cmd');
logLine(log, '$ execute — wasm-cpu, offline, no network, no daemon', 'cmd');
logLine(log, '✓ response: "' + response + '" (placement=' + placement + ')', 'ok');
Expand Down
17 changes: 14 additions & 3 deletions tests/discover-generate.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,23 @@ test('runResponderDemo genuinely executes the checked-in bridge fixture, not a c
assert.equal(miss.digest, hit.digest);
});

test('the fixture digest matches the real checked-in traverse-framework/traverse conformance fixture', async () => {
test('the fixture digests match the real checked-in traverse-framework/traverse conformance fixture', async () => {
// fixtures/models/fixture-responder-1.0.0/model.manifest.json in
// traverse-framework/traverse pins this exact wasm_digest for the same
// 491-byte file — this embeds the real bytes, not a stripped variant.
const { digest } = await runResponderDemo('hi');
assert.equal(digest, 'bf04760b1937c2f2b813b6e28f2fdc6e334833c2dfadc1f7c872f3f28c341294');
// Since traverse-embedder-web 0.14 the pin digest is the SHA-256 of that
// exact signed manifest file.
const { digest, wasmDigest } = await runResponderDemo('hi');
assert.equal(wasmDigest, 'bf04760b1937c2f2b813b6e28f2fdc6e334833c2dfadc1f7c872f3f28c341294');
assert.equal(digest, '50b74bd39bc81da3639d74f2df6e31c243d1a496fde0127486630624b2983763');
});

test('admission goes through registerPackage with a real signature, not the removed insertVerified', async () => {
const gen = await read('src/scripts/discover-generate.js');
assert.match(gen, /registerPackage\(/);
assert.doesNotMatch(gen, /insertVerified/);
// The test-only fixture key is labelled as such, never presented as production trust.
assert.match(gen, /TEST-ONLY public key/);
});

test('/discover states the generation panel honestly and does not overclaim', async () => {
Expand Down
Loading