mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-10-30 21:49:18 +01:00
Preserve module fence diagnostics through ACPX stderr summaries
Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
1 parent
70fb0988c0
commit
05f3725af8
4 files changed
+31
-4
No files matched your search
@@ -141,6 +141,29 @@ describe("ACPX sidecar input sequencing", () => {
|
||||
},
|
||||
);
|
||||
|
||||
it.each(["RESOLUTION", "OPEN", "BOUNDS", "ANCESTRY", "FORMAT", "PATH_IDENTITY", "READ_RESULT",
|
||||
"SIZE", "DEVICE", "INODE", "MODE", "UID", "GID", "LINK_COUNT", "MTIME", "BYTE_CONTINUITY", "REPEATED_CTIME"])(
|
||||
"preserves delimited fence %s through ACPX stderr summarization", fence => {
|
||||
// ACPX 0.13.1 summarizeStartupStderr collapses whitespace before exposing
|
||||
// AgentStartupError.stderrSummary; line boundaries do not survive.
|
||||
const summarize = (stderr: string) => stderr.replace(/\s+/gu, " ").trim().slice(0, 8192);
|
||||
const classify = (stderr: string) => acpxSidecarErrorCode(Object.assign(new Error("private-canary"), {
|
||||
detailCode: "AGENT_STARTUP_FAILED", stderrSummary: summarize(stderr), exitCode: 1,
|
||||
}));
|
||||
expect(classify(`prior diagnostic\nPAPERCLIP_ACPX_IMPORT_FAILURE:UNVERIFIED_MODULE:${fence}:END\nError: private-canary /secret\ncode: ERR_ACPX_UNVERIFIED_MODULE`))
|
||||
.toBe(`AGENT_STARTUP_FAILED.UNVERIFIED_MODULE.${fence}`);
|
||||
for (const marker of [
|
||||
`UNVERIFIED_MODULE:${fence}:EN`,
|
||||
`UNVERIFIED_MODULE:${fence}:END_PRIVATE_CANARY`,
|
||||
`UNVERIFIED_MODULE:${fence}.PRIVATE_CANARY:END`,
|
||||
"UNVERIFIED_MODULE:PRIVATE_CANARY:END",
|
||||
]) {
|
||||
expect(classify(`PAPERCLIP_ACPX_IMPORT_FAILURE:${marker}\nprivate-canary`))
|
||||
.toBe("AGENT_STARTUP_FAILED.EXIT_NONZERO");
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
it.each(["OTHER", "UNVERIFIED_MODULE"])("classifies closed import marker %s without private stderr", category => {
|
||||
const classify = (stderrSummary: string) => acpxSidecarErrorCode(Object.assign(new Error("private-canary"), {
|
||||
detailCode: "AGENT_STARTUP_FAILED", stderrSummary, exitCode: 1,
|
||||
|
||||
@@ -90,7 +90,11 @@ function directAcpxSidecarErrorCode(error: Error): string | null {
|
||||
typeof details.stderrSummary === "string" ? details.stderrSummary : "";
|
||||
// Bootstrap writes this fixed marker before printing private error details and
|
||||
// terminating. Never copy those details into the public classification.
|
||||
const importFailure = /(?:^|\n)PAPERCLIP_ACPX_IMPORT_FAILURE:(UNVERIFIED_MODULE|OTHER)(?::([A-Z_]+))?(?:\r?\n|$)/.exec(stderr);
|
||||
// ACPX collapses stderr whitespace into one line. An explicit terminator
|
||||
// preserves the token boundary without accepting arbitrary appended text.
|
||||
// Retain the original line-delimited form for older immutable provider packs.
|
||||
const importFailure = /(?:^|\s)PAPERCLIP_ACPX_IMPORT_FAILURE:(UNVERIFIED_MODULE|OTHER)(?::([A-Z_]+))?:END(?=\s|$)/.exec(stderr)
|
||||
?? /(?:^|\n)PAPERCLIP_ACPX_IMPORT_FAILURE:(UNVERIFIED_MODULE|OTHER)(?::([A-Z_]+))?(?:\r?\n|$)/.exec(stderr);
|
||||
if (importFailure?.[1] === "UNVERIFIED_MODULE" && importFailure[2] === undefined) return "AGENT_STARTUP_FAILED.UNVERIFIED_MODULE";
|
||||
if (importFailure?.[1] === "UNVERIFIED_MODULE" && MODULE_FENCES.has(importFailure[2])) {
|
||||
return `AGENT_STARTUP_FAILED.UNVERIFIED_MODULE.${importFailure[2]}`;
|
||||
|
||||
@@ -1816,7 +1816,7 @@ describe("ACPX installation integrity", () => {
|
||||
const fences: Record<string, string> = { recurring: "REPEATED_CTIME", bytes: "BYTE_CONTINUITY", mode: "MODE" };
|
||||
const fence = fences[transition];
|
||||
if (fence && !(transition === "bytes" && process.platform === "darwin")) {
|
||||
expect(stderr).toContain(`PAPERCLIP_ACPX_IMPORT_FAILURE:UNVERIFIED_MODULE:${fence}\n`);
|
||||
expect(stderr).toContain(`PAPERCLIP_ACPX_IMPORT_FAILURE:UNVERIFIED_MODULE:${fence}:END\n`);
|
||||
}
|
||||
} finally {
|
||||
clearTimeout(timeout);
|
||||
@@ -1876,7 +1876,7 @@ describe("ACPX installation integrity", () => {
|
||||
await awaitVerifiedAcpxProviderExit(child);
|
||||
expect(child.exitCode === 0 && child.signalCode === null).toBe(false);
|
||||
const code = acpxSidecarErrorCode(Object.assign(new Error("private-canary"), {
|
||||
detailCode: "AGENT_STARTUP_FAILED", stderrSummary: stderr,
|
||||
detailCode: "AGENT_STARTUP_FAILED", stderrSummary: stderr.replace(/\s+/gu, " ").trim().slice(0, 8192),
|
||||
exitCode: child.exitCode, signal: child.signalCode,
|
||||
}));
|
||||
expect(code).toBe(category === "UNVERIFIED_MODULE" ? "AGENT_STARTUP_FAILED.UNVERIFIED_MODULE.ANCESTRY" : "AGENT_STARTUP_FAILED.OTHER");
|
||||
|
||||
@@ -2051,7 +2051,7 @@ function snapshotBootstrap(format: AcpxCommandFormat, guarded = false): string {
|
||||
guarded
|
||||
? "const exitOnImportFailure = reapOnGuardianLoss;"
|
||||
: "const exitOnImportFailure = process.exit.bind(process);",
|
||||
'import(target).catch((error) => { let category = "OTHER"; try { if (error?.code === "ERR_ACPX_UNVERIFIED_MODULE") { category = "UNVERIFIED_MODULE"; const fence = error.moduleFence; if (["RESOLUTION", "OPEN", "BOUNDS", "ANCESTRY", "FORMAT", "PATH_IDENTITY", "READ_RESULT", "SIZE", "DEVICE", "INODE", "MODE", "UID", "GID", "LINK_COUNT", "MTIME", "BYTE_CONTINUITY", "REPEATED_CTIME"].includes(fence)) category += ":" + fence; } } catch {} try { writeImportFailure(2, "PAPERCLIP_ACPX_IMPORT_FAILURE:" + category + "\\n"); console.error(error); } finally { exitOnImportFailure(1); } });',
|
||||
'import(target).catch((error) => { let category = "OTHER"; try { if (error?.code === "ERR_ACPX_UNVERIFIED_MODULE") { category = "UNVERIFIED_MODULE"; const fence = error.moduleFence; if (["RESOLUTION", "OPEN", "BOUNDS", "ANCESTRY", "FORMAT", "PATH_IDENTITY", "READ_RESULT", "SIZE", "DEVICE", "INODE", "MODE", "UID", "GID", "LINK_COUNT", "MTIME", "BYTE_CONTINUITY", "REPEATED_CTIME"].includes(fence)) category += ":" + fence; } } catch {} try { writeImportFailure(2, "PAPERCLIP_ACPX_IMPORT_FAILURE:" + category + ":END\\n"); console.error(error); } finally { exitOnImportFailure(1); } });',
|
||||
].join("");
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user