Update: 修正诊断 (2026-06-26)
原 issue 说"staleReason=null"是字段不存在导致的误判——CoverageInventoryStatus(数组条目)只有 freshness: "fresh" | "stale",没有 staleReason 字段。但"全部 stale"这个现象本身需要深究。
诊断脚本结果(53 条 coverage,2 fresh / 51 stale):
id=72 kind=all fpMatch=false fspMatch=true countMatch=true → content changed (advisory)
id=80 kind=cwd fpMatch=false fspMatch=false countMatch=false → file set grew 508→528 (real stale)
id=113 kind=cwd fpMatch=false fspMatch=true countMatch=false → file set grew 43→45 (real stale)
id=112 kind=cwd fpMatch=false fspMatch=true countMatch=false → file set grew 8→9 (real stale)
id=81 kind=cwd fpMatch=false fspMatch=true countMatch=false → file set grew 38→50 (real stale)
真正的 bug
"全部 stale"本身是正确行为——codex session 不断新增,coverage 当然 stale。但有两个缺陷:
-
CoverageInventoryStatus 缺少 staleReason 字段:用户/agent 无法区分 "advisory (content changed, 查询仍可用)" 和 "real stale (file set grew, 需要 sync)"。RequestedCoverageStatus 有 staleReason,但数组条目没有。
-
isAdvisorySourceContentStale 只作用于 requestedCoverage:coverage 数组里的条目无法享受 advisory 判定,全部裸露为 "stale",造成"全部 stale"的恐慌性 UX。
Fix
- 给
CoverageInventoryStatus 加 staleReason: "none" | "source_content_changed" | "source_set_changed" 字段。
- 在
toCoverageInventoryStatus 里计算 staleReason,逻辑复用 requestedCoverageStaleReason。
- (可选)给
CoverageInventoryStatus 加 advisory: boolean 字段,对 codex + source_content_changed 标 true。
Impact
- 6 个 agent 在真实数据测试中 3/6 报告 coverage 警告噪音。有了 staleReason 后,agent 可以判断"advisory 的忽略,real stale 的才 sync"。
- 论文 RQ3 (dynamic update robustness):区分 advisory 和 real stale 是 maintenance 模块的基本要求。
原始 issue (保留供参考)
shlog status --source codex --json 显示几乎所有 coverage 都是 freshness=stale。用户/agent 无法判断是否需要 sync。
Update: 修正诊断 (2026-06-26)
原 issue 说"staleReason=null"是字段不存在导致的误判——
CoverageInventoryStatus(数组条目)只有freshness: "fresh" | "stale",没有staleReason字段。但"全部 stale"这个现象本身需要深究。诊断脚本结果(53 条 coverage,2 fresh / 51 stale):
真正的 bug
"全部 stale"本身是正确行为——codex session 不断新增,coverage 当然 stale。但有两个缺陷:
CoverageInventoryStatus缺少staleReason字段:用户/agent 无法区分 "advisory (content changed, 查询仍可用)" 和 "real stale (file set grew, 需要 sync)"。RequestedCoverageStatus有staleReason,但数组条目没有。isAdvisorySourceContentStale只作用于requestedCoverage:coverage 数组里的条目无法享受 advisory 判定,全部裸露为 "stale",造成"全部 stale"的恐慌性 UX。Fix
CoverageInventoryStatus加staleReason: "none" | "source_content_changed" | "source_set_changed"字段。toCoverageInventoryStatus里计算 staleReason,逻辑复用requestedCoverageStaleReason。CoverageInventoryStatus加advisory: boolean字段,对 codex + source_content_changed 标 true。Impact
原始 issue (保留供参考)
shlog status --source codex --json显示几乎所有 coverage 都是freshness=stale。用户/agent 无法判断是否需要 sync。