qwen serve 守护进程本地文本读取设计:delegateReadTextFileToClient 能力开关与安全边界剖析
qwen serve 守护进程本地文本读取设计delegateReadTextFileToClient 能力开关与安全边界剖析【免费下载链接】qwen-codeAn open-source AI coding agent that lives in your terminal.项目地址: https://gitcode.com/GitHub_Trending/qw/qwen-code导读本文围绕 qwen-code 仓库中 daemon-local-text-reads.md 设计文档展开深入剖析qwen serve守护进程daemon如何通过BridgeOptions.delegateReadTextFileToClient开关将 ACP 子进程的文本读取从委派给客户端文件系统服务WFS切换为子进程本地读取同时保留最终文本写入的委派。读完本文你将理解该能力开关的默认值、三种qwen serve工作区运行时的接入方式、读取与写入两侧的行为差异、确认 payload 的 SSE 扇出暴露以及失败关闭边界的真实覆盖范围与限制。一、设计决策一个开关两侧能力1.1 决策摘要BridgeOptions.delegateReadTextFileToClient是 ACP bridge 构造选项中控制文本读取路径的开关其定义位于 bridgeOptions.ts默认值为true文本读取委派给客户端daemon 宿主侧文件系统服务从而保持通用 ACP、IDE、远程、虚拟文件系统virtual-filesystem宿主的一贯行为同主机qwen serve运行时显式设为false此时 ACP initialize 能力capability为{ readTextFile: false, writeTextFile: true }即文本读取不再委派子进程使用其常规 CLI 文件系统服务完成所有文本读取最终 ACP 文本写入则保持委派二者相互独立调用方注入的 bridge如测试、Mode A 进程内消费者、channels / IDE companion完全由调用方自己控制该开关仓库不替它们做决定。1.2 默认值下的能力协商delegateReadTextFileToClient为true默认时bridge 在initialize阶段向 ACP 子进程通告的clientCapabilities.fs为{ readTextFile: true, writeTextFile: true }该行为由 bridge-file-capabilities.test.ts 的测试用例delegates reads to the ACP client by default锁定构造 bridge不传任何覆盖→preheat()→ 断言initializeCalls[0].clientCapabilities.fs等于上述对象。1.3 同主机运行时关闭读取委派在qwen serve侧createServeApp构造默认 bridge 时显式传入delegateReadTextFileToClient: false见 server.ts。此时 ACP initialize 能力变为{ readTextFile: false, writeTextFile: true }对应的测试用例是 bridge-file-capabilities.test.ts 的can keep text reads in a same-host ACP child传入delegateReadTextFileToClient: false后断言能力协商结果为readTextFile: false、writeTextFile: true。该开关直接决定FileSystemService.readTextFile这一能力点在 ACP 子进程中的可用性。关闭后子进程内部所有走readTextFile的调用包括后续提到的共享文本预读都落在常规 CLI 文件系统服务上不再经过 daemon 侧注入的BridgeFileSystem适配器。二、行为变化读取侧权限流与共享预读2.1 直接外部文本 read_file 的权限流能力关闭后子进程对工作区外路径的直接文本read_file调用使用常规 CLI 权限流默认权限为ask请求用户确认批准approval允许读取拒绝则阻止工具执行允许规则allow rules与自动批准模式AUTO / AUTO_EDIT / YOLO 等的行为与纯 CLI 运行完全一致。非文本read_file路径如图片等二进制读取此前已由子进程本地读取本设计不改变这部分行为。2.2 共享文本预读随能力一并迁移由于该能力作用于FileSystemService.readTextFile这一个统一入口以下操作的共享文本预读也会随之从 WFS 移到常规 CLI 文件系统服务write_file写入前的整文件预读edit编辑前的文件快照读取notebook 操作notebook_edit的预读模拟 sed 编辑器的预读artifact 操作的读取。2.3 有意接受的取舍清单这一迁移是有意为之的取舍读取侧从此接受 CLI 的读取限制与行为而不再享受 WFSWorkspaceFileSystem侧的以下保护与限制维度WFS 侧委派读取CLI 常规文件系统服务本地读取返回输出 / 全快照上限256 KiB 返回输出上限、全快照上限不适用由 CLI 自身限制约束大文本扫描上限8 MiB 大文本扫描上限不适用读取审计发出fs.access等审计事件不发出 WFSfs.access符号链接拒绝symlink rejection由 CLI 策略处理TOCTOU具备读取侧 TOCTOU 保护不适用注意直接read_file仍应用核心的行数与输出限制且这些限制受其既有配置约束。设计文档明确指出本文档是这份取舍清单的唯一所有者single owner其他文档通过引用本文档而非重复陈述这些限制因此调整某一项限制时不会留下过时副本。三、写入侧保持委派同主机窄路由读取变为子进程本地但最终 ACP 文本写入保持委派。设计文档指出一条窄的同主机路由关闭了内置文本工具的已批准外部写入失败问题——即此前工具被批准后在最终 WFS 边界才因path_outside_workspace失败、进而诱导模型改用 shell 重试的系统性序列。该路由的细节由配套文档 daemon-external-tool-text-writes.md 完整承载其要点如下来自write_file、edit、notebook_edit、模拟 sed 的严格标记的最终调用toolWriteOrigin字段仅由工具execute()内的最终服务调用创建不属于任何模型工具 schema可被 daemon 持有的 bridge 适配器路由到宿主写入器host writer前提是目标在工作区之外标记写入仍保留信任trust、符号链接、大小、代次generation、原子写入、模式mode与审计执行——即writeTextOverwrite的全部安全不变量通过 5 MiB UTF-8 预检、最终编码字节上限、0600临时文件、最佳努力 fsync、rename 前代次复查、原子发布等机制落地通用 ACP 写入与 HTTP 写入保持工作区范围未标记的 ACP 写入、调用方注入的 filesystem factory、任意 shell 重定向、父目录创建、文件历史辅助与提交归属均不享受该例外只有 daemon 创建的适配器显式启用同主机工具写入、元数据对象恰好为version: 1且带一个被识别的source、且 filesystem factory 实现了writeSameHostToolText三个条件同时满足时才接受该例外否则走普通 WFS 路由并以path_outside_workspace失败。该配套文档还强调这一改动不承诺模型永远不会选择 shell 或在遭遇独立策略失败如大小上限、符号链接拒绝后重试 shell已批准的整文件预读内存压力、预批准 diff 扇出、缺乏 daemon 本地读取退出开关是三个独立的遗留关注点。四、预批准暴露确认 payload 的 SSE 扇出设计文档特别点名了一个容易被忽略的暴露面确认confirmationpayload 是通过读取文件构建的因此对工作区外路径的 edit 或 write 确认其 diff 中会携带该文件的实际内容daemon 会在批准决策产生之前把这个 payload 扇出fan out给该 session 的每一个已附加 SSE 订阅者而在交互式 CLI 中同样的 diff 只有终端前的那个人能看到。这一差异源于一个安全模型假设经过身份验证的 daemon 客户端被视为同一个安全主体one security principal。设计文档在此明示该框架是因为它很容易被阅读者略过——任何能附加到 session SSE 流的认证客户端都可能看到尚未获批的外部文件内容快照。同时需要澄清边界HTTP 文件系统路由如/glob、/list仍保持工作区范围Agent 的glob、ls、grep等发现类工具行为不受该能力影响最终 ACPwriteTextFile内容写入保持委派工作区内走 WFS工作区外走窄门控宿主写入器两者都保留信任、符号链接、原子写入、大小与审计执行这并不意味着每次 agent 写入或辅助操作都经过 WFS。五、资源与审计边界审计差异子进程本地文本读取不产生 WFSfs.access直接外部read_file保留其权限审计permission audit与核心文件操作遥测。OS 身份同主机读取以 daemon 用户的 OS 身份运行。qwen serve的信任模型是一台机器、一个 UID、一个安全主体它不是 OS 沙箱——同一 UID 下被替换的子进程通过 shell 本身就拥有等效文件系统权限daemon-external-tool-text-writes.md 中同样明确路由元数据是 provenance 而非 OS 凭证。六、兼容性与失败关闭的真实边界6.1 受影响范围仅以下运行时会禁用读取委派默认嵌入式 daemon bridgeprimary主、static-secondary静态次要、dynamic动态三类qwen serve工作区运行时。WFS 适配器保留其读取实现目的是一旦出现意外的、或违反能力协商的委派读取仍能到达工作区边界对外部路径失败关闭fails closed。6.2 失败关闭是受限的不是绝对的设计文档明确指出存在第二个预先存在的绕过路径AcpFileSystemService在委派读取被path_outside_workspace或symlink_escape拒绝时会检查路径的 realpath 是否位于其管理的读取根read roots之下若是则本地重试读取。这些根包括POSIX 上无条件包含的/tmpQWEN_ACP_LOCAL_READ_ROOTS环境变量命名的任何路径。因此边界只对这些根之外的路径失败关闭。daemon 通过为子进程设置QWEN_ACP_LOCAL_READ_ROOTS为空中和了环境变量供给的那一半。在源码中acpAgent.ts 给出了本地读取根的完整构造逻辑buildAcpLocalReadRoots项目临时目录、subagents目录、session 运行时临时目录自动记忆根auto-memory与用户级自动记忆根用户技能目录、用户扩展目录计划plans目录与ReadFileTool.getDefaultPermission的免确认设计保持一致用户工作流目录与工作流运行产物目录平台默认根POSIX_TMP_LOCAL_READ_ROOTWindows 上为空数组以及QWEN_ACP_LOCAL_READ_ROOTS解析结果——解析时按path.delimiter切分、去空白、只保留绝对路径见parseAcpLocalReadRootsEnv。6.3 能力关闭后重试路径不可达在 daemon 中能力关闭的前提下上述重试路径本来就不可达能力检查在尝试委派调用之前就已返回子进程根本不会发起委派读取。因此该重试逻辑现在只守卫保持委派启用的通用 ACP 宿主——它是为通用场景保留的防御性兜底而非 daemon 当前主路径的一部分。七、总结delegateReadTextFileToClient是qwen serve在通用 ACP 兼容性与同主机部署效率/一致性之间做出的显式选择默认委派true保住 IDE、远程、虚拟文件系统等泛化宿主的既有语义同主机关闭false让子进程用常规 CLI 文件系统服务完成文本读取获得与纯 CLI 一致的权限流与限制语义同时用配套的窄路由机制保住最终文本写入的 WFS 级安全不变量边界诚实地受限失败关闭仅覆盖读取根之外的路径/tmp与QWEN_ACP_LOCAL_READ_ROOTS构成既有例外而 daemon 通过清空该环境变量进一步收窄了攻击面暴露面被明示预批准确认 diff 的 SSE 扇出、单安全主体假设是部署多订阅者 daemon 时不可忽略的安全上下文。如需继续深入建议依次阅读daemon-external-tool-text-writes.md写入侧完整威胁模型、bridgeOptions.ts开关与fileSystem注入缝、bridgeFileSystem.tsBridgeFileSystem适配器契约、bridge-file-capabilities.test.ts能力协商测试以及 server.tsdaemon 侧实际接线。【免费下载链接】qwen-codeAn open-source AI coding agent that lives in your terminal.项目地址: https://gitcode.com/GitHub_Trending/qw/qwen-code创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
上一篇/下一篇内容由系统自动关联
返回资讯列表 →