import test from "node:test"; import assert from "node:assert/strict"; import { DatabaseSync } from "node:sqlite"; import { readFileSync } from "node:fs"; import { answerLab, validExperiment, validPlan } from "../lib/lab-server.mjs"; import { answerQuestion } from "../lib/guide-server.mjs"; import { BUDGET_ID, LIMIT_MICROS, RESERVATION_MICROS, reserveRequest, allowRate } from "../lib/guide-budget.mjs"; import { readVisitorRequest } from "../lib/request-guard.mjs"; import { documentPolicy, workerPolicy, securityHeaders } from "../lib/security-headers.mjs"; const reference = JSON.parse(readFileSync(new URL("../lib/lab-reference.json", import.meta.url), "utf8")); const initial = { left: 60, right: 80, dataset: "diverse" }; const plan = { action: "compare", left: 100, right: 50, dataset: "diverse", message: "Compare all A with an equal mix." }; const request = (body = { stage: "plan", question: "What changes when I diversify?", experiment: initial }, extra = {}) => new Request("https://daneanderson.dev/api/lab", { method: "POST", headers: { Origin: "https://daneanderson.dev", "Content-Type": "application/json", ...extra }, body: JSON.stringify(body) }); const response = text => Response.json({ output: [{ type: "message", content: [{ type: "output_text", text }] }] }); function database() { const sqlite = new DatabaseSync(":memory:"); sqlite.exec(readFileSync(new URL("../drizzle/0000_magenta_rawhide_kid.sql", import.meta.url), "utf8")); const db = { prepare(sql) { const stmt = sqlite.prepare(sql); return { bind(...args) { return { async run() { return stmt.run(...args); }, async first() { return stmt.get(...args); } }; } }; } }; return { db, sqlite }; } function options(db, overrides = {}) { return { db, key: "test-placeholder", enabled: true, reference, hashIp: async () => "shared-visitor", now: Date.parse("2026-10-24T12:00:00Z"), fetcher: async () => response(JSON.stringify(plan)), ...overrides }; } test("only bounded allocation data can become an experiment", () => { assert.equal(validExperiment(initial), true); for (const bad of [{ ...initial, left: -1 }, { ...initial, left: 101 }, { ...initial, left: 0.5 }, { ...initial, left: "60" }, { ...initial, left: true }, { ...initial, right: Infinity }, { ...initial, dataset: "https://example.com/data" }, { ...initial, code: "import os" }]) assert.equal(validExperiment(bad), false); assert.equal(validPlan(plan), true); assert.equal(validPlan({ ...plan, action: "execute_python" }), false); assert.equal(validPlan({ ...plan, code: "print('untrusted')" }), false); }); test("model context comes from Python reference results, and each call is bounded and reserved", async () => { const { db, sqlite } = database(); let calls = 0; const result = await answerLab(request(), options(db, { fetcher: async (url, init) => { calls++; assert.equal(sqlite.prepare("SELECT requests FROM guide_budget").get().requests, 1); assert.equal(url, "https://api.openai.com/v1/responses"); const p = JSON.parse(init.body); assert.ok(Buffer.byteLength(init.body) <= 6000); assert.equal(p.max_output_tokens, 600); assert.equal(p.store, false); assert.equal(p.tools, undefined); assert.equal(p.text.format.strict, true); assert.deepEqual(JSON.parse(p.input).calculatedSnapshot.left, reference.diverse[60]); return response(JSON.stringify(plan)); } })); assert.equal(result.status, 200); assert.equal(calls, 1); assert.deepEqual((await result.json()).plan, plan); }); test("forged summaries, oversized requests, cross-site requests and unknown fields never reach the model", async () => { const { db } = database(); let calls = 0; const opts = options(db, { fetcher: async () => { calls++; return response("bad"); } }); const base = { stage: "explain", question: "Explain", experiment: initial }; for (const req of [request({ ...base, result: { totalReturn: 999 } }), request({ ...base, question: "x".repeat(701) }), request(base, { Origin: "https://other.test" }), request(base, { "Sec-Fetch-Site": "cross-site" }), request(base, { "Content-Type": "application/jsonx" }), request({ ...base, experiment: { ...initial, left: -50 } })]) assert.ok((await answerLab(req, opts)).status >= 400); assert.equal(calls, 0); }); test("invalid or incomplete model plans are rejected and never retried", async () => { for (const text of ["not json", JSON.stringify({ ...plan, left: 101 }), JSON.stringify({ ...plan, action: "shell" })]) { const { db, sqlite } = database(); let calls = 0; const res = await answerLab(request(), options(db, { fetcher: async () => { calls++; return response(text); } })); assert.equal(res.status, 503); assert.equal(calls, 1); assert.equal(sqlite.prepare("SELECT reserved_micros FROM guide_budget").get().reserved_micros, RESERVATION_MICROS); } }); test("tour, lab planning and lab explanation compete for the same final reservation", async () => { const { db, sqlite } = database(); await reserveRequest(db); sqlite.prepare("UPDATE guide_budget SET reserved_micros=? WHERE id=?").run(LIMIT_MICROS - RESERVATION_MICROS, BUDGET_ID); let calls = 0; const fetcher = async () => { calls++; return response(JSON.stringify(plan)); }; const opts = options(db, { fetcher }); const tour = request({ project: "quantcore", question: "Why a library?" }); const results = await Promise.all([ answerLab(request(), opts), answerLab(request({ stage: "explain", question: "Explain", experiment: initial }), opts), answerQuestion(tour, { ...opts, projects: [{ id: "quantcore", name: "QuantCore", decision: "Python calculates.", story: "Reusable tools.", facts: "Python library.", status: "Built." }] }) ]); assert.equal(calls, 1); assert.equal(results.filter(r => r.status === 200).length, 1); assert.equal(sqlite.prepare("SELECT reserved_micros FROM guide_budget").get().reserved_micros, LIMIT_MICROS); assert.equal(await reserveRequest(db), false); }); test("failed explanation consumes its reservation, with no retry or refund", async () => { const { db, sqlite } = database(); let calls = 0; await answerLab(request(), options(db)); const res = await answerLab(request({ stage: "explain", question: "Explain", experiment: initial }), options(db, { fetcher: async () => { calls++; throw new Error("timeout"); } })); assert.equal(res.status, 503); assert.equal(calls, 1); assert.equal(sqlite.prepare("SELECT reserved_micros FROM guide_budget").get().reserved_micros, 2 * RESERVATION_MICROS); }); test("missing storage, disabled AI, expiry and the shared hourly quota fail closed", async () => { const { db } = database(); let calls = 0; const fetcher = async () => { calls++; return response(JSON.stringify(plan)); }; for (const overrides of [{ db: null }, { enabled: false }, { key: "" }, { now: Date.parse("2026-11-23") }, { db: { prepare() { throw Error("offline"); } } }]) assert.equal((await answerLab(request(), options(db, { fetcher, ...overrides }))).status, 503); assert.equal(calls, 0); for (let i = 0; i < 8; i++) await allowRate(db, "shared-visitor", Date.parse("2026-10-24T12:00:00Z")); assert.equal((await answerLab(request(), options(db, { fetcher }))).status, 429); assert.equal(calls, 0); }); test("rate cleanup is bounded and never touches the lifetime ledger", async () => { const { db, sqlite } = database(); await reserveRequest(db); for (let i = 0; i < 150; i++) sqlite.prepare("INSERT INTO guide_rate VALUES (?,1,1)").run(`old-${i}`); await allowRate(db, "current", 10000); assert.equal(sqlite.prepare("SELECT COUNT(*) AS n FROM guide_rate WHERE expires=1").get().n, 50); assert.equal(sqlite.prepare("SELECT reserved_micros FROM guide_budget").get().reserved_micros, RESERVATION_MICROS); }); test("chunked oversize and broken request streams return controlled errors", async () => { const make = stream => new Request("https://daneanderson.dev/api/lab", { method: "POST", headers: { Origin: "https://daneanderson.dev", "Content-Type": "application/json" }, body: stream, duplex: "half" }); const large = new ReadableStream({ start(c) { c.enqueue(new Uint8Array(5000)); c.close(); } }); await assert.rejects(readVisitorRequest(make(large)), e => e.status === 413); const broken = new ReadableStream({ start(c) { c.error(new Error("interrupted")); } }); await assert.rejects(readVisitorRequest(make(broken)), e => e.status === 400); }); test("security policy uses a nonce without broad inline script or eval permissions", () => { const policy = documentPolicy("test-nonce"); const scripts = policy.split(";").find(s => s.trim().startsWith("script-src ")); assert.ok(scripts.includes("'nonce-test-nonce'")); assert.ok(!scripts.includes("'unsafe-inline'")); assert.ok(!scripts.includes("'unsafe-eval'")); const headers = securityHeaders(new Response("ok", { headers: { "Content-Type": "text/html" } }), policy).headers; assert.equal(headers.get("X-Content-Type-Options"), "nosniff"); assert.equal(headers.get("X-Frame-Options"), "DENY"); assert.equal(headers.get("Cache-Control"), "no-store"); assert.ok(headers.get("Permissions-Policy").includes("microphone=()")); const workerHeaders = securityHeaders(new Response("source", { headers: { "Content-Type": "text/javascript" } }), workerPolicy()).headers; assert.ok(workerHeaders.get("Content-Security-Policy").includes("https://cdn.jsdelivr.net/pyodide/v314.0.7/full/")); assert.ok(workerHeaders.get("Content-Security-Policy").includes("'wasm-unsafe-eval'")); assert.ok(!workerHeaders.get("Content-Security-Policy").includes("'unsafe-eval'")); }); test("a stalled body is cancelled within the input deadline", async () => { let cancelled = false; const stream = new ReadableStream({ cancel() { cancelled = true; } }); const req = new Request("https://daneanderson.dev/api/lab", { method: "POST", headers: { Origin: "https://daneanderson.dev", "Content-Type": "application/json" }, body: stream, duplex: "half" }); await assert.rejects(readVisitorRequest(req), e => e.status === 408); assert.equal(cancelled, true); });