perf(runner): skip wake payloads in ordinary authority reads (#17600)

Omit saved wake payloads from ordinary unlocked Native authority reads. Load the current full wake for mail restrictions. Preserve stored rows, locked mutation reads, and current authorization predicates.

Verified with full build and typecheck, 2,360 affected tests, real PostgreSQL byte and response checks, counterfactual performance and mail authorization failures, complete exact-head CI, and Greptile 5/5 Medium with no unresolved comments.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
Devin FoleyandPaperclip authored and GitHub committed 2026-10-25 05:36:43 -07:00
1 parent 2e47c42fad
commit 8c6bd5a83b
3 files changed
+50 -8

No files matched your search

@@ -1,4 +1,4 @@
import { connectorToolDefinitionsForSkills } from "../connector-runtime.js";
import * as connectorRuntime from "../connector-runtime.js";
import * as cloudIdentity from "../cloud-runtime-identity.js";
import { afterAll, afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
import { randomUUID } from "node:crypto";
@@ -101,7 +101,7 @@ describe("PaperclipRunnerToolAuthority", () => {
});
it("registers pinned connector definitions without discovery and rejects revoked assignments at use", async () => {
const connectorAssignments = connectorToolDefinitionsForSkills(new Set([
const connectorAssignments = connectorRuntime.connectorToolDefinitionsForSkills(new Set([
"paperclipai/paperclip/slack", "paperclipai/paperclip/browser-use-cloud", "custom/agentmail",
]));
expect(connectorAssignments).toHaveLength(1);
@@ -244,7 +244,7 @@ describe("PaperclipRunnerToolAuthority", () => {
}
});
it("reads tool authority without transferring unused launch renderings", async () => {
it("reads tool authority without transferring unused launch renderings or wake payloads", async () => {
const binding = { companyId, agentId, issueId, runId };
const authority = new PaperclipRunnerToolAuthority(db, binding);
const contextCall = { tool: "get_task_context", callId: "launch-context-read", arguments: {} };
@@ -255,7 +255,7 @@ describe("PaperclipRunnerToolAuthority", () => {
const context = { ...original.contextSnapshot, executionContinuation: { savedInput: payload }, paperclipTaskMarkdown: payload,
paperclipTaskMarkdownCompact: payload, paperclipTaskMarkdownAssignment: payload, paperclipTaskMarkdownAssignmentCompact: payload,
paperclipWorkspace: { savedInput: payload }, paperclipEnvironment: { savedInput: payload },
paperclipContinuationSummary: payload, paperclipWakeComment: payload };
paperclipContinuationSummary: payload, paperclipWakeComment: payload, paperclipWake: { retainedPayload: payload } };
await db.update(heartbeatRuns).set({ contextSnapshot: context }).where(eq(heartbeatRuns.id, runId));
const [expanded] = await db.select().from(heartbeatRuns).where(eq(heartbeatRuns.id, runId));
const observed = createDb(temporary!.connectionString), events: Array<Record<string, unknown>> = [], now = Date.now();
@@ -280,6 +280,45 @@ describe("PaperclipRunnerToolAuthority", () => {
}
});
it("checks the current full wake before mail actions while ordinary tools omit its payload", async () => {
const connectorAssignments = connectorRuntime.connectorToolDefinitionsForSkills(new Set(["paperclipai/paperclip/agentmail"]));
const name = connectorAssignments.flatMap(assignment => assignment.tools).find(tool => tool.name.startsWith("agentmail_"))!.name;
const authority = new PaperclipRunnerToolAuthority(db, { companyId, agentId, issueId, runId, connectorAssignments });
const [original] = await db.select().from(heartbeatRuns).where(eq(heartbeatRuns.id, runId));
const dispatch = vi.spyOn(connectorRuntime, "executeConnectorTool").mockResolvedValue({ outcome: "mail-dispatched" });
const wake = {
reason: "External chat message received", externalChatProvider: "github", checkedOutByHarness: true,
issue: { id: issueId, identifier: "RNT-1", title: "Conversation", description: "Task", descriptionTruncated: false,
status: "in_progress", workMode: "standard" },
commentWindow: { requestedCount: 1, includedCount: 1, missingCount: 0 }, commentIds: ["wake-comment"],
latestCommentId: "wake-comment", comments: [{ id: "wake-comment", issueId, body: "Reply here", bodyTruncated: false, authorType: "user" }],
fallbackFetchNeeded: false,
};
const call = { tool: name, callId: "current-mail-wake", arguments: {} };
try {
await db.update(heartbeatRuns).set({ contextSnapshot: { issueId, paperclipWake: wake } }).where(eq(heartbeatRuns.id, runId));
await expect(authority.execute(call)).rejects.toThrow("Restricted chat runs cannot use email actions");
expect(dispatch).not.toHaveBeenCalled();
await expect(authority.execute({ tool: "get_task_context", callId: "chat-task-context", arguments: {} }))
.resolves.toMatchObject({ activeTask: { id: issueId } });
await db.update(heartbeatRuns).set({ contextSnapshot: { issueId } }).where(eq(heartbeatRuns.id, runId));
await expect(authority.execute(call)).resolves.toEqual({ outcome: "mail-dispatched" });
expect(dispatch).toHaveBeenCalledTimes(1);
await db.update(heartbeatRuns).set({ contextSnapshot: { issueId, paperclipWake: { ...wake, checkedOutByHarness: false,
externalChatExecutionBound: true, issue: { ...wake.issue, status: "in_review" } } } }).where(eq(heartbeatRuns.id, runId));
await expect(authority.execute(call)).rejects.toThrow("Restricted chat runs cannot use email actions");
expect(dispatch).toHaveBeenCalledTimes(1);
for (const context of [{ issueId, source: "chat:github" }, { issueId, paperclipExternalChatQuestionResponse: true }]) {
await db.update(heartbeatRuns).set({ contextSnapshot: context }).where(eq(heartbeatRuns.id, runId));
await expect(authority.execute(call)).rejects.toThrow("Restricted chat runs cannot use email actions");
expect(dispatch).toHaveBeenCalledTimes(1);
}
} finally {
dispatch.mockRestore();
await db.update(heartbeatRuns).set({ contextSnapshot: original.contextSnapshot }).where(eq(heartbeatRuns.id, runId));
}
});
it("preserves platform receipt provenance in both mixed task history readers", async () => {
const at = new Date("2026-10-10T12:00:00Z");
const commentIds = Array.from({ length: 4 }, () => randomUUID());
@@ -449,7 +449,7 @@ export class PaperclipRunnerToolAuthority {
}
if (isConnectorTool(call.tool)) {
if (!(this.binding.connectorAssignments ?? []).some((assignment) => assignment.tools.some((tool) => tool.name === call.tool))) throw forbidden("Connector tool is not available to this run");
const { run } = await this.#boundContext();
const { run } = await this.#boundContext({ includeChatWake: call.tool.startsWith("agentmail_") });
const snapshot = record(run.contextSnapshot);
if (call.tool.startsWith("agentmail_") && (isPaperclipExternalChatContractTurn(snapshot.paperclipWake) || String(snapshot.source ?? "").startsWith("chat:") || snapshot.paperclipExternalChatQuestionResponse)) throw forbidden("Restricted chat runs cannot use email actions");
return executeConnectorTool(this.db, this.binding, call.tool, call.arguments);
@@ -1225,7 +1225,7 @@ export class PaperclipRunnerToolAuthority {
...(this.binding.museRuntime ? { authorizingUserId: this.binding.externalAuthorizingUserId } : {}) };
}
async #boundContext() {
async #boundContext(options: { includeChatWake?: boolean } = {}) {
if (this.binding.museRuntime && !this.binding.externalAuthorizingUserId) throw forbidden("Muse authorizer is unavailable");
const [row] = await this.db.select({ issue: issues, actor: agents, run: {
id: heartbeatRuns.id,
@@ -1239,6 +1239,7 @@ export class PaperclipRunnerToolAuthority {
then ${heartbeatRuns.contextSnapshot} - array['executionContinuation', 'paperclipTaskMarkdown',
'paperclipTaskMarkdownCompact', 'paperclipTaskMarkdownAssignment', 'paperclipTaskMarkdownAssignmentCompact',
'paperclipWorkspace', 'paperclipEnvironment', 'paperclipContinuationSummary', 'paperclipWakeComment']
${options.includeChatWake ? sql`` : sql`- 'paperclipWake'`}
else ${heartbeatRuns.contextSnapshot} end`,
resultJson: heartbeatRuns.resultJson,
} })