mirror of
https://github.com/Ryder-Sun/Meldwork.git
synced 2026-11-07 06:56:03 -10:00
Enforce run mode on connector write permission events
Reject workspace-write permission events in read-only runs so a connector cannot escalate the active permission mode. Checks: connector runtime tests; desktop pack.
This commit is contained in:
1 parent
3b1a618b37
commit
ee457b563e
2 files changed
+23
-2
No files matched your search
@@ -87,7 +87,7 @@ function assertOutboundDestination(connector, value, outbound = {}) {
|
||||
return origin
|
||||
}
|
||||
|
||||
function assertEventCapabilities(connector, input) {
|
||||
function assertEventCapabilities(connector, input, permissionMode) {
|
||||
const type = String(input?.type || '')
|
||||
if (!connector.capabilities.eventTypes.includes(type)) {
|
||||
fail('AGENT_CONNECTOR_EVENT_UNDECLARED')
|
||||
@@ -95,6 +95,10 @@ function assertEventCapabilities(connector, input) {
|
||||
if (type === 'Cancelled' && !connector.capabilities.session.cancel) {
|
||||
fail('AGENT_CONNECTOR_CANCEL_UNSUPPORTED')
|
||||
}
|
||||
if (type === 'Permission' && input.permission === 'workspace-write'
|
||||
&& permissionMode !== 'workspace-write') {
|
||||
fail('AGENT_CONNECTOR_PERMISSION_MODE_UNSUPPORTED')
|
||||
}
|
||||
if (type === 'Usage') {
|
||||
for (const field of Object.keys(input?.usage || {})) {
|
||||
if (connector.capabilities.usage[field] !== true) {
|
||||
@@ -415,7 +419,7 @@ class AgentConnectorRuntime {
|
||||
}
|
||||
const attachments = validatedAttachments(options.attachments, connector.capabilities)
|
||||
const emit = (input) => {
|
||||
assertEventCapabilities(connector, input)
|
||||
assertEventCapabilities(connector, input, permissionMode)
|
||||
const event = parseConnectorRunEvent(input, provenance)
|
||||
const duplicate = state.events.find(existing => existing.eventId === event.eventId)
|
||||
if (duplicate && canonicalJson(duplicate) === canonicalJson(event)) return event
|
||||
|
||||
@@ -369,6 +369,23 @@ test('a recipe declaring Permission retains the permission request callback', as
|
||||
assert.equal(permissions, 1)
|
||||
})
|
||||
|
||||
test('workspace write permission events respect the active run mode', async () => {
|
||||
const { runtime } = runtimeFixture(async input => {
|
||||
input.emit({ eventId: 'write-request', cursor: 'write-request', sequence: 1,
|
||||
type: 'Permission', requestId: 'write-request', permission: 'workspace-write', decision: 'requested' })
|
||||
return {}
|
||||
}, { permissionModes: ['read-only', 'workspace-write'] })
|
||||
const agent = runtime.detectAgents()[0]
|
||||
await assert.rejects(runtime.run(agent, 'Review', '/tmp/workspace', {
|
||||
runId: 'run-read-only-write', agentRunId: 'agent-run-read-only-write', sandbox: 'read-only',
|
||||
}), { message: 'AGENT_CONNECTOR_PERMISSION_MODE_UNSUPPORTED' })
|
||||
const allowed = await runtime.run(agent, 'Review', '/tmp/workspace', {
|
||||
runId: 'run-write', agentRunId: 'agent-run-write', sandbox: 'workspace-write',
|
||||
})
|
||||
assert.equal(allowed.outcome, 'waiting_permission')
|
||||
assert.equal(allowed.waitingRequest.permission, 'workspace-write')
|
||||
})
|
||||
|
||||
test('Connector outcome references must come from declared, validated events', async () => {
|
||||
const artifactId = `artifact-${'a'.repeat(64)}`
|
||||
const evidenceId = `evidence-${'b'.repeat(64)}`
|
||||
|
||||
Reference in new issue
Block a user