{
  "$schema": "https://bestaiskill.com/schemas/agent-install/2.json",
  "skill": "setup-notifications-via-wecom",
  "built": "2026-10-26",
  "control_level": 4,
  "control_level_label": "L4 高权限",
  "capabilities": [
    "execute_command",
    "install_deps",
    "network",
    "write_file"
  ],
  "required_controls": {
    "agent": [
      "sandbox_recommended",
      "graded_authorization"
    ],
    "admin": [
      "approval_process",
      "rollback_support",
      "full_audit"
    ]
  },
  "evidence": [
    {
      "file": "scripts/",
      "summary": "Executes local script or command: uv run --no-project python scripts/set_recipient.py --scope self|others --l"
    },
    {
      "file": "scripts/ 或 SKILL.md",
      "summary": "Declares dynamic installation of external language package dependencies"
    },
    {
      "file": "网络端点",
      "summary": "Declares external network access: POST https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=<KEY> (JSON payload {\"ms"
    },
    {
      "file": "本地工作目录",
      "summary": "File I/O and artifact output: creates config directory and config.json under ~/.config (completed via shell by user or agent, SKILL.md specifies chmod 60"
    }
  ],
  "verification": {
    "method": "第二遍独立复核（找茬视角）：①glob 清点目录（含隐藏文件）：SKILL.md / evals/evals.json / references/message_best_practices.md / scripts×2 / tests×1，共 6 个文件，无隐藏脚本；②以 raw 整读 send_wecom.py（303 行）与 set_recipient.py，逐行核对 config 字段校验、指纹比对、outbox 摘要校验、代理清理与写盘路径；③对全目录做安全 token 终扫（requests/httpx/socket/eval/exec/os.system/base64/Authorization/token/secret/access_token/.env/~/）并扫描 >200 字符无空格长行——除预期的 webhook 示例与 config 路径外零命中；④把 SKILL.md 的每条外部依赖与命令回到脚本/文档核对调用点；⑤核对 references 与 SKILL.md 的 8 条规范是否一致；⑥读 tests/test_recipient_config.py 确认「保留 webhook 与权限位」有真实断言而非只有声明；⑦git 核对 pin commit 与目录历史。",
    "second_pass": [
      {
        "item": "每条外部依赖的调用点是否真实存在",
        "status": "ok",
        "detail": "webhook 端点（SKILL.md Quick Start 第 2 步 + 脚本 docstring + 内联 curl 三处一致）、uv --no-project（SKILL.md 命令块，脚本以 uv run 方式被调用）、python3/urllib（脚本 import 段与 urllib.request.Request/urlopen）、curl（SKILL.md 内联等价示例）、env -u / env|grep（SKILL.md 两处）。无推测项。"
      },
      {
        "item": "凭证/密钥处理是否有反例（例如把 webhook 打印出去、写入日志、发往第三方）",
        "status": "ok",
        "detail": "反例检索失败：全目录 grep webhook 的每一处均不打印其值——SKILL.md 的 set_recipient 说明写 'without exposing or rewriting the webhook value'；脚本只把它用于 urllib.request.Request(webhook_url, …)，出错时的报错文案（load_config 的四条 sys.exit 提示）不含 URL 本身；唯一的 webhook 值落点是 config.json 与用户自行执行的 echo（SKILL.md 明示 chmod 600）。发信目标与密钥归属同一服务。第一遍结论成立。"
      },
      {
        "item": "「self 可自动发、others 需人工确认」是否只是文档口号（脚本是否真的挡）",
        "status": "ok",
        "detail": "脚本层面真实生效：recipient_scope 不在 {self, others} 即 sys.exit(1)；outbox 自动路径额外要求 payload.delivery 的 recipient_scope 必须为 'self'、recipient_label 与 webhook_sha256 必须与当前 config 完全一致，任一不符即拒绝（'Outbox item is not bound to this explicit self target'）。不是纯口号。"
      },
      {
        "item": "发信器指纹绑定能否被绕过（是否只在文档里说、代码里没验）",
        "status": "ok",
        "detail": "代码里确实验：send_wecom.py 同时比对 sender_path != running_sender 与 sha256_path(sender_path) != sender_sha256，两处不符都 sys.exit(1)。相应地，config 本身被篡改时这两个字段可被一起改写——这是该机制的边界，已在 security.injection_surface 第 ③ 点写明，不算被遗漏。"
      },
      {
        "item": "写盘是否可能损坏配置或放宽权限",
        "status": "ok",
        "detail": "set_recipient.py 用 O_EXCL 建临时文件、fsync 文件、os.chmod(tmp, mode) 后 os.replace，并对父目录 fsync；mode 取自原文件（stat.S_IMODE(path.stat().st_mode) or 0o600），不会放宽。tests 里 test_setter_preserves_webhook_and_mode 对 webhook 与权限有直接断言。结论成立。"
      },
      {
        "item": "references 与 SKILL.md 的规范条数/内容是否一致",
        "status": "ok",
        "detail": "SKILL.md 的 Message Best Practices 8 条（标题先行/状态vs增量/数字定义/地点用词/去噪音/精确不居高临下/验证指标/下一步）在 references/message_best_practices.md 中为 12 节（多出告警 vs 状态更新、告警额外规则、常见错误模板、发送前自检），属扩充而非冲突。"
      },
      {
        "item": "同一 pin 下本 skill 是否曾产出过旧侦查记录",
        "status": "ok",
        "detail": "data/analysis 目录中不存在 setup-notifications-via-wecom.json 的旧记录（本次为首次产出）。同 repo 其他 slug 有旧记录的情况见各自文件。"
      },
      {
        "item": "pin commit 与 skill.path 是否与任务书一致",
        "status": "ok",
        "detail": "git rev-parse HEAD = d5c4678cb5d4fd6acc9c922690df035dbd33d247；目录位于仓库根，相对路径 setup-notifications-via-wecom；本目录最后提交 878f947（2026-09-07）。GitHub API 复核 MIT / stars 1392 / pushed 2026-09-15T09:30:04Z。"
      }
    ],
    "level": 1,
    "level_label": "V1 已固定",
    "commit": "d5c4678cb5d4fd6acc9c922690df035dbd33d247",
    "sha256": "75c3e6008604ce8160c29a5d060495263c267c9da31abe8b8073d1c7366b5331",
    "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/setup-notifications-via-wecom.tar.gz",
    "sha256": "75c3e6008604ce8160c29a5d060495263c267c9da31abe8b8073d1c7366b5331",
    "commit": "d5c4678cb5d4fd6acc9c922690df035dbd33d247"
  },
  "original": {
    "github": "https://github.com/daymade/claude-code-skills/tree/main/setup-notifications-via-wecom",
    "path": "setup-notifications-via-wecom",
    "commit": "d5c4678cb5d4fd6acc9c922690df035dbd33d247"
  }
}