mirror of
https://github.com/morluto/rea.git
synced 2026-11-11 01:13:39 +00:00
* 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>
139 lines
4.7 KiB
TypeScript
139 lines
4.7 KiB
TypeScript
import { execFile } from "node:child_process";
|
|
import { mkdir, writeFile } from "node:fs/promises";
|
|
import { join } from "node:path";
|
|
import { fileURLToPath } from "node:url";
|
|
import { promisify } from "node:util";
|
|
import { expect, it } from "vitest";
|
|
import { z } from "zod";
|
|
|
|
import { createTestTempDirectory } from "../../fixtures/temporaryDirectory.js";
|
|
|
|
const exec = promisify(execFile);
|
|
const observationSchema = z.strictObject({
|
|
accepted: z.boolean(),
|
|
catalogRequests: z.number().int().nonnegative(),
|
|
corruptedReplies: z.number().int().nonnegative(),
|
|
toolCalls: z.number().int().nonnegative(),
|
|
toolTimeouts: z.array(z.number().nullable()),
|
|
error: z
|
|
.strictObject({
|
|
name: z.string(),
|
|
message: z.string(),
|
|
code: z.union([z.number(), z.string()]).nullable(),
|
|
})
|
|
.nullable(),
|
|
});
|
|
|
|
async function probe(mode: string, name = "Fixture.app") {
|
|
const root = await createTestTempDirectory("rea-artifact-mcp-schema-");
|
|
const target = join(root, name);
|
|
await mkdir(join(target, "Contents", "Resources"), { recursive: true });
|
|
await writeFile(
|
|
join(target, "Contents", "Info.plist"),
|
|
'<?xml version="1.0"?><plist version="1.0"><dict><key>CFBundleIdentifier</key><string>dev.rea.schema-probe</string></dict></plist>',
|
|
);
|
|
const { stdout } = await exec(
|
|
process.execPath,
|
|
[
|
|
fileURLToPath(
|
|
new URL("../../fixtures/artifactMcpVerifierProbe.mjs", import.meta.url),
|
|
),
|
|
mode,
|
|
target,
|
|
],
|
|
// Retain cleanup time within the existing 30s test budget.
|
|
{ timeout: 25_000 },
|
|
);
|
|
return observationSchema.parse(JSON.parse(stdout));
|
|
}
|
|
|
|
it("validates the real resource admission reply against its advertised schema", async () => {
|
|
expect(await probe("healthy", "Fixture.app")).toEqual({
|
|
accepted: true,
|
|
catalogRequests: 1,
|
|
corruptedReplies: 0,
|
|
toolCalls: 1,
|
|
toolTimeouts: [null],
|
|
error: null,
|
|
});
|
|
});
|
|
|
|
it.each(["Fixture.app", "Fixture with spaces 雨.app"])(
|
|
"rejects a corrupted canonical path in a real admission reply: %s",
|
|
async (name) => {
|
|
const result = await probe("corrupt", name);
|
|
expect(result.accepted).toBe(false);
|
|
expect(result.catalogRequests).toBe(1);
|
|
expect(result.corruptedReplies).toBe(1);
|
|
expect(result.error).toMatchObject({
|
|
name: "ProtocolError",
|
|
code: -32602,
|
|
message: expect.stringMatching(/output schema.*canonical_path/u),
|
|
});
|
|
},
|
|
);
|
|
|
|
it.each(["reuse", "concurrent"])(
|
|
"shares one schema discovery within one MCP connection: %s",
|
|
async (mode) => {
|
|
const result = await probe(mode);
|
|
expect(result.accepted).toBe(true);
|
|
expect(result.catalogRequests).toBe(1);
|
|
expect(result.toolCalls).toBe(mode === "reuse" ? 3 : 2);
|
|
},
|
|
);
|
|
|
|
it("binds the new advertised schema after reconnecting the same client", async () => {
|
|
const result = await probe("reconnect");
|
|
expect(result.accepted).toBe(false);
|
|
expect(result.catalogRequests).toBe(2);
|
|
expect(result.toolCalls).toBe(2);
|
|
expect(result.error).toMatchObject({
|
|
code: -32602,
|
|
message: expect.stringContaining("__rea_second_connection"),
|
|
});
|
|
});
|
|
|
|
it("rejects an omitted output schema before calling the advertised tool", async () => {
|
|
const result = await probe("missing-schema");
|
|
expect(result.accepted).toBe(false);
|
|
expect(result.toolCalls).toBe(0);
|
|
expect(result.error?.message).toMatch(/omitted its output schema/u);
|
|
});
|
|
|
|
it("rejects a supplied schema override before dispatching that call", async () => {
|
|
const result = await probe("override");
|
|
expect(result.accepted).toBe(false);
|
|
expect(result.toolCalls).toBe(1);
|
|
expect(result.error?.message).toMatch(/owns the advertised schema/u);
|
|
});
|
|
|
|
it("preserves explicit request timeouts on schema-bound calls", async () => {
|
|
const result = await probe("request-options");
|
|
expect(result.accepted).toBe(true);
|
|
expect(result.catalogRequests).toBe(1);
|
|
expect(result.toolTimeouts).toEqual([null, 12_345]);
|
|
});
|
|
|
|
it.each(["duplicate-first", "duplicate-last"])(
|
|
"rejects ambiguous named schemas independently of catalog order: %s",
|
|
async (mode) => {
|
|
const result = await probe(mode);
|
|
expect(result.accepted).toBe(false);
|
|
expect(result.toolCalls).toBe(0);
|
|
expect(result.error?.message).toMatch(/Duplicate MCP tool/u);
|
|
},
|
|
);
|
|
|
|
it("preserves cancellation received during final transport cleanup", async () => {
|
|
const result = await probe("cancel-finalization");
|
|
expect(result.accepted).toBe(false);
|
|
expect(result.error?.message).toBe("cancelled during final cleanup");
|
|
});
|
|
|
|
it("retains a work failure when cancellation arrives during cleanup", async () => {
|
|
const result = await probe("failure-cancel-finalization");
|
|
expect(result.accepted).toBe(false);
|
|
expect(result.error?.message).toBe("work failed before cancellation");
|
|
});
|