Skip to content

Commit a6d782e

Browse files
committed
fix(copilot): require approval for run_block and run_from_block
All four workflow run tools reach the same executor, but the catalog only gated run_workflow and run_workflow_until_block. The approval gate is a pure catalog lookup, so an agent steered into run_from_block (which runs every block downstream of its start) or run_block executed the workflow with no approval card. Flag both siblings and assert every tool in WORKFLOW_TOOL_NAMES carries requiresApproval.
1 parent e4627fb commit a6d782e

2 files changed

Lines changed: 18 additions & 0 deletions

File tree

‎apps/sim/lib/mothership/generated/tool-catalog-v1.ts‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5440,6 +5440,7 @@ export const RunBlock: ToolCatalogEntry = {
54405440
required: ['workflowId', 'blockId'],
54415441
},
54425442
clientExecutable: true,
5443+
requiresApproval: true,
54435444
}
54445445

54455446
export const RunCode: ToolCatalogEntry = {
@@ -5618,6 +5619,7 @@ export const RunFromBlock: ToolCatalogEntry = {
56185619
required: ['workflowId', 'startBlockId'],
56195620
},
56205621
clientExecutable: true,
5622+
requiresApproval: true,
56215623
}
56225624

56235625
export const RunFunction: ToolCatalogEntry = {

‎apps/sim/lib/mothership/request/tools/permission.test.ts‎

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,22 @@ describe('gated tools are askable', () => {
199199

200200
expect(ungatable).toEqual([])
201201
})
202+
203+
it('gates every tool that runs a workflow', async () => {
204+
// They all reach the same executor: run_from_block runs everything
205+
// downstream of its start block, so an ungated sibling would run what
206+
// run_workflow asks about without asking.
207+
const { TOOL_CATALOG } = await vi.importActual<
208+
typeof import('@/lib/mothership/generated/tool-catalog-v1')
209+
>('@/lib/mothership/generated/tool-catalog-v1')
210+
const { WORKFLOW_TOOL_NAMES } = await vi.importActual<
211+
typeof import('@/lib/mothership/tools/client-executed-tools')
212+
>('@/lib/mothership/tools/client-executed-tools')
213+
214+
const ungated = WORKFLOW_TOOL_NAMES.filter((name) => !TOOL_CATALOG[name]?.requiresApproval)
215+
216+
expect(ungated).toEqual([])
217+
})
202218
})
203219

204220
describe('runGatedToolExecution', () => {

0 commit comments

Comments
 (0)