ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

qwen-code Daemon 未信任工作区只读会话目录(Untrusted Workspace Read-only Session Catalog)设计解析

qwen-code Daemon 未信任工作区只读会话目录(Untrusted Workspace Read-only Session Catalog)设计解析 qwen-code Daemon 未信任工作区只读会话目录Untrusted Workspace Read-only Session Catalog设计解析【免费下载链接】qwen-codeAn open-source AI coding agent that lives in your terminal.项目地址: https://gitcode.com/GitHub_Trending/qw/qwen-code导读qwen-code 的 multi-workspace daemon 在运行时会为多个工作区提供统一的服务入口。当某个非主工作区在启动时未被标记为信任trustedfalsedaemon 并不会粗暴地拒绝所有访问而是为其暴露一条收窄的只读会话目录read-only session catalog只返回持久化的会话摘要与会话组织 sidecar 数据绝不附加会话、拉起 ACP 子进程、合并运行时实时状态或解析工作区控制的能力定义。读完本文你将掌握该目录的完整路由矩阵、安全不变量、会话目录语义、Web Shell 侧行为与失败兼容策略并能结合源码与测试用例理解其底层实现边界。该设计对应的核心文档为 daemon-untrusted-workspace-session-catalog.md本文以它为骨架并引用仓库中的路由实现session.ts与端到端测试multi-workspace-sessions.test.ts进行深化。背景为什么需要“只读目录”而不是直接拒绝在 qwen-code 的多工作区架构中daemon 会持有 bearer token 并管理多个已注册工作区。启动时信任状态为false的工作区untrusted workspace意味着daemon 不应在该工作区创建会话、启动 ACP 子进程、执行外部命令或解析工作区控制的配置。但如果完全拒绝客户端尤其是 Web Shell连“这个工作区里曾经有哪些会话、如何分组”都无法得知体验上等同于盲区。本设计引入的目录是一条纯读路径它只消费磁盘上已持久化的会话摘要session summaries和会话组织 sidecarsession-organization sidecar从而让用户在一侧看到“未信任工作区里有哪些历史会话”同时不承担任何执行、变更或运行时绑定。关键定位文档原文强调这是路由白名单route allowlist不是工作区 ACLworkspace ACL。持有 daemon bearer token 的客户端可以读取每个已注册工作区的允许数据信任trust依然只作为执行与变更的门禁不构成独立的认证主体。安全不变量每条新放开的读路径都必须满足文档为“每一条新放开的未信任工作区读路径”列出了一组必须全部满足的条件这也是实现 review 时的硬性检查清单不得调用loadSettings()也不得走任何 settings 迁移/修复路径不得创建、修复、重写或以其他方式修改存储目录读取期间抑制 file-backed 调试日志避免畸形记录以读副作用的形式创建或追加调试日志不得调用ensureChannel()或任何其他 ACP 子进程启动路径不得查询或合并未信任运行时的实时 bridge 状态不得执行外部命令不得发现或解析工作区 agents、skills、hooks、MCP 配置或其他项目控制的能力定义。实现层面实时状态边界通过内部mergeLive: false读策略在所有会话列表形态default、organized、parentSessionId过滤上强制执行。同一个异步读边界只抑制 file-backed 调试日志受信任请求与边界外的日志不受影响。存储缺失时返回空目录畸形条目沿用现有 best-effort 读取行为且不修复文件。源码佐证路由解析函数resolveQualifiedSessionTargetsession.ts对非主且未信任的工作区默认拒绝只有显式传入allowUntrustedSecondary: true的读路径才放行——这正是“白名单化”的实现载体if ( !runtime.trusted (!options.allowUntrustedSecondary || runtime.primary) ) { sendUntrustedWorkspaceResponse(res, { workspaceCwd: runtime.workspaceCwd, workspaceId: runtime.workspaceId, }); return undefined; }放行后返回{ kind: ordinary, runtime }继续走持久化目录逻辑未放行则立即以统一的untrusted_workspace响应格式失败关闭fail closed。路由矩阵哪些放行、哪些 403、哪些直接拒绝文档给出的路由矩阵默认针对未信任的次要工作区另有说明除外是理解该功能最核心的一张表Surface结果数据来源与约束GET /workspace/:id/sessions200仅持久化会话文件id 或编码后的 canonical cwd 选择器GET /workspaces/:workspace/sessions200同样仅持久化目录GET /workspace/:id/session-groups200仅组织 sidecar任意已注册 id 或编码 cwdGET /workspaces/:workspace/session-groups200仅组织 sidecar文件读、bytes、stat、list、glob既有行为既有文件系统读策略不变工作区信任 GET/request既有行为既有信任配置语义不变/capabilities、/daemon/status既有行为既有 daemon 诊断不变复数会话/分组变更403变更信任门禁不变单数分组变更既有行为仍仅主工作区可用次要选择器失败关闭Settings、permissions、providers403settings 加载可能迁移、备份或修复文件Memory403当前响应包含全局内存路径而非仅工作区投影Env403暴露凭据存在性与 proxy/host 诊断Preflight403可能执行 git、npm、ripgrep 或其他探测MCP、tools、hooks403与实时 bridge 状态或项目配置耦合Skills、agents403发现并解析项目控制的定义Transcript403当前路径可能启动 ACPcursor 初始化可能写入 HMAC keyExport、session status/context/tasks403尚无工作区限定的仅持久化实现ACP HTTP/WebSocket、voice、channels被拒执行、进程或长生命周期运行时能力其它边界行为未知绝对路径、嵌套或未注册的工作区选择器继续以既有400 workspace_mismatch失败关闭畸形的 legacy 单数选择器保留既有400校验消息两种情况都不会回退到主工作区不 fallback 到 primary复数路由对未信任的主工作区继续返回403 untrusted_workspace单数主工作区路由保留既有兼容行为。测试佐证在 multi-workspace-sessions.test.ts 中/workspace/:id/sessions、/workspace/:id/session-groups与/sessions/search对未知/嵌套选择器均断言400与code: workspace_mismatch/workspaces/...形态则断言完整的workspaceCount、boundWorkspace、requestedWorkspace错误体。而变更类路径如POST /session、rewind、restore、model/approval-mode 变更在未信任工作区上均断言403且code: untrusted_workspace并验证 bridge 的spawnCalls/restoreCalls为空——即门禁在 bridge 执行之前就已生效见 multi-workspace-sessions.test.ts。会话目录语义persisted-only 模式持久化只读模式保留既有行为archiveState如archived过滤vieworganized与grouppinned或具名分组 id组织视图parentSessionId子会话过滤cursor 与 page-size 分页。它永不从实时运行时填充 pending interactions、turn errors 或 client state既有持久化摘要默认值如clientCount: 0、hasActivePrompt: false保持 wire-compatible永不调用bridge.listWorkspaceSessions()。受信任的次要与主工作区保持既有持久化/实时合并行为。不新增任何路由、wire 字段、schema 或能力标签旧客户端继续处理403而随 daemon 一起发布的 Web Shell 消费新的200响应——这是向后兼容的关键设计。测试佐证multi-workspace-sessions.test.ts构造 active/archived 两个持久化会话 一个仅在 bridge 实时摘要中出现的liveOnlyId对archiveStatearchived、vieworganizedgrouppinned、具名分组三种查询均返回正确的持久化会话且断言secondaryBridge.listCalls为空数组live merge 未发生。分页测试multi-workspace-sessions.test.ts验证size2首屏返回最新两条并给出nextCursor第二屏返回剩余一条且nextCursor为 undefined。存储副作用缺失即空、畸形不修复、日志被抑制这一节对应文档的“Failure and Compatibility Behavior”与安全不变量中的存储/日志条款测试覆盖非常完整缺失存储返回空目录测试multi-workspace-sessions.test.ts先确认projectDir尚不存在ENOENT请求sessions?vieworganized与session-groups均返回200与空数组listCalls为空且请求后projectDir依然不存在——读操作绝不创建存储。畸形 JSONL 不修复测试multi-workspace-sessions.test.ts预写{not-json}的会话文件与session-organization.v1.json请求后断言目录条目、两个文件内容与请求前完全一致同时设置QWEN_DEBUG_LOG_FILE1并注入 debug session读目录后再写debug sentinel日志断言调试日志文件包含sentinel 但不包含Failed to parse line——证明读取期间 file-backed 调试日志被抑制畸形记录无法以读副作用创建/追加调试日志。不可读的组织 sidecar 返回既有空读视图与 warning读取不修复它Web Shell 请求失败保留既有空状态与 console warningTrust GET 继续观察磁盘上当前的信任配置并告知调用方运行时变更需要重启本改动不将其转换为 boot snapshot。Web Shell 行为未信任的次要工作区在 Web Shell 中保持可展开并同时标注untrusted与read-only展开执行一次目录读取reloadToken变化会再次读取但禁用常规的十秒轮询因为该 daemon 无法在此工作区创建会话展开不会选中或激活该工作区持久化会话渲染为非交互行rolenoteaccessible name 包含会话名、日期与说明必须信任该工作区后才能打开会话行不绑定鼠标/键盘激活不应用 active-session 样式受信任工作区行为不变未信任的主工作区保持禁用等待单独的 primary safe-mode 设计。未完成事项Deferred Work文档明确列出后续规划也即当前实现的边界无副作用的 settings 与 trust 快照加载器仅工作区的 memory 投影脱敏后的环境与配置检查不解析项目定义的 skills/agents 清单不启动 ACP、不初始化 cursor HMAC key 的 daemon 本地 transcript 读取器以及真正只读的会话查看器动态信任应用、运行时重建与工作区移除/排空draining。这些条目表明当前目录是第一阶段的安全收窄后续将把更多只读能力尤其 transcript 与 settings以无副作用的方式迁移进来。小结未信任工作区只读会话目录是 qwen-code multi-workspace daemon 中“信任门禁”与“可观测性”之间的平衡点以mergeLive: false的持久化只读策略 路由白名单实现最小暴露用七条安全不变量约束每一条新放开的读路径并通过workspace_mismatch/untrusted_workspace两级错误保持旧客户端兼容。仓库中的 session.ts 提供路由放行逻辑multi-workspace-sessions.test.ts 则从存储零副作用、日志抑制、live 不合并、分页与错误码五个维度验证了设计契约。【免费下载链接】qwen-codeAn open-source AI coding agent that lives in your terminal.项目地址: https://gitcode.com/GitHub_Trending/qw/qwen-code创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表