{
  "$schema": "https://bestaiskill.com/schemas/agent-install/2.json",
  "skill": "ralph-wiggum-marketer",
  "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 scripts or commands: hooks/stop-hook.sh (Claude Code Stop event matcher \"*\", timeout 30s; executed whenever the agent attempts to conclude a turn)"
    },
    {
      "file": "scripts/ 或 SKILL.md",
      "summary": "Declares dynamic installation of external language package dependencies"
    },
    {
      "file": "网络端点",
      "summary": "Declares external network access: Indirect network surface 1: dependency installation fetching packages—package-lock.json records resolved https://registry.npmjs.org/..."
    },
    {
      "file": "本地工作目录",
      "summary": "File read/write and artifact output: data/content.db (SQLite): init.js uses const DB_PATH = './data/content.db' along with mkdirSync"
    }
  ],
  "verification": {
    "method": "第二遍独立重读 + 反查（不沿用第一遍结论，换角度找茬）：① 目录级反查：find 全量文件（含 .claude-plugin 与 .gitignore）确认资产面共 24 个文件、无 node_modules、无未申报脚本；② 行为反查：带『hook 究竟何时跑、几条出口』重读 stop-hook.sh 全部 101 行，逐分支核对 exit 0 / decision:allow / decision:block；③ 网络与凭证反查：全仓检索 fetch|axios|http.|API_KEY|api_key|process.env|curl|wget|token|secret，逐个核对命中项（仅 README 链接、package-lock resolved、${CLAUDE_PLUGIN_ROOT}、allowed-tools 的 WebFetch），确认无一处是脚本发起的网络/凭证读取；④ 启动路径反查（关键）：反向搜索谁创建 .claude/ralph-marketer-loop.local.md（全仓 grep ralph-marketer-loop），确认只有 hook 读改、cancel 删除、.gitignore 忽略，无任何命令创建；⑤ 写盘反查：核对 init.js 的 DB_PATH 与 mkdirSync、hook 的 sed -i、prompt.md 的 git add -A、ralph-init 的 cp 清单，确认每个写入路径真实存在；⑥ 功能声明 vs 实现反查：README 称 'autonomous copywriter'、SKILL 称 'Analyze your Twitter/LinkedIn'，仓库内却无抓取实现与 LLM 调用，逐条区分『prompt 承诺』与『代码能力』；⑦ 依赖反查：读 package-lock.json 顶层与 better-sqlite3 节点，确认 hasInstallScript=true 与 prebuild-install 链；⑧ 元数据反查：本地核实 license（无 LICENSE 文件，仅三处文本声明）与 gh api license=null 一致；⑨ 模板反查：确认 templates/progress.txt 引用的 scripts/ralph/ralph.sh 在仓库内不存在。",
    "second_pass": [
      {
        "item": "Stop hook 注册与执行时机",
        "status": "ok",
        "detail": "hooks/hooks.json 仅一条 hook：事件 Stop、matcher \"*\"、command ${CLAUDE_PLUGIN_ROOT}/hooks/stop-hook.sh、timeout 30；stop-hook.sh 逐行确认接收 stdin JSON、无状态文件即 exit 0、有状态文件才介入。"
      },
      {
        "item": "「循环如何被启动」——第一遍默认成立，第二遍证伪",
        "status": "discrepancy",
        "detail": "全仓 grep ralph-marketer-loop 只命中 3 处：stop-hook.sh 读取/更新、ralph-cancel.md 删除、.gitignore 忽略。没有任何命令或脚本创建该状态文件（ralph-marketer.md 全文仅描述迭代协议与 $ARGUMENTS，无写入指令）。结论：按仓库代码，/ralph-marketer 执行后若无外部手段创建状态文件，hook 不会拦停、循环不会启动——插件缺『arm loop』这一步，使用前需自行创建 .claude/ralph-marketer-loop.local.md（或依赖未入库的 ralph.sh，见下条）。"
      },
      {
        "item": "progress.txt 引用的 scripts/ralph/ralph.sh",
        "status": "discrepancy",
        "detail": "templates/progress.txt 第 37 行 'Loop script: `scripts/ralph/ralph.sh`' 与 README 的『Ralph is a Bash loop』叙事互相印证，但 find 全量文件确认仓库内不存在 ralph.sh；实际循环由 Stop hook 实现。该引用是遗留/未入库说明，照模板找脚本会扑空。"
      },
      {
        "item": "脚本内是否有网络调用或凭证读取",
        "status": "unlocatable",
        "detail": "对 .js/.sh 检索 fetch/axios/http./API_KEY/api_key/process.env/curl/wget/token/secret 零命中——即『未发现任何一处』；但无法据此证明运行期绝对无网络（npm 安装与 agent 的 WebFetch 属外部工具面），故按 unlocatable 记录，并在 security.reason 中以这两条外部面说明档位。"
      },
      {
        "item": "jq 依赖未声明，缺失时完成信号静默失效",
        "status": "discrepancy",
        "detail": "stop-hook.sh 用 jq 提取 .transcript[-1].content，但 README/命令文档均未提 jq 依赖，脚本以 '2>/dev/null || echo \"\"' 静默降级——jq 缺失时 LAST_OUTPUT 恒为空，<promise>COMPLETE</promise> 永不触发，循环只能靠 max_iterations 或 /ralph-cancel 结束。属真实使用陷阱（安全上无害，安全上是『无法自停』的风险）。"
      },
      {
        "item": "状态文件容错与 sed -i 跨平台兼容",
        "status": "ok",
        "detail": "iteration 非数字 → 告警 + rm 状态文件 + exit 0（防坏状态锁死）；max_iterations 非数字 → 回退 999999；sed -i 先试 BSD 写法（sed -i ''）再回退 GNU 写法；set -e 与 `||` 组合不会误退。"
      },
      {
        "item": "回注内容来源与拼装是否如实",
        "status": "ok",
        "detail": "PROMPT=$(sed -n '/^---$/,/^---$/!p' \"$LOOP_STATE_FILE\") 取 frontmatter 之后全文；空则 cat scripts/ralph/prompt.md；再空则一行默认文案。最终 cat << EOF 输出 {\"decision\": \"block\", \"message\": \"$SYSTEM_MSG\"} —— 与 Claude Code Stop hook 协议相符（协议本身由宿主定义，不在本仓可校验范围）。"
      },
      {
        "item": "SQLite 表数与 schema 完整性",
        "status": "ok",
        "detail": "init.js 内共 14 个 CREATE TABLE（founder_content、competitor_content、trends、research、communications、voice_profile、content_patterns、research_briefs、content_ideas、content_plan、drafts、critique_results、published、agent_log），与其 console.log 自述一致；content_plan/drafts 有 CHECK 枚举与外键，foreign_keys 已开启，DB 路径相对 cwd。"
      },
      {
        "item": "README 的 schema 描述 vs 实际表结构",
        "status": "discrepancy",
        "detail": "README「Database Schema」段只列 trends/research/communications/content_plan/drafts/published/agent_log 七张简表，字段也与实际不符（未提 voice_profile/content_ideas/critique_results/research_briefs 等），属未同步的旧文档；一切以 scripts/src/db/init.js 为准。"
      },
      {
        "item": "功能声明 vs 实际能力（夸大检查）",
        "status": "discrepancy",
        "detail": "SKILL.md 承诺 'analyze my content'、'Analyze your Twitter/LinkedIn'、'research competitors'，但仓库内无任何抓取/解析实现（无 HTTP 客户端、无平台 API），全靠宿主 agent 手工或 WebFetch 完成；'autonomous' 也由 hook + 宿主 agent 承担，插件自身无推理能力。这些是 prompt 层面的期望，不是代码保证的能力。"
      },
      {
        "item": "copywriter SKILL 的触发面与工作流",
        "status": "ok",
        "detail": "frontmatter name=ralph-copywriter（目录 skills/copywriter）、description 为触发短语清单；正文的七相位 DISCOVER→LEARN→RESEARCH→IDEATE→WRITE→CRITIQUE→ITERATE、Founder Test、Red Flags、Draft 1-5 迭代阶梯均逐字存在，且未声称自动化抓取或对接发布平台。"
      },
      {
        "item": "依赖与安装期行为",
        "status": "ok",
        "detail": "package.json 唯一依赖 better-sqlite3 ^11.0.0；package-lock 锁定 11.10.0 且 hasInstallScript=true，依赖链含 prebuild-install/bindings。属原生模块安装期构建，是常见供应链注意点，未发现本仓注入或混淆代码。"
      },
      {
        "item": "license 元数据核对",
        "status": "discrepancy",
        "detail": "仓库根无 LICENSE 文件（find 确认），只有 README 的 '## License → MIT' 与 package.json / plugin.json / marketplace.json 的 \"license\": \"MIT\" 文本声明；GitHub API license=null 与此吻合。README 叙事与 gh 元数据不一致，商用/二次分发前应要求作者补文件。"
      },
      {
        "item": "seed 数据真实性与外发风险",
        "status": "ok",
        "detail": "seed.js 样例一律指向 example.com / twitter.com/example / competitor-a.com 等占位域名，公司叙事为虚构的 'AI Writing Assistant 2.0' 与 TechCorp；无真实客户数据、无外发行为，可安全用于本地 bootstrap，但需提醒用户替换为自家素材。"
      }
    ],
    "level": 1,
    "level_label": "V1 已固定",
    "commit": "4c1f5f3bdfd2a55a0403bb4e30e5466337bebf41",
    "sha256": "525719530027f17dc889f340241e3312e178f8e5c36b13a9c5c563a3f2f781e4",
    "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/ralph-wiggum-marketer.tar.gz",
    "sha256": "525719530027f17dc889f340241e3312e178f8e5c36b13a9c5c563a3f2f781e4",
    "commit": "4c1f5f3bdfd2a55a0403bb4e30e5466337bebf41"
  },
  "original": {
    "github": "https://github.com/muratcankoylan/ralph-wiggum-marketer/tree/main/skills/copywriter",
    "path": "skills/copywriter",
    "commit": "4c1f5f3bdfd2a55a0403bb4e30e5466337bebf41"
  }
}