{
  "$schema": "https://bestaiskill.com/schemas/agent-install/2.json",
  "skill": "openclaw",
  "built": "2026-10-26",
  "control_level": 4,
  "control_level_label": "L4 高权限",
  "capabilities": [
    "execute_command",
    "network",
    "write_file"
  ],
  "required_controls": {
    "agent": [
      "sandbox_recommended",
      "graded_authorization"
    ],
    "admin": [
      "approval_process",
      "rollback_support",
      "full_audit"
    ]
  },
  "evidence": [
    {
      "file": "scripts/",
      "summary": "Execute local scripts or commands: python3 scripts/cli.py <audit|diff|copy|add-model|list|switch> (or run individual sub-scripts directly)"
    },
    {
      "file": "环境变量 / API Key",
      "summary": "Read vendor service keys: models.providers.*.apiKey in openclaw.json: read into memory and written back alongside the entire config (the script never extracts this field explicitly); copy/"
    },
    {
      "file": "本地工作目录",
      "summary": "File read/write and artifact output: <config_dir>/config-backups/<stem>-<UTC_timestamp>.json (backed up prior to every write operation)"
    }
  ],
  "verification": {
    "method": "第二遍独立于第一遍重做取证（换角度抓错）：①不引用第一遍结论，重新 raw 读 openclaw/scripts 全部 8 个脚本，逐行找网络/凭证/写入/子进程调用点；②对 scripts/ 做反向 token 扫描：urllib|requests.|socket|http.client|httpx|curl |wget → 零命中，os.environ|getenv|apiKey → 零命中（apiKey 仅出现在 references/openclaw_architecture.md 的 schema 示例里，scripts 内不存在），据此把 external_deps 的 network 项收回为「仅配置字段、无调用」；③对 evidence 引用的每条 quote 用脚本做逐字子串比对（quote in file.read()），全部命中后才落盘；④按用户提示的四个重点逐条反查：写哪个配置文件（resolve_config_path→save_config 就地覆写原文件）、是否备份（backup_config 在三次写路径中均先于 save_config 调用，grep save_config/backup_config 调用点确认顺序）、是否发网络请求做 endpoint probe（无任何 HTTP 客户端，restart 是本地子进程）、是否读 env 里的 API key（零 os.environ/getenv）；⑤对 SKILL.md 逐条声明做「声明 vs 代码」比对（见 second_pass）；⑥用 git rev-parse HEAD 核对工作副本 == pin commit d5c4678，并 find -type f 确认两个 skill 目录无隐藏文件/额外资产。",
    "second_pass": [
      {
        "item": "SKILL.md 声明「Backups: every write operation copies the config to config-backups/<stem>-<utc-timestamp>.json」是否与代码一致",
        "status": "ok",
        "detail": "三条写路径 copy_provider.py / add_model.py / switch_model.py 都在 save_config 之前调用 backup_config(config_path)，且 openclaw_config.backup_config 用 datetime.now(timezone.utc) 生成时间戳、文件名格式恰为 f\"{p.stem}-{ts}{p.suffix}\"；SKILL.md 关于「keeps the 20 most recent backups」也对得上 max_backups: int = 20 默认值与 existing[:-max_backups] 裁剪。"
      },
      {
        "item": "SKILL.md 声明「switch 是唯一改 agents.defaults.model 的子命令」",
        "status": "ok",
        "detail": "grep set_default_model 的调用点只有 switch_model.py 一处；add_model.py 只写 agents.defaults.models（别名映射），copy_provider.py 只写 models.providers 与别名，compare/list/audit 纯只读，声明成立。"
      },
      {
        "item": "SKILL.md「Restart: write subcommands support --restart to restart the OpenClaw gateway after saving」",
        "status": "ok",
        "detail": "三个写脚本都定义了 --restart 并调用 restart_gateway()；且未给 --restart 时会打印「NOTE: You must restart the OpenClaw gateway...」提示，行为与文档一致。副产物确认：restart_gateway 的第三档是系统级 systemctl（无 --user），文档未提及这一越权风险，已写进 verdict.risks。"
      },
      {
        "item": "external_deps 里是否漏掉了网络调用（有没有隐藏的 endpoint probe 或遥测）",
        "status": "ok",
        "detail": "反向扫描 scripts/ 全部 8 文件：无 import urllib/requests/socket/httpx，无 curl/wget 字符串，无任何 URL 常量。openclaw 与 openclaw-model-switch 的关键差异（后者文档要求 curl 探针）在此得到对照确认。network 依赖项仅保留「配置里存在 baseUrl 字段」这一事实，并显式标注 skill 自身不请求。"
      },
      {
        "item": "是否读 env 里的 API key / 密钥",
        "status": "ok",
        "detail": "scripts/ 内 os.environ、getenv 零命中；openclaw_config.py 里 import os 的唯一用途是 os.path.getmtime 做备份排序。凭证面仅为「随配置整份读写的 apiKey 字段」与「copy/add-model 把 provider 块连同 apiKey 深拷贝到目标配置」，已在 security.credential_reads 如实登记而非留空。"
      },
      {
        "item": "「copy 不删目标独有模型」是否为真（找反例：有没有静默覆盖整个 provider 的分支）",
        "status": "ok",
        "detail": "反例检查通过：当目标已有该 provider 时走 merge_provider（只按 id 增补/更新、且注释明确 does not remove target-only models），不整块替换；唯一整体替换发生在「目标根本没有该 provider」时（copy.deepcopy(source_provider)），此时不存在目标独有模型可丢。--alias 分支只做 target_aliases[ref] = deepcopy(detail) 的增补，也不删。"
      },
      {
        "item": "备份保留逻辑会不会误删非备份文件",
        "status": "discrepancy",
        "detail": "发现第一遍未记的边界：裁剪用 backup_dir.glob(f\"{p.stem}-*{p.suffix}\") 匹配，若用户在 config-backups/ 目录里放了同名模式的其它文件（例如手工备份 openclaw-手工.json，而 stem 恰为 openclaw），mtime 最旧的会被 unlink。属真实但低概率的删除面，已补进 verdict.risks。"
      },
      {
        "item": "功能声明 vs 实际能力夸大检查（SKILL.md / README 有没有说到做不到的事）",
        "status": "ok",
        "detail": "SKILL.md 的六子命令、昵称注册表、三级默认路径、备份与 20 份上限、dry-run、restart、自动 audit 全部可在代码中一一落到实处，未发现夸大。唯一「文档比代码多说一句」的是 references/deepseek_patch_sop.md 的示例命令 `add-model gateway-provider references/deepseek_model.json`（相对路径需从 skill 根执行），属示例语境问题而非能力夸大。"
      },
      {
        "item": "quote 逐字存在性（防伪自检）",
        "status": "ok",
        "detail": "写盘前后各跑一次校验脚本：把本 JSON 里每一条 evidence.quote 作为子串到其 evidence.file 的原文中查找，全部命中（含多行 quote 的缩进与换行符）。未使用任何 paraphrase 冒充 quote。"
      }
    ],
    "level": 1,
    "level_label": "V1 已固定",
    "commit": "d5c4678cb5d4fd6acc9c922690df035dbd33d247",
    "sha256": "c792eb95fa4dde39d5c54d1177c6629379bec9cffb06291d4b9990239c8e904f",
    "reviewed_by": null,
    "reviewed_at": null
  },
  "assessed_at": "2026-10-25",
  "method_version": "2.0",
  "mirror": {
    "archive": "https://skillpub.pages.dev/r2/v/2026-09-15/openclaw.tar.gz",
    "sha256": "c792eb95fa4dde39d5c54d1177c6629379bec9cffb06291d4b9990239c8e904f",
    "commit": "d5c4678cb5d4fd6acc9c922690df035dbd33d247"
  },
  "original": {
    "github": "https://github.com/daymade/claude-code-skills/tree/main/openclaw",
    "path": "openclaw",
    "commit": "d5c4678cb5d4fd6acc9c922690df035dbd33d247"
  }
}