{
  "$schema": "https://bestaiskill.com/schemas/agent-install/2.json",
  "skill": "pr-to-video",
  "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 script or command: node <SKILL_DIR>/scripts/project-dir.mjs --pr \"$PR\" (resolves project directory; configurable via PR_TO_VIDEO_P"
    },
    {
      "file": "网络端点",
      "summary": "Declare external network access: GitHub: all PR reads go through gh (github.com + api.github.com), gh handles auth and retries; large PR file lists use paginated API calls"
    },
    {
      "file": "本地工作目录",
      "summary": "File I/O and artifact output: Within PROJECT_DIR (never in caller repo): capture/{pr.json,diff.patch,extracted/{tokens.json,"
    }
  ],
  "verification": {
    "method": "第二遍独立重读 + 反查：① 全量文件清单核对（含隐藏）= SKILL.md + 5 份 references + 1 份 sub-agents/frame-worker.md + scripts/（含 scripts/lib/ 与 4 个 *.test.mjs）共 33 个，与 skills-manifest.json 的 files=33 一致；② token 扫描（http(s) URL / fetch( / process.env / execFileSync|spawnSync|spawn( / writeFile|mkdir / TOKEN|KEY|SECRET）逐条打开核对来源；③ 逐条回查 external_deps 的调用点在源码中真实存在（非文档推测）；④ 找反例：是否存在未声明的网络调用、隐藏脚本、混淆内容；⑤ 把 SKILL.md 的声明与脚本实际能力逐项对照。",
    "second_pass": [
      {
        "item": "gh 凭证是否真被使用（橙档证据之一）",
        "status": "ok",
        "detail": "fetch-pr.mjs 顶部注释写明「gh runs HERE so auth / not-found / private-repo errors surface with gh's own stderr and exit 1」，实现里第一步就是 `if (!ghTry([\"auth\", \"status\"]).ok) { die(\"gh is not authenticated — run: gh auth login\"); }`，随后 pr view / api 分页 / pr diff 三处都用同一 execFileSync 包装。调用点真实存在。"
      },
      {
        "item": "HeyGen 凭证与 TTS/BGM 实现到底在谁身上（避免把别家行为算进档位）",
        "status": "ok",
        "detail": "本 skill 的 scripts/audio.mjs 头注释自述「The TTS / BGM / SFX implementation no longer lives here: it is the shared engine at ../../media-use/audio/scripts/audio.mjs」，实现只做 SCRIPT/STORYBOARD → audio_request.json 的映射与回写；凭证读取发生在被指名的姊妹 skill 内。按范式「他人 skill 被指名调用只写进 reason、不作档位依据」，橙档依据只用本目录自身可取证的两条：SKILL.md 明写音频共用 ~/.heygen 凭证，以及 fetch-pr.mjs 的 gh 凭证依赖。"
      },
      {
        "item": "头像下载的防护是否真实（是否只是口号）",
        "status": "ok",
        "detail": "fetch-people-avatars.mjs 里有 AVATAR_HOSTS 白名单 + isAllowedAvatarUrl（拒绝非 GitHub 主机）与 isUnderProject（写入路径必须在项目目录内，防 ../../ 逃逸），并以 softExit 保证任何失败都 exit 0；注释解释了 github.com/<login>.png 302 到 avatars.githubusercontent.com 属同主控重定向。防护与注释一致，非表面文章。"
      },
      {
        "item": "「无 asset-staging 步骤」的声明与随包代码是否一致",
        "status": "discrepancy",
        "detail": "SKILL.md Step 4 明写 `There is **no asset-staging step** — the only real assets are the credits avatars, already in `assets/`。`，但 scripts/lib/assets.mjs 的头注释仍写着「Shared by stage-assets.mjs (Step 4 close, BEFORE the frame workers run) and assemble-index.mjs (Step 5, idempotent backstop)」，而 **pr-to-video 目录内并不存在 stage-assets.mjs**（该脚本只存在于同仓 product-launch-video 与 music-to-video），assemble-index.mjs 第 521 行也仍在注释里引用它。结论：这是复用姊妹 skill 时残留的过期注释（audio.mjs 自述该适配层在复用者之间「intentionally identical」，可解释来源）；实际行为与 SKILL.md 一致（只有 assemble-index 作为幂等兜底暂存头像），但读者若去找 Step 4 的 stage-assets 会找不到——对 pin commit 有效的真实出入。"
      },
      {
        "item": "是否漏掉未声明的网络调用",
        "status": "ok",
        "detail": "全目录 URL 命中仅 5 处：两处 gsap CDN（assemble-index.mjs 与 captions.mjs，产物期）、一处 ingest.mjs 的 `https://github.com/${login}.png?size=200` 头像 URL、两处测试文件里的 PR fixture URL；fetch( 仅出现在 fetch-people-avatars.mjs（带白名单）；无其它隐藏端点。"
      },
      {
        "item": "「Step 1 无 capture、只读 gh」与脚本能力是否相符",
        "status": "ok",
        "detail": "fetch-pr.mjs 只写 capture/pr.json 与 capture/diff.patch（头注释明确 no scratch dir），ingest.mjs 是纯离线变换，两者都不抓网页；Quick Reference 亦写明「no Step 1 capture」。与 description「the input is a code change, not a website」一致，无夸大。"
      }
    ],
    "level": 1,
    "level_label": "V1 已固定",
    "commit": "d2f0bc7f34837da54ae22063772d75d75ce26477",
    "sha256": "8f260d47a576b3e2498a104c79020f445f2d1f58e77b31de7b08f377a1a5886d",
    "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-28/pr-to-video.tar.gz",
    "sha256": "8f260d47a576b3e2498a104c79020f445f2d1f58e77b31de7b08f377a1a5886d",
    "commit": "d2f0bc7f34837da54ae22063772d75d75ce26477"
  },
  "original": {
    "github": "https://github.com/heygen-com/hyperframes/tree/main/skills/pr-to-video",
    "path": "skills/pr-to-video",
    "commit": "d2f0bc7f34837da54ae22063772d75d75ce26477"
  }
}