Repository navigation
[提案] Windows 原生透明 Workspace:跨平台文件系统语义与挂载架构解耦 #454
Description
Notice: it is still in progress and content below may be changed at any time.
此提案包含适配 Windows 原生运行,调整架构以消除对特定 OS 的耦合。以及计划做到透明,也就是把 layerfs 这一层对模型抽象掉,在 harness 里集成一个插件适配 layerfs。
目前尚未确定透明设计的职责边界,以及能不能实现。
目标
希望 LayerFS 能在 Windows 原生环境运行,不依赖 WSL2 或 Docker,让 Windows 上现有的 Agent 软件直接打开并使用 LayerFS Workspace。
这里的“透明”(尚未作为必选实现目标,透明设计可能并不适用于 layerfs 或者有实现困难),它主要针对模型及日常文件操作:模型继续使用 Agent 软件已有的读文件、编辑、搜索和终端工具,不需要额外提示词、LayerFS 专用工具或文件系统操作知识。Agent 的文件工具、终端和启动的原生程序访问同一个工作目录;Branch、Commit、回退和 Workspace 生命周期由模型之外的宿主、扩展或控制组件管理。
挂载/投影后端尚未确定:WinFsp 和 ProjFS 都是候选。
这是架构与功能提案,不是已有支持声明。关联 #446、#452。
与当前工作关系
以本次审阅的主分支 ad78914e36b258b360daf13aec164b5655814689 为基准:
- LayerFS 2.0 roadmap #446 的 D2 涉及原生平台支持,B1 涉及 Provider 抽象;B4 当前写的是 Windows through WSL2,与本提案的 Windows native 目标不同。
- Windows-native Store route: Store engine and SDK Store face on native Windows #452 提供 Windows 原生 Store 路线:SQLite、跨进程 writer lane、文件身份、项目导入及进程内 SDK Store 调用。该 PR 明确不提供 Windows Workspace、挂载 daemon 或 Exec,不能等同于完整 Windows 支持。
- Windows-native Store route: Store engine and SDK Store face on native Windows #452 的 SDK 改动仍基于
sdk/js/native/,主分支现有 binding 位于api/binding/;集成时需要对齐现有 API 结构。 - 当前 AGENTS.md 已允许外部进程通过普通文件系统调用访问 Workspace,不要求调用
workspace_api.exec。因此,完整 Windows Exec/Sandbox Provider 不必成为透明文件系统接入的前置条件。
当前 blocker
| 层次 | 现状 | 需要解决的问题 |
|---|---|---|
| Windows 文件系统入口 | layerfs-fuse 的 mount/request/session 等模块仅在 Linux 编译;#452 预设只打通 Store |
Windows 原生应用的文件 API 尚无通向 Workspace 的挂载/投影入口 |
| 挂载与部署 | workspace.mount(sandbox, branch) 要求运行中的 Sandbox,并经其 daemon 挂载,结果包含 container/image |
需要本机目录挂载,不应强制依附 Docker 容器或接管 Agent 的进程执行 |
| 名称模型 | PathName 要求 UTF-8、单名称最多 255 字节,名称按字节排序和比较 |
Windows 名称编码、大小写查找与冲突、仅改变大小写的重命名等不能只在路径分隔符转换中解决 |
| 元数据 | PortableMetadata 当前主要是 mode、mtime;Workspace 属性修改接口主要是 mode/mtime/size |
Windows 属性及需要保留的元数据必须贯通导入、实时修改、Commit 和重新挂载,不能仅临时合成 stat |
| 引用生命周期 | Overlay 的 KernelEffect::Entry/Open 带有 lookup reference、open descriptor 等 FUSE 风格协议 |
需要区分通用文件身份/引用所有权与 FUSE LOOKUP/FORGET、Windows handle/Cleanup/Close 的平台协议 |
| Capture 与 Commit | 当前捕获的是 Workspace 已本地发布的修改前沿 | Windows 缓存、映射写入和持续打开文件需要与捕获边界衔接;不能把工具返回、单个句柄关闭或一次文件变化通知当作整个 Workspace 的一致快照 |
相关源码:
建议的架构改动
1. 保留存储与历史核心,重新划分平台边界
优先复用现有内容寻址、对象编码、内容构造、History、Branch 和 publication 机制,不为 Windows 建第二套 Store 或对象编码器。
需要重新设计的是名称/元数据语义、活跃 Workspace 状态与捕获、平台文件引用生命周期,以及挂载与执行的关系。已有 inode/稳定文件身份并不是 Linux 专属概念,不应仅因这些术语就推倒重写。
以下是职责边界,不要求每一层新增 crate、服务或 RPC:
Windows Agent 软件、编辑器、终端及其子进程
│ 普通 Windows 文件 API
▼
Windows 挂载/投影后端(WinFsp / ProjFS,待定)
│
▼
Workspace:名称、元数据、当前视图、变化与稳定捕获
│
▼
共享 Content / Storage / History / Persistence
宿主/控制组件 ── 创建、挂载、Commit、分支、回退、关闭
2. 将 Workspace 挂载与 Sandbox/Agent 执行解耦
提供 Windows 本地挂载的生命周期入口,明确项目、Branch、Workspace 和宿主目录的关系,不强制要求 image、Docker volume 或容器身份。
Agent 软件可以自行启动 PowerShell、Git、Node、Python、编译器及后台进程。LayerFS 先负责文件系统视图和版本管理,原生执行 Provider 可以后续单独加入。
3. 明确名称语义,而不是散落 Windows 特判
区分宿主路径与 Store 内逻辑路径,明确无损名称编码及首版支持范围,不用 to_string_lossy() 默默改变文件身份。
为项目/文件树明确名称查找与冲突策略,保留原始大小写;创建、导入、重命名、直接 Store 写入和 merge 必须使用一致规则。例如两个分支分别创建 Config.json 与 config.json,不能在 merge 后才由 Windows 挂载层发现不可表示的歧义。名称排序与名称等价关系需要区分,不宜用简单 lowercase 代替 Windows 名称规则。
4. 元数据与平台生命周期分开处理
利用已有属性树扩展需要版本化的 Windows 元数据,并贯通 Workspace 修改和 Commit;不把所有 Windows 属性压缩为 POSIX mode。
核心保留稳定文件身份、打开引用、删除后的存活状态与捕获所需的所有权;FUSE LOOKUP/FORGET 与 Windows handle/Cleanup/Close 等留在各自的平台边界。由驱动框架处理的共享打开、锁等能力不应在核心重复实现,但平台操作产生的生命周期必须与核心对应。
硬链接、符号链接/junction、只读属性、文件时间、ACL、命名流等的具体支持范围需要明确。硬链接是否为首版必需尚未决定,不把复制文件视为硬链接的等价实现。
5. 透明接入优先采用持续 Workspace
建议首个接入模式为“一个会话/任务对应一个持续 Workspace”:文件工具、搜索、终端和监听器都访问同一个挂载目录,避免文件工具直接读取 Branch 已提交状态、终端却读取另一份活跃 Workspace 的双视图问题。
Commit 可以由宿主在任务或工具调用边界触发。若需要“每次工具调用一个 Commit”,宿主必须取得工具边界事件;文件系统本身无法从一串 I/O 推断模型工具调用边界。这不要求模型感知 LayerFS。
6. 挂载后端决定活跃写入层,不能假设只有回调适配差异
- WinFsp 候选:优先研究原生 Windows API,将文件操作接入现有 Workspace/SQLite Overlay,尽量复用 Capture 与 Commit。需要处理 Windows 生命周期和缓存;官方目前明确不支持硬链接,不能仅在 LayerFS 用户态补一个
Link回调就视为解决。 - ProjFS 候选:按需投影已提交内容,修改后的 Full File 位于本地文件系统。若采用,应明确引入 NTFS 活跃写入层及其变化索引、稳定捕获、内容构造和基线推进方案。它不是现有 SQLite Overlay 的薄替代,也不能依靠关闭通知或每次整树重扫来假装已有同等 Capture 语义。
两条路线都应复用相同的内容构造与历史发布机制。后端选定之前,不要求同时维护两套生产实现。
后端选择:尚未确定
| 候选 | 主要价值 | 必须回答的问题 |
|---|---|---|
| WinFsp | 更接近当前自定义文件系统及 SQLite Overlay 架构 | 硬链接缺口如何处理?Windows 打开/删除/重命名、缓存与 Capture 如何对接? |
| ProjFS | 利用本地 NTFS 处理活跃文件,提供按需物化 | 如何获取稳定的增量快照?Full File、tombstone、hard-link 身份及基线更新如何维护?多 Workspace 的本地缓存与磁盘成本是多少? |
应围绕实际 Windows 开发工作负载比较,而不是只验证挂载成功或读写一个文本文件。没有实测前不预设性能优劣,也不声称其中任一方案提供完整 NTFS 等价行为。
官方资料:WinFsp NTFS compatibility、WinFsp native API、ProjFS cache state、ProjFS view changes。
期望交付
无需 WSL2/Docker;模型不需要学习 LayerFS;文件工具与原生命令看到同一份活跃状态;Workspace 能增量提交;两个 Workspace 的未提交修改互不干扰;历史视图保留约定范围内的名称、内容、元数据与链接语义。
核心问题不是“能否在 Windows 编译 Store”,而是“能否让普通 Windows 应用通过标准文件 API 使用一个语义一致、可捕获、可版本化的 LayerFS Workspace”。
Activity