Q37: skill tool text tells the CEO the truth about grants

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
ZacharyZhang-NYandClaude Opus 5.5 committed 2026-10-08 07:11:43 -04:00
1 parent 25d054d954
commit e726c36bac
3 files changed
+18 -4

No files matched your search

+2 -2
View File
@@ -200,12 +200,12 @@ export const AGENT_TOOLS: ToolDefinition[] = [
},
{
name: "list_skills",
description: "See the company's skill library and who holds each skill. You carry every skill automatically as CEO; teammates only run with skills you grant them.",
description: "See the company's skill library and who holds each skill. A skill joins an agent's runs only once granted, the CEO included; house-style skills are carried by everyone.",
parameters: { type: "object", additionalProperties: false, properties: {}, required: [] },
},
{
name: "grant_skill",
description: "CEO only: grant a teammate one of the company's skills so its instructions join their next run. Match the skill to the job.",
description: "CEO only: grant a teammate, or yourself, one of the company's skills so its instructions join their next run. Match the skill to the job.",
parameters: {
type: "object",
additionalProperties: false,
+1 -1
View File
@@ -132,7 +132,7 @@ function capabilityBriefing(input: AgentInstructionContext): string {
);
if (input.isCeo) {
lines.push(
"You are the CEO: you automatically carry every connected service, and access for everyone else is yours to manage — when you delegate work that needs an external service, grant it first with grant_connector and take it back with revoke_connector when done. The company also ships a built-in skill library: staff every hire with the skills their role needs by passing skills to hire_agent (several per person is normal), and adjust later with grant_skill / revoke_skill. A teammate without the grant cannot use the tool or skill, so grant before you assign. The humanizer skill is company house style — every agent, you included, carries it automatically and must write like a person, not like an AI.",
"You are the CEO: you automatically carry every connected service, and access for everyone else is yours to manage — when you delegate work that needs an external service, grant it first with grant_connector and take it back with revoke_connector when done. The company also ships a built-in skill library: staff every hire with the skills their role needs by passing skills to hire_agent (several per person is normal), and adjust later with grant_skill / revoke_skill. You run only with skills granted to you too: grant yourself a playbook before you rely on it. A teammate without the grant cannot use the tool or skill, so grant before you assign. The humanizer skill is company house style — every agent, you included, carries it automatically and must write like a person, not like an AI.",
);
} else if (input.connectorNames.length === 0) {
lines.push(
+15 -1
View File
@@ -6,7 +6,7 @@ import { DatabaseConnection } from "../../src/main/database/connection";
import { OrganizationService } from "../../src/main/services/organization-service";
import { ChatService } from "../../src/main/services/chat-service";
import { SkillService } from "../../src/main/services/skill-service";
import { dispatchAgentTool, type AgentToolContext } from "../../src/main/services/agent-tools";
import { AGENT_TOOLS, dispatchAgentTool, type AgentToolContext } from "../../src/main/services/agent-tools";
function call(name: string, args: Record<string, unknown>) {
return { id: `call_${randomUUID()}`, name, arguments: args };
@@ -75,6 +75,20 @@ function importSkill(h: Harness, name: string, slug: string): void {
}
describe("skill grants", () => {
test("the CEO runs only with granted skills, as the tool text says, and can grant itself", () => {
const h = harness();
importSkill(h, "Release Gate", "release-gate");
const listSkills = AGENT_TOOLS.find((tool) => tool.name === "list_skills");
expect(listSkills?.description).not.toContain("every skill automatically");
expect(listSkills?.description).toContain("the CEO included");
const skills = new SkillService(h.connection.db, "");
expect(skills.hasRuntimeSkills(h.orgId, h.ceoId)).toBe(false);
expect(dispatchAgentTool(h.deps, h.ceoCtx, call("grant_skill", { agent_name: "CEO", skill: "release-gate" })))
.toBe("CEO now has the Release Gate skill; it joins their next run.");
expect(skills.hasRuntimeSkills(h.orgId, h.ceoId)).toBe(true);
h.connection.close();
});
test("the CEO grants and revokes skills for teammates", () => {
const h = harness();
importSkill(h, "Release Gate", "release-gate");