Linux版WorkBuddy默认使用了更强的砂盒,导致在不关闭砂盒的情况下WorkBuddy会话与主用户之间的进程空间隔离,$HOME目录也隔离。因此需要Skill根据这个特殊情况更新相应的描述。
[Compatibility] bsk 在 WorkBuddy(bubblewrap 沙盒)中 daemon 无法存活与 PID 校验假失败的分析与解法
环境
| 项目 |
版本/说明 |
| OS |
Linux x64 |
| bsk CLI |
0.21 |
| 浏览器扩展 |
Chrome 扩展,protocol 1.1 |
| Agent 宿主 |
WorkBuddy(内置 CodeBuddy Code 同源 CLI 引擎) |
| 沙盒实现 |
bubblewrap(WorkBuddy 的 Bash Sandbox,Linux 下用 bwrap 做 OS 级隔离) |
现象
bsk status / bsk daemon start 首次运行报 Permission denied,尝试写入 /root/.bsk 失败
bsk daemon start 偶发成功,但下一条命令执行时 daemon 已死,报 error: ensure daemon is running
- daemon 明明存活(端口 52800 在监听、日志有
daemon ready、Unix socket 可连接),CLI 仍报 ensure daemon is running
bsk session start 成功返回 session id,紧接着的 bsk navigate 报 session not registered or already stopped
根因分析(已在实测中逐项验证)
WorkBuddy 沙盒对 Bash 命令施加了以下隔离,与 bsk 的 daemon 架构产生 4 个冲突点:
1. HOME 环境变量为空 → bsk 落盘位置错误
沙盒内执行时 HOME 为空字符串,bsk 回退到 /root/.bsk,而该路径在沙盒内不可写:
FAIL bsk home writable create bsk home /root/.bsk: Permission denied (os error 13)
解法:所有命令显式 export BSK_HOME=/home/wzk/.bsk(并配置该目录已在宿主侧文件白名单中)。
2. 进程树清理 → daemon 无法跨命令存活(最核心问题)
沙盒对每条 Bash 命令使用独立的隔离环境,命令结束后其派生的整棵进程树被终止。bsk daemon start 虽然默认 auto-detach(除非 --foreground),但 daemon 作为命令的子进程依然随命令结束被杀。
日志证据——每条命令都重新经历完整的启动流程(daemon lock acquired → daemon ready,PID 不断变化:5 → 6 → 7 → 10 → 3967462...):
{"timestamp":"2026-09-10T06:09:38.689850Z","level":"INFO","fields":{"message":"daemon lock acquired", ...}}
{"timestamp":"2026-09-10T06:09:48.369885Z","level":"INFO","fields":{"message":"daemon lock acquired", ...}}
{"timestamp":"2026-09-10T06:09:58.xxxxxxZ","level":"INFO","fields":{"message":"daemon lock acquired", ...}}
解法:将 daemon 挂在宿主的「常驻后台任务」上,并以沙盒外模式(WorkBuddy 的 dangerouslyDisableSandbox 逃生舱)运行:
export BSK_HOME=/home/wzk/.bsk && bsk daemon start && sleep 7200
# 以 run_in_background + dangerouslyDisableSandbox 方式执行,daemon 可稳定存活
3. PID namespace 隔离 → CLI 存活校验假失败
沙盒内外 PID 命名空间不同。daemon 在沙盒外运行后,daemon.json 记录的 pid(如 5)在沙盒内不存在:
$ ls -d /proc/5
ls: cannot access '/proc/5': No such file or directory
$ python3 -c "import os; os.kill(5, 0)"
ProcessLookupError
bsk CLI 连接前会校验 daemon.json 中的 pid 是否存活,校验失败即拒绝连接并报 ensure daemon is running——尽管 daemon 实际运行正常(以下均可证明 daemon 存活:TCP 127.0.0.1:52800 可连通、Unix socket /home/wzk/.bsk/run/daemon.sock 可连通、daemon 日志持续输出、bsk status 偶发成功)。
时序上还有一个偶发现象:同一命令内先跑 bsk status(成功)再跑 bsk session stop(失败),说明校验存在竞态或多次校验路径不一致。
解法(绕过):命令包一层重试循环,直到输出不含该错误:
for i in $(seq 1 8); do
out=$(bsk snapshot --session owqy 2>&1)
echo "$out" | grep -q "ensure daemon" || { echo "$out"; break; }
sleep 2
done
4. daemon 异常死亡留下残留文件 → 后续启动失败
daemon 被沙盒杀掉后,run/daemon.sock、daemon.json、daemon.lock 残留,导致下次 bsk daemon start 卡在 daemon lock acquired 后无下文,3 秒超时报 daemon failed to start within 3s (no valid daemon.json)。
解法:启动前清理:
rm -f $BSK_HOME/run/daemon.sock $BSK_HOME/daemon.json $BSK_HOME/daemon.lock
(建议 bsk 在启动时对无进程占用的残留 socket/lock 做自动回收。)
已验证可用的完整流程
在上述解法全部应用后,以下链路已端到端跑通:
bsk session start → 返回 session id(owqy)
bsk navigate https://example.com --session owqy
→ tab=1682150359 reached=load url=https://example.com/
bsk snapshot --session owqy
→ 正确返回 "Example Domain" 页面无障碍树
bsk session stop owqy → stopped owqy
另注:daemon 重启后浏览器扩展自动重连存在退避延迟(实测约 30 秒内重连成功),期间 bsk session start 报 no browser is connected to the daemon,等待即可。
对官方的建议
- 文档:在 README / AGENT_INSTALL.md / SKILL.md 中增加「沙盒化 Agent 宿主(bubblewrap/Seatbelt 等)」章节,说明 daemon 需要沙盒外常驻运行
- CLI:提供跳过 pid 校验、直接尝试连接 socket 的降级路径(如
--no-pid-check 或校验失败时 fallback 到 socket 连接探测——socket 能连上即说明 daemon 存活,pid 校验在 PID namespace 隔离场景下并不可靠)
- daemon:启动时自动回收无进程占用的残留
daemon.sock / daemon.lock
- 兼容性:HOME 为空时给出更明确的报错提示(提示设置
BSK_HOME)
Linux版WorkBuddy默认使用了更强的砂盒,导致在不关闭砂盒的情况下WorkBuddy会话与主用户之间的进程空间隔离,$HOME目录也隔离。因此需要Skill根据这个特殊情况更新相应的描述。
[Compatibility] bsk 在 WorkBuddy(bubblewrap 沙盒)中 daemon 无法存活与 PID 校验假失败的分析与解法
环境
现象
bsk status/bsk daemon start首次运行报Permission denied,尝试写入/root/.bsk失败bsk daemon start偶发成功,但下一条命令执行时 daemon 已死,报error: ensure daemon is runningdaemon ready、Unix socket 可连接),CLI 仍报ensure daemon is runningbsk session start成功返回 session id,紧接着的bsk navigate报session not registered or already stopped根因分析(已在实测中逐项验证)
WorkBuddy 沙盒对 Bash 命令施加了以下隔离,与 bsk 的 daemon 架构产生 4 个冲突点:
1. HOME 环境变量为空 → bsk 落盘位置错误
沙盒内执行时
HOME为空字符串,bsk 回退到/root/.bsk,而该路径在沙盒内不可写:解法:所有命令显式
export BSK_HOME=/home/wzk/.bsk(并配置该目录已在宿主侧文件白名单中)。2. 进程树清理 → daemon 无法跨命令存活(最核心问题)
沙盒对每条 Bash 命令使用独立的隔离环境,命令结束后其派生的整棵进程树被终止。
bsk daemon start虽然默认 auto-detach(除非--foreground),但 daemon 作为命令的子进程依然随命令结束被杀。日志证据——每条命令都重新经历完整的启动流程(
daemon lock acquired→daemon ready,PID 不断变化:5 → 6 → 7 → 10 → 3967462...):{"timestamp":"2026-09-10T06:09:38.689850Z","level":"INFO","fields":{"message":"daemon lock acquired", ...}} {"timestamp":"2026-09-10T06:09:48.369885Z","level":"INFO","fields":{"message":"daemon lock acquired", ...}} {"timestamp":"2026-09-10T06:09:58.xxxxxxZ","level":"INFO","fields":{"message":"daemon lock acquired", ...}}解法:将 daemon 挂在宿主的「常驻后台任务」上,并以沙盒外模式(WorkBuddy 的
dangerouslyDisableSandbox逃生舱)运行:3. PID namespace 隔离 → CLI 存活校验假失败
沙盒内外 PID 命名空间不同。daemon 在沙盒外运行后,
daemon.json记录的 pid(如5)在沙盒内不存在:bsk CLI 连接前会校验
daemon.json中的 pid 是否存活,校验失败即拒绝连接并报ensure daemon is running——尽管 daemon 实际运行正常(以下均可证明 daemon 存活:TCP 127.0.0.1:52800 可连通、Unix socket/home/wzk/.bsk/run/daemon.sock可连通、daemon 日志持续输出、bsk status偶发成功)。时序上还有一个偶发现象:同一命令内先跑
bsk status(成功)再跑bsk session stop(失败),说明校验存在竞态或多次校验路径不一致。解法(绕过):命令包一层重试循环,直到输出不含该错误:
4. daemon 异常死亡留下残留文件 → 后续启动失败
daemon 被沙盒杀掉后,
run/daemon.sock、daemon.json、daemon.lock残留,导致下次bsk daemon start卡在daemon lock acquired后无下文,3 秒超时报daemon failed to start within 3s (no valid daemon.json)。解法:启动前清理:
(建议 bsk 在启动时对无进程占用的残留 socket/lock 做自动回收。)
已验证可用的完整流程
在上述解法全部应用后,以下链路已端到端跑通:
另注:daemon 重启后浏览器扩展自动重连存在退避延迟(实测约 30 秒内重连成功),期间
bsk session start报no browser is connected to the daemon,等待即可。对官方的建议
--no-pid-check或校验失败时 fallback 到 socket 连接探测——socket 能连上即说明 daemon 存活,pid 校验在 PID namespace 隔离场景下并不可靠)daemon.sock/daemon.lockBSK_HOME)