← Files QuarryFi R&D TrackerARCHIVED FILE
tests/hook-regression.mjs
12 KB · Oct 2, 2026 · 00:30 UTC
import assert from "node:assert/strict";
import { execFileSync } from "node:child_process";
import { createHash } from "node:crypto";
import {
chmodSync,
copyFileSync,
existsSync,
mkdtempSync,
mkdirSync,
readdirSync,
readFileSync,
rmSync,
writeFileSync,
} from "node:fs";
import { tmpdir } from "node:os";
import { dirname, join, resolve } from "node:path";
import { fileURLToPath } from "node:url";
const repoRoot = resolve(dirname(fileURLToPath(import.meta.url)), "..");
const hookPath = join(repoRoot, "hooks", "track-session.sh");
const manifest = JSON.parse(readFileSync(join(repoRoot, ".codex-plugin", "plugin.json"), "utf8"));
const hooksConfig = JSON.parse(readFileSync(join(repoRoot, "hooks", "hooks.json"), "utf8"));
const tmpHome = mkdtempSync(join(tmpdir(), "quarryfi-codex-hook-"));
const projectRoot = join(tmpHome, "work", 'client-"a');
const projectDir = join(projectRoot, "app");
const configDir = join(tmpHome, ".quarryfi");
const binDir = join(tmpHome, "bin");
const captureDir = join(tmpHome, "captures");
const packagedPluginRoot = join(tmpHome, "marketplace-package");
assertSupportedCodexHooks();
assertRootHookBundleIsDiscoverable();
assertHookCommandsUsePluginRoot();
assertProductionHostname();
assertPublicRuntimeDetection();
try {
mkdirSync(projectDir, { recursive: true });
mkdirSync(configDir, { recursive: true });
mkdirSync(binDir, { recursive: true });
mkdirSync(captureDir, { recursive: true });
writeFileSync(join(projectDir, "package.json"), "{}\n");
writeFileSync(join(projectDir, 'service-"quoted.test.ts'), "export const privateValue = 'never transmit me';\n");
execFileSync("git", ["init", "-q", projectDir]);
execFileSync("git", ["-C", projectDir, "config", "user.email", "tracker-test@quarryfi.test"]);
execFileSync("git", ["-C", projectDir, "config", "user.name", "QuarryFi Tracker Test"]);
execFileSync("git", ["-C", projectDir, "add", "package.json"]);
execFileSync("git", ["-C", projectDir, "commit", "-qm", "test fixture"]);
execFileSync("git", ["-C", projectDir, "checkout", "-qb", 'feature/"privacy']);
execFileSync("git", ["-C", projectDir, "remote", "add", "origin", "git@github.com:QuarryFi/private-example.git"]);
installFakeCurl();
writeFileSync(
join(configDir, "config.json"),
JSON.stringify({
profiles: [
{ name: 'Client "A"', api_key: "qf_client_a", api_url: "https://capture.invalid", projects: [projectRoot] },
{ name: "Catch All", api_key: "qf_catch_all", api_url: "http://127.0.0.1:9999", projects: [] },
{ name: "Other Client", api_key: "qf_other", projects: [join(tmpHome, "other")] },
],
}, null, 2),
{ mode: 0o600 },
);
runHook(["UserPromptSubmit", projectDir, 'ci-"session']);
assertTimerIdentityVersioned();
let requests = readCapturedRequests();
assert.equal(requests.length, 2);
assert.deepEqual(
requests.map((request) => request.authorization).sort(),
["Authorization: Bearer qf_catch_all", "Authorization: Bearer qf_client_a"],
);
assertSafeRequests(requests, 'ci-"session', "javascript");
clearCaptures();
runManifestHook({
eventName: "UserPromptSubmit",
cwd: projectDir,
sessionId: 'manifest-"session',
filePath: join(projectDir, 'service-"quoted.test.ts'),
});
requests = readCapturedRequests();
assert.equal(requests.length, 2, "manifest hook must run from a project cwd");
assertSafeRequests(requests, 'manifest-"session', "typescript");
for (const request of requests) {
assert.equal(request.payload.heartbeats[0].activity_kind, "test");
assert.equal(request.payload.heartbeats[0].language, "typescript");
}
clearCaptures();
installNonExecutableMarketplaceFixture();
runManifestHook({
eventName: "UserPromptSubmit",
cwd: join(projectRoot, "marketplace-app"),
sessionId: "marketplace-mode-session",
filePath: join(projectRoot, "marketplace-app", "package.json"),
pluginRoot: packagedPluginRoot,
});
requests = readCapturedRequests();
assert.equal(requests.length, 2, "marketplace hook must run when archive strips executable bits");
assertIdleTimerExpires();
console.log("Codex tracker privacy and lifecycle regression passed.");
} finally {
try {
runHook(["Stop", projectDir, "cleanup-session"]);
} catch {
// Best-effort timer cleanup; the temporary HOME is removed below.
}
stopHookTimers();
rmSync(tmpHome, { recursive: true, force: true });
}
function installFakeCurl() {
const fakeCurl = join(binDir, "curl");
writeFileSync(fakeCurl, `#!/bin/sh
capture=$(mktemp "$QF_CAPTURE_DIR/request.XXXXXX") || exit 1
printf '%s\n' "$@" > "$capture.args"
payload=''
authorization=''
url=''
while [ "$#" -gt 0 ]; do
case "$1" in
-d)
shift
payload="$1"
;;
-H)
shift
case "$1" in Authorization:*) authorization="$1" ;; esac
;;
http://*|https://*) url="$1" ;;
esac
shift
done
printf '%s' "$payload" > "$capture.payload"
printf '%s' "$authorization" > "$capture.authorization"
printf '%s' "$url" > "$capture.url"
printf '204'
`);
chmodSync(fakeCurl, 0o755);
}
function runHook(args) {
execFileSync("bash", [hookPath, ...args], {
cwd: projectDir,
env: testEnv(),
stdio: ["ignore", "ignore", "pipe"],
});
}
function runManifestHook({ eventName, cwd, sessionId, filePath, pluginRoot = repoRoot }) {
const command = hooksConfig.hooks[eventName][0].hooks[0].command;
mkdirSync(cwd, { recursive: true });
execFileSync("bash", ["-c", command], {
cwd,
env: testEnv({ pluginRoot }),
input: JSON.stringify({
hook_event_name: eventName,
cwd,
session_id: sessionId,
tool_input: { file_path: filePath },
}),
stdio: ["pipe", "ignore", "pipe"],
});
}
function testEnv({ pluginRoot = repoRoot } = {}) {
return {
...process.env,
HOME: tmpHome,
PATH: `${binDir}:${process.env.PATH}`,
QF_CAPTURE_DIR: captureDir,
CODEX_CLIENT: "app",
PLUGIN_ROOT: pluginRoot,
};
}
function installNonExecutableMarketplaceFixture() {
mkdirSync(join(packagedPluginRoot, "hooks"), { recursive: true });
mkdirSync(join(packagedPluginRoot, ".codex-plugin"), { recursive: true });
copyFileSync(hookPath, join(packagedPluginRoot, "hooks", "track-session.sh"));
copyFileSync(
join(repoRoot, ".codex-plugin", "plugin.json"),
join(packagedPluginRoot, ".codex-plugin", "plugin.json"),
);
chmodSync(join(packagedPluginRoot, "hooks", "track-session.sh"), 0o644);
}
function readCapturedRequests() {
return readdirSync(captureDir)
.filter((name) => name.endsWith(".payload"))
.sort()
.map((name) => {
const base = join(captureDir, name.slice(0, -".payload".length));
return {
args: readFileSync(`${base}.args`, "utf8"),
authorization: readFileSync(`${base}.authorization`, "utf8"),
url: readFileSync(`${base}.url`, "utf8"),
payload: JSON.parse(readFileSync(`${base}.payload`, "utf8")),
};
});
}
function clearCaptures() {
for (const name of readdirSync(captureDir)) rmSync(join(captureDir, name));
}
function assertSafeRequests(requests, expectedSessionId, expectedLanguage) {
for (const request of requests) {
assert.equal(request.url, "https://quarryfi.com/api/heartbeat");
assert.match(request.args, /--proto\n=https/);
assert.match(request.args, /--tlsv1\.2/);
assert.ok(!request.args.includes("capture.invalid"));
assert.ok(!request.args.includes("127.0.0.1"));
assert.equal(request.payload.client.plugin_version, manifest.version);
assert.equal(request.payload.client.hook_mode, "event_plus_timer");
assert.match(request.payload.client.runtime_channel, /^codex_/);
assert.equal(request.payload.client.host_app, "codex_app");
const [heartbeat] = request.payload.heartbeats;
assert.equal(heartbeat.source, "codex");
assert.equal(heartbeat.event, "heartbeat");
assert.equal(heartbeat.session_id, expectedSessionId);
assert.equal(heartbeat.project_name, "app");
assert.equal(heartbeat.language, expectedLanguage);
assert.equal(heartbeat.branch, 'feature/"privacy');
assert.match(heartbeat.head_sha, /^[a-f0-9]{40}$/);
assert.match(heartbeat.repo_fingerprint, /^[a-f0-9]{64}$/);
assert.equal(heartbeat.changed_file_count, 0);
for (const forbidden of ["source_code", "diff", "prompt", "command", "file_path", "remote_url"]) {
assert.equal(forbidden in heartbeat, false, `heartbeat must not include ${forbidden}`);
}
assert.ok(!JSON.stringify(request.payload).includes("privateValue"));
assert.ok(!JSON.stringify(request.payload).includes(tmpHome));
}
}
function assertSupportedCodexHooks() {
const supportedEvents = new Set([
"PreToolUse", "PermissionRequest", "PostToolUse", "PreCompact", "PostCompact",
"UserPromptSubmit", "SubagentStart", "SubagentStop", "SessionStart", "Stop",
]);
for (const eventName of Object.keys(hooksConfig.hooks ?? {})) {
assert.ok(supportedEvents.has(eventName), `${eventName} is not a supported Codex hook event`);
}
const postToolUseGroups = hooksConfig.hooks?.PostToolUse ?? [];
assert.ok(postToolUseGroups.length > 0, "PostToolUse hook must be registered");
assert.ok(postToolUseGroups.some((group) => group.matcher === "*" || group.matcher === undefined));
}
function assertRootHookBundleIsDiscoverable() {
assert.equal("hooks" in manifest, false, "plugin.json must stay inside the accepted ingestion schema");
assert.equal(existsSync(join(repoRoot, "hooks", "hooks.json")), true, "default hook bundle must exist");
assert.equal(existsSync(join(repoRoot, "hooks.json")), false, "legacy root hook bundle must not be duplicated");
}
function assertPublicRuntimeDetection() {
const hook = readFileSync(hookPath, "utf8");
assert.match(hook, /openai-curated-remote/);
assert.match(hook, /codex_public_directory_cache/);
}
function assertHookCommandsUsePluginRoot() {
for (const [eventName, groups] of Object.entries(hooksConfig.hooks ?? {})) {
for (const group of groups) {
for (const hook of group.hooks ?? []) {
assert.match(
hook.command,
/^bash "\$PLUGIN_ROOT\/hooks\/track-session\.sh" /,
`${eventName} must use PLUGIN_ROOT through bash`,
);
}
}
}
}
function assertProductionHostname() {
const retiredHostname = "quarryfi.smashedstudiosllc.workers.dev";
for (const relativePath of [
".codex-plugin/plugin.json", "hooks/track-session.sh", "setup.sh", "skills/quarryfi-status/SKILL.md",
]) {
const contents = readFileSync(join(repoRoot, relativePath), "utf8");
assert.ok(!contents.includes(retiredHostname), `${relativePath} must not use the retired hostname`);
}
}
function assertIdleTimerExpires() {
const hash = createHash("sha256").update(projectDir).digest("hex").slice(0, 12);
const stateDir = join(configDir, `session-codex-${hash}`);
mkdirSync(stateDir, { recursive: true });
writeFileSync(join(stateDir, "session_id"), "idle-session");
writeFileSync(join(stateDir, "last_activity"), "0");
execFileSync("bash", [hookPath, "__timer_loop", projectDir, "idle-session"], {
cwd: projectDir,
env: testEnv(),
stdio: ["ignore", "ignore", "pipe"],
timeout: 2_000,
});
assert.equal(existsSync(join(stateDir, "timer.pid")), false, "idle timer must remove its PID file");
const audit = readFileSync(join(configDir, "audit.log"), "utf8");
assert.match(audit, /timer_expired:idle/);
}
function assertTimerIdentityVersioned() {
const hash = createHash("sha256").update(projectDir).digest("hex").slice(0, 12);
const pidFile = join(configDir, `session-codex-${hash}`, "timer.pid");
assert.match(readFileSync(pidFile, "utf8"), /^\d+\|[a-f0-9]{12}$/);
}
function stopHookTimers() {
try {
for (const entry of readdirSync(configDir)) {
const pidFile = join(configDir, entry, "timer.pid");
if (!entry.startsWith("session-codex-") || !existsSync(pidFile)) continue;
const pid = Number.parseInt(readFileSync(pidFile, "utf8").split("|", 1)[0], 10);
if (Number.isInteger(pid) && pid > 0) {
try { process.kill(pid, "SIGTERM"); } catch { /* Timer may already be gone. */ }
}
}
} catch {
// Best-effort cleanup only.
}
}
SHA-256: ca35361e435139bfa58f8bd05f5de3eb49025cc719042b7f84fdabfbbf7260f5