feat: add assistant proposal worker runtime

This commit is contained in:
zenord
2026-08-18 18:48:47 +08:00
parent 947f19e3cd
commit b4121c9fd6
32 changed files with 2827 additions and 986 deletions
+25 -2
View File
@@ -4,9 +4,9 @@ import { EventEmitter } from "node:events";
import os from "node:os";
import path from "node:path";
import test from "node:test";
import { writeConfigFile } from "../src/cli/config-file.js";
import { configDigest, writeConfigFile } from "../src/cli/config-file.js";
import { assertSetupPidSafe, instanceDirectory, instanceRunnerPath, matchesInstanceRunner, runInstanceCommand } from "../src/cli/instance.js";
import { runInstanceRunner, waitForShutdown } from "../src/cli/instance-runner.js";
import { assertRunnerConfigSnapshot, assertRunnerWorkspaceSafety, runInstanceRunner, waitForShutdown } from "../src/cli/instance-runner.js";
import { parseConfig } from "../src/config.js";
test("instance paths reject traversal and config identity mismatch", async () => {
@@ -69,6 +69,29 @@ test("instance runner rejects unsafe argument and config paths before starting a
await assert.rejects(runInstanceRunner([path.join(os.tmpdir(), `missing-runner-${Date.now()}.json`)]), /Runtime config does not exist/);
});
test("instance runner binds startup to the validated config snapshot and repeats workspace checks", async (t) => {
const root = fs.mkdtempSync(path.join(os.tmpdir(), "gori-runner-safety-"));
t.after(() => fs.rmSync(root, { recursive: true, force: true }));
const parent = path.join(root, "workspace");
const child = path.join(parent, "child");
fs.mkdirSync(child, { recursive: true });
const config = parseConfig({
configVersion: 3,
bot: { id: "runner-bot", workspace: child, persona: "test", agent: { id: "kimi", command: "kimi", args: ["acp"] }, permissions: { mode: "deny" } },
gateway: { platform: { type: "webhook", secret: "secret" } },
runtime: {}
});
const configFile = path.join(root, "instances", "runner-bot", "config.json");
writeConfigFile(configFile, config);
assert.doesNotThrow(() => assertRunnerConfigSnapshot(config, configDigest(config)));
assert.throws(() => assertRunnerConfigSnapshot(config, "changed"), /config changed/);
assert.throws(() => assertRunnerWorkspaceSafety(config, path.join(root, "wrong.json"), root), /directory contract/);
const peer = parseConfig({ ...config, bot: { ...config.bot, id: "peer-bot", workspace: parent } });
writeConfigFile(path.join(root, "instances", "peer-bot", "config.json"), peer);
assert.throws(() => assertRunnerWorkspaceSafety(config, configFile, root), /identical, parent, or child workspace/);
});
test("instance runner gracefully shuts down once on SIGTERM", async () => {
const signals = new EventEmitter();
let shutdowns = 0;