make_private_dir 无条件 chmod:沙箱/受限环境下 doctor 及所有依赖 Config() 的命令直接崩溃

Author: royalskynetCreated Sep 10, 2026Updated Sep 10, 2026

环境

  • Agent Reach v1.5.0agent-reach version
  • macOS 26.6 (Darwin 25.6.0),Python 3.14
  • 运行在 Claude Code 的沙箱内:文件系统白名单机制,chmod(2) / fchmod(2) 系统调用被拒绝

现象

任何走 Config() 的命令都直接崩溃,doctor 完全不可用:

$ agent-reach doctor --json
Traceback (most recent call last):
  File "/Users/…/bin/agent-reach", line 10, in <module>
    sys.exit(main())
  File "…/agent_reach/cli.py", line 147, in main
    _cmd_doctor(args)
  File "…/agent_reach/cli.py", line 1483, in _cmd_doctor
    config = Config()
  File "…/agent_reach/config.py", line 36, in __init__
    self._ensure_dir()
  File "…/agent_reach/config.py", line 41, in _ensure_dir
    make_private_dir(self.config_dir)
  File "…/agent_reach/utils/paths.py", line 15, in make_private_dir
    os.chmod(target, 0o700)
PermissionError: [Errno 1] Operation not permitted: '/Users/…/.agent-reach'

关键点:目录权限本来就是对的

$ ls -ld ~/.agent-reach
drwx------  6 …  192 Jul  5 22:45 /Users/…/.agent-reach

已经是 0700这次 chmod 是个 no-op,却让整个命令挂掉。

main 分支的改写没有解决

main 已把 os.chmod(target, 0o700) 换成 fd 版本:

dir_fd = os.open(target, flags)
try:
    ensure_no_symlink_path(target, "私密目录")
    if hasattr(os, "fchmod"):
        os.fchmod(dir_fd, 0o700)
finally:
    os.close(dir_fd)

fchmod 同样是 chmod 系统调用。本机实测两者都被拒:

os.chmod   -> PermissionError: [Errno 1] Operation not permitted: '/Users/…/.agent-reach'
os.fchmod  -> PermissionError: [Errno 1] Operation not permitted

symlink 加固是好事,但没有改变「权限已正确时仍强制 chmod」这个失败模式

建议修法

权限已满足就跳过;即使失败也不该让整个 CLI 崩溃(这是加固措施,不是功能前提):

import stat

def make_private_dir(path):
    target = ensure_no_symlink_path(path, "私密目录")
    target.mkdir(mode=0o700, parents=True, exist_ok=True)
    ensure_no_symlink_path(target, "私密目录")
    if sys.platform == "win32":
        return target

    flags = os.O_RDONLY | getattr(os, "O_DIRECTORY", 0) | getattr(os, "O_NOFOLLOW", 0)
    dir_fd = os.open(target, flags)
    try:
        ensure_no_symlink_path(target, "私密目录")
        st = os.fstat(dir_fd)
        if stat.S_IMODE(st.st_mode) != 0o700 and hasattr(os, "fchmod"):
            try:
                os.fchmod(dir_fd, 0o700)
            except PermissionError:
                # 受限环境(容器/沙箱/托管 agent)可能禁用 chmod 系统调用。
                # 目录已存在且不经过 symlink,降级为警告而不是中断。
                warnings.warn(f"无法收紧 {target} 的权限(当前 {oct(stat.S_IMODE(st.st_mode))})")
    finally:
        os.close(dir_fd)
    return target

要点:

  1. 先查 st_mode,已是 0700 就不调用 —— 覆盖绝大多数情况
  2. PermissionError 降级为警告 —— 加固失败不该让 doctor 这种诊断命令无法运行

影响

README 把 agent-reach doctor 定位成「一条命令告诉你哪个通、哪个不通、怎么修」,SKILL.md 的常驻规则第 1 条也要求「动手前先跑 agent-reach doctor --json,按各平台 active_backend 字段选命令组」。

在受限环境里这条路径永远走不通,agent 只能跳过体检、盲猜后端。而「容器 / 沙箱 / 托管 agent 环境」恰好是这个工具的主要使用场景之一。

补充:版本与 tag 的代码不一致

本机 agent-reach versionv1.5.0,但安装的 agent_reach/utils/paths.pymake_private_dir;而 v1.5.0 tag 上的同名文件只有 1521 字节、只含 yt-dlp helper、没有 make_private_dir。不确定是打包快照与 tag 不同步,还是我这边安装源的问题,一并提出供参考。