55 lines
2.3 KiB
TypeScript
55 lines
2.3 KiB
TypeScript
import * as fs from "node:fs";
|
|
import * as os from "node:os";
|
|
import * as path from "node:path";
|
|
import { describe, expect, it } from "vitest";
|
|
import { createModelAccessReceipt, writeModelAccessReceipt } from "./model-access-receipt.js";
|
|
|
|
describe("model access receipt", () => {
|
|
it("verifies available model surfaces with freshness", () => {
|
|
const receipt = createModelAccessReceipt({
|
|
now: new Date("2026-06-27T00:00:00.000Z"),
|
|
freshnessHours: 6,
|
|
probes: [
|
|
{ surface: "openrouter", command: "fixture", status: "available", model: "openai/codex", evidence: "API_OK" },
|
|
],
|
|
});
|
|
|
|
expect(receipt.schema).toBe("fable.model_access.receipt.v1");
|
|
expect(receipt.decision).toBe("verified");
|
|
expect(receipt.freshness.expiresAt).toBe("2026-06-27T06:00:00.000Z");
|
|
expect(receipt.claims).toEqual(["openrouter:openai/codex available"]);
|
|
});
|
|
|
|
it("does not claim ChatGPT Cyber when blocked", () => {
|
|
const receipt = createModelAccessReceipt({
|
|
probes: [
|
|
{ surface: "chatgpt-cyber", command: "curl https://chatgpt.com/cyber", status: "blocked", evidence: "403 Forbidden" },
|
|
{ surface: "pi", command: "pi --list-models cyber", status: "missing", evidence: "No models matching cyber" },
|
|
],
|
|
});
|
|
|
|
expect(receipt.decision).toBe("blocked");
|
|
expect(receipt.claims).toEqual([]);
|
|
expect(receipt.reasons).toContain("ChatGPT Cyber access not verified");
|
|
});
|
|
|
|
it("tracks Fugu Ultra without claiming access", () => {
|
|
const receipt = createModelAccessReceipt({
|
|
probes: [{ surface: "sakana-fugu", command: "sakana/fugu-ultra access probe", status: "unknown", model: "fugu-ultra", evidence: "not probed; do not buy or bypass with VPN" }],
|
|
});
|
|
|
|
expect(receipt.decision).toBe("blocked");
|
|
expect(receipt.claims).toEqual([]);
|
|
expect(receipt.reasons).toContain("one or more model surfaces are unknown");
|
|
});
|
|
|
|
it("writes a JSON receipt", () => {
|
|
const dir = fs.mkdtempSync(path.join(os.tmpdir(), "model-access-"));
|
|
const file = path.join(dir, "receipt.json");
|
|
|
|
writeModelAccessReceipt(file, createModelAccessReceipt({ probes: [{ surface: "other", command: "echo ok", status: "available", evidence: "ok" }] }));
|
|
|
|
expect(fs.readFileSync(file, "utf-8")).toContain("fable.model_access.receipt.v1");
|
|
});
|
|
});
|