docs(tasks): 5b6abc23 验收通过;降级路径 review 出 BUG-959~961

降级正文直接 send,不过 Pass 4:实跑「我保证你一定会升职」原样送达、
回执只有 contract-degraded(959)。uncontractedText 跨 attempt 不清零,
两次 attempt 的正文拼一起送出(960)。降级后仍空跑一轮 compose(961)。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0193vBv6w5MV2cifdTUu9H5P
This commit is contained in:
Jesse_Chen
2026-09-18 09:10:48 +00:00
co-authored by Claude Opus 5
parent 877128cec4
commit 895a85bcbe
2 changed files with 68 additions and 0 deletions
+1
View File
@@ -139,6 +139,7 @@
| `TASK-consult-three-channels-fix-20260918.md` | `PROGRESS-consult-three-channels-fix-20260918.md` | 验收修复单:领域上限解耦(945)、31s 预算断言(946)、校正思考分片门(947)、Pass 4 按模式分流(948)、容量算术(949) | 已验收通过(Claude:tsc 0 / lint 0 error / npm test 3491 条 31 红且与基线 `742ffbc6` 同一组、原 12 条红全绿 / `/` 仍 Static / 首屏 js gzip 468,388 B 较基线 +0.02%);review 另出 BUG-950~953 见下一行 | `e32ce624` | | `TASK-consult-three-channels-fix-20260918.md` | `PROGRESS-consult-three-channels-fix-20260918.md` | 验收修复单:领域上限解耦(945)、31s 预算断言(946)、校正思考分片门(947)、Pass 4 按模式分流(948)、容量算术(949) | 已验收通过(Claude:tsc 0 / lint 0 error / npm test 3491 条 31 红且与基线 `742ffbc6` 同一组、原 12 条红全绿 / `/` 仍 Static / 首屏 js gzip 468,388 B 较基线 +0.02%);review 另出 BUG-950~953 见下一行 | `e32ce624` |
| `TASK-consult-pass4-streaming-20260918.md` | `PROGRESS-consult-pass4-streaming-20260918.md` | 验收 review 三轮:Pass 4 一 hold 正文就整段蹦出、逐字流式消失(BUG-950 产品拍板按句放行);无出生分钟模式整段被一句拒绝顶掉、一般知识句一起丢(951 改按句丢弃);该模式下日期不留痕(952);校正流 token 级 thinking 是死链,按 P2 删除并把测试翻转成否定合同(953)。基线 `1e553976` | 待验收 | `cd4775ae` | | `TASK-consult-pass4-streaming-20260918.md` | `PROGRESS-consult-pass4-streaming-20260918.md` | 验收 review 三轮:Pass 4 一 hold 正文就整段蹦出、逐字流式消失(BUG-950 产品拍板按句放行);无出生分钟模式整段被一句拒绝顶掉、一般知识句一起丢(951 改按句丢弃);该模式下日期不留痕(952);校正流 token 级 thinking 是死链,按 P2 删除并把测试翻转成否定合同(953)。基线 `1e553976` | 待验收 | `cd4775ae` |
| `TASK-window-consult-contract-20260918.md` | `PROGRESS-window-consult-contract-20260918.md` | **P0 线上**:申报时段模式**自 2026-08-21 起每轮秒败**(69ms、0 token、模型从未被调用)。服务端日志实证根因:窗口 Agent attach 了 `jyotishSkillBinding()`,但 `windowJyotishInstructions` 从来不含方法块 marker,输入处理器直接 abort(BUG-954)。abort 与「模型没调工具」同码,是它藏四周的原因(955);另含合同未绿不得丢正文(956)、计算不该由模型触发(957,须等 954 上线后另轮)、窗口指令应期冲突(958)。基线 `9cdcf96b` | 待验收 | `5b6abc23` | | `TASK-window-consult-contract-20260918.md` | `PROGRESS-window-consult-contract-20260918.md` | **P0 线上**:申报时段模式**自 2026-08-21 起每轮秒败**(69ms、0 token、模型从未被调用)。服务端日志实证根因:窗口 Agent attach 了 `jyotishSkillBinding()`,但 `windowJyotishInstructions` 从来不含方法块 marker,输入处理器直接 abort(BUG-954)。abort 与「模型没调工具」同码,是它藏四周的原因(955);另含合同未绿不得丢正文(956)、计算不该由模型触发(957,须等 954 上线后另轮)、窗口指令应期冲突(958)。基线 `9cdcf96b` | 待验收 | `5b6abc23` |
| `TASK-contract-degraded-pass4-20260918.md` | — | 验收 review:BUG-956 新增的降级交付路径绕过 Pass 4,保证句原样送达(BUG-959);`uncontractedText` 跨 attempt 不清零,同一轮正文说两遍(960);降级后还空跑一轮 compose(961)。基线 `877128ce` | 待领取 | — |
| `TASK-first-paint-dead-screen-fallback-20260917.md` | — | 真机:首页永远停在「正在载入账户」,兜底全在没跑起来的 bundle 里(BUG-936 investigating)。根 layout 加与 bundle 无关的内联兜底 + 去掉本仓正则后行断言 | 待领取 | — | | `TASK-first-paint-dead-screen-fallback-20260917.md` | — | 真机:首页永远停在「正在载入账户」,兜底全在没跑起来的 bundle 里(BUG-936 investigating)。根 layout 加与 bundle 无关的内联兜底 + 去掉本仓正则后行断言 | 待领取 | — |
| `TASK-consultation-answer-start-anchor-20260917.md` | `PROGRESS-consultation-answer-start-anchor-20260917.md` | 主会话回答落在结尾:`useConversationScrollAnchor` 是贴底跟随,流式期间视口钉在最后一个字,回答开头滚出视口;改为发送后问题钉顶、回答向下长、长出视口显示「跳到最新」、末尾动态留白;产品追加拍板:校正面同一语义(推翻 BUG-041/048 贴底),本轮开头 = 用户行或新助手行。BUG 段 930 起 | 已验收(经修复单) | `worktree/green-harbor-5be3` | | `TASK-consultation-answer-start-anchor-20260917.md` | `PROGRESS-consultation-answer-start-anchor-20260917.md` | 主会话回答落在结尾:`useConversationScrollAnchor` 是贴底跟随,流式期间视口钉在最后一个字,回答开头滚出视口;改为发送后问题钉顶、回答向下长、长出视口显示「跳到最新」、末尾动态留白;产品追加拍板:校正面同一语义(推翻 BUG-041/048 贴底),本轮开头 = 用户行或新助手行。BUG 段 930 起 | 已验收(经修复单) | `worktree/green-harbor-5be3` |
| `TASK-consultation-answer-start-anchor-fix-20260917.md` | `PROGRESS-consultation-answer-start-anchor-fix-20260917.md` | 验收修复单:F1 头就是留白行时留白按整视口算(BUG-931);F2 留白只在钉住期间存在(BUG-932);前置:先修 e4e73f56 的两处 TS 错否则门禁不过 | 已验收 | `cc1a8980`(Claude 验收:tsc 0 / lint 0 error / npm test 3457 条 39 红与 11c0028d 逐条一致、新增 2 条绿 / `next build --webpack` 通过、`/` Static、首屏 gzip 591,242(较 09-16 基线 582,800 +1.45%,含会话列表单)/ Chrome 真实布局 S1–S6 全部通过,S6 新助手行距顶 16px 且增高不动,S5 不再写留白);真机六条欠 | | `TASK-consultation-answer-start-anchor-fix-20260917.md` | `PROGRESS-consultation-answer-start-anchor-fix-20260917.md` | 验收修复单:F1 头就是留白行时留白按整视口算(BUG-931);F2 留白只在钉住期间存在(BUG-932);前置:先修 e4e73f56 的两处 TS 错否则门禁不过 | 已验收 | `cc1a8980`(Claude 验收:tsc 0 / lint 0 error / npm test 3457 条 39 红与 11c0028d 逐条一致、新增 2 条绿 / `next build --webpack` 通过、`/` Static、首屏 gzip 591,242(较 09-16 基线 582,800 +1.45%,含会话列表单)/ Chrome 真实布局 S1–S6 全部通过,S6 新助手行距顶 16px 且增高不动,S5 不再写留白);真机六条欠 |
@@ -0,0 +1,67 @@
# TASK · 降级交付路径补 Pass 4 与去重(2026-09-18 第五轮)
> 基线:`origin/staging` @ `877128ce`(含 `5b6abc23`,BUG-954~956/958 已由 Claude 验收通过)。
> 前序:`TASK-window-consult-contract-20260918.md`。
> BUG 编号起点:开工时最大号为 **BUG-958**,本单占 **BUG-959 ~ BUG-961**。
> 全部来自 `5b6abc23` 的验收 review,都落在 BUG-956 新增的降级交付路径上,不重开设计。
## 0. 决策记录
BUG-956 的原始要求是「合同未绿但模型写了字,就把字交付出去,别让用户白等一场只看到系统错误」。这条不变。本单补的是它漏掉的两件事:**降级正文同样要过 Pass 4**,以及**两次 attempt 的正文不许拼在一起送出**。
`TASK-window-consult-contract-20260918.md` §4 只写了「交付该正文 + 服务端说明 + 回执追加 `contract-degraded`」,没写「先过 Pass 4」,实现照做无过。本单把口径补齐。
## 1. BUG-959(P1)降级正文绕过 Pass 4
**实证**(`877128ce` 实跑 `streamAgentResponse`,`requireTool: true`、`pass4Mode: "verified_chart"`、模型不调工具只写字):
```
输入:「我保证你一定会升职。」「方向上可以推进。」
送达 answer.delta:「我保证你一定会升职。方向上可以推进。」+ 降级说明句
state.steps 里的 pass4 相关:只有 contract-degraded,没有 pass4-reject:guarantee
```
根因:`stream-agent-response.ts:717-731` 的降级分支直接 `send(controller, { type: "answer.delta", text: uncontractedText })`,没有走 `releasePass4Sentences` / `classifyPass4`。
风险等级高于普通路径:降级正文**是模型在没有任何计算依据时自己写的**,保证性结论、无出生分钟的个人盘断言恰恰最容易出现在这里,而这条路径上 Pass 4 完全不生效。
**要求**:
1. 降级正文按句过 Pass 4(复用 `releasePass4Sentences`,而不是另写一遍分句逻辑):命中 `reject` 的句子丢弃,其余交付;`observe` 照记。
2. 全部句子都被丢弃时:`general_no_birth_time` 用 `GENERAL_NO_BIRTH_TIME_REFUSAL`,其余模式维持 `runtime_contract_incomplete`(不扣点),不得发一句只有降级说明的空回答。
3. 降级说明句(`CONTRACT_DEGRADED_NOTE`)是服务端确定性文案,不过 Pass 4,仍然附在末尾。
4. 验收标准:新增测试——降级路径 + `pass4Mode` + 含保证句的正文 → 保证句不出现在任何 `answer.delta`,回执同时有 `contract-degraded` 与 `pass4-reject:guarantee`;`e32ce624` 之后的既有降级测试补上 `pass4Mode` 参数。
## 2. BUG-960(P1)两次 attempt 的正文被拼起来一起送出
**实证**:同一次运行里,第一次 attempt 与合同 retry 的正文都进了 `uncontractedText`,降级时一起送出,用户看到同一轮的内容被说了两遍。
根因:`stream-agent-response.ts` 的 `uncontractedText += text` 只在 `contractReady` 为真时清零(`uncontractedText = ""`)。合同一直红就一路累加,attempt 之间没有边界。
**要求**:每次 attempt 开始时清空 `uncontractedText`,降级只交付**最后一次** attempt 的正文。验收:两次 attempt 各写一段不同文字的假流 → 降级正文只含第二段。
## 3. BUG-961(P2)降级之后还会空跑一轮 compose
**实证**:降级分支执行后,流程继续走到 `publishFindings` / `composeOnce`;本命形状的事件序列里出现 `activity` → `phase.started` → `phase.completed`,但该轮 compose 的产出没有送达用户。等于白花一次模型调用与一段墙钟。
**要求**:降级交付后直接收口(发 `run.completed` 前不再进入 Pass 2 / Pass 3)。验收:降级路径的事件序列里不再出现 `phase.started{phase:"compose"}`;`composeAnswer` 在该路径上零次调用。
## 4. 硬红线
1. `tsc --noEmit` 0 错、`npm run lint` 0 error、`npm test` 失败数不超过基线 `877128ce` 实测的 31 条且清单逐条一致;测试总数不低于 3501。
2. 不得为了让降级路径通过而放宽 `contractReady()`。
3. 降级交付仍然只在「模型写了字、但一次计算都没成功」时发生;模型既没调工具也没写字,维持 `runtime_contract_incomplete` 不扣点。
4. 不得在降级正文上做句内改写——按句丢弃是门,不是刀。
5. 改既有断言写「原值 / 新值 / 原因」三栏。
## 5. 开工前置
```bash
git fetch origin --prune
git worktree add -b codex/contract-degraded-pass4-20260918 \
.worktrees/contract-degraded-pass4-20260918 origin/staging
cd .worktrees/contract-degraded-pass4-20260918/frontend
npm test 2>&1 | grep -E "^# (tests|pass|fail)" # 开工基线:tests 3501 / pass 3455 / fail 31
```
收工:`docs/tasks/PROGRESS-contract-degraded-pass4-20260918.md` + `docs/BUG_HISTORY.md`(BUG-959~961)+ `CHANGELOG.md`(若降级文案有变),与代码同一批推 `staging`。