Files
stack/agents/filbert/work/slice1-s1-review/probe.mjs
T
2026-10-04 22:40:19 -05:00

161 lines
12 KiB
JavaScript

// Row 36 review probes (Filbert). Imports the candidate from the scratch clone.
import { mkdirSync, mkdtempSync, writeFileSync, readFileSync, chmodSync, symlinkSync } from "node:fs";
import { join } from "node:path";
const R = `${process.env.HOME}/filbert-scratch/r36/repo`;
const B = await import(`${R}/packages/business/src/index.mjs`);
const H = await import(`${R}/packages/business/tests/helpers.mjs`);
const base = `${process.env.HOME}/filbert-scratch/r36/probe/work`;
mkdirSync(base, { recursive: true });
let n = 0;
const out = (name, ok, detail = "") => console.log(`${ok ? "PASS" : "FAIL"} ${name}${detail ? ` :: ${detail}` : ""}`);
const tryRun = (f) => { try { return { ok: true, v: f() }; } catch (e) { return { ok: false, e: e.message, code: e.exitCode }; } };
function setup(mut = (d) => d, project = null) {
const root = mkdtempSync(join(base, "b-"));
H.systemConfig(root);
const env = { MOSAIC_CONFIG: join(root, "config", "config.json") };
const doc = mut(H.businessDoc(root));
const dir = join(root, "config");
H.writeJson(join(dir, "businesses", "acme.json"), doc);
if (project) H.writeJson(join(root, "project", ".mosaic", "project.json"), project);
const rolesDir = join(R, "roles");
return { root, env, dir, rolesDir };
}
function load(s) { return B.loadBusiness("acme", { rolesDir: s.rolesDir, dir: s.dir, env: s.env }); }
// A. example refuses as shipped, and each placeholder refuses alone.
{
const ex = JSON.parse(readFileSync(`${R}/packages/business/examples/mosaic-stack.example.json`, "utf8"));
const r = tryRun(() => B.validateBusinessDocument(ex, "mosaic-stack.json", { rolesDir: `${R}/roles` }));
out("A1 example refuses as shipped", !r.ok, r.e);
const fixBots = structuredClone(ex); let id = 10;
fixBots.tracker.sync.botId = id++; for (const v of Object.values(fixBots.roles)) v.tracker.botId = id++;
const r2 = tryRun(() => B.validateBusinessDocument(fixBots, "mosaic-stack.json", { rolesDir: `${R}/roles` }));
out("A2 bot ids fixed, dates still placeholders: refuses", !r2.ok, r2.e);
const fixDates = JSON.parse(JSON.stringify(ex).replaceAll("YYYY-MM-DD", "2099-01-01"));
const r3 = tryRun(() => B.validateBusinessDocument(fixDates, "mosaic-stack.json", { rolesDir: `${R}/roles` }));
out("A3 dates fixed, bot ids 0: refuses", !r3.ok, r3.e);
const both = JSON.parse(JSON.stringify(fixBots).replaceAll("YYYY-MM-DD", "2099-01-01"));
const r4 = tryRun(() => B.validateBusinessDocument(both, "mosaic-stack.json", { rolesDir: `${R}/roles` }));
out("A4 both fixed: document validates (shape only; token files are a CLI check)", r4.ok, r4.e);
}
// B. resolver precedence, intersect, refusals.
const sys = (root) => H.systemFor(root);
{
const s = setup((d) => { d.vars["limits.tools"] = ["read", "grep", "bash", "write"]; d.vars["limits.network"] = "open";
d.roles.coder.vars = { harness: "pi", "limits.tools": ["read", "bash", "edit", "write"], "limits.network": "open" }; return d; },
{ projectVersion: 1, id: "stack", vars: { "tracker.pollSeconds": 45, "limits.tools": ["read", "bash", "grep", "write"] },
roles: { coder: { vars: { "tracker.pollSeconds": 20 } } } });
const b = load(s);
const p = B.loadProject(join(s.root, "project"));
const r = B.resolveInstance({ system: sys(s.root), business: b, project: p, instance: "coder" });
out("B1 replace: project roles.<i> beats project beats business", r.vars["tracker.pollSeconds"] === 20, `${r.vars["tracker.pollSeconds"]} from ${r.provenance["tracker.pollSeconds"]}`);
out("B2 limits.tools intersects business ∩ project ∩ agent ∩ ceiling", JSON.stringify(r.limits.tools) === JSON.stringify(["read", "write", "bash"]), JSON.stringify(r.limits.tools));
out("B3 limits.network open can't widen role api-only", r.limits.network === "api-only", r.limits.network);
const r0 = B.resolveInstance({ system: sys(s.root), business: b, instance: "coder" });
out("B4 no project: business value", r0.vars["tracker.pollSeconds"] === 60, String(r0.vars["tracker.pollSeconds"]));
out("B5 default kept when unset", r0.vars["tracker.reconcileMinutes"] === 60 && r0.provenance["tracker.reconcileMinutes"] === "default");
}
for (const [name, mut] of [
["B6 unknown key at business refuses", (d) => { d.vars["tracker.pollseconds"] = 30; return d; }],
["B7 agent-only key (harness) at business refuses", (d) => { d.vars.harness = "pi"; return d; }],
["B8 business-only key at agent refuses", (d) => { d.roles.coder.vars = { "tracker.baseUrl": "http://x" }; return d; }],
["B9 system key at business refuses", (d) => { d.vars.dataRoot = "/x"; return d; }],
["B10 __proto__ key refuses", (d) => JSON.parse(JSON.stringify(d).replace('"vars":{', '"vars":{"__proto__":{"a":1},')) ],
["B11 limits.network outside vocabulary refuses", (d) => { d.vars["limits.network"] = "lan"; return d; }],
["B12 limits.authority unknown action refuses", (d) => { d.vars["limits.authority"] = ["task.delete"]; return d; }],
]) {
const s = setup(mut);
const r = tryRun(() => load(s));
out(name, !r.ok && r.code === 2, r.e);
}
for (const [name, project] of [
["B13 project file: agent key (model) at project vars refuses", { projectVersion: 1, id: "stack", vars: { model: "x" }, roles: {} }],
["B14 project roles.<i>: agent key refuses (project layer)", { projectVersion: 1, id: "stack", vars: {}, roles: { coder: { vars: { harness: "pi" } } } }],
["B15 project roles names undeclared instance refuses", { projectVersion: 1, id: "stack", vars: {}, roles: { ghost: { vars: {} } } }],
["B16 project roles.constructor refuses", { projectVersion: 1, id: "stack", vars: {}, roles: { constructor: { vars: {} } } }],
]) {
const s = setup((d) => d, project);
const b = load(s);
const r = tryRun(() => B.resolveInstance({ system: sys(s.root), business: b, project: B.loadProject(join(s.root, "project")), instance: "coder" }));
out(name, !r.ok, r.e);
}
{
const s = setup();
const b = load(s);
for (const inst of ["constructor", "toString", "__proto__"]) {
const r = tryRun(() => B.resolveInstance({ system: sys(s.root), business: b, instance: inst }));
out(`B17 instance ${inst} refuses`, !r.ok, r.e);
}
}
// C. authority: limits.authority allowlist, role.launch.
{
const s = setup((d) => { d.vars["limits.authority"] = ["task.create", "task.assign", "role.launch", "message.send", "task.scope.change", "review.verdict"];
d.roles.pm.vars = { ...d.roles.pm.vars, "limits.authority": ["task.create", "role.launch", "task.scope.change", "task.close"] }; return d; });
const b = load(s);
const pm = B.resolveInstance({ system: sys(s.root), business: b, instance: "pm" });
out("C1 pm within = definition ∩ business ∩ agent", JSON.stringify(pm.limits.authority.withinRole) === JSON.stringify(["task.create", "role.launch"]), JSON.stringify(pm.limits.authority));
out("C2 pm cross keeps scope.change, drops priority.change", JSON.stringify(pm.limits.authority.crossRole) === JSON.stringify(["task.scope.change"]));
out("C3 classify: dropped action is gated", B.classify(pm, "task.assign") === "gated" && B.classify(pm, "task.priority.change") === "gated");
out("C4 classify: gated-only action is gated", B.classify(pm, "deploy") === "gated");
out("C5 limits can't grant an action outside the definition (review.verdict for pm)", B.classify(pm, "review.verdict") === "gated");
const rv = B.resolveInstance({ system: sys(s.root), business: b, instance: "reviewer" });
out("C6 reviewer keeps only listed actions", JSON.stringify(rv.limits.authority.withinRole) === JSON.stringify(["review.verdict", "message.send"]), JSON.stringify(rv.limits.authority.withinRole));
const e = tryRun(() => B.classify(pm, "task.delete"));
out("C7 classify unknown action refuses", !e.ok, e.e);
}
{
const s = setup();
const b = load(s);
const pm = B.resolveInstance({ system: sys(s.root), business: b, instance: "pm" });
out("C8 pm with launch.by=pm: role.launch within", B.classify(pm, "role.launch") === "within" && pm.launch !== null);
const s2 = setup((d) => { delete d.launch; return d; });
const r2 = tryRun(() => load(s2));
if (r2.ok) { const pm2 = B.resolveInstance({ system: sys(s2.root), business: r2.v, instance: "pm" });
out("C9 no launch block: pm role.launch gated", B.classify(pm2, "role.launch") === "gated" && pm2.launch === null); }
else out("C9 no launch block: business refuses (launch required)", true, r2.e);
const s3 = setup((d) => { d.launch.by = "cto"; d.launch.instances = ["coder", "reviewer"]; return d; });
const r3 = tryRun(() => load(s3));
if (r3.ok) {
const cto = B.resolveInstance({ system: sys(s3.root), business: r3.v, instance: "cto" });
const pm3 = B.resolveInstance({ system: sys(s3.root), business: r3.v, instance: "pm" });
out("C10 launch.by=cto (no role.launch in cto definition) accepted", true, `cto.launch=${cto.launch ? "set" : "null"} classify(cto, role.launch)=${B.classify(cto, "role.launch")} classify(pm, role.launch)=${B.classify(pm3, "role.launch")}`);
} else out("C10 launch.by=cto refuses", true, r3.e);
const s4 = setup((d) => { d.roles.pm.vars = { ...d.roles.pm.vars, "limits.authority": ["task.create"] }; return d; });
const b4 = load(s4);
const pm4 = B.resolveInstance({ system: sys(s4.root), business: b4, instance: "pm" });
out("C11 limits.authority drops role.launch for launch.by", true, `launch=${pm4.launch ? "set" : "null"} classify=${B.classify(pm4, "role.launch")}`);
}
// D. credentials: never opened (fs hook counts opens of token paths).
{
const s = setup();
const b = load(s);
const refs = [...Object.values(b.tracker.sync.credentials), ...Object.values(b.roles).flatMap((r) => Object.values(r.credentials))];
const opened = globalThis.__opened;
opened.length = 0;
const problems = refs.flatMap((ref) => B.checkCredentialRef(ref, { forbiddenRoots: [R] }).problems);
const tokenOpens = opened.filter((p) => refs.some((ref) => ref.file && String(p).startsWith(ref.file)));
out("D1 checkCredentialRef on 9 token files: 0 opens", tokenOpens.length === 0 && problems.length === 0, `refs=${refs.length} opens=${JSON.stringify(tokenOpens)} problems=${problems.length}`);
// symlinked parent pointing into a forbidden root
const inRepo = join(s.root, "fakerepo"); mkdirSync(join(inRepo, "sec"), { recursive: true });
const tok = join(inRepo, "sec", "t.token"); writeFileSync(tok, "x"); chmodSync(tok, 0o600);
const link = join(s.root, "outside"); symlinkSync(join(inRepo, "sec"), link);
const ref = B.parseCredentialRef({ file: join(link, "t.token"), rotateBy: "2099-01-01" }, "gitea", "p");
const r = B.checkCredentialRef(ref, { forbiddenRoots: [inRepo] });
out("D2 token reached through a symlinked parent inside a forbidden root refuses", r.problems.some((p) => p.includes("inside")), JSON.stringify(r.problems));
chmodSync(tok, 0o640);
const r2 = B.checkCredentialRef(B.parseCredentialRef({ file: tok, expires: "2099-01-01" }, "vikunja", "p"), {});
out("D3 mode 640 refuses", r2.problems.some((p) => p.includes("mode")), JSON.stringify(r2.problems));
const r3 = B.checkCredentialRef(B.parseCredentialRef({ file: tok, expires: "2000-01-01" }, "vikunja", "p"), {});
out("D4 expired vikunja refuses", r3.problems.some((p) => p.includes("expired")));
const r4 = B.checkCredentialRef(B.parseCredentialRef({ env: "GITEA_TOKEN", rotateBy: "2000-01-01" }, "gitea", "p"), { env: {} });
out("D5 gitea rotateBy past only warns; env unset only warns", r4.problems.length === 0 && r4.warnings.length === 2, JSON.stringify(r4.warnings));
}
{ // hook sanity: the business file read is seen
const s = setup(); globalThis.__opened.length = 0; load(s);
out("D0 hook sees the business file read", globalThis.__opened.some((p) => p.endsWith("acme.json")), String(globalThis.__opened.length));
}