Something went wrong. Try again.
A local-first event pipeline for independent agents, built on Jazz.
Something went wrong. Try again.
26 kB · 630 lines
TypeScript
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631import fs from "node:fs/promises";import { afterEach, describe, expect, test } from "vitest";import type { ModelAdapterIdentity } from "../src/adapters/model-adapters.js";import { outputContractForDeclaration, outputContractIdentityJson } from "../src/agents/output-contracts.js";import { CORRECTION_PROPOSAL_EVENT_TYPE, REPAIR_REQUEST_EVENT_TYPE, RepairRequestCoordinator, createRepairPolicy,} from "../src/agents/repairs.js";import { ThoughtAgentRuntime } from "../src/agents/runtime.js";import { AgentRunFailure, type AgentRunner, type ThoughtAgentDeclaration } from "../src/agents/types.js";import { sha256, type JsonObject } from "../src/core/json.js";import { stableKey } from "../src/core/ids.js";import type { JazzThoughtStore } from "../src/jazz/store.js";import { projectTrainingExamples, recordJudgment, retractJudgment } from "../src/training/judgments.js";import { temporaryProject, testInferenceAccountingPolicy, testStore } from "./helpers.js";
const stores: JazzThoughtStore[] = [];const roots: string[] = [];
const malformedCandidate = "PRIVATE_MALFORMED_MODEL_TEXT";
afterEach(async () => { await Promise.all(stores.splice(0).map((store) => store.close())); await Promise.all(roots.splice(0).map((root) => fs.rm(root, { recursive: true, force: true })));});
describe("append-only output repair", () => { test("emits one deterministic request and one inert sandbox-role proposal across restart reconciliation", async () => { const { store } = await fixtureStore(); await appendSource(store); const original = originalDeclaration(); const repair = repairDeclaration(); let repairCalls = 0; const runner = fixtureRunner(original, async (contextText) => { repairCalls += 1; expect(contextText).toContain(original.systemPrompt); expect(contextText).toContain("A source item that needs a bounded observation"); expect(contextText).not.toContain(malformedCandidate); return validOutput("Conservative repaired observation"); });
const firstRuntime = new ThoughtAgentRuntime(store, [runner]); const first = await firstRuntime.consumeBacklog([original, repair]);
expect(first).toHaveLength(2); expect(first[0]).toMatchObject({ declaration: { id: original.id }, error: expect.any(String) }); expect(first[1]).toMatchObject({ declaration: { id: repair.id, role: "repair" }, output: { summary: "Conservative repaired observation" }, derivedEvent: { type: CORRECTION_PROPOSAL_EVENT_TYPE }, }); expect(repairCalls).toBe(1); const accounting = await store.listInferenceAccounting(); expect(accounting).toHaveLength(2); expect(accounting.map((record) => record.agentId).sort()).toEqual([original.id, repair.id].sort()); expect(accounting.every((record) => record.status === "settled" && record.usageStatus === "unavailable")).toBe(true);
const requests = await store.listEvents({ types: [REPAIR_REQUEST_EVENT_TYPE] }); const proposals = await store.listEvents({ types: [CORRECTION_PROPOSAL_EVENT_TYPE] }); expect(requests).toHaveLength(1); expect(proposals).toHaveLength(1); expect(requests[0]).toMatchObject({ parentEventId: expect.any(String), rootEventId: expect.any(String), payload: { originalRunId: expect.any(String), originalFailedEventId: expect.any(String), declarationFingerprint: expect.stringMatching(/^[a-f0-9]{64}$/), promptSha256: sha256(original.systemPrompt), outputContract: outputContractIdentityJson(outputContractForDeclaration(original)), model: { provider: "tinker", id: "fixture-model", checkpointRevision: "fixture-checkpoint", adapterRevision: "pi-openai-completions-v1", }, evidenceSha256: expect.stringMatching(/^[a-f0-9]{64}$/), }, }); expect(proposals[0]).toMatchObject({ parentEventId: requests[0]!.id, rootEventId: requests[0]!.rootEventId, payload: { originalRunId: requests[0]!.payload.originalRunId, repairRequestEventId: requests[0]!.id, repairRunId: expect.any(String), originalTriggerEventId: requests[0]!.payload.originalTriggerEventId, sourceRootEventId: requests[0]!.rootEventId, originalModel: requests[0]!.payload.model, repairModel: { provider: "tinker", id: "fixture-model", executionAdapterRevision: "pi-openai-completions-v1", }, structuredOutput: validOutput("Conservative repaired observation"), }, });
const serialized = JSON.stringify({ requests, proposals, runs: await store.listRuns(), events: await store.listEvents() }); expect(serialized).not.toContain(malformedCandidate); expect(serialized).not.toContain("rawOutput"); expect(serialized).not.toContain("providerBody");
const restartedRuntime = new ThoughtAgentRuntime(store, [runner]); const second = await restartedRuntime.consumeBacklog([original, repair]); expect(second).toEqual([]); expect(repairCalls).toBe(1); expect(await store.listEvents({ types: [REPAIR_REQUEST_EVENT_TYPE] })).toHaveLength(1); expect(await store.listEvents({ types: [CORRECTION_PROPOSAL_EVENT_TYPE] })).toHaveLength(1); });
test("consumes a reconciled repair request already present when live consumers start", async () => { const { store } = await fixtureStore(); await appendSource(store); const original = originalDeclaration("restart-observer"); const repair = repairDeclaration(); await new ThoughtAgentRuntime(store, [fixtureRunner(original, async () => validOutput("unused"))]) .consumeBacklog([original]); expect(await store.listEvents({ types: [REPAIR_REQUEST_EVENT_TYPE] })).toHaveLength(1);
let repairCalls = 0; const restarted = new ThoughtAgentRuntime(store, [fixtureRunner(original, async () => { repairCalls += 1; return validOutput("Recovered from startup backlog"); })]); const consumers = await restarted.startConsumers([original, repair]); await consumers.drain(); await consumers.stop(); expect(repairCalls).toBe(1); expect(await store.listEvents({ types: [CORRECTION_PROPOSAL_EVENT_TYPE] })).toHaveLength(1); });
test("does not request repair for infrastructure, provider, timeout, auth, or incomplete failures", async () => { const { store } = await fixtureStore(); await appendSource(store); const diagnostics = new Map<string, { diagnostic: JsonObject; advanceProgress?: boolean }>([ ["provider", { diagnostic: { code: "provider-run-failed", stage: "provider" } }], ["rate-limit", { diagnostic: { code: "rate-limited", stage: "provider" } }], ["timeout", { diagnostic: { code: "timeout", stage: "provider" } }], ["sandbox", { diagnostic: { code: "sandbox-unavailable", stage: "sandbox-execution" }, advanceProgress: false }], ["auth", { diagnostic: { code: "credential-missing", stage: "configuration" } }], ["incomplete", { diagnostic: { code: "invalid-final-output", stage: "final-output-validation", reason: "invalid-json" } }], ]); const runner: AgentRunner = { mode: "pi", run: async ({ declaration }) => { const failure = diagnostics.get(declaration.id)!; throw new AgentRunFailure("Fixture failure", { diagnostic: failure.diagnostic, ...(failure.advanceProgress === false ? { advanceProgress: false } : {}), }); }, }; const declarations = [...diagnostics.keys()].map((id) => originalDeclaration(id));
await new ThoughtAgentRuntime(store, [runner]).consumeBacklog(declarations);
expect(await store.listEvents({ types: [REPAIR_REQUEST_EVENT_TYPE] })).toEqual([]); });
test("requires an explicit stable-rule allowlist for semantic validation failures", async () => { const { store } = await fixtureStore(); await appendSource(store); const original = originalDeclaration("semantic-observer"); const semanticDiagnostic: JsonObject = { ...invalidOutputDiagnostic(original), code: "semantic-output-invalid", reason: "semantic-output-invalid", semanticValidationId: "semantic.observation.consistency@1", validationIssues: [{ code: "semantic-consistency", path: ["recommendation"] }], }; const runner: AgentRunner = { mode: "pi", run: async () => { throw new AgentRunFailure("Semantic output rejected", { diagnostic: semanticDiagnostic }); }, }; await new ThoughtAgentRuntime(store, [runner]).consumeBacklog([original]); expect(await store.listEvents({ types: [REPAIR_REQUEST_EVENT_TYPE] })).toEqual([]);
const disallowed = await new RepairRequestCoordinator(store, createRepairPolicy(["semantic.other@1"])) .reconcile([original]); expect(disallowed.inserted).toBe(0); const allowed = await new RepairRequestCoordinator(store, createRepairPolicy(["semantic.observation.consistency@1"])) .reconcile([original]); expect(allowed.inserted).toBe(1); expect((await store.listEvents({ types: [REPAIR_REQUEST_EVENT_TYPE] }))[0]).toMatchObject({ payload: { failure: { code: "semantic-output-invalid", semanticValidationId: "semantic.observation.consistency@1", validationIssues: [{ code: "semantic-consistency", path: ["recommendation"] }], }, }, }); });
test("a failed repair advances its request and cannot recurse", async () => { const { store } = await fixtureStore(); await appendSource(store); const original = originalDeclaration(); const repair = repairDeclaration(); let repairCalls = 0; const runner = fixtureRunner(original, async () => { repairCalls += 1; return { ...validOutput("Invalid repair"), unexpected: "schema drift" } as never; }); const runtime = new ThoughtAgentRuntime(store, [runner]);
const first = await runtime.consumeBacklog([original, repair]); expect(first).toHaveLength(2); expect(first[1]).toMatchObject({ declaration: { role: "repair" }, error: "Agent final output rejected by canonical contract" }); expect(await store.listEvents({ types: [REPAIR_REQUEST_EVENT_TYPE] })).toHaveLength(1); expect(await store.listEvents({ types: [CORRECTION_PROPOSAL_EVENT_TYPE] })).toEqual([]); expect((await store.listRuns()).filter((run) => run.agentId === repair.id)).toEqual([ expect.objectContaining({ status: "failed", outputEventIds: [] }), ]);
expect(await runtime.consumeBacklog([original, repair])).toEqual([]); expect(repairCalls).toBe(1); expect(await store.listEvents({ types: [REPAIR_REQUEST_EVENT_TYPE] })).toHaveLength(1); });
test("only active human judgments make a proposal effective or training-eligible", async () => { const { store } = await fixtureStore(); await appendSource(store); const original = originalDeclaration(); const repair = repairDeclaration(); const runner = fixtureRunner(original, async () => validOutput("Proposed repair")); await new ThoughtAgentRuntime(store, [runner]).consumeBacklog([original, repair]); const originalRun = (await store.listRuns()).find((run) => run.agentId === original.id)!; const repairRun = (await store.listRuns()).find((run) => run.agentId === repair.id)!; const proposal = (await store.listEvents({ types: [CORRECTION_PROPOSAL_EVENT_TYPE] }))[0]!; const projectionId = stableKey("effective-output", originalRun.id);
expect(await store.getProjection(projectionId)).toMatchObject({ payload: { originalRunId: originalRun.id, status: "unresolved" }, }); expect(await projectTrainingExamples(store)).toEqual([]);
const rejected = await recordJudgment(store, { runId: repairRun.id, kind: "reject", criterion: "repair-fidelity", criterionVersion: 1, qualityEligible: true, externalExportEligible: true, sensitiveExternalExportAuthorized: true, }); expect(await store.getProjection(projectionId)).toMatchObject({ payload: { originalRunId: originalRun.id, status: "unresolved" }, }); expect(await projectTrainingExamples(store)).toEqual([]);
await store.appendTrace({ id: "repair-trace-allowed", runId: repairRun.id, sequence: 1, type: "sandbox.provider.request", payload: { bodySha256: sha256("SECRET_PROVIDER_BODY"), raw: "SECRET_ALLOWED_TRACE_PAYLOAD" }, createdAt: "2026-07-15T00:00:02.000Z", }); await store.appendTrace({ id: "repair-trace-disallowed", runId: repairRun.id, sequence: 2, type: "untrusted.raw.model.output", payload: { raw: "SECRET_DISALLOWED_TRACE_PAYLOAD" }, createdAt: "2026-07-15T00:00:03.000Z", }); const accepted = await recordJudgment(store, { runId: repairRun.id, kind: "accept", criterion: "repair-fidelity", criterionVersion: 1, qualityEligible: true, externalExportEligible: true, sensitiveExternalExportAuthorized: true, supersedesJudgmentEventId: rejected.id, }); expect(await store.getProjection(projectionId)).toMatchObject({ payload: { originalRunId: originalRun.id, status: "repair", authority: "accept", repairRunId: repairRun.id, judgmentEventId: accepted.id, originalModel: { provider: originalRun.provider, id: originalRun.model, executionAdapterRevision: originalRun.executionAdapterRevision, }, repairModel: { provider: repairRun.provider, id: repairRun.model, executionAdapterRevision: repairRun.executionAdapterRevision, }, structuredOutput: validOutput("Proposed repair"), }, });
const correctedOutput = validOutput("Human-corrected repair"); const corrected = await recordJudgment(store, { runId: repairRun.id, kind: "correct", criterion: "repair-fidelity", criterionVersion: 1, replacementOutput: correctedOutput, qualityEligible: true, externalExportEligible: true, sensitiveExternalExportAuthorized: true, supersedesJudgmentEventId: accepted.id, }); expect(await store.getProjection(projectionId)).toMatchObject({ payload: { status: "repair", authority: "correct", judgmentEventId: corrected.id, structuredOutput: correctedOutput, }, }); expect(await projectTrainingExamples(store)).toEqual([]); const examples = await projectTrainingExamples(store, { includeSensitivePrivate: true }); expect(examples).toEqual([ expect.objectContaining({ kind: "correct", chosen: correctedOutput, rejected: validOutput("Proposed repair"), input: { event: { type: "stream.thought.source.rss.item", schemaVersion: 1, sourceKind: "rss", privacy: "private", }, contextManifest: expect.any(Object), }, trajectory: [{ sequence: 1, type: "sandbox.provider.request" }], provenance: expect.objectContaining({ outputContract: outputContractIdentityJson(outputContractForDeclaration(original)), repair: true, }), originalProvenance: expect.objectContaining({ provider: originalRun.provider, model: originalRun.model, outputContract: outputContractIdentityJson(outputContractForDeclaration(original)), }), }), ]); const serializedExamples = JSON.stringify(examples); expect(serializedExamples).not.toContain("SECRET_PROVIDER_BODY"); expect(serializedExamples).not.toContain("SECRET_ALLOWED_TRACE_PAYLOAD"); expect(serializedExamples).not.toContain("SECRET_DISALLOWED_TRACE_PAYLOAD"); expect(serializedExamples).not.toContain("A source item that needs a bounded observation");
await store.upsertRun({ ...originalRun, modelAdapter: forbiddenAdapterIdentity(), privacy: "private" }); expect(await projectTrainingExamples(store, { includeSensitivePrivate: true, includeRestrictedModelAdapters: true, })).toEqual([]); await store.upsertRun(originalRun);
const source = (await store.listEvents({ types: ["stream.thought.source.rss.item"] }))[0]!; const feedback = await store.appendEvent({ type: "stream.thought.source.telegram.reaction", schemaVersion: 1, source: "telegram:fixture", sourceKind: "telegram", externalId: "retract-feedback", idempotencyKey: "retract-feedback", occurredAt: "2026-07-15T00:00:04.000Z", actor: "telegram:user:fixture", rootEventId: source.rootEventId, parentEventId: proposal.id, correlationId: repairRun.id, privacy: "private", payload: { emoji: "undo" }, }); const receipt = await store.appendEvent({ type: "stream.thought.action.telegram.send.delivered", schemaVersion: 1, source: "telegram:dispatcher-fixture", sourceKind: "system", externalId: "repair-delivery", idempotencyKey: "repair-delivery", occurredAt: "2026-07-15T00:00:03.500Z", actor: "telegram:dispatcher-fixture", rootEventId: source.rootEventId, parentEventId: proposal.id, correlationId: repairRun.id, privacy: "private", payload: { runIds: [repairRun.id], messageId: 42 }, }); await retractJudgment(store, { runId: repairRun.id, criterion: "repair-fidelity", criterionVersion: 1, retractedJudgmentEventId: corrected.id, feedbackSourceEventId: feedback.event.id, deliveryReceiptEventId: receipt.event.id, }); expect(await store.getProjection(projectionId)).toMatchObject({ payload: { originalRunId: originalRun.id, status: "unresolved" }, }); expect(await projectTrainingExamples(store)).toEqual([]); });
test("rejects corrections that do not validate against the original output contract", async () => { const { store } = await fixtureStore(); await appendSource(store); const original = originalDeclaration(); const repair = repairDeclaration(); await new ThoughtAgentRuntime(store, [fixtureRunner(original, async () => validOutput("Proposed repair"))]) .consumeBacklog([original, repair]); const repairRun = (await store.listRuns()).find((run) => run.agentId === repair.id)!;
await expect(recordJudgment(store, { runId: repairRun.id, kind: "correct", criterion: "repair-fidelity", criterionVersion: 1, replacementOutput: { summary: "Missing contract fields" }, qualityEligible: true, externalExportEligible: true, sensitiveExternalExportAuthorized: true, })).rejects.toThrow("Output does not satisfy stream.thought.output.observation@1"); expect(await store.listEvents({ types: ["stream.thought.judgment.training-example"] })).toEqual([]); });
test("an interrupted repair is terminally abandoned and never generates a second proposal attempt", async () => { const { store } = await fixtureStore(); await appendSource(store); const original = originalDeclaration(); const originalOnlyRunner = fixtureRunner(original, async () => validOutput("unused")); await new ThoughtAgentRuntime(store, [originalOnlyRunner]).consumeBacklog([original]); const request = (await store.listEvents({ types: [REPAIR_REQUEST_EVENT_TYPE] }))[0]!; const repair = repairDeclaration(); const executionKey = stableKey("execution", repair.id, String(repair.version), request.id); const interruptedRunId = stableKey("run", executionKey, "1"); await store.upsertRun({ id: interruptedRunId, executionKey, triggerEventId: request.id, agentId: repair.id, agentVersion: repair.version, status: "running", inputEventIds: [request.id], outputEventIds: [], attempt: 1, provider: "tinker", model: "fixture-model", adapterRevision: "fixture", promptHash: sha256(repair.systemPrompt), contextManifest: {}, createdAt: "2026-07-15T00:00:00.000Z", startedAt: "2026-07-15T00:00:00.000Z", updatedAt: "2026-07-15T00:00:00.000Z", }); let repairCalls = 0; const repairRunner: AgentRunner = { mode: "pi", run: async () => { repairCalls += 1; return validOutput("Must not be called"); }, }; const runtime = new ThoughtAgentRuntime(store, [repairRunner]);
const first = await runtime.consumeBacklog([repair]); expect(first).toEqual([ expect.objectContaining({ runId: interruptedRunId, error: "Interrupted repair run was terminally abandoned without another proposal attempt", }), ]); expect(repairCalls).toBe(0); expect(await store.getRun(interruptedRunId)).toMatchObject({ status: "abandoned" }); expect(await store.listEvents({ types: [CORRECTION_PROPOSAL_EVENT_TYPE] })).toEqual([]); expect(await runtime.consumeBacklog([repair])).toEqual([]); expect(repairCalls).toBe(0); });});
async function fixtureStore(): Promise<{ project: string; store: JazzThoughtStore }> { const project = await temporaryProject(); roots.push(project); const store = await testStore(project); stores.push(store); return { project, store };}
async function appendSource(store: JazzThoughtStore): Promise<void> { await store.appendEvent({ type: "stream.thought.source.rss.item", schemaVersion: 1, source: "rss:fixture", sourceKind: "rss", externalId: "repair-fixture", idempotencyKey: "repair-fixture", occurredAt: "2026-07-15T00:00:00.000Z", actor: "rss:fixture", correlationId: "repair-fixture", privacy: "private", payload: { title: "A source item that needs a bounded observation" }, });}
function fixtureRunner( original: ThoughtAgentDeclaration, repairOutput: (contextText: string) => Promise<ReturnType<typeof validOutput>>,): AgentRunner { return { mode: "pi", run: async ({ declaration, context }) => { if ((declaration.role ?? "standard") === "repair") return repairOutput(context.text); throw new AgentRunFailure("Pi final output rejected: expected one strict JSON object", { diagnostic: invalidOutputDiagnostic(original), }); }, };}
function invalidOutputDiagnostic(declaration: ThoughtAgentDeclaration): JsonObject { return { code: "invalid-final-output", stage: "final-output-validation", reason: "invalid-json", assistantMessages: 1, textParts: 1, textChars: malformedCandidate.length, textSha256: sha256(malformedCandidate), thinkingParts: 0, thinkingChars: 0, thinkingRedacted: true, toolCallParts: 0, otherParts: 0, stopReason: "stop", outputContract: outputContractIdentityJson(outputContractForDeclaration(declaration)), provider: "tinker", model: "fixture-model", checkpointRevision: "fixture-checkpoint", };}
function originalDeclaration(id = "original-observer"): ThoughtAgentDeclaration { return { id, version: 1, name: id, description: "Original fixture observer", mode: "pi", role: "standard", outputContract: outputContractForDeclaration({} as ThoughtAgentDeclaration), provider: "tinker", providerProfile: "tinker-default", model: "fixture-model", eventTypes: ["stream.thought.source.rss.item"], compiledEventTypes: ["stream.thought.source.rss.item"], sourcePatterns: ["rss:fixture"], acceptedPrivacy: ["private"], outputEventType: "stream.thought.derived.document.read", emit: ["stream.thought.derived.document.read"], promptRef: "prompts/original.md", systemPrompt: "Observe the source fixture.", enabled: true, maxEvents: 1, maxInputChars: 10_000, maxOutputTokens: 500, timeoutMs: 5_000, accounting: testInferenceAccountingPolicy(), tools: [], externalActions: false, };}
function repairDeclaration(): ThoughtAgentDeclaration { return { id: "output-repair", version: 1, name: "Output repair", description: "Repair fixture", mode: "pi", role: "repair", outputContract: outputContractForDeclaration({} as ThoughtAgentDeclaration), provider: "tinker", providerProfile: "tinker-default", model: "fixture-model", eventTypes: [REPAIR_REQUEST_EVENT_TYPE], compiledEventTypes: [REPAIR_REQUEST_EVENT_TYPE], sourcePatterns: ["repair:output-contract"], acceptedPrivacy: ["private"], outputEventType: CORRECTION_PROPOSAL_EVENT_TYPE, emit: [CORRECTION_PROPOSAL_EVENT_TYPE], promptRef: "prompts/output-repair.md", systemPrompt: "Propose one contract-valid correction.", enabled: true, maxEvents: 2, maxInputChars: 64_000, maxOutputTokens: 2_000, timeoutMs: 60_000, accounting: testInferenceAccountingPolicy(), tools: [], externalActions: false, };}
function validOutput(summary: string) { return { summary, tags: ["repair"], importance: "normal" as const, confidence: 0.7 };}
function forbiddenAdapterIdentity(): ModelAdapterIdentity { return { id: "forbidden-original-adapter", version: 1, description: "Forbidden original repair fixture", releasedAt: "2026-07-15T00:00:00.000Z", manifestSha256: "a".repeat(64), checkpointSelector: { kind: "env", reference: "THOUGHTSTREAM_FORBIDDEN_FIXTURE" }, providerProfile: "tinker-default", baseModel: "Qwen/Qwen3.5-4B", dataset: { id: "forbidden-dataset", sha256: "b".repeat(64) }, evals: [{ id: "forbidden-eval", sha256: "c".repeat(64) }], capabilities: ["repair-fixture"], privacyClass: "private", exportClass: "forbidden", binding: { checkpointReferenceSha256: "d".repeat(64) }, };}