问题描述
下载 Agent 工作区 zip(GET /agents/{id}/workspace/archive)时,包内 AGENTS.md 的内容不是该 workspace 自己的 AGENTS.md,而是 backend host 用户目录根目录下的那份同名 AGENTS.md。其余文件(SOUL.md / USER.md / IDENTITY.md 等)内容均正确,只有 AGENTS.md 错位——包条目名正确(AGENTS.md),文件内容却是错的,zip 校验和检查不出来。
复现步骤
- 部署 Octop,配置 agent backend
root_dir 指向用户主目录(如 /home/<user>),workspace_dir 为默认 scoped 路径(~/.octop/workspaces/<agentId>/)
- 在用户主目录根放一份与 workspace 内内容不同的
AGENTS.md
- 下载该 workspace 的 zip:
GET /agents/{agent_id}/workspace/archive
- 解压后对比:
| 文件 |
md5 / 大小 |
workspace 内真实 AGENTS.md |
6510ae29… / 10687 B |
主目录根 AGENTS.md |
a17ef267… / 2867 B |
导出 zip 内 AGENTS.md |
a17ef267…(与主目录根一致,错误) |
根因分析(疑似)
src/octop/infra/backup/workspace_archive.py 的 _list_file_paths():
storage = str(path)
ws_root = str(workspace.workspace_dir)
if storage.startswith(ws_root):
rel = storage[len(ws_root):].lstrip("/\\")
if rel:
paths.append(rel); continue
paths.append(storage.lstrip("/")) # fallback:不匹配 workspace_dir 时把路径直接当条目名
aglob("**/*", ".") 返回的 storage path 形态取决于 backend 实现;当路径不以 workspace_dir 开头时,fallback 会 lstrip("/") 后当相对条目名——host 绝对路径会被污染进包(如 data/users/.../AGENTS.md)。
- 下载环节
adownload_bytes(rel) 的相对路径解析基准疑似是 backend root_dir 而非 workspace_dir:裸名 AGENTS.md 被解析到主目录根,读回的是主目录根的文件内容(本例 zip 内恰好是根条目 AGENTS.md,内容来自 host 用户目录根)。virtual filesystem 挂载时同名文件遮蔽(workspace 根文件被 root 层同名文件遮蔽)也符合现象。
影响
- workspace 导出 / 系统备份(
system_archive 同样走 export_workspace_zip)会静默携带错误文件,且文件名与结构正确,难以从 zip 本身察觉。
- 导入到其他环境后,agent 每轮注入的
AGENTS.md 是主机的旧文件,行为错乱且排查成本高(熟悉 AGENTS.md 语义的用户会直接踩中)。
- 只要 backend root(或主目录根)存在与 workspace 内文件同名的文件(
AGENTS.md 最常见,用户常在主目录根放全局说明书),就会被污染。
建议
_list_file_paths:不匹配 workspace_dir 的 path 不要 lstrip 后直接入包——应基于 workspace_dir 重新规整,或跳过并记录警告。
adownload_bytes / backend 下载的路径解析基准明确为 workspace_dir,相对路径禁止解析到 root_dir 之外(顺带封掉路径穿越类风险)。
- 导出完成后加逐文件内容校验(hash 对比源 workspace),避免静默污染。
环境
- 独立部署 Octop(数据目录
~/.octop),backend 为本地 filesystem + 自定义 root_dir
- 版本:0.9.x(以参考安装 0.9.31)
问题描述
下载 Agent 工作区 zip(
GET /agents/{id}/workspace/archive)时,包内AGENTS.md的内容不是该 workspace 自己的AGENTS.md,而是 backend host 用户目录根目录下的那份同名AGENTS.md。其余文件(SOUL.md/USER.md/IDENTITY.md等)内容均正确,只有AGENTS.md错位——包条目名正确(AGENTS.md),文件内容却是错的,zip 校验和检查不出来。复现步骤
root_dir指向用户主目录(如/home/<user>),workspace_dir为默认 scoped 路径(~/.octop/workspaces/<agentId>/)AGENTS.mdGET /agents/{agent_id}/workspace/archiveAGENTS.md6510ae29…/ 10687 BAGENTS.mda17ef267…/ 2867 BAGENTS.mda17ef267…(与主目录根一致,错误)根因分析(疑似)
src/octop/infra/backup/workspace_archive.py的_list_file_paths():aglob("**/*", ".")返回的 storage path 形态取决于 backend 实现;当路径不以workspace_dir开头时,fallback 会lstrip("/")后当相对条目名——host 绝对路径会被污染进包(如data/users/.../AGENTS.md)。adownload_bytes(rel)的相对路径解析基准疑似是 backendroot_dir而非workspace_dir:裸名AGENTS.md被解析到主目录根,读回的是主目录根的文件内容(本例 zip 内恰好是根条目AGENTS.md,内容来自 host 用户目录根)。virtual filesystem 挂载时同名文件遮蔽(workspace 根文件被 root 层同名文件遮蔽)也符合现象。影响
system_archive同样走export_workspace_zip)会静默携带错误文件,且文件名与结构正确,难以从 zip 本身察觉。AGENTS.md是主机的旧文件,行为错乱且排查成本高(熟悉AGENTS.md语义的用户会直接踩中)。AGENTS.md最常见,用户常在主目录根放全局说明书),就会被污染。建议
_list_file_paths:不匹配workspace_dir的 path 不要lstrip后直接入包——应基于workspace_dir重新规整,或跳过并记录警告。adownload_bytes/ backend 下载的路径解析基准明确为workspace_dir,相对路径禁止解析到root_dir之外(顺带封掉路径穿越类风险)。环境
~/.octop),backend 为本地 filesystem + 自定义root_dir