import test from "node:test"; import assert from "node:assert/strict"; import { join } from "node:path"; import { BusinessError, checkVars, loadBusiness, loadProject, projectFilePath, systemVars, } from "../src/index.mjs"; import { businessDoc, REPO_ROLES, tmp, writeJson } from "./helpers.mjs"; import { checkRoutes, launchSettings } from "../src/launch-settings.mjs"; import { OrganizationError } from "../src/organization.mjs"; const SECRET = "sk-test-NOT-A-SECRET-1234"; function hidesValue(fn, key, reason) { assert.throws(fn, (error) => { assert.ok(error instanceof BusinessError); assert.equal(error.name, "BusinessError"); assert.equal(error.exitCode, 2); assert.ok(error.message.includes(`variable ${key}`), error.message); if (reason) assert.match(error.message, reason); assert.ok(!error.message.includes(SECRET), "refusal disclosed a var value"); assert.ok(!String(error).includes(SECRET), "rendered error disclosed a var value"); return true; }); } for (const [scope, key, value] of [ ["business", "tracker.kind", SECRET], ["agent", "thinking", SECRET], ["agent", "model", SECRET], ]) { test(`organization file ${scope} ${key} refusal names its key and hides its value`, () => { const root = tmp(); const doc = businessDoc(root); if (scope === "agent") doc.roles.coder.vars[key] = value; else doc.vars[key] = value; writeJson(join(root, "businesses/acme.json"), doc); hidesValue(() => loadBusiness("acme", { dir: root, rolesDir: REPO_ROLES }), key, key === "model" ? /unknown model/ : /one of/); }); } for (const scope of ["project", "role"]) { test(`project file ${scope} var refusal names its key and hides its value`, () => { const root = tmp(); const vars = { "tracker.project": SECRET }; writeJson(projectFilePath(root), { projectVersion: 1, id: "stack", ...(scope === "project" ? { vars } : { roles: { coder: { vars } } }), }); hidesValue(() => loadProject(root), "tracker.project", /positive integer/); }); } test("systemVars accepts user values and refuses malformed ones without quoting them", () => { const config = { environment: "development", dataRoot: "/d", execution: { backend: "docker", provider: "zai", model: "m", adapter: "pi" }, }; for (const key of ["environment", "dataRoot", "execution.backend", "execution.provider", "execution.model", "execution.adapter"]) { const bad = structuredClone(config); const value = { pasted: SECRET }; if (key.startsWith("execution.")) bad.execution[key.slice("execution.".length)] = value; else bad[key] = value; hidesValue(() => systemVars(bad), key); } }); // Exercise every validator that used to quote a scalar, a nested leaf or a duplicate. // Removing any of their redactions must fail here even if a caller sanitizes its error. for (const [key, layer, value, reason] of [ ["tracker.kind", "business", SECRET, /one of/], ["harness", "agent", `${SECRET}!`, /harness module name/], ["fallback.harness", "agent", `${SECRET}!`, /harness module name/], ["thinking", "agent", { pasted: [SECRET] }, /one of/], ["fallback.thinking", "agent", SECRET, /one of/], ["tracker.reconcileMinutes", "business", SECRET, /integer of at least 1/], ["tracker.pollSeconds", "project", SECRET, /integer of at least 10/], ["tracker.baseUrl", "business", SECRET, /http or https URL/], ["gitea.baseUrl", "business", SECRET, /http or https URL/], ["web.searxng", "business", `http://${SECRET}.example`, /https, or http on loopback/], ["git.workingBranch", "project", `${SECRET}!`, /git branch name/], ["git.protectedBranches", "project", [SECRET, `${SECRET}!`], /git branch name/], ["git.protectedBranches", "project", [SECRET, SECRET], /duplicate entry/], ["suites", "project", [SECRET, SECRET], /duplicate entry/], ["tracker.descendants", "project", SECRET, /true or false/], ["bus.tester", "business", SECRET, /true or false/], ["tracker.project", "project", SECRET, /positive integer/], ["limits.tools", "agent", ["read", SECRET], /unsupported tool/], ["limits.authority", "agent", ["message.send", SECRET], /unknown action/], ["limits.network", "agent", SECRET, /one of/], ]) { test(`checkVars hides refused ${key}: ${reason.source}`, () => { hidesValue(() => checkVars({ [key]: value }, layer, "fixture vars"), key, reason); }); } for (const prefix of ["", "fallback."]) { test(`route writer unknown ${prefix}model names its key and hides its value`, () => { const root = tmp(); const doc = businessDoc(root); writeJson(join(root, "businesses/acme.json"), doc); const settings = launchSettings({ dir: root, rolesDir: REPO_ROLES }); const route = { harness: "pi", model: Object.keys(doc.launch.models)[0], thinking: "high", fallback: null }; if (prefix) route.fallback = { harness: "pi", model: SECRET, thinking: "high" }; else route.model = SECRET; assert.throws(() => settings.setRoutes("acme", { revision: settings.writer.read("acme").revision, routes: { coder: route }, }, "jason"), error => { assert.ok(error instanceof OrganizationError); assert.equal(error.code, "unknown-model"); assert.ok(!String(error).includes(SECRET)); assert.ok(error.message.includes(`variable ${prefix}model`), error.message); return true; }); }); for (const [field, code] of [ ["model", "unknown-model"], ["harness", "harness-off"], ["harness", "harness-refused"], ["thinking", "thinking-unsupported"], ]) { test(`route check ${prefix}${field} ${code} names its key and hides its value`, () => { const vars = prefix ? { harness: "pi", model: "listed", thinking: "high", "fallback.harness": "pi", "fallback.model": "listed", "fallback.thinking": "high", } : { harness: "pi", model: "listed", thinking: "high" }; const key = `${prefix}${field}`; vars[key] = SECRET; const proposed = { roles: { coder: { vars } }, launch: { models: { listed: {} } }, plugins: { harness: code === "harness-refused" ? ["pi", SECRET] : ["pi"] }, }; assert.throws(() => checkRoutes({ proposed, levels: name => name === SECRET ? null : ["high"] }), error => { assert.ok(error instanceof OrganizationError); assert.equal(error.code, code); assert.ok(!String(error).includes(SECRET), "route refusal disclosed a var value"); assert.ok(error.message.includes(`variable ${key}`), error.message); return true; }); }); } }