Files
reverse-engineering-anything/tests/boundary/filesystem/nativePascalVerifier.test.ts
T
3e8a5f76d0 feat(native): retain LLDB source coordinates and verify Pascal calls (#2800)
* feat(native): retain LLDB source coordinates and verify Pascal call entries

Preserve partial line-table attribution for native locations and historical
evidence compatibility. Verify owned Free Pascal call entries through CLI/MCP.

Refs #2382, #2372, #2397

Co-Authored-By: Codex <noreply@openai.com>

* docs: namespace native specifications by domain and feature

Use stable descriptive paths instead of numeric prefixes to avoid parallel contribution collisions.

Co-Authored-By: Codex <noreply@openai.com>

* fix(native): bound Pascal verification and compare caller coordinates

Address review findings at their producing boundaries and preserve directly affected consumers. Source inspection and git diff --check completed. Tests and automated checks were not run at the user’s explicit request.

* fix(native): bound compiler shutdown and source-coordinate fixtures

* docs: clarify historical native source verification

* fix(native): preserve source attribution and compiler ownership

* docs(native): qualify retained source attribution

* fix(ci): clean up native Pascal verifier processes

* test(native): type the Pascal verifier helper import after merging main

Main now typechecks this boundary test, which imports the untyped
canonical-temporary-directory helper and reads an unknown catch value.
Add the helper's declaration file and narrow the caught error.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* test(native): verify partial source attribution caveat

* fix(native): retain verifier compiler cleanup ownership

* fix(native): forward verifier cancellation and measure path bytes

CLI and MCP artifact runs observe the verifier abort signal, and a
failed Pascal verifier test stops the compiler group before deleting
its directory. Repeated source locations grow by measured UTF-8 JSON
bytes; workflow tokens, CPU and peak memory stay unmeasured.

---------

Co-authored-by: Matheus Breguêz <matbrgz@gmail.com>
Co-authored-by: Codex <noreply@openai.com>
Co-authored-by: Kaoru0822 <208281322+kaoru0822-kitauji@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
2026-11-07 23:25:20 +08:00

124 lines
4.2 KiB
TypeScript

import { spawn } from "node:child_process";
import {
chmod,
readFile,
readdir,
realpath,
rm,
symlink,
writeFile,
} from "node:fs/promises";
import { basename, join } from "node:path";
import { expect, it } from "vitest";
import { createCanonicalTemporaryDirectory } from "../../../scripts/lib/canonical-temporary-directory.mjs";
import { createTestTempDirectory } from "../../fixtures/temporaryDirectory.js";
it("uses the canonical spelling for a verifier directory allocated through a symlink", async () => {
const root = await createTestTempDirectory("rea-pascal-verifier-path-");
const alias = join(root, "alias");
await symlink(root, alias, process.platform === "win32" ? "junction" : "dir");
const allocated = await createCanonicalTemporaryDirectory(
"rea-pascal-calls-",
alias,
);
try {
expect(allocated.path).toBe(await realpath(allocated.allocatedPath));
expect(allocated.path).not.toBe(
join(alias, basename(allocated.allocatedPath)),
);
} finally {
await rm(allocated.allocatedPath, { recursive: true, force: true });
}
});
it.skipIf(process.platform !== "darwin")(
"forwards verifier SIGTERM to the owned compiler group and removes its temporary directory",
async () => {
const root = await createTestTempDirectory("rea-pascal-verifier-cancel-");
const fakeCompiler = join(root, "fake-fpc");
const pidFile = join(root, "compiler-pids.txt");
await writeFile(
fakeCompiler,
'#!/usr/bin/env node\nimport { spawn } from "node:child_process";\nimport { writeFileSync } from "node:fs";\nconst child = spawn(process.execPath, ["-e", "setInterval(() => undefined, 1000)"], { stdio: "ignore" });\nwriteFileSync(process.env.REA_VERIFY_TEST_PID_FILE, `${process.pid} ${child.pid}\\n`);\nawait new Promise(() => undefined);\n',
);
await chmod(fakeCompiler, 0o700);
const verifier = spawn(
process.execPath,
["scripts/verify-native-pascal-calls.mjs"],
{
cwd: process.cwd(),
env: {
...process.env,
TMPDIR: root,
REA_VERIFY_FPC_COMMAND: fakeCompiler,
REA_VERIFY_TEST_PID_FILE: pidFile,
},
stdio: "ignore",
},
);
try {
const deadline = Date.now() + 10_000;
let pids: number[] | undefined;
while (Date.now() < deadline) {
try {
pids = (await readFile(pidFile, "utf8"))
.trim()
.split(/\s+/u)
.map(Number);
break;
} catch (cause: unknown) {
if ((cause as NodeJS.ErrnoException).code !== "ENOENT") throw cause;
await new Promise((resolve) => setTimeout(resolve, 20));
}
}
expect(pids, "the fake compiler started").toHaveLength(2);
verifier.kill("SIGTERM");
const result = await new Promise<{
code: number | null;
signal: NodeJS.Signals | null;
}>((resolve, reject) => {
verifier.once("error", reject);
verifier.once("close", (code, signal) => resolve({ code, signal }));
});
expect(result).toEqual({ code: 143, signal: null });
for (const pid of pids ?? [])
expect(() => process.kill(pid, 0)).toThrow();
expect(
(await readdir(root)).filter((name) =>
name.startsWith("rea-pascal-calls-"),
),
).toEqual([]);
} finally {
if (verifier.exitCode === null && verifier.signalCode === null) {
verifier.kill("SIGTERM");
await new Promise((resolve) => {
const timer = setTimeout(() => {
verifier.kill("SIGKILL");
resolve(undefined);
}, 1_000);
verifier.once("close", () => {
clearTimeout(timer);
resolve(undefined);
});
});
}
try {
const recorded = (await readFile(pidFile, "utf8"))
.trim()
.split(/\s+/u)
.map(Number);
for (const pid of recorded) {
try {
process.kill(pid, "SIGKILL");
} catch {
// The owned compiler group already exited.
}
}
} catch (cause: unknown) {
if ((cause as NodeJS.ErrnoException).code !== "ENOENT") throw cause;
}
await rm(root, { recursive: true, force: true });
}
},
);