{
  "head": "0baa9ebe8b7f9ecc46f675acbf1f56ac65378957",
  "findings": [
    {
      "id": "AUDIO-N01",
      "p": 1,
      "title": "音频补发布把曾发布对象的人工待发布草稿一并发布",
      "file": "application/src/main/java/cn/jojo/cc/biz/service/english/dict/impl/EnglishAudioBackfillBizServiceImpl.java",
      "start": 168,
      "end": 176,
      "trigger": "导入/补录无音频词已发布且有在途TTS；运营上传人工音频、改翻译并保存，未点发布；TTS随后completed。",
      "mechanism": "编辑保留hasPublished=1并置status=0；completed发现人工音频仍返回true；queryInFlight只检查hasPublished而非当前草稿状态，调用完整publishWord/Phrase，锁内重读当前主表、翻译、全部变体发布。",
      "impact": "未审核翻译、改名或变体配置进入PROD，待发布状态被系统改为已发布，违反Spec6只改不发布正式库完全不变。",
      "counter_evidence": "人工音频不会被TTS覆盖；从未发布hasPublished=0确实不自动发布。Spec17自身写hasPublished=1补发布，与草稿隔离冲突，需设计裁决而不能说仅实现漏判。",
      "kind": "相对e9f2fb1b新增异步链路",
      "evidence_status": "当前源码确定机制，未跑业务环境",
      "validation": "当前原方法逐字抽取隔离javac探针已执行，见audio-probe/results.txt；外围服务/DAO替身，未连业务环境",
      "evidence": "audio-probe/results.txt"
    },
    {
      "id": "AUDIO-N02",
      "p": 2,
      "title": "completed下载永久失败与查询异常均绕过超时收口",
      "file": "application/src/main/java/cn/jojo/cc/biz/service/english/dict/impl/EnglishAudioBackfillBizServiceImpl.java",
      "start": 248,
      "end": 292,
      "trigger": "状态持续completed，但下载404/过期/OSS保存失败；或状态查询持续报错；提交时间超过1800秒。",
      "mechanism": "elapsed超时只位于null/running分支；query异常直接return，completed保存null也return并保留任务。每轮ORDER BY taskTime,id LIMIT batch重复拿最老行。",
      "impact": "该词永久无音频且不再补提交；当坏任务达到batch还会饿死后续在途任务。",
      "counter_evidence": "null/running超时确实cancel并清理，普通一过性下载失败下轮能恢复；问题限定持续失败。",
      "kind": "相对e9f2fb1b新增异步链路",
      "evidence_status": "当前源码确定机制，未跑业务环境",
      "validation": "当前原方法逐字抽取隔离javac探针已执行，见audio-probe/results.txt；外围服务/DAO替身，未连业务环境",
      "evidence": "audio-probe/results.txt"
    },
    {
      "id": "AUDIO-N03",
      "p": 2,
      "title": "失败上限只统计提交抛错，平台终态失败与超时会无限重新提交",
      "file": "application/src/main/java/cn/jojo/cc/biz/service/english/dict/impl/EnglishAudioBackfillBizServiceImpl.java",
      "start": 151,
      "end": 157,
      "trigger": "平台submit一直成功，但每次合成都failed/cancelled或running超时。",
      "mechanism": "submit成功立即clearFailCount；终态失败和超时只清任务号、不增加失败计数；下轮pending重新提交；永远达不到maxRetry=3。",
      "impact": "同一无效词反复消耗合成配额，违反Spec17失败3次停止和配置同一行最多提交次数。",
      "counter_evidence": "提交API连续抛错确实计数并停手7天；这不是所有失败均无上限。",
      "kind": "相对e9f2fb1b新增异步链路",
      "evidence_status": "当前源码确定机制，未跑业务环境",
      "validation": "静态顺向和反向调用核验；未执行Maven、未访问业务DB/TTS"
    },
    {
      "id": "AUDIO-N04",
      "p": 2,
      "title": "达到提交失败上限的最早ID持续占满候选批次，后续词无法补音频",
      "file": "application/src/main/java/cn/jojo/cc/biz/service/english/dict/impl/EnglishAudioBackfillBizServiceImpl.java",
      "start": 143,
      "end": 146,
      "trigger": "最小ID的batch条IMPORT/AUTOFILL词提交连续失败达到上限，随后TTS恢复且还有更大ID待生成词。",
      "mechanism": "SQL先按ID升序LIMIT batch；maxRetry仅业务循环内判断后return，未推进游标/排除冷却行；7天计数TTL内每轮仍选择同一批。",
      "impact": "后续健康词最多7天也无合成任务；批次条数配置变小放大此影响。",
      "counter_evidence": "不是数据库全量饥饿，限某表前batch被失败上限占满；7天过期或人工补齐能释放。",
      "kind": "相对e9f2fb1b新增异步链路",
      "evidence_status": "当前源码确定机制，未跑业务环境",
      "validation": "静态顺向和反向调用核验；未执行Maven、未访问业务DB/TTS"
    },
    {
      "id": "AUDIO-N05",
      "p": 2,
      "title": "异步回填只更新音频列，完整性及教研缓存保持旧值",
      "file": "infrastructure/repository/src/main/java/cn/jojo/cc/core/service/impl/english/EnglishWordCoreServiceImpl.java",
      "start": 301,
      "end": 316,
      "trigger": "导入词已有音标和翻译，唯一缺音频completeness=0；TTS成功回填。",
      "mechanism": "markAudioCompleted只set音频和清任务两列，不重算completeness；回填服务不调用教学缓存失效；补发布复制JY完整性0到PROD而不重算。",
      "impact": "即使最终音频齐全，管理筛选仍有缺失、RPC complete=false；已缓存TEACHING详情仍可无音频直到常规过期。",
      "counter_evidence": "人工保存走mergeForCompleteness会重算；缺音标或翻译词仍应不完整，不能用它们验证本问题。",
      "kind": "相对e9f2fb1b新增异步链路",
      "evidence_status": "当前源码确定机制，未跑业务环境",
      "validation": "静态顺向和反向调用核验；未执行Maven、未访问业务DB/TTS"
    }
  ],
  "previous": {
    "19": "最新Spec5.1新增mp3/wav门槛；白名单代码仍在但已不应按旧契约定缺陷，Spec5.2/Plan02无格式校验仍冲突",
    "20": "当前saveWord采用mergeForCompleteness；人工省略audioUrl必填拦截，原误标路径已修复"
  }
}