diff --git a/apps/cli/reference/README.i18n.yaml b/apps/cli/reference/README.i18n.yaml index 29cdfac304..22ed72dfb9 100644 --- a/apps/cli/reference/README.i18n.yaml +++ b/apps/cli/reference/README.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write apps/cli/reference/README.md -README.md: 07b162517b90215a6552810124f15c435144f7d4 -README.zh.md: 80030707474e59e76583ed7edc5ddce56334cc03 +README.md: 8264e2e9f57a6687a1cddae15012324790b555ad +README.zh.md: 84bd37e43a982a307a2df8045f7f3703e5b9a8b4 diff --git a/apps/cli/reference/README.md b/apps/cli/reference/README.md index 07b162517b..8264e2e9f5 100644 --- a/apps/cli/reference/README.md +++ b/apps/cli/reference/README.md @@ -51,7 +51,7 @@ Process shutdown gives the plugin tree up to five seconds to dispose. The first All modes treat the invoking directory as the default workspace root, load applicable `AGENTS.md` or `CLAUDE.md` instructions with a 65,536-byte render budget, and use an in-memory SQLite session content index. Long-lived surfaces watch valid edits of both `cordis.patch.yml` layers (profile and home) and reapply them transactionally; one-shot runs read the files once at startup. -New sessions default to the `workspace-write` permission preset. Bash and filesystem mutations are restricted to the session workspace and platform temporary roots; reads, network access, and process visibility are not confined. `DSH_PERMISSION_MODE` changes the process fallback. Stored General-settings permissions affect later Web sessions, not an already-open one. On win32 hosts booting a shipped profile, the Windows platform layer removes the permission, sandbox, and approval rows entirely: the pwsh shell and the fs tools run unconfined with no workspace boundary (Windows has no OS sandbox runner — landlock/bwrap/seatbelt are POSIX-only — so the shipped posture is honest danger-full-access rather than a boundary the shell could bypass), and `DSH_PERMISSION_MODE` and stored permission settings have no effect there. +New sessions default to the `workspace-write` permission preset. Bash and filesystem mutations are restricted to the session workspace and platform temporary roots; reads, network access, and process visibility are not confined. `DSH_PERMISSION_MODE` changes the process fallback. Stored General-settings permissions affect later Web sessions, not an already-open one. On win32 hosts booting a shipped profile, the same permission surface runs over the Windows ACL restricted-token runner: the pwsh executor and the fs tools enforce the workspace boundary through `@deepseek-ai/dsh-sandbox-windows-acl` exactly as on POSIX (the Windows `workspace-write` grant is the workspace plus the real temp directory; `read-only` grants nothing). `DSH_TOOLS_MODE` selects `native`, `code`, or `both` for the process; another value fails at boot. [`config/core-web.cordis.yml`](../config/core-web.cordis.yml) is an optional RL-compatible `--patch` overlay that pins native mode, renders only `DSH_SYSTEM_PROMPT` or `You are a helpful software engineer assistant.` as the system prompt, disables Workspace instructions and every Web runtime prompt contribution, and exposes only persistent `bash` and `str_replace_editor` while retaining the shipped host, browser, workspace, persistence, and permission composition. diff --git a/apps/cli/reference/README.zh.md b/apps/cli/reference/README.zh.md index 8003070747..84bd37e43a 100644 --- a/apps/cli/reference/README.zh.md +++ b/apps/cli/reference/README.zh.md @@ -51,7 +51,7 @@ dsh web --dump-config 所有模式都将调用目录作为默认 workspace 根目录,以 65,536 字节渲染预算加载适用的 `AGENTS.md` 或 `CLAUDE.md` 指令,并使用内存 SQLite 会话内容索引。常驻 surface 监视两个 `cordis.patch.yml` 层(profile 与 home)的有效编辑并以事务方式重新应用;一次性运行只在启动时读取这些文件一次。 -新会话默认使用 `workspace-write` 权限预设。Bash 和文件系统修改仅限于会话 workspace 与平台临时根目录;读取、网络访问和进程可见性不受限制。`DSH_PERMISSION_MODE` 更改进程后备值。General settings 中存储的权限影响后续 Web 会话,不改变已打开的会话。在 win32 主机启动交付 profile 时,Windows 平台层会整体移除 permission、sandbox 与 approval 行:pwsh shell 与 fs 工具不受限运行,不存在 workspace 边界(Windows 上没有 OS 级 sandbox runner——landlock/bwrap/seatbelt 均为 POSIX 专属——因此交付姿态是诚实的 danger-full-access,而不是一个 shell 可以绕过的边界),`DSH_PERMISSION_MODE` 与存储的权限设置在彼处也不生效。 +新会话默认使用 `workspace-write` 权限预设。Bash 和文件系统修改仅限于会话 workspace 与平台临时根目录;读取、网络访问和进程可见性不受限制。`DSH_PERMISSION_MODE` 更改进程后备值。General settings 中存储的权限影响后续 Web 会话,不改变已打开的会话。在 win32 主机启动交付 profile 时,同一权限面运行在 Windows ACL 受限令牌 runner 之上:pwsh 执行器与 fs 工具通过 `@deepseek-ai/dsh-sandbox-windows-acl` 执行与 POSIX 完全一致的 workspace 边界(Windows 的 `workspace-write` 授权是工作区加真实 temp 目录;`read-only` 不授予任何写入)。 `DSH_TOOLS_MODE` 为进程选择 `native`、`code` 或 `both`;其他值会导致启动失败。[`config/core-web.cordis.yml`](../config/core-web.cordis.yml) 是可选的 RL 兼容 `--patch` overlay:它固定使用 `native` 模式,仅将 `DSH_SYSTEM_PROMPT` 或 `You are a helpful software engineer assistant.` 渲染为系统提示词,禁用 Workspace 指令与所有 Web 运行时提示词贡献,并且在保留随附宿主、浏览器、workspace、持久化和权限组合的同时,仅暴露持久 `bash` 和 `str_replace_editor`。 diff --git a/apps/cli/src/windows-shell.ts b/apps/cli/src/windows-shell.ts index 425699ef4f..6bdca7b741 100644 --- a/apps/cli/src/windows-shell.ts +++ b/apps/cli/src/windows-shell.ts @@ -1,8 +1,8 @@ /** * The Windows shell platform layer: on win32 hosts the shipped profile - * compositions swap the POSIX-only bash stack for the PowerShell stack - * (`@deepseek-ai/dsh-pwsh-local` + `@deepseek-ai/dsh-tool-pwsh`), matching - * the Windows-pwsh-default roadmap. The layer is the base bundle's + * compositions swap the POSIX-only bash stack for the sandbox-confined + * PowerShell stack (`@deepseek-ai/dsh-pwsh-sandbox` + + * `@deepseek-ai/dsh-tool-pwsh`), matching the Windows-pwsh-default roadmap. The layer is the base bundle's * `windows.cordis.patch.yml`, injected by the launcher between the bundle * layers and the user layers so a user patch can still override it — the * only override channel is composition config, like every other roster diff --git a/apps/cli/tests/windows-shell.spec.ts b/apps/cli/tests/windows-shell.spec.ts index 80ba40cc34..15f5e0521b 100644 --- a/apps/cli/tests/windows-shell.spec.ts +++ b/apps/cli/tests/windows-shell.spec.ts @@ -14,8 +14,8 @@ import { const WINDOWS_PATCH = `- id: bash-sandbox disabled: true - insert: - - id: pwsh-local - name: '@deepseek-ai/dsh-pwsh-local' + - id: pwsh-sandbox + name: '@deepseek-ai/dsh-pwsh-sandbox' ` /** One fake bundle layer rooted in a temp directory. */ @@ -48,7 +48,7 @@ describe('resolveWindowsShellLayer', () => { expect(layer?.label.endsWith(WINDOWS_SHELL_PATCH_FILENAME)).toBe(true) expect(layer?.patches).toEqual([ { id: 'bash-sandbox', disabled: true }, - { insert: [{ id: 'pwsh-local', name: '@deepseek-ai/dsh-pwsh-local' }] }, + { insert: [{ id: 'pwsh-sandbox', name: '@deepseek-ai/dsh-pwsh-sandbox' }] }, ]) }) @@ -73,7 +73,7 @@ describe('the shipped Windows composition (real bundle layers)', () => { // suite composes the shipped patch files, not test fixtures. const anchor = fileURLToPath(new URL('../package.json', import.meta.url)) - it('composes the win32 danger-full-access roster through the real patch layers', () => { + it('composes the win32 confined roster through the real patch layers', () => { home = mkdtempSync(join(tmpdir(), 'dsh-windows-home-')) initProfile(join(home, PROFILES_DIR, 'web'), ['@deepseek-ai/dsh-base', '@deepseek-ai/dsh-web-app']) const profile = loadProfile('dsh', 'web', anchor, home) @@ -85,19 +85,24 @@ describe('the shipped Windows composition (real bundle layers)', () => { message => warnings.push(message), ) const byId = new Map(rows.map(row => [row.id, row])) - for (const id of ['bash-sandbox', 'tool-bash', 'permission', 'ui-permission', - 'sandbox', 'sandbox-policy', 'fs-sandbox', 'approval']) { + // Only the POSIX bash stack leaves the roster: the permission surface + // (sandbox/sandbox-policy/fs-sandbox, permission, approval) stays enabled + // exactly as on POSIX — the confined pwsh executor is what changes. + for (const id of ['bash-sandbox', 'tool-bash']) { expect(byId.get(id)?.disabled, `row ${id}`).toBe(true) } - for (const id of ['pwsh-local', 'tool-pwsh', 'fs-local']) { + for (const id of ['permission', 'ui-permission', 'sandbox', 'sandbox-policy', 'fs-sandbox', 'approval']) { + expect(byId.get(id)?.disabled, `row ${id}`).not.toBe(true) + } + for (const id of ['pwsh-sandbox', 'tool-pwsh']) { expect(byId.has(id), `inserted row ${id}`).toBe(true) } - // The web-app layer provides ui-permission, so the full web profile - // composes without any no-match warning. + // The patch touches only base-owned rows plus inserts, so the full web + // profile composes without any no-match warning. expect(warnings).toEqual([]) }) - it('leaves POSIX untouched and base-only profiles warned but harmless', () => { + it('leaves POSIX untouched and base-only profiles compose without warnings', () => { home = mkdtempSync(join(tmpdir(), 'dsh-windows-home-')) initProfile(join(home, PROFILES_DIR, 'web'), ['@deepseek-ai/dsh-base', '@deepseek-ai/dsh-web-app']) const profile = loadProfile('dsh', 'web', anchor, home) @@ -106,10 +111,11 @@ describe('the shipped Windows composition (real bundle layers)', () => { const posixById = new Map(posixRows.map(row => [row.id, row])) expect(posixById.get('bash-sandbox')?.disabled).not.toBe(true) expect(posixById.has('pwsh-local')).toBe(false) + expect(posixById.has('pwsh-sandbox')).toBe(false) - // A base-only custom profile (the DEFAULT_PROFILE_BUNDLES template): - // ui-permission has no row to patch, so the shipped layer warns once per - // composition — never fails — exactly as its header comment documents. + // A base-only custom profile (the DEFAULT_PROFILE_BUNDLES template): the + // patch touches only base-owned rows (bash-sandbox/tool-bash) plus its + // inserts, so the composition produces no no-match warning. initProfile(join(home, PROFILES_DIR, 'base-only'), ['@deepseek-ai/dsh-base']) const baseOnly = loadProfile('dsh', 'base-only', anchor, home) const baseWarnings: string[] = [] @@ -119,6 +125,6 @@ describe('the shipped Windows composition (real bundle layers)', () => { [...baseOnly.layers.map(layer => layer.patches), win32!.patches], message => baseWarnings.push(message), ) - expect(baseWarnings.some(message => message.includes('ui-permission'))).toBe(true) + expect(baseWarnings).toEqual([]) }) }) diff --git a/docs/core-data-structures/sandbox.i18n.yaml b/docs/core-data-structures/sandbox.i18n.yaml index 34691ad25b..be2c311fd1 100644 --- a/docs/core-data-structures/sandbox.i18n.yaml +++ b/docs/core-data-structures/sandbox.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write docs/core-data-structures/sandbox.md -sandbox.md: 9e5feafe046f18dad49aeaf281793f0b8e03c240 -sandbox.zh.md: a1314d1b78eb0d46ea4c8ca5aa330ee83bf89132 +sandbox.md: af2b9043c52f35b7f38b368de1420d0e2856a963 +sandbox.zh.md: 5638e76769639525b1884756805d0e0cef1e870e diff --git a/docs/core-data-structures/sandbox.md b/docs/core-data-structures/sandbox.md index 9e5feafe04..af2b9043c5 100644 --- a/docs/core-data-structures/sandbox.md +++ b/docs/core-data-structures/sandbox.md @@ -8,7 +8,7 @@ Source: [`packages/sandbox/sandbox/src/index.ts`](../../packages/sandbox/sandbox ## Modes and enforcement -`SandboxMode` governs filesystem effects only. `read-only` denies writes except the required `/dev/null` sink; `workspace-write` permits writes under the workspace root and the backend's promised temp area; `danger-full-access` bypasses confinement. Network and process visibility are outside this vocabulary. +`SandboxMode` governs filesystem effects only. `read-only` denies every write — the POSIX runners additionally grant the `/dev/null` sink their shells require, while the Windows ACL runner grants nothing; `workspace-write` permits writes under the workspace root and the backend's promised temp area; `danger-full-access` bypasses confinement. Network and process visibility are outside this vocabulary. ```ts type-equiv /** diff --git a/docs/core-data-structures/sandbox.zh.md b/docs/core-data-structures/sandbox.zh.md index a1314d1b78..5638e76769 100644 --- a/docs/core-data-structures/sandbox.zh.md +++ b/docs/core-data-structures/sandbox.zh.md @@ -8,7 +8,7 @@ ## 模式与强制执行 -`SandboxMode` 仅管控文件系统效果。`read-only` 拒绝所有写入(必需的 `/dev/null` 接收器除外);`workspace-write` 允许在工作区根目录及后端承诺的临时区域下写入;`danger-full-access` 绕过隔离。网络与进程可见性不在此处的定义范围内。 +`SandboxMode` 仅管控文件系统效果。`read-only` 拒绝所有写入——POSIX runner 还会授予其 shell 所需的 `/dev/null` 接收器,而 Windows ACL runner 不授予任何写入;`workspace-write` 允许在工作区根目录及后端承诺的临时区域下写入;`danger-full-access` 绕过隔离。网络与进程可见性不在此处的定义范围内。 ```ts type-equiv /** diff --git a/packages/bundle/base/README.i18n.yaml b/packages/bundle/base/README.i18n.yaml index cc58dd3f8f..19f2c66290 100644 --- a/packages/bundle/base/README.i18n.yaml +++ b/packages/bundle/base/README.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write packages/bundle/base/README.md -README.md: 9e2a6305fff592eb63f927dfcc4f32437edeb1cc -README.zh.md: 6159c23047bba4ced3345125901cc0c3ff7cd960 +README.md: de89e8c5d1fcf78fcd47ebdb98c1d1fc3bb0bd5f +README.zh.md: 45ab3d9fa3c750984d903475b3c9e027e9e95d1c diff --git a/packages/bundle/base/README.md b/packages/bundle/base/README.md index 9e2a6305ff..de89e8c5d1 100644 --- a/packages/bundle/base/README.md +++ b/packages/bundle/base/README.md @@ -4,7 +4,7 @@ English | [中文](README.zh.md) The shared dsh core as a profile bundle: [`cordis.patch.yml`](cordis.patch.yml) inserts every base plugin row — model adapters, tools, persistence, policy, settings/credentials, repository Plugins, telemetry — over the empty profile root, as the first layer of every profile's `dsh.profile.bundles` list. Later bundle layers (e.g. [`dsh-web-app`](../web-app/README.md)) and the user's profile `cordis.patch.yml` override these rows by id; a patch replaces a row's whole `config`, so mode-specific values live in mode bundles, not here. The package has no runtime API; the profile composer resolves the universal patch through the `dsh.bundle.patch` manifest field, and the launcher reads the Windows platform layer below from code on win32 hosts. -Windows hosts booting a shipped profile additionally receive [`windows.cordis.patch.yml`](windows.cordis.patch.yml): it disables the POSIX-only sandboxed stacks — the bash executor/tool, the permission switcher (dsh-permission requires a confining executor), the sandbox/fs-policy stack, and the approval service — and inserts the PowerShell executor and tool (`@deepseek-ai/dsh-pwsh-local`, `@deepseek-ai/dsh-tool-pwsh`) plus the unconfined `dsh-fs-local`. Windows has no OS sandbox runner (landlock/bwrap/seatbelt are POSIX-only), so the shipped posture is honest danger-full-access rather than a boundary only the fs tools pretend to enforce; nothing in the roster asks for approval, so the approval service is absent. The launcher applies the layer between the bundle layers and the user layers on win32 hosts; a Windows host that prefers the bash stack restores it through its profile or home `cordis.patch.yml` (disable `pwsh-local`/`tool-pwsh` and re-enable `bash-sandbox`/`tool-bash` — both executors register the same `bash` service, so an incomplete recipe fails loud at load). POSIX hosts never receive it. +Windows hosts booting a shipped profile additionally receive [`windows.cordis.patch.yml`](windows.cordis.patch.yml): it disables the POSIX-only bash stack (`bash-sandbox`/`tool-bash`) and inserts the sandbox-confined PowerShell stack (`@deepseek-ai/dsh-pwsh-sandbox`, `@deepseek-ai/dsh-tool-pwsh`). The permission surface stays exactly as on POSIX: `sandbox`/`sandbox-policy` enforce the file-effect policy through the Windows ACL restricted-token runner (the win32 chain of `dsh-sandbox-local` → `@deepseek-ai/dsh-sandbox-windows-acl`), the permission switcher and the approval service run unchanged, and `fs-sandbox` keeps fencing `ctx.fs` writes — mounting `dsh-fs-local` alongside it would double-register `ctx.fs` and fail the load. The launcher applies the layer between the bundle layers and the user layers on win32 hosts; a Windows host that prefers the unconfined local pwsh executor or full access overrides these rows through its profile or home `cordis.patch.yml` (the bash-restore recipe must be complete: disable `pwsh-sandbox`/`tool-pwsh` AND re-enable `bash-sandbox`/`tool-bash` — both executor families register the same `bash` service, so an incomplete recipe fails loud at load). POSIX hosts never receive it. The row set and its rationale are documented inline in the patch file; the [generated composition graph](../../../apps/cli/composition.md) renders it. @@ -19,4 +19,4 @@ None directly; each inserted row's package owns its effect. ## Known Limitations and Deferred Work - **A patch replaces whole row configs** — profile overrides must restate every field a row keeps; there is no deep-merge layer. -- **Windows has no sandbox and no approval** — no OS runner exists on win32 (landlock/bwrap/seatbelt are POSIX-only), so the Windows platform layer removes the whole sandbox stack (`sandbox`/`sandbox-policy`/`fs-sandbox` disabled, `dsh-fs-local` provides `ctx.fs`), the permission switcher leaves the roster, and the approval service is disabled — nothing on Windows asks for approval, so the model is never told approval exists. Everything degrades to danger-full-access: the shell is unconfined and the fs tools make no confinement claims. +- **The Windows temp grant is the real temp directory** — `workspace-write` confines writes to the workspace plus the host temp area (the same backend-defined choice the Landlock rung makes); `read-only` grants nothing. See `@deepseek-ai/dsh-sandbox-windows-acl`. diff --git a/packages/bundle/base/README.zh.md b/packages/bundle/base/README.zh.md index 6159c23047..45ab3d9fa3 100644 --- a/packages/bundle/base/README.zh.md +++ b/packages/bundle/base/README.zh.md @@ -4,7 +4,7 @@ 以 profile 组合包形式交付的共享 dsh 核心:[`cordis.patch.yml`](cordis.patch.yml) 在空的 profile 根之上插入全部基础插件行——模型适配器、工具、持久化、策略、settings/credentials、repository 插件、遥测——作为每个 profile 的 `dsh.profile.bundles` 列表中的第一层。后续的组合包层(例如 [`dsh-web-app`](../web-app/README.md))和用户 profile 的 `cordis.patch.yml` 按 id 覆盖这些行;patch 会替换目标行的整个 `config`,因此模式专属的值放在各模式组合包中,而不是这里。该包没有运行时 API;profile 组合器通过 manifest(元数据清单)的 `dsh.bundle.patch` 字段解析通用 patch,启动器在 win32 主机上通过代码读取下面的 Windows 平台层。 -启动交付 profile 的 Windows 主机还会额外收到 [`windows.cordis.patch.yml`](windows.cordis.patch.yml):它禁用仅 POSIX 的受限栈——bash 执行器/工具、权限切换器(dsh-permission 要求有限权能力的执行器)、sandbox/fs 策略栈与 approval 服务——并插入 PowerShell 执行器与工具(`@deepseek-ai/dsh-pwsh-local`、`@deepseek-ai/dsh-tool-pwsh`)以及不限权的 `dsh-fs-local`。Windows 上没有 OS 级 sandbox runner(landlock/bwrap/seatbelt 均为 POSIX 专属),因此交付姿态是诚实的 danger-full-access,而不是一个只有 fs 工具假装执行的边界;清单里没有任何动作需要审批,因此 approval 服务缺席。启动器在 win32 主机上把它应用于 bundle 层与用户层之间;偏好 bash 栈的 Windows 主机通过其 profile 或 home 的 `cordis.patch.yml` 恢复 bash 栈(禁用 `pwsh-local`/`tool-pwsh` 并重新启用 `bash-sandbox`/`tool-bash`——两个执行器注册同一个 `bash` 服务,配方不完整会在加载时 fail loud)。POSIX 主机永远不会收到它。 +启动交付 profile 的 Windows 主机还会额外收到 [`windows.cordis.patch.yml`](windows.cordis.patch.yml):它禁用仅 POSIX 的 bash 栈(`bash-sandbox`/`tool-bash`),并插入沙盒受限的 PowerShell 栈(`@deepseek-ai/dsh-pwsh-sandbox`、`@deepseek-ai/dsh-tool-pwsh`)。权限面与 POSIX 完全一致:`sandbox`/`sandbox-policy` 通过 Windows ACL 受限令牌 runner(`dsh-sandbox-local` 的 win32 链 → `@deepseek-ai/dsh-sandbox-windows-acl`)执行文件效果策略,权限切换器与 approval 服务原样运行,`fs-sandbox` 继续围栏 `ctx.fs` 写入——在其旁再挂载 `dsh-fs-local` 会重复注册 `ctx.fs` 并在加载时失败。启动器在 win32 主机上把该层应用于 bundle 层与用户层之间;偏好不限权本地 pwsh 执行器或完整访问的 Windows 主机通过其 profile 或 home 的 `cordis.patch.yml` 覆盖这些行(bash 恢复配方必须完整:禁用 `pwsh-sandbox`/`tool-pwsh` 并重新启用 `bash-sandbox`/`tool-bash`——两个执行器家族注册同一个 `bash` 服务,配方不完整会在加载时 fail loud)。POSIX 主机永远不会收到它。 行集合及其设计依据以行内注释写在 patch 文件里;[生成的组合图](../../../apps/cli/composition.md)负责渲染它。 @@ -19,4 +19,4 @@ ## 已知限制与延期工作 - **patch 会替换整行 `config`**:profile 覆盖必须重述该行需要保留的每个字段;不存在深度合并层。 -- **Windows 上没有沙箱、没有 approval**:win32 上不存在 OS 级 runner(landlock/bwrap/seatbelt 均为 POSIX 专属),因此 Windows 平台层移除整个 sandbox 栈——`sandbox`/`sandbox-policy`/`fs-sandbox` 被禁用,由 `dsh-fs-local` 提供 `ctx.fs`——权限切换器离开清单,approval 服务也被禁用:Windows 上没有任何动作需要审批,模型也不会被告知审批存在。一切退化为 danger-full-access:shell 不限权,fs 工具也不做任何限权声明。 +- **Windows 的临时目录授权是真实 temp 目录**——`workspace-write` 把写入限制在工作区与宿主 temp 区域(与 Landlock 档位相同的后端定义选择);`read-only` 不授予任何写入。见 `@deepseek-ai/dsh-sandbox-windows-acl`。 diff --git a/packages/bundle/base/tests/base.spec.ts b/packages/bundle/base/tests/base.spec.ts index ab2dc874ce..2da84a0931 100644 --- a/packages/bundle/base/tests/base.spec.ts +++ b/packages/bundle/base/tests/base.spec.ts @@ -52,7 +52,7 @@ describe('dsh-base bundle', () => { const inserted = parsed .flatMap(patch => patch.insert ?? []) .map(row => row.id) - expect(inserted).toEqual(['pwsh-sandbox', 'tool-pwsh', 'fs-local']) + expect(inserted).toEqual(['pwsh-sandbox', 'tool-pwsh']) // The patch no longer touches the permission/approval surface at all. expect(parsed.find(patch => patch.id === 'approval')).toBeUndefined() expect(parsed.find(patch => patch.id === 'permission')).toBeUndefined() diff --git a/packages/bundle/base/windows.cordis.patch.yml b/packages/bundle/base/windows.cordis.patch.yml index 66ed54112f..6db6a57098 100644 --- a/packages/bundle/base/windows.cordis.patch.yml +++ b/packages/bundle/base/windows.cordis.patch.yml @@ -5,7 +5,9 @@ # stack is the SANDBOXED PowerShell executor plus the full permission # surface: sandbox/sandbox-policy enforce the file-effect policy, the # permission switcher and the approval service run exactly as on POSIX, and -# fs-sandbox fences the in-process filesystem view. Only the POSIX bash +# the fs row stays the base's sandboxed provider (fs-sandbox) — mounting +# dsh-fs-local alongside it would double-register ctx.fs and fail the load. +# Only the POSIX bash # stack (bash-sandbox/tool-bash) is disabled — bash has no Windows runner. # A Windows host that prefers the unconfined local pwsh executor or full # access overrides these rows through its profile or home cordis.patch.yml. @@ -27,6 +29,3 @@ - id: tool-pwsh name: '@deepseek-ai/dsh-tool-pwsh' - - - id: fs-local - name: '@deepseek-ai/dsh-fs-local'