Verify private task denial contracts with current master

Preserve existing PR history and verified downstream privacy rules.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
DottaandPaperclip committed 2026-10-06 20:18:30 -05:00
commit 7b0755dac2
5 files changed
+14 -13

No files matched your search

@@ -7571,14 +7571,6 @@ it("preserves prepared input and completion feedback through runnerd and the rea
`], { maxBuffer: 16 * 1024 * 1024 });
await writeFile(proxy, proxyBytes, { mode: 0o755 });
const digest = (file: string) => `sha256:${createHash("sha256").update(readFileSync(file)).digest("hex")}`;
// Linux runner images can install Node with group-write permission. Qualify
// an isolated copy without mutating the host. Keep the original on macOS,
// where Homebrew Node can load dylibs relative to its installation directory.
const providerNode = process.platform === "linux" ? join(root, "node") : process.execPath;
if (providerNode !== process.execPath) {
await cp(process.execPath, providerNode);
await chmod(providerNode, 0o755);
}
const runtime = join(root, "opencode");
const bundle = createCapabilityRunnerdCodexTransport({
provider: "opencode",
@@ -190,8 +190,9 @@ const support = await getEmbeddedPostgresTestSupport();
{ projectId: f.projectId, assigneeAgentId: null, assigneeUserId: "board-user" },
]) {
const result = await create(path, fields);
expect(result.status, JSON.stringify(result.body)).toBe(403);
expect(result.body.error).toMatch(/outside.*boundary|cannot assign work to board users|different company/i);
const hiddenProject = fields.projectId !== f.projectId && path.startsWith("/api/companies/");
expect(result.status, JSON.stringify(result.body)).toBe(hiddenProject ? 404 : 403);
expect(result.body.error).toMatch(hiddenProject ? /^Project not found$/ : /outside.*boundary|cannot assign work to board users|different company/i);
}
}
const after = await server.db.select({ id: issues.id }).from(issues).where(eq(issues.companyId, f.companyId));
@@ -232,7 +233,10 @@ const support = await getEmbeddedPostgresTestSupport();
body: JSON.stringify({ title: "Root cannot escape into another project", parentId: f.issueId,
projectId: outside.id, assigneeAgentId: f.agentId, status: "backlog" }),
});
expect(response.status, JSON.stringify(await response.json())).toBe(403);
const denied = await response.json();
const hiddenProject = path.startsWith("/api/companies/");
expect(response.status, JSON.stringify(denied)).toBe(hiddenProject ? 404 : 403);
expect(denied.error).toMatch(hiddenProject ? /^Project not found$/ : /outside.*boundary/i);
}
await expect(call(f, "create_task", { title: "Native root cannot escape", projectId: outside.id,
idempotencyKey: "root-outside", status: "backlog" })).rejects.toThrow(/outside.*boundary/);
@@ -1734,7 +1734,7 @@ describeEmbeddedPostgres(
const before = await snapshot(db);
const res = await attempt.req();
expect(res.status, `${attempt.id}: ${JSON.stringify(res.body)}`).toBe(
["LT approvals", "LT-15/16", "LT-19", "LT-26 child", "LT-26 company issue", "LT-26 interaction", "LT-06 resume", "LT-06 blocker mutation"].includes(attempt.id) ? 403 : 404,
["LT approvals", "LT-15/16", "LT-19", "LT-26 child", "LT-26 child with unauthorized assignee", "LT-26 company issue", "LT-26 interaction", "LT-06 resume", "LT-06 blocker mutation"].includes(attempt.id) ? 403 : 404,
);
expectNoCanary(res.body, ...forbiddenMarkers);
const after = await snapshot(db);
@@ -265,6 +265,7 @@ describeEmbeddedPostgres("gateway connector invocation telemetry", () => {
}, 30_000);
afterEach(async () => {
vi.useRealTimers();
track.mockClear();
failLogActivityForAction.current = null;
await db.delete(activityLog);
@@ -379,6 +380,9 @@ describeEmbeddedPostgres("gateway connector invocation telemetry", () => {
}, 30_000);
it("emits one denied event for a policy block and one rate_limited event past the limit", async () => {
// Both calls must land in the same policy window, even across a minute boundary.
vi.useFakeTimers({ toFake: ["Date"] });
vi.setSystemTime(new Date("2026-10-06T12:00:30Z"));
const f = await fixture();
await db.insert(toolPolicies).values({
companyId: f.company.id,
@@ -508,7 +508,8 @@ describe("AI repair inside the card", () => {
setupOptionsMock.mockResolvedValue({ interaction, existingConnections: [], aiConnection: binding, aiConnectionRequiresAdoption: true });
if (fails) adoptMock.mockRejectedValue(new Error("Connection test failed"));
else adoptMock.mockResolvedValue({ ...interaction, status: "accepted" });
renderBody(interaction); await flush();
renderBody(interaction);
await waitForAssertion(() => expect(button("Connect OpenAI")).toBeDefined());
await act(() => button("Connect OpenAI")!.click());
await act(() => button("Reconnect selected account")!.click());
expect(adoptMock).not.toHaveBeenCalled();