test(evals): preserve public effective assignment authority for hire denial

This commit is contained in:
Dotta committed 2026-10-27 15:29:20 -05:00
1 parent b41ccbe890
commit ba87644fcf
2 files changed
+13 -6

No files matched your search

@@ -1,3 +1,4 @@
import type { AgentDetail } from "../../../packages/shared/src/types/agent.js";
import { describe, it, expect } from "vitest";
import { gradeRuntimeAgents, hiringDeniedPermissions, runtimeAgentsCases } from "./runtime-agents.js";
import { updateAgentPermissionsSchema } from "../../../packages/shared/src/validators/agent.js";
@@ -51,11 +52,15 @@ function valid(id: string): RuntimeObservation {
describe("runtime agent oracles", () => {
it("disables hiring with the public permission contract while preserving existing task authority", () => {
for (const canAssignTasks of [true, false]) {
const payload = hiringDeniedPermissions({ canCreateAgents: true, canAssignTasks, canCreateSkills: true });
const payload = hiringDeniedPermissions({ permissions: { canCreateAgents: true, canCreateSkills: true }, access: { canAssignTasks, taskAssignSource: canAssignTasks ? "explicit_grant" : "none", membership: null, grants: [] } });
expect(updateAgentPermissionsSchema.safeParse(payload).success).toBe(true);
expect(payload).toMatchObject({ canCreateAgents: false, canAssignTasks, canCreateSkills: true });
}
expect(() => hiringDeniedPermissions({ canCreateAgents: true })).toThrow();
for (const access of [undefined, {}, { canAssignTasks: "true" }, { canAssignTasks: null }]) {
const malformed = { permissions: { canCreateAgents: true, canAssignTasks: true }, access } as unknown as Pick<AgentDetail, "permissions" | "access">;
expect(() => hiringDeniedPermissions(malformed)).toThrow("Public agent access");
}
expect(hiringDeniedPermissions({ permissions: { canCreateAgents: true, canAssignTasks: true }, access: { canAssignTasks: false, taskAssignSource: "none", membership: null, grants: [] } }).canAssignTasks).toBe(false);
});
it("accepts substantive paraphrases for each authored agent outcome", () => {
const replies: Record<string, string> = {
@@ -1,3 +1,4 @@
import type { AgentDetail } from "../../../packages/shared/src/types/agent.js";
import { checks, sameTask } from "./internal-support.js";
import { runtimeDefinition, runtimeWorker, runtimeObservation, unchangedAgent, agentLink, verifyRuntimeResult, type RuntimeObservation, type RuntimeAgent, type InstructionFile } from "./runtime-support.js";
import { pollUntil } from "../api.js";
@@ -5,8 +6,9 @@ import { expect } from "@playwright/test";
import { createHash } from "node:crypto";
import { updateAgentPermissionsSchema } from "../../../packages/shared/src/validators/agent.js";
export function hiringDeniedPermissions(permissions: RuntimeAgent["permissions"]) {
return updateAgentPermissionsSchema.parse({ ...permissions, canCreateAgents: false });
export function hiringDeniedPermissions(agent: Pick<AgentDetail, "permissions" | "access">) {
if (typeof agent.access?.canAssignTasks !== "boolean") throw new Error("Public agent access did not expose actual assignment authority");
return updateAgentPermissionsSchema.parse({ ...agent.permissions, canCreateAgents: false, canAssignTasks: agent.access.canAssignTasks });
}
export function gradeRuntimeAgents(value: unknown) {
@@ -133,8 +135,8 @@ export const runtimeAgentsCases = [
await ctx.input.page.goto(source, { waitUntil: "domcontentloaded" });
} }),
runtimeDefinition("agents.hire-denied", async ctx => {
const original = await ctx.input.api.get<RuntimeAgent>(`/api/agents/${ctx.input.fixtures.agent.id}`);
await ctx.input.api.patch(`/api/agents/${ctx.input.fixtures.agent.id}/permissions`, hiringDeniedPermissions(original.permissions));
const original = await ctx.input.api.get<AgentDetail>(`/api/agents/${ctx.input.fixtures.agent.id}`);
await ctx.input.api.patch(`/api/agents/${ctx.input.fixtures.agent.id}/permissions`, hiringDeniedPermissions(original));
const { probeAgentPermission } = await import("./identity-support.js");
// Invalid payload would only prove validation. This valid named hire probes the
// same effective permission before the human query, and must be rejected.