Files
stack/agents/darkwing/work/s6-review/probe/dangling-write.mjs
T
jason.woltjeandClaude Opus 5.5 f19787ee60 docs(review): row 41 slice 1 S6 round 1 review, changes (darkwing)
R1 and R3 block: a late broker reply shifts later replies on the host IPC
channel, and a dangling workspace symlink passes the gate. R2 (close waits
on an open launch.sock client) should be fixed in the same round. Probes,
mutants and suite outputs alongside. Comment 26995 on #1523, queue rev 247.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-09 20:21:28 -05:00

28 lines
1.7 KiB
JavaScript

// A dangling symlink in the workspace that points outside it. decide() walks
// up to the nearest existing ancestor with existsSync, which follows links,
// so the link itself counts as "missing" and the path passes. Then the same
// two calls pi's write tool makes (core/tools/write.js:45-48: mkdir of the
// dirname, recursive, then writeFile) create the file outside.
import { existsSync, mkdirSync, mkdtempSync, readFileSync, rmSync, symlinkSync } from "node:fs";
import { mkdir, writeFile } from "node:fs/promises";
import { dirname, join } from "node:path";
import { tmpdir } from "node:os";
const { decide } = await import(`${process.env.WT}/packages/harness/src/gate.mjs`);
const root = mkdtempSync(join(tmpdir(), "r41-dangle-"));
const ws = join(root, "ws");
const outside = join(root, "outside", "planted.txt");
mkdirSync(dirname(outside), { recursive: true });
mkdirSync(ws);
symlinkSync(outside, join(ws, "notes.md")); // as a checked-out repo could carry it
for (const harness of ["pi", "claude-code"]) {
const policy = { harness, workspace: ws, tools: ["write", "edit"], typed: [] };
const [tool, field] = harness === "pi" ? ["write", "path"] : ["Write", "file_path"];
console.log(`${harness} ${tool} {${field}: "notes.md"}:`, JSON.stringify(decide(policy, tool, { [field]: harness === "pi" ? "notes.md" : join(ws, "notes.md") })));
}
console.log("outside file exists before:", existsSync(outside));
const target = join(ws, "notes.md");
await mkdir(dirname(target), { recursive: true });
await writeFile(target, "written through the gate\n", "utf-8");
console.log("outside file after pi's write calls:", existsSync(outside) ? JSON.stringify(readFileSync(outside, "utf8")) : "absent");
rmSync(root, { recursive: true, force: true });