fix(FN-4488): align policy typing across gate resolution
Fusion-Task-Id: FN-4488 Fusion-Task-Lineage: 3fc1ac43-490f-43f2-a27e-4fdceb64d9c4
This commit is contained in:
@@ -1,7 +1,6 @@
|
||||
import "./AgentPermissionPolicyEditor.css";
|
||||
import {
|
||||
AGENT_PERMISSION_POLICY_ACTION_CATEGORIES,
|
||||
normalizeAgentPermissionPolicyFromPreset,
|
||||
type AgentPermissionPolicy,
|
||||
type AgentPermissionPolicyDisposition,
|
||||
type AgentPermissionPolicyRules,
|
||||
@@ -37,8 +36,32 @@ function buildAllowRules(): AgentPermissionPolicyRules {
|
||||
};
|
||||
}
|
||||
|
||||
function getPresetRules(presetId: AgentPermissionPolicy["presetId"]): AgentPermissionPolicyRules {
|
||||
return normalizeAgentPermissionPolicyFromPreset(presetId).rules;
|
||||
const PRESET_RULES: Record<"unrestricted" | "approval-required" | "locked-down", AgentPermissionPolicyRules> = {
|
||||
unrestricted: {
|
||||
git_write: "allow",
|
||||
file_write_delete: "allow",
|
||||
command_execution: "allow",
|
||||
network_api: "allow",
|
||||
task_agent_mutation: "allow",
|
||||
},
|
||||
"approval-required": {
|
||||
git_write: "require-approval",
|
||||
file_write_delete: "require-approval",
|
||||
command_execution: "require-approval",
|
||||
network_api: "require-approval",
|
||||
task_agent_mutation: "require-approval",
|
||||
},
|
||||
"locked-down": {
|
||||
git_write: "block",
|
||||
file_write_delete: "block",
|
||||
command_execution: "block",
|
||||
network_api: "block",
|
||||
task_agent_mutation: "block",
|
||||
},
|
||||
};
|
||||
|
||||
function getPresetRules(presetId: "unrestricted" | "approval-required" | "locked-down"): AgentPermissionPolicyRules {
|
||||
return PRESET_RULES[presetId];
|
||||
}
|
||||
|
||||
function matchesRules(a: AgentPermissionPolicyRules, b: AgentPermissionPolicyRules): boolean {
|
||||
@@ -46,9 +69,9 @@ function matchesRules(a: AgentPermissionPolicyRules, b: AgentPermissionPolicyRul
|
||||
}
|
||||
|
||||
function derivePresetFromRules(rules: AgentPermissionPolicyRules): AgentPermissionPolicy["presetId"] {
|
||||
if (matchesRules(rules, getPresetRules("unrestricted"))) return "unrestricted";
|
||||
if (matchesRules(rules, getPresetRules("approval-required"))) return "approval-required";
|
||||
if (matchesRules(rules, getPresetRules("locked-down"))) return "locked-down";
|
||||
if (matchesRules(rules, PRESET_RULES.unrestricted)) return "unrestricted";
|
||||
if (matchesRules(rules, PRESET_RULES["approval-required"])) return "approval-required";
|
||||
if (matchesRules(rules, PRESET_RULES["locked-down"])) return "locked-down";
|
||||
return "custom";
|
||||
}
|
||||
|
||||
@@ -66,7 +89,7 @@ export function AgentPermissionPolicyEditor({ value, projectDefault, mode, onCha
|
||||
onChange({ presetId: "custom", rules: { ...rules } });
|
||||
return;
|
||||
}
|
||||
onChange({ presetId: preset as AgentPermissionPolicy["presetId"], rules: getPresetRules(preset as AgentPermissionPolicy["presetId"]) });
|
||||
onChange({ presetId: preset as AgentPermissionPolicy["presetId"], rules: getPresetRules(preset as "unrestricted" | "approval-required" | "locked-down") });
|
||||
};
|
||||
|
||||
const setRule = (category: keyof AgentPermissionPolicyRules, next: string) => {
|
||||
|
||||
@@ -33,7 +33,13 @@ describe("agent action gate project-default resolution", () => {
|
||||
const permissionPolicy = resolveEffectiveAgentPermissionPolicy(
|
||||
{
|
||||
presetId: "custom",
|
||||
rules: { command_execution: "allow" },
|
||||
rules: {
|
||||
git_write: "allow",
|
||||
file_write_delete: "allow",
|
||||
command_execution: "allow",
|
||||
network_api: "allow",
|
||||
task_agent_mutation: "allow",
|
||||
},
|
||||
},
|
||||
{ rules: { command_execution: "require-approval" } },
|
||||
);
|
||||
|
||||
@@ -892,7 +892,7 @@ export class HeartbeatMonitor {
|
||||
return this.approvalRequestStore;
|
||||
}
|
||||
|
||||
private buildActionGateContext(agent: Agent, taskId?: string, runId?: string, projectDefaultPolicy?: { rules?: import("@fusion/core").AgentPermissionPolicy["rules"] }): AgentActionGateContext | undefined {
|
||||
private buildActionGateContext(agent: Agent, taskId?: string, runId?: string, projectDefaultPolicy?: { rules?: Partial<import("@fusion/core").AgentPermissionPolicy["rules"]> }): AgentActionGateContext | undefined {
|
||||
if (isEphemeralAgent(agent)) {
|
||||
return undefined;
|
||||
}
|
||||
@@ -945,7 +945,7 @@ export class HeartbeatMonitor {
|
||||
};
|
||||
}
|
||||
|
||||
private buildPermanentAgentGatingContext(agent: Agent, taskId?: string, runId?: string, projectDefaultPolicy?: { rules?: import("@fusion/core").AgentPermissionPolicy["rules"] }): import("@fusion/core").PermanentAgentGatingContext | undefined {
|
||||
private buildPermanentAgentGatingContext(agent: Agent, taskId?: string, runId?: string, projectDefaultPolicy?: { rules?: Partial<import("@fusion/core").AgentPermissionPolicy["rules"]> }): import("@fusion/core").PermanentAgentGatingContext | undefined {
|
||||
if (isEphemeralAgent(agent)) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
@@ -974,7 +974,7 @@ export class TaskExecutor {
|
||||
return this._approvalRequestStore;
|
||||
}
|
||||
|
||||
private buildActionGateContext(taskId: string | undefined, agent: Agent | null | undefined, projectDefaultPolicy?: { rules?: import("@fusion/core").AgentPermissionPolicy["rules"] }): AgentActionGateContext | undefined {
|
||||
private buildActionGateContext(taskId: string | undefined, agent: Agent | null | undefined, projectDefaultPolicy?: { rules?: Partial<import("@fusion/core").AgentPermissionPolicy["rules"]> }): AgentActionGateContext | undefined {
|
||||
if (!agent || isEphemeralAgent(agent)) {
|
||||
return undefined;
|
||||
}
|
||||
@@ -1040,7 +1040,7 @@ export class TaskExecutor {
|
||||
};
|
||||
}
|
||||
|
||||
private buildPermanentAgentGatingContext(taskId: string | undefined, agent: Agent | null | undefined, projectDefaultPolicy?: { rules?: import("@fusion/core").AgentPermissionPolicy["rules"] }): import("@fusion/core").PermanentAgentGatingContext | undefined {
|
||||
private buildPermanentAgentGatingContext(taskId: string | undefined, agent: Agent | null | undefined, projectDefaultPolicy?: { rules?: Partial<import("@fusion/core").AgentPermissionPolicy["rules"]> }): import("@fusion/core").PermanentAgentGatingContext | undefined {
|
||||
if (!agent || isEphemeralAgent(agent)) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user