---
name: eval-session
description: 对一次已完成的 sid-code 任务会话做三段式评估(结果 + LLM 过程 + harness),通过轨迹找出 sid-code 自身的 bug 和可优化地方,先产出带 file:line 证据的评估结果,经人类二次确认后再派生 todo-fix 清单,目的是驱动 sid-code 后续优化。执行者可以是任意 agent(Claude Code / sid-code 自己 / 其他),被评对象始终是 sid-code 的轨迹+源码——两者解耦,需在 sid-code 仓库根跑脚本。当用户说"评估这个会话""复盘这次任务""做过程评估/结果评估""看看 sid-code 有什么问题""eval session"时触发。输入是一个完整会话 id(形如 20260723-101222-5ca82fd3);也接受轨迹目录路径,但需先从中提取出会话 id 再喂给工具。只做评估、只出报告,不改代码(修复另开会话)。
---

# eval-session:sid-code 任务会话三段式评估

## 目的锚点(每次执行前先默念一遍,防止跑偏)

**通过一次会话的轨迹,做结果评估 + 过程评估(LLM + harness),找出 sid-code 的 bug 和可优化地方,驱动后续优化。**

这句话里有两个常被做丢的重点:

1. **是"bug **和**可优化地方",不是只找 bug。** 任务跑对了但绕了远路、花了冤枉钱、某个 nudge 太弱、缺一个能力——这些都不是缺陷,却正是 sid-code 该优化的地方。只盯"崩没崩"会系统性漏掉一半价值。
2. **是"找出 sid-code 的问题",不是"评模型考了几分"。** LLM 过程评估不是目的,是**手段**——模型的每一次失误/低效,都要回问一句"harness 本可以拦住/让它更容易做对吗?",能翻译成 harness 改进的才是产出。评模型本身,评完就作废了。

> 术语统一:本 skill 把最终产出统称**发现(finding)**,分两类——**缺陷(bug)**(行为错误,该修)与**优化点(opportunity)**(不算错但值得改进:效率/成本/引导强度/能力缺失)。§3 报告两类都要出,别把优化点硬塞进"缺陷"栏,也别丢掉。

## 核心原则:结果先行,fix 是派生物

**评估结果本身就是交付物,不是通往 todo-fix 的过场。** 顺序不可颠倒:

```text
三段评估结果(主交付物,要写透)
   ↓  人类复核 + 二次确认(gate:未确认不进入下一步)
todo-fix 清单(派生物,每条都必须回指某条已确认的评估结论)
   ↓  修复(另开会话,本 skill 不做)
验证修改生效(按 todo-fix 里预置的"验证方法"逐条确认)
```

三条硬约束:

1. **评估结果要写透,不能压成一行表格。** 每段用叙述 + 证据展开,像给人看的分析报告,而不是待办清单的附录。宁可结果段长,也不要为了赶 todo-fix 而把判断依据省略。正向样本、边界、"措辞超出证据"这类细节都要保留——它们正是结果可信度的来源。
2. **todo-fix 的每一条都要可追溯到评估结论。** 格式:`fix 项 ← 源自 §X 发现 N`。没有对应评估结论的 fix 项不许出现(否则就是凭空臆想的改动)。
3. **人类是决策者,skill 只提供依据。** 报告必须专门列出"需要人类二次确认的判断项"(见 Phase 6),这些点没拿到人类确认之前,不能当成定论驱动修复。

## 工具与大模型的职责分层(谁产事实、谁下结论)

评估既依赖脚本也依赖大模型,但**分工必须清晰**——混了就会要么幻觉数字,要么把工具误报当结论:

| 层 | 谁做 | 产出 | 铁规则 |
| --- | --- | --- | --- |
| 确定性层 | trace-digest + 手写 bash/python | 计数、解析、配对、聚合等**可复现的事实 + 假设** | 大模型**不许口算/臆造数字**;该由工具算的必须真跑 |
| 验证层 | 大模型 | 把工具的假设逐条拿去 read 原始数据 + read 源码,证实/证伪 | 工具的假设**未经此层验证不许进报告**;拒掉假阳性 |
| 判断层 | 大模型 | 严重度、"缺陷 vs 取舍 vs 优化点"边界、修复方向、MEMORY 关联 | 任何脚本都做不了,只能大模型下 |

**一句话:工具产"事实+假设",大模型产"结论"。任何结论都不能停在工具未验证的输出上;任何该由工具算的数字都不能由大模型口算。** 脚本出错或遗漏时,由验证层兜住——而且**脚本自身的缺陷就是一条 harness 发现**(如"并行子代理误报循环"),按 §3 写进报告,流程因此自我改进。

## 目的与边界

对一次**已完成**的 sid-code 任务会话做系统评估,核心目的是**找出 sid-code(harness/工具本身)的 bug 和可优化地方**。

**本 skill 只评估、只出报告,自己不改任何代码。** 针对 sid-code 缺陷/优化点的实施在另一个会话做——本 skill 要为它铺好两件事:① 每个发现预置"验证方法"(修完怎么确认生效);② 明确哪些结论需人类拍板。

> **区分两个"改代码":** "本 skill 不改代码"指的是**评估动作本身**不动 sid-code 源码。但**被评估的那次会话**可能已经做了代码改动(如任务含"修复所有缺口")——那些改动是**交付物**,恰恰是结果评估要严查的对象(见 Phase 2 代码改动五关)。别因为"不改代码"就跳过对被评会话已落地修复的核查。

**三段是什么(输入源不同,别混):**

| 段 | 评什么 | 输入源 | 产出 |
| --- | --- | --- | --- |
| 一·结果评估 | 交付物是否可靠/准确 | 交付物 + 代码(ground truth) | 可靠性判定(逐条核对) |
| 二·LLM 过程评估 | 模型编排/委派/诚实度/效率好不好 | 轨迹(session.traj/events) | 模型表现 + 正向样本 + 短板(每条短板都要过"harness 桥") |
| 三·harness 评估 | sid-code 自身有什么 bug + 优化点 | 轨迹 + 代码 + §1/§2 的桥接产物 | 缺陷 + 优化点(根因/规模/复发/验证方法) |

> 第一段能不能做,取决于任务有没有可验证的交付物。纯问答/探索类任务可能没有交付物 → 第一段标"不适用",直接做二、三段。**但二、三段永远要做**——即便没有交付物,过程和 harness 层依然可能藏着 bug 和优化点。

## 执行环境约定(先分清"谁在评""评谁")

**执行本 skill 的 agent(Claude Code / sid-code 自己 / 其他)与被评估的对象是两回事,别混。** 被评对象永远是 **sid-code 的轨迹 + 源码**,执行者可以是任何 agent、cwd 也不保证在 sid-code 仓库。因此:

1. **两类路径分清**:
   - **被评对象的运行时产物**——`~/.sid-code/trajectories/sessions/`(轨迹)、`~/.sid-code/usage-ledger.jsonl`(账本)是 sid-code 运行时写死的**绝对位置**,和执行者是谁、cwd 在哪无关,直接用。
   - **需在 sid-code 仓库内跑的命令**——`bun scripts/trace-digest.ts`、报告输出目录 `docs/bugfixes/todo/eval/`、以及修复期的 `bun test`/`git stash`/`make build` 全都**相对 sid-code 仓库根**。执行前先确认当前 cwd 就是 sid-code 仓库根(`ls scripts/trace-digest.ts` 能命中);不在则先 `cd` 过去或用仓库绝对路径,别在别的 cwd 下盲跑导致"脚本找不到 / 报告写错地方"。
2. **MEMORY.md 交叉核对是"有则做"的增强,不是硬前提**:铁律第 4 条要查的 `MEMORY.md` 是**这台机器上为 sid-code 维护的项目记忆**。执行者若能读到(如就是本机 Claude Code / sid-code)就核对;读不到(换机器、无该项目记忆)则**跳过并在报告注明"未核对历史记忆,复发性判断置信度下降"**,不要因路径不存在而报错或卡住。
3. **sid-code 仓库根怎么定位**:优先用用户明示的路径;未明示时,从 `~/.sid-code` 或轨迹里的线索找,或直接问用户"sid-code 仓库在哪"。别假设 cwd 已经在那里。

## 铁律(不可跳过——这几条是评估可信的分水岭)

1. **每条结论必带证据**:`file:line`(代码)或实测数据(命令输出/统计),禁止臆测。写不出证据的判断降级为"假设",并给证伪条件。
2. **声称"测试通过 / 有单测闭环"必须真跑**:执行 `bun test <文件>` 并把 pass/fail 数贴进报告。**只读到测试文件存在 ≠ 测试通过**——这是最容易犯的过度声称。
3. **结论前先验证**:对交付物里的每条"已落地/已修复"声明,亲自 read 对应代码确认,不转述、不盲信(包括不盲信子代理的返回)。
4. **交叉核对 MEMORY.md(有则做)**:发现的 harness 问题,若能读到本机为 sid-code 维护的项目记忆(通常在 `~/.claude/projects/.../memory/MEMORY.md`),查是否已有记录——**复发的老问题**要显式标注(比一次性问题严重),新问题考虑提示用户存记忆。**读不到该记忆时**(换机器 / 执行者非本机 agent)按「执行环境约定 §2」跳过并注明,不硬卡。**MEMORY 引用的常量/阈值/`file:line` 要拿现码验一遍——记忆是时点快照,漂移很常见;记忆写 X、现码是 Y,这个漂移本身就是一条产出**(至少值得回填修正记忆,也可能揭示某处被静默改过。实证:20260723-140029 撞见 MEMORY 记 `PAIRING_TIMEOUT 600s`、现码 120s)。
5. **区分 trace-digest 的已知假阳性**(见下"陷阱"),别把工具的误报当成真缺陷写进报告。
6. **每条"模型的锅"都要过 harness 桥**(见 Phase 3.5):模型失误/低效不能只记进 §2 就算完,必须回问"harness 本可以拦住/让它更容易做对吗?",能翻译成 harness 改进的进 §3。**这是本 skill 出货的主通道,不是可选项。**
7. **比对两组计数/index 前,先确认它们数的是不是同一个东西**:trace 里存在多套 index 命名空间(如 collector 的 pair index 跑到 90、queryLoop 的 turnCount 只到 32、StreamPhase 的 obsIndex 用满整场循环),名字都叫 `index`/`turn` 但语义不同。**"某 index 在 N 之后消失/对不上"极易被误判成数据丢失 bug**,下结论前必须先 read 源码确认两边的 index 由谁分配(实证:20260723-140029 差点把"StreamPhase index 32 后消失"写成流事件丢失,核对后才发现是 turnCount vs pair index 两套命名空间——它反而成了真发现的证据)。凡跨事件类型比对计数,这一步不可省。

## 执行流程(半自动:机械首过 + 逐段人工核实)

> **"三段"与 Phase 的映射**:名字里的"三段"= Phase 2(结果)/ Phase 3(LLM 过程)/ Phase 4(harness),是评估的三块内容主体;Phase 0/1 是前置校验与首过,Phase 3.5 是跨段桥接,Phase 5/6 是落报告与派生 todo-fix。别把"三段"和多个 Phase 当成两套东西。

### Phase 0 — 输入校验 + 适评性分诊(preflight,必做,不可跳过)

**在跑任何评估前,先确认"评估目标"唯一、可评估、且值得评。** 这一步是防"静默评估错目标"+"在低产会话上白费力气"的闸门。

1. **拿到能唯一定位会话的 id。** 工具的 id 解析是"精确匹配 → 日期前缀匹配"(见 `digest.ts` 的 `resolveSession`):完整 id、或**日期开头的前缀**(如 `20260723-1012`)都能命中;但 **hash 后缀**(如 `5ca82fd3`)不是前缀,`startsWith` 匹配不到,别当成"输后 8 位就行"。
   - 用户给的是**轨迹目录路径** → 取路径最后一段目录名作为 id(如 `.../sessions/20260723-101222-5ca82fd3` → 用整段,或其日期前缀)。
   - 用户给的是 **hash 后缀 / 中段片段**(如 `5ca82fd3`)→ 前缀匹配无效,跑 `bun scripts/trace-digest.ts --list` 找完整 id。**注意 `--list` 只列最近 20 个**——目标会话更早时它列不出来,别据此判"不存在",直接去 `~/.sid-code/trajectories/sessions` 目录按后缀 grep 目录名拿完整 id。匹配到多个让用户选,0 个如实报告并停。
2. **绝不允许空参数跑默认值。** 空参数时 trace-digest 会**静默选"latest"**——这几乎必然评错对象。若用户没给 id,**停下来问**,或先 `--list` 列出候选让用户选,不要自作主张评最近那个。
3. **确认目标会话状态可评估。** 用 `--list` 或首过摘要头一行看:
   - 空会话(步骤 ≈1、0 token、`user_interrupt`,如敲个 "hi" 就退)→ **无可评估内容**,告知用户"这是空会话,没有值得评估的轨迹",不要硬凑三段。
   - `error` / `unknown` / 还在跑的会话 → 可以评,但要在报告显著位置标注会话**未正常收尾**,评估结论需考虑数据可能不完整。
4. **警惕"同 id 不同状态"。** 会话被续跑(resume)后,同一个 id 的步数/成本会变。若用户是针对"某次交付物"做评估,先确认当前轨迹与那次交付物对得上(比对步数/时间/交付物提及的动作),别拿续跑后的膨胀轨迹评一个早期交付物。
5. **适评性分诊(为"系统性找 bug"服务)。** 单个会话大概率是干净的——直接深挖一个**任意**会话,找到 harness 问题的期望产出很低。所以:
   - **用户指定了会话** → 照评,但在报告开头点明这次会话的"信号密度"(有无 error/hang/高成本/异常收尾/经过 compaction/子代理/plan mode),让读者知道期望值。
   - **用户只说"找找 sid-code 有什么问题"、没指定会话** → 别抓一个就评。先按 `references/analysis-cookbook.md` 的**批量分诊查询**扫最近一批会话,挑出高产候选(error 收尾 / 成本离群 / 步数离群 / warn.log 有本会话错误 / 触发过防线),列给用户选,或对 top-N 逐个评。**主动选样是"系统性发现"的主武器,不是可选项。**

校验通过、拿到唯一且可评估的会话后,才进入 Phase 1 首过。

### Phase 1 — 机械首过(必做)

```bash
bun scripts/trace-digest.ts <完整-session-id>
```

> 该命令相对 **sid-code 仓库根**执行(见「执行环境约定」)。先确认 cwd 在仓库根(`ls scripts/trace-digest.ts` 能命中),否则 `cd` 过去或用绝对路径。轨迹数据本身在 `~/.sid-code/`,脚本会自己去读,与 cwd 无关。

若命令报"未找到 session ..."→ 先排除"cwd 不对/脚本路径错",再回到 Phase 0 第 1 条(id 不完整/不存在),不要继续。

拿到 L0 事实层(机器可验证,带出处)、L1 假设层(带证伪条件)、工具序列、子代理执行、provider 健康、成本。**这是首过锚点,不是结论**——L1 假设必须逐条消解证伪条件后才能采信。

**trace-digest 不是全部,别只依赖它。** 它只做**单会话**首过,有已知假阳性,且不读源码、不做语义判断。凡它做不到的——跨会话聚合(如"X% 会话缺 SessionEnd")、自定义切片、定向验证某个假设——**自己写 bash/python 查询**(经验证的片段见 `references/analysis-cookbook.md`,含 `session.traj` 是单 JSON 非 JSONL 这类坑)。首过用现成脚本,别重造它已有的那一整套检测器;脚本盲区用手写查询补。

补充数据源(按需):

- `session.traj`(顶层 JSON,含 `trajectory[]`/`history`/`metadata`)——用 `python3 -c "import json;o=json.load(open('session.traj'))"` 解析,**不是 JSONL**。
- `events.jsonl`(hook 事件时间线)——统计事件类型、看有无 SessionEnd/TurnError、子代理时间戳。
- `warn.log`(WARN/ERROR 持久化)——注意区分"启动时对历史会话的诊断扫描"和"本会话的错误"。
- 交付物文件 + 其声称改动的源码。

**数据文件损坏/缺失的处理(轨迹错误):**

- `session.traj` **解析失败**(截断/非法 JSON,常见于会话被强杀)→ **不要放弃整场评估**:trace-digest 首过多半仍可用(它容错更强),`events.jsonl` 逐行独立、坏行可跳过。降级策略:以首过 + events 为准做二、三段,在报告显著位置标注"session.traj 损坏,部分过程细节缺失,结论置信度下降"。
- **某个数据文件缺失**(如无 `events.jsonl` / 无交付物)→ 对应的段标"数据缺失,无法评估"而非硬凑;缺 events 则 SessionEnd/子代理时序类结论标为"无法确认"。
- **首过与逐行解析结果打架**(如首过说 29 步、traj 里只有 10 步)→ 说明轨迹被截断或续跑过,以更保守的一方为准,并在报告里点出这个不一致本身(它可能就是一条 harness 缺陷线索)。
- 原则:**任何"数据不可信/缺失"都要显式写进报告**,绝不用缺失数据默默补全或臆测——宁可标"无法确认",不可假装评过。

### Phase 2 — 结果评估(写透,别压缩)

**先判交付物类型**——不同类型的核对深度不同,别一把尺子量到底:

- **文档类**(报告/方案/分析):核对其声明与 ground truth(代码/数据)是否一致,盯"过度声称"。
- **代码改动类**(改了源码/加了测试/修了缺口):除了"改没改",还要验**改得对不对、是不是空壳**。会话若做了修复(如任务含"修复所有缺口"),这一支必做,不能只看"文件动了"就算落地。

若有**文档类**交付物:逐条抽取**可验证声明**(如"X 已落地在 file:line""测试通过""缺陷 Y 未修复"),对每条 read 代码/跑命令验证 → 判定成立/不成立/部分/措辞超证据。**特别盯过度声称**:声称测试通过是否真跑?声称"全部落地"有无未覆盖项?

若有**代码改动类**交付物,逐个改动按下面五关核对(这几关是"真修复 vs 假交差"的分水岭):

1. **改动范围核对**:`git diff --stat`(或比对改动文件清单)确认实际改的文件与交付物声称的一致——没有偷偷多改、也没有漏改声称要改的。
2. **空壳检测**:改动是真实现还是占位/空函数/TODO?read 关键改动确认有实质逻辑。
3. **API 真实性**:改动调用的函数/字段/签名是否**真实存在**(read 被调方定位),不是幻觉 API。弱模型高发"调了个不存在的方法还测过了"。
4. **测试真实驱动目标路径**:新增/改动的测试是否真的走到了目标代码分支(read 测试断言 vs 目标代码,确认不是"测了个假路径"或恒真断言)。
5. **"测试通过"声称独立复核**:这是**最需警惕的过度声称**。不仅要真跑 `bun test`,若模型声称"某些失败是预先存在、与本次无关",要**独立验证**——`git stash` 改动后在干净树上重跑,确认失败确实预存在(别让真 bug 伪装成"预存在",也别把预存在甩锅给本次改动)。

无论哪类,产出都要有**明确可靠性结论 + 逐条核对表 + 值得单独点出的细节**(如"模型正确处理了某个容易漏的边界""某处措辞略超证据但不影响结论")。这些叙述细节不是可选项——它们是"结果为什么可信"的依据。

> **别在这里停:** 交付物里每一处"不成立/部分/措辞超证据",都是 Phase 3.5 的桥料——它常常指向一条 harness 缺陷或优化点(如"模型漏改了一个文件"背后可能是"harness 没给它足够的改动清单核对能力")。标记出来,带到桥。

### Phase 3 — LLM 过程评估(写透,含正向样本 + 成本基线)

从轨迹评估模型这次干得怎么样。至少覆盖:

- **宏观画像**:模型 / 结束原因 / 步数 / API 次数 / 耗时 / 成本 / 主循环 token vs 子代理 token。
- **成本/效率带基线判读(为"可优化地方"服务)**:光抄数字没用,要给出"贵不贵、绕没绕"的判断口径:
  - **同类对比**:能读到历史 eval 报告 / 账本时,拿同类任务的 API 次数、步数、成本做横比(如"同类审计任务通常 3 次 API,本次 8 次")。读不到基线就标"无基线,仅记录"。
  - **内部结构比**:重活是否压在子代理里(主循环 token 应显著小于子代理合计)?有没有本可并行却串行的 fan-out?有没有重复读同一文件/重复跑同一命令?
  - **离群即线索**:任何显著离群的成本/步数/耗时,即便任务成功,也要追一句"为什么"——它多半对应一条**优化点**(而非缺陷),带到 Phase 3.5。
- **编排结构**:任务拆解是否合理?fan-out 是否真并行(看子代理派发时间戳)?主上下文是否精简?
- **委派质量**:子代理 prompt 是否带足上下文 + 强约束 + 固定输出格式?agent 类型选对没(explore 只读 vs general-purpose)?
- **证据纪律与诚实度**:结论是否带 file:line?是否敢标"未完成/部分/不确定"?有没有对没读的东西下结论?
- **验证闭环**:该跑的验证(测试/构建)跑了没?
- **正向样本必须记**:做得好的地方作为同类任务模板参照(不是只挑毛病)。

产出:模型表现评估 + 正向样本 + 明确的过程短板(尤其"该验证没验证""该并行没并行""重复劳动"类)。**每条短板和每个离群点都要进 Phase 3.5 的桥,别停在"模型不行"。**

### Phase 3.5 — 跨段桥接(把"模型的锅/低效"翻译成 harness 发现)【本 skill 出货主通道】

这一步是三段之间最出货的地方,**不能跳**。目的:防止 §2/§3 发现的模型失误/低效大量沉淀成"模型不行"然后作废——它们本是 harness bug 和优化点的富矿。

对 §2、§3 里的**每一条**模型失误 / 低效 / 离群,逐条过这三问:

1. **harness 本可以拦住这个错吗?**(如模型"假称测试通过"→ harness 有没有强制跑测试的闸门?没有 → 一条优化点)
2. **harness 本可以让模型更容易做对吗?**(如模型漏改文件 → harness 有没有给出改动清单核对?nudge 够不够强?这类是你记忆里 `harness-llm-visibility-gap` 的来路)
3. **这个低效是 harness 造成的吗?**(如串行本可并行 → 是编排 API 不好用,还是模型没用?重复读文件 → 有没有缓存/去重机制?)

- **三问都答"否"(纯模型能力问题,harness 无能为力)** → 留在 §2 作为过程短板,**明确标注"已过桥,判定为纯模型问题,非 harness"**(让读者知道你没偷懒漏桥)。
- **任一问答"是"** → 翻译成一条 §3 发现(缺陷或优化点),带上"源自 §2/§3 第 X 条"的溯源。

> 反过来也做一次:§2 里模型**做得特别顺**的地方,是不是某个 harness 机制帮了忙?值得记为"harness 正向样本"(哪些机制在起作用,别在后续优化里误删)。

### Phase 4 — harness(sid-code)缺陷 + 优化点评估【重心】

从轨迹反查 sid-code 工具侧的问题。**关键:把"模型的锅"和"工具的锅"分开——只有工具侧可控的才算 harness 发现。** 输入有两路:① 轨迹里的异常信号(被动);② Phase 3.5 桥接产物(主动)。两路都要走。

**A. 异常信号反查(崩溃类,留下痕迹的):**

- 轨迹里的异常信号(错误、hang、成本异常、数据丢失)——追到是不是工具机制导致;
- 可观测性缺陷(该记的没记、误报、语义混淆);
- 数据完整性(轨迹/账本/成本落盘是否完整);
- 与 MEMORY.md 里已知缺陷的关联(复发?加重?波及面更广?)。

**B. 能力链路探针(静默类,不报错的——这类最容易被漏,必须主动查):**

崩溃有痕迹,但 sid-code 最值钱的一类问题**不报错**:信息被悄悄丢弃、该触发的没触发、判断悄悄放行。这类靠"等信号"永远抓不到,只能**主动巡查**。看这次会话经过了哪些链路,经过的就去查它的行为对不对:

| 链路 | 经过了就查 | 常见静默问题 |
| --- | --- | --- |
| **compaction / 上下文压缩** | 长会话被压缩后,关键信息(任务约束/已定决策)有没有丢?压缩后模型有没有"忘事"重做? | 静默丢信息、压缩边界切错 |
| **子代理 / workflow** | 子代理结果有没有真回注主循环?后台通知有没有出队?hook 有没有触发? | 承诺回注但从不出队(见记忆 `subagent-bg-notification-fix`) |
| **plan mode / todo** | 该触发 plan/todo 的长任务触发了吗?todo 有没有回注? | 触发率低、exit_plan 空转(见记忆 `long-task-omission-*`) |
| **权限 / hook** | 权限判定放行/拦截对不对?hook matcher 有没有过度匹配/漏匹配? | 规则静默失配(见记忆 `permission-hitl-*`、`hook-system-*`) |
| **reminder / nudge 注入** | 有没有重复注入幻影提醒?模型有没有误判"被截断/重播"? | 无去重无封顶刷屏(见记忆 `reminder-nag-replay`) |
| **成本 / 账本落盘** | 本会话成本入账本了吗?side-call 计了吗? | 只在 SessionEnd 落盘、影子调用漏计(见记忆 `trajectory-cost-call-undercapture`) |
| **续跑 / resume** | resume 后状态对得上吗?内部消息有没有泄漏到 TUI? | 冻结快照死锁(见记忆 `gitstatus-frozen-snapshot-deadlock`) |

> 这张表是**探针提示,不是封闭清单**——sid-code 在演进,发现新链路就补。目的是把评估从"等报错"改成"主动体检"。没经过的链路不用硬查,标"本会话未经过"即可。

**每个发现(缺陷或优化点)必须**:read 代码定位根因(file:line)+ 判类型(缺陷/优化点)+ 判严重度或收益 + 估波及规模(跨会话统计佐证更佳)+ 给方向 + **预置"验证方法"**(修完之后靠什么命令/断言确认真的生效——这是为后续"验证修改生效"铺路)。

### Phase 5 — 落评估结果报告(主交付物)+ 跨报告收敛

按 `references/output-template.md` 的结构,把 §0–§4(三段评估结果 + 澄清)写透,落到:

```text
docs/bugfixes/todo/eval/<session-id>-eval.md
```

(目录不存在则创建。统一路径 + 统一结构 → 历次报告可 diff,能看出同一 harness 问题是否复发。)

**跨报告收敛(防同一问题在多份报告里反复出现却从不聚合):** 落盘前,`grep` 一遍 `docs/bugfixes/todo/eval/` 下已有报告,看本次发现是否在历史报告里出现过:

```bash
# 在 sid-code 仓库根跑;换关键词为本次发现的根因文件/症状
grep -rl "collector.ts\|account.*落盘\|<本次发现关键词>" docs/bugfixes/todo/eval/ 2>/dev/null
```

- **命中历史报告** → 本次报告里显式标注"**跨报告复发**:同类问题已在 `<报告名>` 出现过 N 次",严重度相应上调(反复出现说明没被修 / 修了没生效)。这比单会话统计更能说明系统性。
- **未命中** → 标为"本报告首次记录"。

**此时先停下来把评估结果讲给用户听。** 结果是主交付物,要让用户看到完整的三段分析,而不是直接甩一张 fix 表。

### Phase 6 — 人类二次确认(gate)+ 派生 todo-fix

**先确认,再派生。** 报告的 §5 要专列"需人类二次确认的判断项"——凡是含主观取舍的地方都要摆出来请人拍板,例如:

- 严重度/优先级评级是否认同;
- "这是设计取舍还是缺陷还是优化点"这类边界判断;
- 优化点的收益估算是否值得投入(有些优化点收益 < 改动风险,该主动标"不建议动");
- 修复方向里的路线选择(如"增量落盘 vs 放宽兜底门槛");
- 波及规模的估算口径是否可接受。

**把这些点显式呈现给用户,等用户确认/修正后**,再在 §6 生成 todo-fix 清单。每条 todo-fix:

- `← 源自 §X 发现 N`(可追溯,不可凭空);
- 标类型(缺陷 / 优化点)+ 优先级(依据 = 已确认的严重度/收益/复发性);
- 带 **验证方法**(来自 Phase 4 预置的,修完照此确认生效);
- 明确"当前未实施,修复另开会话"。

> 若用户在会话中直接确认了,就据确认结果收敛报告;若用户不在场,报告要清楚标注"以下判断待人类确认后方可驱动修复",不能默认自己拍板。

## 后续:修复与验证生效(本 skill 不执行,但要交代清楚)

修复在另一个会话做。届时遵循项目 CLAUDE.md 验证铁律:改完跑 `bun test` 全量 + `make build`,**并按本报告 todo-fix 里每条预置的"验证方法"逐条确认修改真的生效**(如"改完后重新评估一个同类会话,确认账本已有该会话记录"),而不是只看编译通过就算完。本 skill 的职责是把这些验证方法提前写好,让修复会话有据可依。

## 陷阱:trace-digest 的已知假阳性(别当真缺陷)

这些是工具的检测局限,核实后多半不是本会话的真问题:

- **`session_end_missing`**:SessionEnd 只在退出路径触发,交互会话任务完成后仍在 REPL → 缺 SessionEnd 是常态,**不等于 hang/崩溃**。看是不是 `end_turn` 干净收尾 + heartbeat 正常。(注:这背后**确实**有"成本不落账本"的真缺陷,但那是另一回事,别和"进程被杀"混淆。)
- **`repeated_tool_shape_run` / `hypothesis_stuck_loop`**:shape 检测只按"工具名+首参"连续计数,**不看时间戳**。并行 fan-out 的多个 sub_agent(同一时间戳派发)会被误报成"原地打转"。逐个比对派发时间戳/参数再判。
- **工具序列 `✗`**:可能只是"截断读取"(大文件只读了一段)或并行派发标记,**不一定是失败**。以 `subagent_execution_outcome` 的成功/失败计数为准。
- **`warn.log` 里成批的"hang/僵尸会话"**:通常是**启动时**对历史会话的诊断扫描,不是本会话的问题。看时间戳和 session_id 是否本会话。
- **`model_call_unpaired_watchdog`(标[高]"疑似 hang")**:配对看门狗阈值仅 2 分钟(`collector.ts` 里 `PAIRING_TIMEOUT_MS`,grep 确认当前值),慢模型(glm/deepseek)+长上下文下单轮生成超阈值是常态,会被误报成 hang。**核实法**:比对该 index 的 `BeforeModel → AfterModelRaw` 真实耗时 + `AfterModelRaw` 的 `output_tokens`(大输出 + 流在走 = 慢响应,非 hang;实证 20260723-140029 index=60 是 222s 出 14006 token 的慢响应被误报)。注:**这个误报机制本身是坐实的真 harness 缺陷**——(a) 阈值偏紧;(b) `stream_snapshot` **结构性永远为 null**:看门狗用 collector 的 pair index 查快照,StreamPhase 却用 queryLoop 的 turnCount 注册,两套 index 命名空间 key 从不匹配(不是"loopId 拿不到",是 index 数值本身对不上,见铁律 7 + MEMORY `[[watchdog-snapshot-index-mismatch]]`)。核实后写进 §3,别只当假阳性略过。
  > 行号会随 collector.ts 改动漂移(该文件很活跃),上面只给符号名(`PAIRING_TIMEOUT_MS`/`getStreamSnapshot`/`turnCount`),写报告前用 `grep -n` 现查行号,别照抄 skill 里的旧行号。
- **`session-summary.json` 的错误字段(发现 3 已修)**:现在有三个字段,分诊/报告用对键:
  - `real_errors`:**诚实错误计数**——仅硬错误信号(`is_error`/TurnError/errors.jsonl/退出 error/侧调用失败/数据损坏),不含 L1 假设与假阳性。**批量分诊主键 = `select(.real_errors>0 or .high_severity_anomalies>0)`**,写报告说"N 个真错误"用这个。
  - `anomalies_count`:high+medium **异常**总数(旧 `errors` 语义,**含假阳性**如 watchdog 慢响应 / stuck_loop),仅供参考。
  - `errors`:已弃用,= `anomalies_count` 的别名(向后兼容旧脚本),**别再用它当分诊主键**。
  - 背景:修复前 `errors` 名实不符(叫 errors 实为 anomalies),假阳性灌水把干净会话误选成"高产候选"。实证 20260723-140029:`errors:3` 但真错误只 1(LSP 超时)。慢响应现已降级为 [低]`model_call_slow_response`,不再进 `high_severity_anomalies`。
- **`CACHE_BREAK`(warn.log)**:warn.log 若已标"本地前缀 hash 未变 → 疑为服务端缓存波动,本地不可控",就是**服务端波动,非 sid-code 缺陷**——归因已正确,别再花时间"修缓存"。反是 harness 归因正确的正向样本(可记进 §2.5)。

## 反哺本 skill:发现新陷阱/新纪律就回填(常驻,不是可选项)

cookbook §三 已定"脚本自身的缺陷是一条 harness 发现"——但那只反哺 `trace-digest`。**本 skill 自己也要在每轮评估后自我进化**:一轮评估里若撞见 **SKILL.md 陷阱节没列的新假阳性**、**一条本可避免的"差点写错"**、或**一个可复用的验证纪律**,它们默认只会死在那份报告里,下一个评估者还得重踩。所以:

- **评估收尾时问一句**:这轮有没有遇到"陷阱节没写、但下次还会坑人"的东西?(新假阳性 / 数据格式坑 / index-namespace 类误判 / MEMORY 漂移模式 / 查询 typo 教训……)
- **有则回填**:补进 SKILL.md「陷阱」节或「铁律」,或 cookbook 的查询片段。**带上实证会话 id 做锚点**(如"实证 20260723-140029"),让后来者能追。回填是 skill 维护动作,**不受"本 skill 不改代码"约束**——那条约束管的是被评的 sid-code 源码,不是 skill 自己的文档。
- **尺度**:只回填"可复用、跨会话成立"的教训;一次性的会话细节不进 skill(那是报告的事)。拿不准就在报告的"记忆建议/skill 建议"里提一句,交人类决定,别擅自塞。
- 本节自身就是这么来的(2026-07-23 一轮评估反哺):新增了铁律 7、陷阱节 3 条(errors 字段 / CACHE_BREAK / watchdog 快照 null 收口)、cookbook heredoc 模板。

## 完成判据

- Phase 0 通过:目标是**唯一、可定位、可评估**的会话(非空参数默认值;完整 id 或能唯一命中的日期前缀均可,hash 后缀需先转成完整 id);空会话/损坏轨迹已按降级策略处理并在报告标注;无指定会话时已做批量分诊选样。
- 执行环境已厘清:脚本在 sid-code 仓库根跑(cwd 确认过),或已注明用绝对路径;MEMORY.md 读不到时报告已注明"未核对历史记忆"而非卡住。
- 报告落在 `docs/bugfixes/todo/eval/<session-id>-eval.md`。
- **§1–§3 三段评估结果写透**:每段有明确结论 + 逐条证据 + 关键细节/正向样本,不是压缩表格。
- 每条结论带 `file:line` 或实测数据;假设带证伪条件。
- 凡声称"测试通过"处,报告里有对应 `bun test` 的实跑输出。
- **若被评会话含代码改动**:结果评估过了 Phase 2 五关(范围/空壳/API 真实性/测试驱动/测试通过独立复核),尤其"预存在失败"经 `git stash` 对照证实。
- **Phase 3.5 桥接已做**:§2/§3 每条模型失误/低效都有归宿(翻译成 §3 发现,或明确标"已过桥、纯模型问题");成本/效率有基线判读或"无基线"标注。
- **Phase 4 双路都走**:异常信号反查 + 能力链路探针(经过的链路都查过,未经过的标注);发现同时含**缺陷和优化点**两类(若确实只有一类,说明理由)。
- Phase 5 跨报告收敛已做:本次发现已 grep 历史报告,复发的已标注。
- §5 列出"需人类二次确认的判断项",且 todo-fix(§6)明确标注"待确认后驱动修复"。
- §6 每条 todo-fix 都 `← 源自 §X 发现 N`(可追溯)+ 标类型(缺陷/优化点)+ 带优先级 + 带"验证方法"。
- 结尾一句话:本会话最值得先动的 sid-code 问题是什么(bug 或优化点,依据 = 已确认的评估结论)。
- **反哺自检**:这轮若撞见陷阱节没列的新假阳性/新纪律/查询坑,已按「反哺本 skill」节回填(或在报告里提请人类决定),没让它只死在报告里。
