Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JUei7K13cYxLHE3Axe4A45
7.0 KiB
7.0 KiB
验收修复单 · D9 自建探针只活在内存里:答题报 stale_probe、GET 无卡、idle 立刻 superseded(2026-09-16)
0. 基线与验收对象
- 验收对象:
227a7571+8d7dfbf0(任务书TASK-rectification-dead-d9-choice-20260916.md,已合入并部署 staging)。 - 代码基线:
8d7dfbf0。分支:codex/rectification-dead-d9-choice-fix-20260916。 - BUG 段:BUG-915 起(基线最大 BUG-914)。
- 门禁数字(本机 Linux,
node_modules软链,next build --webpack):tsc0 错;lint 0 error / 116 warning;npm test3414 条、31 红,失败清单与基线05cf20fb(3405 条、31 红)逐条相同;Python 定向refinement_packet/event_probes/engine_memoization63 绿。门禁本身是绿的,红在生产路径没被测试覆盖。
1. 验收结论
| 项 | 结论 | 证据 |
|---|---|---|
| T1a 不再借最高增益探针 | 通过 | inference-adapter.ts:553 const next = matched;测试断言 probe_id 不再是 D24 |
| T1b 风格题自建探针 | 未通过(P0) | 探针只在 expectedAnswerSchemaFor 盖戳那一刻由 withFollowupOwnedProbe 注入内存 state(server-focus.ts:136),没有进 decision_receipt.inference_state。生产的答题路径 answer-choice.ts:591 用 withNakshatraBoundaryProbe(previousInferenceFromReceipt(receipt)) 读持久化 state,matchProbeForChoice 找不到 probe:d9_relationship:relationship_style → stale_probe → :852 抛 agentic_rectification_stale_probe。我用任务书自己的 fixture 按生产路径回放(state 不含自建探针):applied=false reason=stale_probe。点选或打字回答新的 D9 题都会报错,比修前更糟(修前至少错分入账,修后答不了) |
| T1c 从落库副本投影 | 未通过 | persistedDistinguishCard(method-followup.ts:3319-3350)先要 liveInferenceDistinguishProbe(input.inferenceState) 在持久化 state 里找到该探针,找不到即 null;同一回放里 GET choice_card 为 null。任务书第二条测试是手工把自建探针塞进 buildInferenceState({probes:[D24, 自建]}) 再断言有卡——fixture 不是生产形状(AGENTS §7.4 精神) |
| T1c 过期 → superseded | 未通过(反向误伤) | persistNextInterviewIfIdle(answer-choice.ts:1607-1643):liveDistinguishProbe(持久化 state, schema) 对自建探针恒为 null → staleDistinguish=true → 刚落库的 D9 焦点在每次 idle persist 时被 superseded(route.ts 四处 + agent-run 一处都会调) |
| T2 BUG-913 closed_by_design | 通过 | yearlessPersonalityCanAsk({datedCount:5})===false;结论与 BUG-689 出口一致 |
| T3 BUG-914 一列一句 | 通过 | Python 断言 traits 长度 1、两 option 不同句;前端断言两极不同时进 shared_traits;63 绿 |
| T4 记录 | 通过(需随本单改状态) | BUG-912 现状写 resolved 不成立,改 investigating 直到本单过门 |
总结论:未通过。 根因是一个:自建探针没有像月宿边界探针那样在每个读 state 的地方重建。
2. 修法(照 withNakshatraBoundaryProbe 的既有模式)
月宿边界探针也不在引擎 state 里,它的做法是三处都从 receipt 重建:server-focus.ts:124(盖戳)、answer-choice.ts:591(答题)、inference-adapter.ts:235(previousInferenceFromReceipt 之后)。自建分盘探针照抄:
T1 withOwnedDistinguishProbes(state, receipt)(BUG-915)
- 新函数从
decision_receipt的window_scan.transitions+candidates确定性重建所有varga_observation/precision_stage风格题的自建探针(对每个candidates_differ的层调buildVargaDistinguishFields),追加进state.probes(同 id 不重复)。不依赖当前 followup,避免「哪个 followup 在问」的时序问题。 - 接入点(缺一不可,写成源码契约断言):
server-focus.ts盖戳;answer-choice.ts:591答题;inference-adapter.tspreviousInferenceFromReceipt出口(或紧随其后的同一包装);interview-state.tschoiceCardFromCaseDossier传给投影的inferenceState;persistNextInterviewIfIdle的inferenceForStale;method-followup.ts计划层承接焦点用的liveDistinguishProbe。 - 重算后
answered_probes里的自建条目要能被引擎回写的 state 保留:确认autoRescoreAfterEvidenceChange/ compare 回写inference_state时answered_probes不按probes白名单过滤;若过滤,自建条目要在重建时一并保留。 - 验收(必须走生产路径):
- 回放:持久化 state 只含 D24 → 盖戳得到自建
probe_id→ 用answer-choice.ts同一段代码(导出一个薄函数或直接调用answerRectificationChoice的纯部分)答 C →applied=true、answered_probes末位semantic_key=d9_relationship:relationship_style、后验只按 D9 分组变化。 - GET:同一持久化 state 下
choiceCardFromCaseDossier返回卡且question_id与current_question一致。 - idle:同一状态下
persistNextInterviewIfIdle不 supersede 该焦点;改账本使candidate_split_hash变化后才 supersede 并落下一问。 - 删掉手工塞探针的 fixture,改用上面的生产形状。
- 回放:持久化 state 只含 D24 → 盖戳得到自建
T2 顺带(BUG-916,P2/P3)
agent-run.ts:341-360年月阶段 host 前置(BUG-910)排在dossier.case.sessionId !== sessionId校验之前,跨会话消息也会被写成确定性轮;把前置挪到该校验之后(计费之前不变)。phases: ["answer.host_year_entry"]不在PUBLIC_RECTIFICATION_PHASES;要么登记,要么复用answer.host_fallback。tsc 不报是因为类型是 string。
T3 记录
- BUG-912 改
investigating→ 本单过门后resolved,并写「首版只在盖戳时注入内存 state,答题/GET/idle 三处读持久化 state 找不到」。BUG-915/916 新增。BUG-375 复发段补一句。CHANGELOG、PROGRESS、真机清单更新。
3. 让步顺序
- 若
previousInferenceFromReceipt出口统一注入会让既有rectification-inference-machine断言变红(state.probes 数量),允许只在六个接入点各自包装,但要有源码契约测试钉住六处。 - T2 的 phase 登记可让步为复用
answer.host_fallback。 - T1 验收三条与 T3 不可让步。
4. 开工前置命令
git fetch origin --prune
git worktree add -b codex/rectification-dead-d9-choice-fix-20260916 .worktrees/rectification-dead-d9-choice-fix-20260916 origin/staging
cd .worktrees/rectification-dead-d9-choice-fix-20260916/frontend
./node_modules/.bin/tsx --test tests/rectification-dead-d9-choice-20260916.test.ts tests/rectification-inference-machine*.test.ts 2>&1 | tail -5
grep -o "BUG-[0-9]\+" ../docs/BUG_HISTORY.md | sort -t- -k2 -n | tail -1
5. 给产品负责人
- staging 当前状态:D9/D10 风格题不再错分,但答不了(点选会报错)。在修复单过门前,遇到风格题请先跳过(D)或补一件带年月的事。
- 事发 Case 的 04:48–04:59 仍不可采用(建立在错分上)。