mirror of
https://bitbucket.org/siakitem/my-pi.git
synced 2026-08-28 08:35:57 +00:00
feat: vendor permission system source
This commit is contained in:
@@ -0,0 +1,146 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
|
||||
import { describeSkillInputGate } from "#src/handlers/gates/skill-input";
|
||||
import { makeCheckResult } from "#test/helpers/handler-fixtures";
|
||||
|
||||
// ── helpers ────────────────────────────────────────────────────────────────
|
||||
|
||||
function makeSkillCheck(state: "allow" | "deny" | "ask") {
|
||||
return makeCheckResult({
|
||||
state,
|
||||
toolName: "skill",
|
||||
source: "skill",
|
||||
origin: "global",
|
||||
matchedPattern: "*",
|
||||
});
|
||||
}
|
||||
|
||||
// ── describeSkillInputGate ─────────────────────────────────────────────────
|
||||
|
||||
describe("describeSkillInputGate", () => {
|
||||
it("sets surface to 'skill'", () => {
|
||||
const descriptor = describeSkillInputGate(
|
||||
"librarian",
|
||||
null,
|
||||
makeSkillCheck("allow"),
|
||||
);
|
||||
expect(descriptor.surface).toBe("skill");
|
||||
});
|
||||
|
||||
it("sets input.name to the skill name", () => {
|
||||
const descriptor = describeSkillInputGate(
|
||||
"librarian",
|
||||
null,
|
||||
makeSkillCheck("allow"),
|
||||
);
|
||||
expect(descriptor.input).toEqual({ name: "librarian" });
|
||||
});
|
||||
|
||||
it("passes preCheck through verbatim", () => {
|
||||
const check = makeSkillCheck("deny");
|
||||
const descriptor = describeSkillInputGate("librarian", null, check);
|
||||
expect(descriptor.preCheck).toBe(check);
|
||||
});
|
||||
|
||||
it("makes the skill the payload's decision-relevant value", () => {
|
||||
const descriptor = describeSkillInputGate(
|
||||
"librarian",
|
||||
null,
|
||||
makeSkillCheck("allow"),
|
||||
);
|
||||
expect(descriptor.payload.kind).toBe("skill");
|
||||
expect(descriptor.payload.request.surface).toBe("skill");
|
||||
expect(descriptor.payload.request.value).toBe("librarian");
|
||||
expect(descriptor.payload.request.requester.agentName).toBeNull();
|
||||
});
|
||||
|
||||
it("names the requesting agent on the payload when provided", () => {
|
||||
const descriptor = describeSkillInputGate(
|
||||
"librarian",
|
||||
"code-agent",
|
||||
makeSkillCheck("allow"),
|
||||
);
|
||||
expect(descriptor.payload.request.requester.agentName).toBe("code-agent");
|
||||
});
|
||||
|
||||
it("sets promptDetails source to 'skill_input' with skill name and agent", () => {
|
||||
const descriptor = describeSkillInputGate(
|
||||
"librarian",
|
||||
"code-agent",
|
||||
makeSkillCheck("ask"),
|
||||
);
|
||||
expect(descriptor.promptDetails).toMatchObject({
|
||||
source: "skill_input",
|
||||
agentName: "code-agent",
|
||||
skillName: "librarian",
|
||||
});
|
||||
});
|
||||
|
||||
it("emits a skill payload naming the skill as the decision value", () => {
|
||||
const descriptor = describeSkillInputGate(
|
||||
"librarian",
|
||||
"code-agent",
|
||||
makeSkillCheck("ask"),
|
||||
);
|
||||
|
||||
expect(descriptor.payload.kind).toBe("skill");
|
||||
expect(descriptor.payload.request.value).toBe("librarian");
|
||||
});
|
||||
|
||||
it("names the skill in promptDetails so the prompt can identify it", () => {
|
||||
const descriptor = describeSkillInputGate(
|
||||
"librarian",
|
||||
null,
|
||||
makeSkillCheck("ask"),
|
||||
);
|
||||
expect(descriptor.promptDetails.skillName).toBe("librarian");
|
||||
});
|
||||
|
||||
it("sets logContext source to 'skill_input' with skill name and agent", () => {
|
||||
const descriptor = describeSkillInputGate(
|
||||
"librarian",
|
||||
"code-agent",
|
||||
makeSkillCheck("allow"),
|
||||
);
|
||||
expect(descriptor.logContext).toMatchObject({
|
||||
source: "skill_input",
|
||||
skillName: "librarian",
|
||||
agentName: "code-agent",
|
||||
});
|
||||
});
|
||||
|
||||
it("sets decision surface to 'skill' and value to the skill name", () => {
|
||||
const descriptor = describeSkillInputGate(
|
||||
"my-skill",
|
||||
null,
|
||||
makeSkillCheck("allow"),
|
||||
);
|
||||
expect(descriptor.decision).toEqual({
|
||||
surface: "skill",
|
||||
value: "my-skill",
|
||||
});
|
||||
});
|
||||
|
||||
it("carries the skill name as single-value access facts on promptDetails", () => {
|
||||
const descriptor = describeSkillInputGate(
|
||||
"my-skill",
|
||||
null,
|
||||
makeSkillCheck("ask"),
|
||||
);
|
||||
expect(descriptor.promptDetails.accessIntent).toEqual({
|
||||
surface: "skill",
|
||||
matchValues: ["my-skill"],
|
||||
boundaryValue: null,
|
||||
});
|
||||
});
|
||||
|
||||
it("does not set preResolved or sessionApproval", () => {
|
||||
const descriptor = describeSkillInputGate(
|
||||
"librarian",
|
||||
null,
|
||||
makeSkillCheck("allow"),
|
||||
);
|
||||
expect(descriptor.preResolved).toBeUndefined();
|
||||
expect(descriptor.sessionApproval).toBeUndefined();
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user