Files
stack/agents/filbert/work/slice1-probes/pi-gate.ts
T
jason.woltjeandClaude Opus 5.5 771fc3d270 docs(slice1): row 34 S0 harness probe matrix (filbert)
Pi 0.85.1 and Claude Code 2.1.289 (Agent SDK 0.3.289), 34 cases against a
scripted local model in a loopback-only network namespace. MATRIX.md has
the command, outcome, model-visible message and fail-closed column per
case, and one rely-on line per case. Evidence under evidence/.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-04 22:25:41 -05:00

25 lines
1.3 KiB
TypeScript

// Row S0 probe gate for Pi: a `tool_call` handler that guards the `write`
// tool. GATE_MODE picks the behaviour; GATE_LOG records each invocation, so
// a run shows whether the gate ran at all.
import { appendFileSync } from "node:fs";
const mode = process.env.GATE_MODE ?? "block";
const note = (s: string) => appendFileSync(process.env.GATE_LOG ?? "/dev/null", `${new Date().toISOString()} ${s}\n`);
export default function (pi: any) {
note(`loaded mode=${mode}`);
pi.on("tool_call", async (event: any) => {
note(`invoked tool=${event.toolName} mode=${mode}`);
if (event.toolName !== "write") return undefined;
if (mode === "block") return { block: true, reason: "PROBE-GATE: write is blocked by policy" };
if (mode === "throw") throw new Error("PROBE-GATE crashed (throw)");
if (mode === "throw-string") throw "PROBE-GATE crashed (non-Error throw)";
// "hang" never settles and holds nothing open; "slow" holds a timer, as a
// gate waiting on I/O would, and blocks only after an hour.
if (mode === "hang") return new Promise(() => {});
if (mode === "slow") return new Promise((r) => setTimeout(() => r({ block: true, reason: "PROBE-GATE: blocked after a delay" }), 3_600_000));
if (mode === "exit") process.exit(3);
return undefined;
});
}