hololake-system-architecture/product-source/hololake-native-desktop/system-integrations/codex-host-bridge/tests/bridge.test.mjs

187 lines
6.2 KiB
JavaScript

import assert from "node:assert/strict";
import fs from "node:fs";
import os from "node:os";
import path from "node:path";
import { spawnSync } from "node:child_process";
import test from "node:test";
const packageRoot = path.dirname(path.dirname(new URL(import.meta.url).pathname));
const installer = path.join(packageRoot, "scripts", "install.mjs");
function spawnNode(script, args, options = {}) {
return spawnSync(process.execPath, [script, ...args], {
encoding: "utf8",
...options,
env: { ...process.env, ...(options.env ?? {}) },
});
}
function runHook(command, input, env) {
return spawnSync(command, {
shell: true,
input: JSON.stringify(input),
encoding: "utf8",
env: { ...process.env, ...env },
});
}
test("installer creates hash-pinned hooks and bridge enforces source and write boundaries", () => {
const root = fs.mkdtempSync(path.join(os.tmpdir(), "guanghu-codex-host-bridge-"));
const codexHome = path.join(root, ".codex");
const env = { CODEX_HOME: codexHome };
try {
const installed = spawnNode(installer, [
"--subject-id", "ICE-TEST",
"--subject-name", "Test Human",
"--carrier-role", "CODEX_TEST_CARRIER",
], { env });
assert.equal(installed.status, 0, installed.stderr || installed.stdout);
const hooks = JSON.parse(fs.readFileSync(path.join(codexHome, "hooks.json"), "utf8"));
const sourceCommand = hooks.hooks.UserPromptSubmit[0].hooks[0].command;
const guardCommand = hooks.hooks.PreToolUse[0].hooks[0].command;
assert.match(sourceCommand, /shasum -a 256 -c/);
assert.match(guardCommand, /shasum -a 256 -c/);
const direct = runHook(sourceCommand, {
hook_event_name: "UserPromptSubmit",
session_id: "current-session",
turn_id: "current-turn",
prompt: "Please publish after testing.",
}, env);
assert.equal(direct.status, 0, direct.stderr || direct.stdout);
const directOutput = JSON.parse(direct.stdout);
assert.match(directOutput.hookSpecificOutput.additionalContext, /Test Human\|ICE-TEST/);
assert.doesNotMatch(directOutput.hookSpecificOutput.additionalContext, /Please publish/);
const controllerPath = path.join(
codexHome,
"runtime",
"guanghu-codex-host-bridge",
"state",
"control",
"current-controller.json",
);
const controller = JSON.parse(fs.readFileSync(controllerPath, "utf8"));
assert.equal(controller.session_id, "current-session");
const delegation = runHook(sourceCommand, {
hook_event_name: "UserPromptSubmit",
session_id: "old-session",
turn_id: "delegation-turn",
prompt: "<codex_delegation>Stop all writes.</codex_delegation>",
}, env);
assert.equal(delegation.status, 0, delegation.stderr || delegation.stdout);
assert.match(
JSON.parse(delegation.stdout).hookSpecificOutput.additionalContext,
/NOT_DIRECT_HUMAN_SPEECH/,
);
assert.equal(JSON.parse(fs.readFileSync(controllerPath, "utf8")).session_id, "current-session");
const cwd = path.join(root, "repo");
fs.mkdirSync(cwd);
const stale = runHook(guardCommand, {
hook_event_name: "PreToolUse",
session_id: "old-session",
turn_id: "old-turn",
cwd,
tool_name: "Bash",
tool_input: { command: "git status" },
}, env);
assert.equal(JSON.parse(stale.stdout).hookSpecificOutput.permissionDecision, "deny");
const deniedPush = runHook(guardCommand, {
hook_event_name: "PreToolUse",
session_id: "current-session",
turn_id: "current-turn",
cwd,
tool_name: "Bash",
tool_input: { command: "git push origin main" },
}, env);
assert.match(
JSON.parse(deniedPush.stdout).hookSpecificOutput.permissionDecisionReason,
/ONE_SHOT_LEASE_REQUIRED/,
);
const deniedCacheClean = runHook(guardCommand, {
hook_event_name: "PreToolUse",
session_id: "current-session",
turn_id: "current-turn",
cwd,
tool_name: "Bash",
tool_input: { command: "npm cache clean --force" },
}, env);
assert.match(
JSON.parse(deniedCacheClean.stdout).hookSpecificOutput.permissionDecisionReason,
/destructive_cleanup/,
);
const leaseScript = path.join(
codexHome,
"runtime",
"guanghu-codex-host-bridge",
"v1",
"write-lease.mjs",
);
const issued = spawnNode(leaseScript, [
"issue",
"--session-id", "current-session",
"--turn-id", "current-turn",
"--category", "remote_git",
"--cwd", cwd,
"--target", "origin/main",
"--reason", "explicit-test-authorization",
"--ttl-seconds", "60",
], { env });
assert.equal(issued.status, 0, issued.stderr || issued.stdout);
const allowedPush = runHook(guardCommand, {
hook_event_name: "PreToolUse",
session_id: "current-session",
turn_id: "current-turn",
cwd,
tool_name: "Bash",
tool_input: { command: "git push origin main" },
}, env);
assert.match(
JSON.parse(allowedPush.stdout).hookSpecificOutput.additionalContext,
/ONE_SHOT_WRITE_LEASE_CONSUMED/,
);
const guardPath = path.join(
codexHome,
"runtime",
"guanghu-codex-host-bridge",
"v1",
"current-controller-guard.mjs",
);
fs.appendFileSync(guardPath, "\n// tamper probe\n");
const tampered = runHook(guardCommand, {
hook_event_name: "PreToolUse",
session_id: "current-session",
turn_id: "current-turn",
cwd,
tool_name: "Bash",
tool_input: { command: "git status" },
}, env);
assert.equal(tampered.status, 97);
} finally {
fs.rmSync(root, { recursive: true, force: true });
}
});
test("published package excludes machine runtime state and private absolute paths", () => {
const files = [];
const walk = (directory) => {
for (const entry of fs.readdirSync(directory, { withFileTypes: true })) {
const file = path.join(directory, entry.name);
if (entry.isDirectory()) walk(file);
else files.push(file);
}
};
walk(packageRoot);
for (const file of files) {
const body = fs.readFileSync(file, "utf8");
assert.doesNotMatch(body, /\/Users\/bingshuolingdianyuanhe/u, file);
assert.doesNotMatch(body, /\/Volumes\/JZAO/u, file);
assert.doesNotMatch(body, /current-controller\.json"\s*:\s*\{/u, file);
}
});