v2-refactor-temp/docs/ai/agent-session-workspace.md
当前产品里有两类 workspace:
User-owned workspace
System-owned workspace
path,但不会创建真实目录。path 必须位于应用管理的 system workspace root 下。当前想要的 session 创建、运行与删除逻辑是:
| 用户行为 / 系统阶段 | 期望逻辑 |
|---|---|
| 用户选择已有 workspace | 创建 session,并绑定用户选择的 workspaceId |
| 用户选择 No project | 系统创建一个 system workspace row,然后创建 session 并绑定它 |
| 创建新 session 但没有显式 workspace | 不应该自动继承最近 session 的 workspace |
| 启动 user-owned workspace session | runtime 只校验目录是否存在、是否目录、是否可访问;失败则暴露错误 |
| 启动 system-owned workspace session | runtime 如果发现目录不存在,则先创建该系统目录,再继续校验 |
| 删除 user-owned workspace | 删除该 workspace 对应的所有 session 和 workspace row |
| 删除 system-owned session | 删除对应的一对一 system workspace row / 绑定关系 |
| 删除 user-owned workspace | 永远不删除用户自己的真实目录 |
| 删除 system-owned session/workspace | 不在该流程里删除真实目录 |
| 后续清理 system-owned 真实目录 | 统一放到设置页缓存清除 / 系统工作目录清理能力中处理 |
这里的核心定义是:
session.workspaceId 是一个数据层绑定。path 只是数据字段。path 仍然在 create 阶段生成并保存,runtime 只按已保存的 path 做准备。session.workspaceId -> workspace.id 表达,不需要 workspace 反向绑定 session。也就是说,session 与 workspace 的关系是数据关系,不是文件系统可用性保证。
runtime 是真实目录状态的负责人。
它需要区分 workspace 类型:
User-owned workspace
System-owned workspace
因此 assertClaudeCodeWorkspaceDirectory 当前如果只是 pure assert,可以保留这个纯校验语义;但应该在它之前增加一层更明确的 runtime preparation,例如:
prepareClaudeCodeWorkspaceDirectory(session)
大致语义是:
if (session.workspace.type === 'system') {
ensureSystemWorkspaceDirectory(session.workspace.path)
}
assertClaudeCodeWorkspaceDirectory(session.id, session.workspace.path)
这样职责更清楚:
prepareClaudeCodeWorkspaceDirectory:负责 runtime 启动前的 workspace 准备。ensureSystemWorkspaceDirectory:只允许对 system-owned workspace 创建真实目录,并且必须校验 path 位于应用管理的 system workspace root 下。assertClaudeCodeWorkspaceDirectory:继续只负责校验目录状态。一开始我把 session create/delete 理解成了一个带强 filesystem side effect 的 workflow。
基于这个假设,我认为:
但这个判断过强了。
现在重新明确后,真实需求并不是“创建或删除 session 时处理真实文件目录”,而是:
因此之前把 session create/delete 强行归类为 filesystem orchestration,是不准确的。
如果 session create 只做以下事情:
workspaceId;path;并且 session/workspace delete 只做以下事情:
那么它们仍然可以是 DataApi 操作。
也就是说,关键问题不是“必须改成窄 IPC”,而是:
真实工作目录清理只针对系统创建的目录。
也就是说:
这样可以保持职责统一:
这样比在多个业务删除入口里散落真实目录清理逻辑更清晰,也更容易控制风险。
最终我倾向于这样的设计:
POST /agent-sessions 作为 DataApi 创建入口。assertClaudeCodeWorkspaceDirectory。session.workspaceId -> workspace.id 表达;workspace row 不需要任何反向 session 字段。基于上面的功能背景和职责划分,我现在认为:
session create/delete 不需要移动到窄 IPC。 只要它们不做真实 filesystem 校验/操作,而只是创建/删除 DB row 和 workspace 绑定关系,保留 DataApi 是合理的。 真正需要修正的是去掉隐式继承 latest workspace 的 fallback,并让 workspace binding 显式化。 system-owned workspace 的真实目录在 runtime start 时按需创建;user-owned workspace 永远不自动创建也不删除。 系统创建的真实目录后续统一交给设置页缓存清理能力处理。