fix(sandbox): support real development workspaces

- raise finite development defaults/ceilings and queue capacities
- migrate untouched v1 default policy
- exclude generated output and shipped runtime paths from snapshots
- report snapshot limit errors with the offending path
This commit is contained in:
xiaohan.yuan committed 2026-10-18 18:08:20 +08:00
1 parent c7d6c558e6
commit b2d37472f0
9 files changed
+115 -28

No files matched your search

+1 -1
View File
@@ -111,7 +111,7 @@ try {
await update({ commandsEnabled: true, limits: { fileBytes: 4 } })
await assert.rejects(executeSandboxCommand('echo unsafe>size.txt', context), /上限/)
check('configured snapshot byte limits are enforced before execution', !await fs.stat(join(workspace, 'size.txt')).catch(() => null))
await update({ limits: { fileBytes: 8 * 1024 * 1024 } })
await update({ limits: { fileBytes: 256 * 1024 * 1024 } })
result = await executeSandboxCommand('echo approved>sample.txt', context)
check('native writeback records policy and authorization identities', result.ok && result.data.policyRevision === document.revision && !!result.data.authorizationId)
const operation = await sandboxOperation(result.data.runId)
+7 -1
View File
@@ -106,8 +106,14 @@ try {
check('physical tree replacement is rejected and explicit recovery restores a verified checkpoint', result.ok && result.data.stdout.includes('saved-before-failure') && !await fs.stat(join(workspace, 'root-replaced.txt')).catch(() => null))
let tool = await executeTool('execute_command', { command: 'echo tool-route>tool.txt', workspace: 'persistent' }, context)
check('model-facing command selects the real persistent backend', tool.ok && (tool.data as { writeback?: string }).writeback === 'deferred' && !await fs.stat(join(workspace, 'tool.txt')).catch(() => null))
tool = await executeTool('execute_command', { command: 'echo default-tool-route>default-tool.txt' }, context)
check('model-facing commands default to the retained draft instead of copying on every command', tool.ok
&& (tool.data as { writeback?: string; workspace?: { mode?: string } }).writeback === 'deferred'
&& (tool.data as { workspace?: { mode?: string } }).workspace?.mode === 'persistent'
&& !await fs.stat(join(workspace, 'default-tool.txt')).catch(() => null))
tool = await executeTool('sandbox_workspace', { action: 'changes' }, context)
check('model-facing workspace tool inspects pending draft changes', tool.ok && (tool.data as { changes: Array<{ path: string }> }).changes.some(change => change.path === 'tool.txt'))
check('model-facing workspace tool inspects pending draft changes', tool.ok && (tool.data as { changes: Array<{ path: string }> }).changes.some(change => change.path === 'tool.txt')
&& (tool.data as { changes: Array<{ path: string }> }).changes.some(change => change.path === 'default-tool.txt'))
tool = await executeTool('sandbox_workspace', { action: 'status', sessionId: 'other-session', workspaceRoot: stateRoot }, context)
check('workspace tool rejects caller-supplied ownership and path overrides', !tool.ok && /归属参数/.test(tool.content))
tool = await executeTool('execute_command', { command: 'echo explicit-native>explicit-mode.txt', workspace: 'persistent' }, { ...context, permissionMode: 'full-access' })