import { describe, expect, it, vi } from "vitest"; import { encodeToolcraftModelDocument } from "../canonical/model-document-codec"; import { digestToolcraftModelDocument } from "../canonical/model-document-digest"; import { createModelPrimitive, createValidModelDocument, } from "../canonical/model-document-test-support"; import { TOOLCRAFT_DEFAULT_MODEL_IMPORT_LIMITS } from "../model-import-limits"; import { encodeToolcraftModelRepairPlanEnvelope } from "../topology/model-repair-plan-codec"; import { analyzeToolcraftModel } from "../topology/model-topology-analysis"; import { createToolcraftModelWorkerClient } from "./model-import-worker-client"; import { snapshotToolcraftModelWorkerAnalysisSummary } from "./model-import-worker-diagnostics"; import { copyArrayBuffer, encodedDocumentBuffer, FakeWorker, forgedDigest, importRequest, } from "./model-import-worker-client-test-support"; import { createToolcraftModelWorkerDraftReceiptDigest, createToolcraftModelWorkerReceiptDigest, digestToolcraftModelWorkerBytes, } from "./model-import-worker-receipt"; import { fakeRepairPlan } from "./model-import-worker-runtime-test-support"; describe("createToolcraftModelWorkerClient protocol validation", () => { it("rejects a repair result with a mismatched plan digest before publication", async () => { const worker = new FakeWorker(); const onResult = vi.fn(); const client = createToolcraftModelWorkerClient({ workerFactory: () => worker }); const document = createValidModelDocument(); const plan = fakeRepairPlan(); const planBytes = encodeToolcraftModelRepairPlanEnvelope(plan); const pending = client.repair({ canonicalDocument: encodeToolcraftModelDocument(document), canonicalDocumentDigest: digestToolcraftModelDocument(document), jobId: "hostile-repair", limits: TOOLCRAFT_DEFAULT_MODEL_IMPORT_LIMITS, repairPlanEnvelope: { bytes: planBytes.buffer, envelopeDigest: digestToolcraftModelWorkerBytes(planBytes), planDigest: plan.planDigest, version: 1, }, }, { onResult }); await vi.waitFor(() => expect(worker.posts).toHaveLength(1)); const request = worker.posts[0]!.message; worker.emitMessage({ generation: request.generation, jobId: request.jobId, kind: "progress", phase: "repairing", progress: 0.9, }); worker.emitMessage({ generation: request.generation, jobId: request.jobId, kind: "result", result: { analysis: snapshotToolcraftModelWorkerAnalysisSummary(analyzeToolcraftModel( document, "realtime-mesh", TOOLCRAFT_DEFAULT_MODEL_IMPORT_LIMITS, )), canonicalDocument: encodedDocumentBuffer(), canonicalDocumentDigest: digestToolcraftModelDocument(document), operation: "repair", repairPlanDigest: forgedDigest, receiptDigest: forgedDigest, }, }); await expect(pending).resolves.toMatchObject({ kind: "error", feedback: { code: "model-worker-invalid-message" }, }); expect(worker.terminate).toHaveBeenCalledTimes(1); expect(onResult).not.toHaveBeenCalled(); }); it("rejects a forged repair envelope digest before transferring either buffer", async () => { const worker = new FakeWorker(); const client = createToolcraftModelWorkerClient({ workerFactory: () => worker }); const document = createValidModelDocument(); const plan = fakeRepairPlan(); const envelopeBytes = encodeToolcraftModelRepairPlanEnvelope(plan); const pending = client.repair({ canonicalDocument: encodeToolcraftModelDocument(document), canonicalDocumentDigest: digestToolcraftModelDocument(document), jobId: "forged-repair-envelope", limits: TOOLCRAFT_DEFAULT_MODEL_IMPORT_LIMITS, repairPlanEnvelope: { bytes: envelopeBytes.buffer, envelopeDigest: forgedDigest, planDigest: plan.planDigest, version: 1, }, }); await expect(pending).resolves.toMatchObject({ feedback: { code: "model-worker-repair-envelope-digest-mismatch" }, kind: "error", }); expect(worker.posts).toHaveLength(0); }); it("accepts a verified repairable analysis with its authentic repair plan digest", async () => { const worker = new FakeWorker(); const client = createToolcraftModelWorkerClient({ workerFactory: () => worker }); const document = createValidModelDocument({ primitives: [createModelPrimitive({ normals: undefined })], }); const analysis = analyzeToolcraftModel( document, "realtime-mesh", TOOLCRAFT_DEFAULT_MODEL_IMPORT_LIMITS, ); expect(analysis.outcome).toBe("repairable"); const bytes = encodeToolcraftModelDocument(document); const plan = analysis.repairPlan!; const envelopeBytes = encodeToolcraftModelRepairPlanEnvelope(plan); const repairPlanEnvelope = { bytes: copyArrayBuffer(envelopeBytes), envelopeDigest: digestToolcraftModelWorkerBytes(envelopeBytes), planDigest: plan.planDigest, version: 1 as const, }; const pending = client.importModel(importRequest("repairable-plan")); const request = worker.posts[0]!.message; worker.emitMessage({ generation: request.generation, jobId: request.jobId, kind: "progress", phase: "decoding", progress: 0.9, }); const draftWithoutReceipt = { appearanceResources: [], canonicalDocument: copyArrayBuffer(bytes), canonicalDocumentDigest: digestToolcraftModelDocument(document), }; worker.emitMessage({ draft: { ...draftWithoutReceipt, receiptDigest: createToolcraftModelWorkerDraftReceiptDigest({ draft: draftWithoutReceipt, generation: request.generation, jobId: request.jobId, }), }, generation: request.generation, jobId: request.jobId, kind: "draft", }); worker.emitMessage({ generation: request.generation, jobId: request.jobId, kind: "progress", phase: "analyzing", progress: 0.9, }); const resultWithoutReceipt = { analysis: snapshotToolcraftModelWorkerAnalysisSummary(analysis), appearanceResources: [], canonicalDocument: copyArrayBuffer(bytes), canonicalDocumentDigest: digestToolcraftModelDocument(document), operation: "decode-and-analyze" as const, repairPlanEnvelope, }; worker.emitMessage({ generation: request.generation, jobId: request.jobId, kind: "result", result: { ...resultWithoutReceipt, receiptDigest: createToolcraftModelWorkerReceiptDigest({ generation: request.generation, jobId: request.jobId, result: resultWithoutReceipt, }), }, }); await expect(pending).resolves.toMatchObject({ kind: "result", result: { analysis: { outcome: "repairable" } }, }); expect(worker.terminate).not.toHaveBeenCalled(); }); it("rejects an authenticated repairable outcome without repairable evidence", async () => { const worker = new FakeWorker(); const client = createToolcraftModelWorkerClient({ workerFactory: () => worker }); const document = createValidModelDocument({ primitives: [createModelPrimitive({ normals: undefined })], }); const analysis = analyzeToolcraftModel( document, "realtime-mesh", TOOLCRAFT_DEFAULT_MODEL_IMPORT_LIMITS, ); const bytes = encodeToolcraftModelDocument(document); const plan = analysis.repairPlan!; const envelopeBytes = encodeToolcraftModelRepairPlanEnvelope(plan); const repairPlanEnvelope = { bytes: copyArrayBuffer(envelopeBytes), envelopeDigest: digestToolcraftModelWorkerBytes(envelopeBytes), planDigest: plan.planDigest, version: 1 as const, }; const pending = client.importModel(importRequest("repairable-without-evidence")); const request = worker.posts[0]!.message; const draftWithoutReceipt = { appearanceResources: [], canonicalDocument: copyArrayBuffer(bytes), canonicalDocumentDigest: digestToolcraftModelDocument(document), }; worker.emitMessage({ generation: request.generation, jobId: request.jobId, kind: "progress", phase: "decoding", progress: 0.9, }); worker.emitMessage({ draft: { ...draftWithoutReceipt, receiptDigest: createToolcraftModelWorkerDraftReceiptDigest({ draft: draftWithoutReceipt, generation: request.generation, jobId: request.jobId, }), }, generation: request.generation, jobId: request.jobId, kind: "draft", }); worker.emitMessage({ generation: request.generation, jobId: request.jobId, kind: "progress", phase: "analyzing", progress: 0.9, }); const summary = snapshotToolcraftModelWorkerAnalysisSummary(analysis); const resultWithoutReceipt = { analysis: { ...summary, diagnostics: summary.diagnostics.map((diagnostic) => ({ ...diagnostic, severity: diagnostic.severity === "repairable" ? "info" as const : diagnostic.severity, })), }, appearanceResources: [], canonicalDocument: copyArrayBuffer(bytes), canonicalDocumentDigest: digestToolcraftModelDocument(document), operation: "decode-and-analyze" as const, repairPlanEnvelope, }; worker.emitMessage({ generation: request.generation, jobId: request.jobId, kind: "result", result: { ...resultWithoutReceipt, receiptDigest: createToolcraftModelWorkerReceiptDigest({ generation: request.generation, jobId: request.jobId, result: resultWithoutReceipt, }), }, }); await expect(pending).resolves.toMatchObject({ feedback: { code: "model-worker-invalid-message" }, kind: "error", }); }); it("rejects an authenticated repair result whose outcome contradicts diagnostics", async () => { const worker = new FakeWorker(); const client = createToolcraftModelWorkerClient({ workerFactory: () => worker }); const document = createValidModelDocument(); const plan = fakeRepairPlan(); const documentBytes = encodeToolcraftModelDocument(document); const envelopeBytes = encodeToolcraftModelRepairPlanEnvelope(plan); const envelopeDigest = digestToolcraftModelWorkerBytes(envelopeBytes); const pending = client.repair({ canonicalDocument: documentBytes, canonicalDocumentDigest: digestToolcraftModelDocument(document), jobId: "repair-outcome-contradiction", limits: TOOLCRAFT_DEFAULT_MODEL_IMPORT_LIMITS, repairPlanEnvelope: { bytes: envelopeBytes.buffer, envelopeDigest, planDigest: plan.planDigest, version: 1, }, }); await vi.waitFor(() => expect(worker.posts).toHaveLength(1)); const request = worker.posts[0]!.message; worker.emitMessage({ generation: request.generation, jobId: request.jobId, kind: "progress", phase: "repairing", progress: 0.9, }); const truthful = snapshotToolcraftModelWorkerAnalysisSummary( analyzeToolcraftModel( document, "realtime-mesh", TOOLCRAFT_DEFAULT_MODEL_IMPORT_LIMITS, ), ); const contradictory = { ...truthful, outcome: truthful.diagnostics.some(({ severity }) => severity === "warning") ? "clean" as const : "warning" as const, }; const canonicalDocument = copyArrayBuffer(documentBytes); const resultWithoutReceipt = { analysis: contradictory, canonicalDocument, canonicalDocumentDigest: digestToolcraftModelDocument(document), operation: "repair" as const, repairPlanDigest: plan.planDigest, }; worker.emitMessage({ generation: request.generation, jobId: request.jobId, kind: "result", result: { ...resultWithoutReceipt, receiptDigest: createToolcraftModelWorkerReceiptDigest({ generation: request.generation, jobId: request.jobId, repairPlanEnvelope: { byteLength: envelopeBytes.byteLength, envelopeDigest, planDigest: plan.planDigest, version: 1, }, result: resultWithoutReceipt, }), }, }); await expect(pending).resolves.toMatchObject({ feedback: { code: "model-worker-invalid-message" }, kind: "error", }); });});