Preserve built-in approval permissions

Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
DottaandPaperclip committed 2026-07-09 20:50:34 +00:00
1 parent fc0220ff31
commit fb34ccf398
3 files changed
+31 -1

No files matched your search

@@ -511,6 +511,11 @@ describeEmbeddedPostgres("built-in agents", () => {
it("preserves new-agent approval gates during automatic Reflection Coach provisioning", async () => {
const companyId = await seedCompany({ requireApproval: true });
const mutationPolicy = {
requiresDisplayedDiff: true,
requiresAcceptedTaskInteraction: true,
applyInSeparateFollowUpRun: true,
};
const result = await reconcileBuiltInAgentsOnStartup(db);
@@ -526,6 +531,9 @@ describeEmbeddedPostgres("built-in agents", () => {
name: "Reflection Coach",
status: "pending_approval",
budgetMonthlyCents: 0,
permissions: {
builtInMutationPolicy: mutationPolicy,
},
},
});
expect(state.resources.map((resource) => resource.stockStatus)).toEqual(["missing", "missing", "missing"]);
@@ -538,6 +546,18 @@ describeEmbeddedPostgres("built-in agents", () => {
agentId: state.agentId,
sourceBuiltInAgentKey: "reflection-coach",
featureKeys: ["reflection-coach"],
permissions: expect.objectContaining({
builtInMutationPolicy: mutationPolicy,
}),
},
});
await approvalService(db).approve(approval.id, "board-user", "Approved Reflection Coach");
await expect(builtInAgentService(db).get(companyId, "reflection-coach")).resolves.toMatchObject({
agent: {
permissions: {
builtInMutationPolicy: mutationPolicy,
},
},
});
+9
View File
@@ -176,6 +176,9 @@ function configPatchFromApprovalPayload(payload: Record<string, unknown>) {
if (Object.prototype.hasOwnProperty.call(payload, "metadata")) {
patch.metadata = isPlainRecord(payload.metadata) ? payload.metadata : null;
}
if (isPlainRecord(payload.permissions)) {
patch.permissions = payload.permissions;
}
return patch;
}
@@ -783,6 +786,12 @@ export function agentService(db: Db) {
{ adapterType: (patch.adapterType ?? existing.adapterType) as string },
);
}
if (patch.permissions !== undefined) {
patch.permissions = normalizeAgentPermissions(
patch.permissions,
(patch.role ?? existing.role) as string,
);
}
const updated = await tx
.update(agents)
.set({ ...patch, status: "idle", updatedAt: new Date() })
+2 -1
View File
@@ -1416,7 +1416,7 @@ export function builtInAgentService(db: Db) {
status: "pending_approval",
metadata: builtInMetadata(definition),
runtimeConfig: {},
permissions: {},
permissions: definition.defaultPermissions ?? {},
spentMonthlyCents: 0,
lastHeartbeatAt: null,
}, { allowBuiltInAgentMetadata: true }) as Agent;
@@ -1436,6 +1436,7 @@ export function builtInAgentService(db: Db) {
adapterType: pending.adapterType,
adapterConfig: pending.adapterConfig,
runtimeConfig: pending.runtimeConfig,
permissions: pending.permissions,
budgetMonthlyCents: pending.budgetMonthlyCents,
metadata: pending.metadata,
agentId: pending.id,