diff --git a/src/ml/imf/registry.ts b/src/ml/imf/registry.ts index 7d69e7b..596f915 100644 --- a/src/ml/imf/registry.ts +++ b/src/ml/imf/registry.ts @@ -16,7 +16,7 @@ import { load as loadYaml } from "js-yaml" export const DEFAULT_INDEX_URL = - "https://github.com/interscript/interscript-models/releases/download/index-v10/models-index.yaml" + "https://github.com/interscript/interscript-models/releases/download/index-v12/models-index.yaml" export interface Part { url: string diff --git a/test/client-work.test.ts b/test/client-work.test.ts index 16905c6..c00d372 100644 --- a/test/client-work.test.ts +++ b/test/client-work.test.ts @@ -145,9 +145,9 @@ describe("CORS asset rewrite (13)", () => { it("rewrites canonical interscript-models release URLs too", () => { expect( corsAssetUrl( - "https://github.com/interscript/interscript-models/releases/download/index-v10/models-index.yaml", + "https://github.com/interscript/interscript-models/releases/download/index-v12/models-index.yaml", ), - ).toBe("https://api.interscript.org/v1/assets/index-v10/models-index.yaml") + ).toBe("https://api.interscript.org/v1/assets/index-v12/models-index.yaml") }) it("leaves other hosts and schemes untouched", () => { expect(corsAssetUrl("https://example.com/x.zip")).toBe("https://example.com/x.zip") diff --git a/test/conformance.test.ts b/test/conformance.test.ts new file mode 100644 index 0000000..bd760dd --- /dev/null +++ b/test/conformance.test.ts @@ -0,0 +1,45 @@ +/** + * Frozen conformance fixtures (interscript-models/conformance/) — the + * TypeScript runtime must reproduce the vectors byte-exactly under the + * declared decode mode, or the change does not merge. + * + * Gated on env: SECRYST_E2E_ZIP (the artifact) + CONFORMANCE_VECTORS + * (the fixture file), so CI runs without downloads. + */ + +import { readFileSync } from "node:fs" +import { describe, expect, it } from "vitest" +import { IMFModel } from "../src/ml/imf/index.js" + +const e2eZip = process.env["SECRYST_E2E_ZIP"] +const conformanceVectors = process.env["CONFORMANCE_VECTORS"] + +describe("frozen conformance fixtures", () => { + it.skipIf(!e2eZip || !conformanceVectors)( + "reproduces the vectors byte-exactly (single-row-greedy)", + async () => { + const vectors = JSON.parse( + readFileSync(conformanceVectors!, "utf-8"), + ) as { + model: string + decode: { mode: string } + vectors: { src: string; out: string }[] + } + expect(vectors.decode.mode).toBe("single-row-greedy") + const model = await IMFModel.load(e2eZip!) + const failures: string[] = [] + for (const v of vectors.vectors) { + const got = await model.translate(v.src, 256) + if (got !== v.out) { + failures.push(`${v.src} -> ${got} (expected ${v.out})`) + } + } + await model.dispose() + expect( + failures, + `${vectors.model}: ${failures.length}/${vectors.vectors.length} mismatched`, + ).toEqual([]) + }, + 600_000, + ) +})