import { spawnSync } from 'node:child_process' import { existsSync, readFileSync } from 'node:fs' import { mkdtemp, rm } from 'node:fs/promises' import { homedir } from 'node:os' import { join } from 'node:path' import { afterEach, describe, expect, it } from 'vitest' import { Context } from 'cordis' import { LocalSandboxProvider } from '@deepseek-ai/dsh-sandbox-local' import { bwrapProfileArgs } from '@deepseek-ai/dsh-sandbox-local/src/profiles.ts' import { SandboxBashExecutor } from '@deepseek-ai/dsh-bash-sandbox' /** * Keyless integration of the real provider and executor through public run/start paths. With * no rung forced, a passing bwrap probe selects the ladder's first rung. The tests check world * effects and stamped facts, including EROFS classification through the wrap-carried dialect; * backend-only confinement is covered by `@deepseek-ai/dsh-sandbox-local`. * * Skips when bwrap or unprivileged user namespaces are unavailable. HOME-based paths are * intentional because bwrap replaces `/tmp`, which cannot prove the workspace-root boundary. */ const probe = spawnSync('bwrap', [...bwrapProfileArgs({ mode: 'read-only', workspaceRoot: '/' }), '--', 'true'], { timeout: 5_000, stdio: 'ignore' }) const bwrapUsable = probe.status === 0 let ctx: Context | undefined const tempDirs: string[] = [] afterEach(async () => { await ctx?.fiber.dispose() ctx = undefined await Promise.all(tempDirs.splice(0).map(dir => rm(dir, { recursive: true, force: true }))) }) async function tempDir(base: string): Promise { const dir = await mkdtemp(join(base, 'dsh-bwrap-e2e-')) tempDirs.push(dir) return dir } async function sandboxedBash(workspace: string, mode: 'read-only' | 'workspace-write'): Promise { ctx = new Context() await ctx.plugin(LocalSandboxProvider, {}) await ctx.plugin(SandboxBashExecutor, { mode, cwd: workspace, workspaceRoot: workspace, timeoutMs: 30_000 }) return ctx.bash as SandboxBashExecutor } describe.skipIf(!bwrapUsable)('bash-sandbox: real bwrap confinement through ctx.bash', () => { it('read-only denies a write — the file must NOT exist, and EROFS text classifies as a denial', async () => { const workdir = await tempDir(homedir()) const bash = await sandboxedBash(workdir, 'read-only') const result = await bash.run(bash.resolve({ command: `echo hi > ${workdir}/denied.txt` })) expect(result.exitCode).not.toBe(0) expect(result.sandbox).toEqual({ mode: 'read-only', denied: true, enforcement: 'full' }) expect(existsSync(join(workdir, 'denied.txt'))).toBe(false) }) it('workspace-write lands a write inside the workspace root and still denies one beside it', async () => { const workdir = await tempDir(homedir()) const outside = await tempDir(homedir()) const bash = await sandboxedBash(workdir, 'workspace-write') const inside = await bash.run(bash.resolve({ command: `printf bwrap-ok > ${workdir}/allowed.txt` })) expect(inside.exitCode).toBe(0) expect(inside.sandbox).toEqual({ mode: 'workspace-write', denied: false, enforcement: 'full' }) expect(readFileSync(join(workdir, 'allowed.txt'), 'utf8')).toBe('bwrap-ok') const denied = await bash.run(bash.resolve({ command: `echo hi > ${outside}/denied.txt` })) expect(denied.exitCode).not.toBe(0) expect(denied.sandbox).toEqual({ mode: 'workspace-write', denied: true, enforcement: 'full' }) expect(existsSync(join(outside, 'denied.txt'))).toBe(false) }) it('classifies a background denial once the task settles', async () => { const workdir = await tempDir(homedir()) const bash = await sandboxedBash(workdir, 'read-only') const task = bash.start(bash.resolve({ command: `echo hi > ${workdir}/bg-denied.txt` })) await task.done expect(task.sandbox).toEqual({ mode: 'read-only', denied: true, enforcement: 'full' }) expect(existsSync(join(workdir, 'bg-denied.txt'))).toBe(false) }) it('an approved escalated retry — the spec-level workspace-write override — lands the exact write read-only denied', async () => { const workdir = await tempDir(homedir()) const bash = await sandboxedBash(workdir, 'read-only') const command = `printf escalated > ${workdir}/escalated.txt` const strict = await bash.run(bash.resolve({ command })) expect(strict.exitCode).not.toBe(0) expect(strict.sandbox).toEqual({ mode: 'read-only', denied: true, enforcement: 'full' }) expect(existsSync(join(workdir, 'escalated.txt'))).toBe(false) const retried = await bash.run(bash.resolve({ command, sandboxMode: 'workspace-write' })) expect(retried.exitCode).toBe(0) expect(retried.sandbox).toEqual({ mode: 'workspace-write', denied: false, enforcement: 'full' }) expect(readFileSync(join(workdir, 'escalated.txt'), 'utf8')).toBe('escalated') }) })