{
  "$schema": "https://bestaiskill.com/schemas/agent-install/2.json",
  "skill": "text-message-animation",
  "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": "Local script or command execution: (Validation loop explicitly listed in SKILL.md) `npx remotion still TextThread out/f-{typing,mid,end}.png"
    },
    {
      "file": "网络端点",
      "summary": "External network access declaration: `npx remotion …` and batch stage `@remotion/bundler`/`@remotion/renderer`: fetched via official npm registry on first run"
    },
    {
      "file": "本地工作目录",
      "summary": "File I/O and artifact output: Remotion projects and out/thread.mp4 (or out/chat-001.mp4 … out during batch runs) generated by agent following this skill"
    }
  ],
  "verification": {
    "method": "第二遍独立重读（只读 pin commit 3a800e1e9b9635fa196a07b0143c80f7e9648558）：① 目录清单 `find skills/text-message-animation -type f` 返回 SKILL.md、两份 reference、以及 **0 字节** 的 README.md；② 逐行打开 bubble-recipes.md 与 data-driven.md，核对 SKILL.md 的每条主张是否在实现里成立——三 app 调色板表、尾巴规则、数组→时间线推导、spring 气泡 + 三点指示器、回执/时间戳/tapback、自动滚动、逐条音效、完整 Composition（calculateMetadata + zod schema）、HTML 预览 harness、批量渲染与 Lambda 建议，逐项可定位；③ 对全目录 grep `process.env|api[_-]?key|token|cookie|https?://` 确认 0 命中；④ 回读仓库根 scripts/{contact-sheet.sh,probe-mp4.sh,seek-shot.sh} 确认只调 ffmpeg/ffprobe/本地 playwright 截图；⑤ 复核「三张静帧要带 shipped props」与 reference §5「verify one before all」是否同一条纪律；⑥ 专项检查 cross-file 引用是否存在（发现 csvToThreads 未随包）。",
    "second_pass": [
      {
        "item": "「一次一条 + 打字只出现在收到的消息」是否真在代码里成立（防第一遍只读散文）",
        "status": "ok",
        "detail": "reference §5/§9 的组件把每条消息包在 `<Sequence from={f(m.typingStartMs)}>` 内，仅当 `m.typingLenMs > 0`（由 `m.from === \"them\" ? (m.typingMs ?? 800) : 0` 决定）才渲染 `<Typing />`，随后 `<Sequence from={f(m.enterMs - m.typingStartMs)}>` 弹泡；SKILL.md 也明写 \"Only received messages type; sent messages just pop\"。声明与实现一致。"
      },
      {
        "item": "数据驱动时长（calculateMetadata）是否真能自动出正确长度",
        "status": "ok",
        "detail": "SKILL.md 给 `durationMs = cursor + 1000` 并写 `Compute durationInFrames from durationMs in calculateMetadata`；reference §9 的 Composition 把 `durationInFrames={300}` 标为默认值并由 `calculateMetadata` 覆盖为 `Math.ceil((durationMs / 1000) * 30)`，§4 再次强调 \"never hand-set the duration\"。三处自洽。"
      },
      {
        "item": "reference 示例 import 的模块是否随包分发（第一遍未察觉）",
        "status": "discrepancy",
        "detail": "data-driven.md §5 的批渲染脚本写着 `import { csvToThreads } from \"./csvToThreads\";`，但仓库内并不存在 csvToThreads 文件（全仓仅 .md 与 .sh/.git）。属示意代码：照抄会直接报模块不存在，读者需按 §3 的 CSV 列约定自写映射。同型问题在 CSV 示例里也可见（示例行 `2,Alex,me,no,,400,read` 省略了线程首行）。对 pin commit 有效的真实出入，非虚假能力声明。"
      },
      {
        "item": "音效能力落地是否需要用户自备资产",
        "status": "discrepancy",
        "detail": "SKILL.md 与 reference §8 都用 `staticFile(m.from === \"me\" ? \"send.mp3\" : \"receive.mp3\")`，但仓库内不含任何 mp3；data-driven.md 只在 Tips 里提醒 \"Keep `send.mp3` / `receive.mp3` / fonts in `public/`\"。结论：音效同步是能力，但前置资产（发/收提示音、字体、头像）必须由用户提供——SKILL.md 的输出清单「One pop/ding per message」在缺资产时会静默退化。"
      },
      {
        "item": "「轻量预览（`?t=N`）」与仓库 Light tier 脚本的契约是否真的对齐",
        "status": "ok",
        "detail": "bubble-recipes.md §10 的 HTML 里实现了 `const t = new URLSearchParams(location.search).get(\"t\"); if (t !== null) { tl.pause(); tl.seek(parseFloat(t)); }`，与 scripts/README.md 描述的 seek-shot.sh 契约（页面 load 时 `tl.pause(); tl.seek(t)`）逐字对应。三包中只有本 skill 真能用上 seek-shot.sh。"
      },
      {
        "item": "「one of the highest-retention faceless short-form formats」是否有据",
        "status": "unlocatable",
        "detail": "SKILL.md 开头断言本格式为最高留存的 faceless 形式之一，仓库内无数据、无引用、无来源标注；本次为只读侦查，不验证该断言，仅记为文档声明。"
      },
      {
        "item": "包间一致性：同为 2026-06-22 发布的三个 iart 包，skill 目录结构是否统一",
        "status": "discrepancy",
        "detail": "tiktok 包四个 skill 各带人读 README（1377–1494 字节）；本仓库的 text-message-animation 与 youtube 包的两个 skill 的 README 均为 **0 字节**。功能不受影响（README 非 skill 加载所必需），但包间文档完整度不一致，属可核查的结构出入。"
      }
    ],
    "level": 1,
    "level_label": "V1 已固定",
    "commit": "3a800e1e9b9635fa196a07b0143c80f7e9648558",
    "sha256": "fdd9560a3ce85697db0232e13cb5bf0673e056cefba6d97d5b3ba87da81d4c32",
    "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/text-message-animation.tar.gz",
    "sha256": "fdd9560a3ce85697db0232e13cb5bf0673e056cefba6d97d5b3ba87da81d4c32",
    "commit": "3a800e1e9b9635fa196a07b0143c80f7e9648558"
  },
  "original": {
    "github": "https://github.com/iart-ai/text-message-video-skills/tree/main/skills/text-message-animation",
    "path": "skills/text-message-animation",
    "commit": "3a800e1e9b9635fa196a07b0143c80f7e9648558"
  }
}