tests / route.test.ts
import { describe, expect, it } from "vitest";
import { MANUAL, refusalMessage, route } from "../src/route";
import { HAZARDS, type Assessment, type Hazard, type Settings } from "../src/types";
const settings: Settings = {
blockThreshold: 0.7,
reviewThreshold: 0.35,
severityBlock: 2,
defaultTimeoutSec: 30,
maxTimeoutSec: 120,
maxOutputChars: 20000,
};
function assessment(hazards: Partial<Record<Hazard, number>>, severity = 0): Assessment {
const full = Object.fromEntries(HAZARDS.map(h => [h, 0])) as Record<Hazard, number>;
return { hazards: { ...full, ...hazards }, severity };
}
describe("route", () => {
it("passes when everything is low", () => {
expect(route(assessment({ destroys_data: 0.1 }, 0.4), settings)).toEqual({ kind: "pass" });
});
it("blocks at the block threshold and refuses as uncertain just below it", () => {
expect(route(assessment({ destroys_data: 0.7 }), settings).kind).toBe("block");
expect(route(assessment({ destroys_data: 0.69 }), settings).kind).toBe("uncertain");
});
it("refuses as uncertain at the review threshold and passes just below it", () => {
expect(route(assessment({ obfuscated: 0.35 }), settings).kind).toBe("uncertain");
expect(route(assessment({ obfuscated: 0.34 }), settings).kind).toBe("pass");
});
it("blocks on severity alone", () => {
expect(route(assessment({}, 2), settings).kind).toBe("block");
expect(route(assessment({}, 1.99), settings).kind).toBe("pass");
});
it("names the highest-probability hazard", () => {
const verdict = route(assessment({ network_exfil: 0.5, destroys_data: 0.4 }), settings);
expect(verdict).toMatchObject({ kind: "uncertain", hazard: "network_exfil", probability: 0.5 });
});
it("respects custom thresholds", () => {
const strict = { ...settings, blockThreshold: 0.3, reviewThreshold: 0.1 };
expect(route(assessment({ touches_system: 0.3 }), strict).kind).toBe("block");
});
});
describe("refusalMessage", () => {
it("explains the hazard and tells the model to hand off to the user", () => {
const verdict = route(assessment({ destroys_data: 0.91 }, 2.3), settings);
if (verdict.kind === "pass") throw new Error("expected a refusal");
const message = refusalMessage(verdict);
expect(message).toContain("Blocked");
expect(message).toContain("judged unsafe");
expect(message).toContain("delete or overwrite data");
expect(message).toContain("p=0.91");
expect(message).toContain(MANUAL);
});
it("words uncertain refusals differently from blocks", () => {
const verdict = route(assessment({ destroys_data: 0.5 }), settings);
if (verdict.kind === "pass") throw new Error("expected a refusal");
expect(refusalMessage(verdict)).toContain("could not be confirmed safe");
});
});
tests / route.test.ts
import { describe, expect, it } from "vitest";
import { MANUAL, refusalMessage, route } from "../src/route";
import { HAZARDS, type Assessment, type Hazard, type Settings } from "../src/types";
const settings: Settings = {
blockThreshold: 0.7,
reviewThreshold: 0.35,
severityBlock: 2,
defaultTimeoutSec: 30,
maxTimeoutSec: 120,
maxOutputChars: 20000,
};
function assessment(hazards: Partial<Record<Hazard, number>>, severity = 0): Assessment {
const full = Object.fromEntries(HAZARDS.map(h => [h, 0])) as Record<Hazard, number>;
return { hazards: { ...full, ...hazards }, severity };
}
describe("route", () => {
it("passes when everything is low", () => {
expect(route(assessment({ destroys_data: 0.1 }, 0.4), settings)).toEqual({ kind: "pass" });
});
it("blocks at the block threshold and refuses as uncertain just below it", () => {
expect(route(assessment({ destroys_data: 0.7 }), settings).kind).toBe("block");
expect(route(assessment({ destroys_data: 0.69 }), settings).kind).toBe("uncertain");
});
it("refuses as uncertain at the review threshold and passes just below it", () => {
expect(route(assessment({ obfuscated: 0.35 }), settings).kind).toBe("uncertain");
expect(route(assessment({ obfuscated: 0.34 }), settings).kind).toBe("pass");
});
it("blocks on severity alone", () => {
expect(route(assessment({}, 2), settings).kind).toBe("block");
expect(route(assessment({}, 1.99), settings).kind).toBe("pass");
});
it("names the highest-probability hazard", () => {
const verdict = route(assessment({ network_exfil: 0.5, destroys_data: 0.4 }), settings);
expect(verdict).toMatchObject({ kind: "uncertain", hazard: "network_exfil", probability: 0.5 });
});
it("respects custom thresholds", () => {
const strict = { ...settings, blockThreshold: 0.3, reviewThreshold: 0.1 };
expect(route(assessment({ touches_system: 0.3 }), strict).kind).toBe("block");
});
});
describe("refusalMessage", () => {
it("explains the hazard and tells the model to hand off to the user", () => {
const verdict = route(assessment({ destroys_data: 0.91 }, 2.3), settings);
if (verdict.kind === "pass") throw new Error("expected a refusal");
const message = refusalMessage(verdict);
expect(message).toContain("Blocked");
expect(message).toContain("judged unsafe");
expect(message).toContain("delete or overwrite data");
expect(message).toContain("p=0.91");
expect(message).toContain(MANUAL);
});
it("words uncertain refusals differently from blocks", () => {
const verdict = route(assessment({ destroys_data: 0.5 }), settings);
if (verdict.kind === "pass") throw new Error("expected a refusal");
expect(refusalMessage(verdict)).toContain("could not be confirmed safe");
});
});