diff --git a/tests/runner-e2e/chat-catalog-domains/runtime-provider-cleanup.ts b/tests/runner-e2e/chat-catalog-domains/runtime-provider-cleanup.ts index d6979db307d..96e84f22576 100644 --- a/tests/runner-e2e/chat-catalog-domains/runtime-provider-cleanup.ts +++ b/tests/runner-e2e/chat-catalog-domains/runtime-provider-cleanup.ts @@ -29,7 +29,9 @@ async function providerIdentity(pid: number): Promise { try { const ps = async (field: string) => (await promisify(execFile)("/bin/ps", ["-p", String(pid), "-o", `${field}=`], { timeout: 5_000, maxBuffer: 65_536 })).stdout.trim(); const [uid, parent, executable, command, startedAt] = await Promise.all([ps("uid"), ps("ppid"), ps("comm"), ps("args"), readProcessStartedAt(pid)]); - const canonical = await realpath(ownedNativeExecutablePath(pid, executable)); + // A pinned binary may be executed from an inherited descriptor (/proc/self/fd/N); its real + // executable is then only reachable through the kernel's /proc//exe link. + const canonical = await realpath(ownedNativeExecutablePath(pid, executable)).catch(() => realpath(`/proc/${pid}/exe`)); const args = command.split(/\s+/); // node may carry runtime flags before the script; the absolute proxy script is the last argument. const script = args.at(-1)!, flags = args.slice(1, -1); diff --git a/tests/runner-e2e/launch.ts b/tests/runner-e2e/launch.ts index fa381d8b955..ad27bfe0052 100644 --- a/tests/runner-e2e/launch.ts +++ b/tests/runner-e2e/launch.ts @@ -932,6 +932,7 @@ async function runAttempt(input: { manualDiagnostic!.stage = "seal-original"; await sealStandardOriginalEvidence({ context: manualPrivateHandoff, executionId: candidate.id, source: casePrivateDir, evidence: originalEvidence, secrets: credentials, expectPassScreenshot: originalFeaturePassed }); + manualDiagnostic!.stage = "attach-original"; if (evidence.files.includes(PRIVATE_FRAMEWORK_REPORT)) await referenceSealedFrameworkAttachments(uploadDir, path.join(manualPrivateHandoff.root, "originals", manualCellKind(candidate.id)), candidate.id); } else { diff --git a/tests/runner-e2e/private-attempt-diagnostic.test.ts b/tests/runner-e2e/private-attempt-diagnostic.test.ts index 9750eeb370f..b46a4144189 100644 --- a/tests/runner-e2e/private-attempt-diagnostic.test.ts +++ b/tests/runner-e2e/private-attempt-diagnostic.test.ts @@ -123,7 +123,7 @@ it("retains each remaining fixed scanner reason without dynamic text", () => { import { readFileSync } from "node:fs"; it("gives every fixed packaging, sealing and report-asset refusal a closed finalization code", () => { - const messages = ["manual-private-handoff.ts", "evidence.ts", "manual-private-report-assets.ts", "private-framework-report.ts", "redaction.ts", "manual-private-retention.ts"].flatMap(file => + const messages = ["manual-private-handoff.ts", "evidence.ts", "manual-private-report-assets.ts", "private-framework-report.ts", "redaction.ts", "manual-private-retention.ts", "chat-readiness-detail.ts", "source-sdk-evidence.ts"].flatMap(file => [...readFileSync(new URL(`./${file}`, import.meta.url), "utf8").matchAll(/(?:new Error|budgetFailure)\("([^"$`]+)"/g)].map(match => match[1]!)); expect(messages.length).toBeGreaterThan(20); for (const message of messages) { diff --git a/tests/runner-e2e/private-attempt-diagnostic.ts b/tests/runner-e2e/private-attempt-diagnostic.ts index b1c1eb4d08a..291785c855f 100644 --- a/tests/runner-e2e/private-attempt-diagnostic.ts +++ b/tests/runner-e2e/private-attempt-diagnostic.ts @@ -50,6 +50,31 @@ function carrierReasons(input: unknown, source: "reporter" | "packaging") { })); } const failures = new Map([ + ["Bounded diagnostic unavailable", "bounded-diagnostic-unavailable"], + ["Diagnostic withheld", "diagnostic-withheld"], + ["Diagnostic custody invalid", "diagnostic-custody-invalid"], + ["Source SDK evidence privacy check failed; bytes withheld", "source-sdk-evidence-privacy-check-failed"], + ["Source SDK output custody invalid", "source-sdk-output-custody-invalid"], + ["Source SDK output exceeds evidence bound", "source-sdk-output-exceeds-evidence-bound"], + ["Source SDK output root invalid", "source-sdk-output-root-invalid"], + ["Source SDK retention requires exact source revision", "source-sdk-retention-requires-exact-source"], + ["Source SDK staging custody invalid", "source-sdk-staging-custody-invalid"], + ["Source SDK build completion evidence missing", "source-sdk-build-completion-evidence-missing"], + ["Source SDK build output no longer matches its completed compiler receipt", "source-sdk-build-output-no-longer"], + ["Source SDK output exceeds combined evidence bound", "source-sdk-output-exceeds-combined-evidence"], + ["Source SDK retained filename collision", "source-sdk-retained-filename-collision"], + ["Source SDK retained selection mismatch", "source-sdk-retained-selection-mismatch"], + ["Source SDK retained custody invalid", "source-sdk-retained-custody-invalid"], + ["Source SDK retained receipt missing", "source-sdk-retained-receipt-missing"], + ["Source SDK retained identity mismatch", "source-sdk-retained-identity-mismatch"], + ["Source SDK retained bytes changed", "source-sdk-retained-bytes-changed"], + ["Source SDK public source custody changed", "source-sdk-public-source-custody-changed"], + ["Source SDK public observations changed", "source-sdk-public-observations-changed"], + ["Source SDK published bytes changed", "source-sdk-published-bytes-changed"], + ["SDK audit capture does not match its exact private cell", "sdk-audit-capture-does-not-match"], + ["SDK audit source custody invalid", "sdk-audit-source-custody-invalid"], + ["SDK audit changed during capture", "sdk-audit-changed-during-capture"], + ["SDK audit has an unsupported observation shape", "sdk-audit-has-an-unsupported-observation"], ["Invalid private framework evidence", "invalid-private-framework-evidence"], ["Docker config custody requires the isolated home scan", "docker-config-custody-requires-the-isolated"], ["Private Codex identity policy requires the isolated home root", "private-codex-identity-policy-requires-the"], @@ -166,7 +191,7 @@ export function privateAttemptDiagnostic(input: PrivateAttemptDiagnosticInput) { return { schema: "paperclip.private-attempt-diagnostic/v1", packagingBudget: closedPackagingBudget(record(input.error).evidenceBudget ?? evidence.budget, message), - stage: member(input.stage, ["execution", "package-original", "seal-original"]), + stage: member(input.stage, ["execution", "package-original", "seal-original", "attach-original"]), status: member(result.status, ["passed", "failed", "skipped"]), failureClass: member(result.failureClass, ["candidate_failure", "transient_infrastructure", "permanent_infrastructure", "secret_leak", "cleanup_failure"]), finalization: failures.get(message) ?? (record(input.error).code === "ENOENT" ? "missing-file"