{
  "schemaVersion": 1,
  "slug": "subtitle-cue-timing-validation",
  "locale": "zh",
  "evidenceClass": "executed-local-fixture-not-provider-generation",
  "providerModelTest": false,
  "productionTaskRun": false,
  "runCommand": "node run-recipe.mjs --out ./my-run",
  "environment": {
    "nodeVersion": "v24.18.0",
    "ffmpeg": null
  },
  "title": "SRT 字幕时序校验：重叠、零时长与媒体边界",
  "description": "实际运行纯文本 SRT 校验器，检查三条合法字幕与六份原创错误文件，不涉及字体发现或字幕烧录。",
  "goal": "渲染前拒绝序号歧义、零时长、重叠和超出片尾的字幕。本配方只覆盖明确声明的简单 SRT 子集与输入的两秒媒体边界。",
  "preparation": [
    "只需要 Node.js，不需要第三方包或 FFmpeg。duration.json 明确给出 2000 毫秒媒体边界。",
    "查看 valid.srt：第一条 0–700ms，第二条 700–1400ms，第三条 1500–2000ms；允许相邻字幕，也允许最后结束点等于媒体时长。",
    "保留严格的 HH:MM:SS,mmm --> HH:MM:SS,mmm、连续序号和非空文字。夹具是纯文本，不承诺字体或烧录结果。"
  ],
  "steps": [
    {
      "title": "01. 解析前先写清时序规则",
      "body": "本例使用整数毫秒、从一连续编号、不允许重叠、结束必须晚于开始。媒体边界是明确输入，脚本不会探测真实视频时长；第三条之前的 100 毫秒空隙是刻意保留。"
    },
    {
      "title": "02. 实际解析合法字幕",
      "body": "运行命令后检查 cue-table.json，其中保存三条真实解析的开始与结束数值。开始恰等于上一条结束可以通过，末条也允许恰在 2000 毫秒结束。"
    },
    {
      "title": "03. 重放六份错误字幕",
      "body": "脚本写出并测试重叠、零时长、超边界、错误序号、毫秒格式错误及分钟越界变体。每项预期失败都记录具体异常；即使时间串外形正确，分钟为60仍不合法。"
    },
    {
      "title": "04. 把时序结果交给独立渲染环节",
      "body": "核对九项断言，把时间表与原始 SRT 成套保存。字形覆盖、换行、阅读速度、HTML 扩展与实际画面需要另验；本包不包含 CJK 字体清单或烧录字幕视频。"
    }
  ],
  "acceptance": [
    "合法 valid.srt 实际解析为三条整数毫秒记录。",
    "第二条开始等于第一条 700ms 结束时可以通过。",
    "最后一条恰在 2000ms 媒体边界结束可以通过。",
    "重叠与零时长变体分别因不同原因被拒绝。",
    "2001ms 结束与不连续编号均被拒绝。",
    "毫秒格式错误及分钟60均被拒绝，九项检查全部通过。"
  ],
  "troubleshooting": [
    {
      "symptom": "首尾相接的字幕被误报重叠。",
      "change": "将无重叠规则设为 start >= previousEnd，再实跑 700ms 相接边界。"
    },
    {
      "symptom": "恰好到片尾的末条被拒绝。",
      "change": "先核对输入 durationMilliseconds，确认后允许 end 等于该边界，同时继续拒绝 2001ms。"
    },
    {
      "symptom": "时间串格式正确，但字幕没有可见时长。",
      "change": "只调整 end，使其严格晚于 start，再检查与下一条重叠；不删除零时长规则。"
    }
  ],
  "ending": "合法时序是渲染环节的输入，不能证明指定字体可显示、字幕能放进画布或观众读得完。",
  "assetCaption": "原创 SRT 文本夹具、实际解析时间表与专门的字幕时间泳道图；未进行字幕渲染或模型生成。"
}
