Files
Jyotisha/docs/tasks/TASK-rectification-invite-copy-and-assertions-fix-20260915.md
T
Jesse_ChenandClaude Fable 5 81f8183cc2 docs(tasks): fix the invite copy count and the five stale assertions
验收 a266b6b7 / c5fbee56:tsc、lint、新套件全绿,但 npm test 由 27 涨到 32——
4 条 exit 断言的短语表没加新交付文案、1 条公开字段深比较没加 birth_time_source,
都不是行为回归但违反红线。另有用户可见的数字矛盾:邀请语硬编码「这两分钟」,
同段话却写着「还剩 4 个候选」。本单修文案按候选数出话、两处断言跟上,并给精度
研究 M1b 追加勘误:V1/V2 三档数字与 V0 完全相同且作者自承采集走错路径,判定
作废改为未测(V3 结论保留)。

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0155nFCgCHtoA7jhSDGmZmMu
2026-09-15 01:20:37 +00:00

103 lines
8.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# TASK · 修复单:邀请文案说错候选数 + 5 条断言没跟上 — 2026-09-15
- 基线:`origin/staging` @ `dfb572fc`(代码最新 `c5fbee56`。**staging 当前部署 `cf972f40`BUG-689 / BUG-690 均未上线,本回归没有影响真实用户**)。
- 分支:`codex/rectification-invite-copy-fix-20260915`worktree `.worktrees/rectification-invite-copy-fix-20260915`
- 关联:**本单是 `TASK-rectification-open-collect-invite-20260914.md`BUG-689,实现 `a266b6b7`)与 `TASK-rectification-birth-time-provenance-20260914.md`BUG-690,实现 `c5fbee56`)的验收修复单**。另关联 BUG-688(同一组 exit 断言上一轮刚恢复过)、BUG-587。
- 串行:改 `user-copy.ts` / `collection-question-pool.ts` 文案一处 + 两个测试文件 + 一份研究文档勘误;与在途分支无重叠。
## 1. 事故实证(Claude 验收,2026-09-15
`dfb572fc` 上跑门禁:`tsc --noEmit` 0 错、`npm run lint` 0 error、新增套件(`open-collect-invite` / `birth-time-provenance` / `agent-voice-copy-contract`24/24 全绿、研究单 `tests/test_precision_gate_research.py` 12 passed。
`npm test` **从基线 27 条涨到 32 条**,新增 5 条:
| 文件 | 红掉的断言 | 性质 |
| --- | --- | --- |
| `rectification-exhaustion-exit-20260906.test.ts` | `closed ceiling with training open delivers a range and a concrete next-collect hint``inconsistent projection logs ranked_count 0 and still delivers a gate``last closed-ceiling card concatenates the gate into one append``ensureNonTerminalTurnExit writes a host turn when exhausted with no carrier` | `exitAppendCalls()` 的短语表没有加入 BUG-689 的新交付文案,于是「有没有写出口载体」判成 0 |
| `rectification-decision-authority.test.ts` | `public decision fields are derived from decideRectification` | 深比较的字段集合没有加 BUG-690 新增的 `birth_time_source` |
这 5 条**都不是行为回归**——实测输出里交付旁白写得很完整(下面那段),只是断言的短语表与字段集合过期。但上一轮(BUG-688)刚刚因为同一组断言被弱化而立过修复单,这次**连更新都没做就交付**,违反任务书红线第 1 条(`npm test` 失败数必须等于基线)。
### P2 · 邀请文案说错候选数(用户可见)
实测输出(`rectification-exhaustion-exit` 用例里原文):
```
已经从最初的 20 分钟收到 04:47–04:53 这 6 分钟。眼下更像 04:51。
现在还剩 04:47–04:53 里 4 个候选。这两分钟按现有信息分不开。
你要是还记得确切哪一天的事,不限领域,说出来我接着算——……
```
前一句刚说「还剩 **4 个候选**」,后一句就说「**这两分钟**按现有信息分不开」。根因是 `RECTIFICATION_USER_COPY.rangeDeliveryCollectClosed``frontend/src/lib/rectification-agentic/user-copy.ts:176`)把「这两分钟」硬编码进了句首——它原本是 tie-break 用语(`rangeDeliveryTieBreakUsed`,那里确实是两个候选),BUG-689 复用时没有按实际候选数改写。
调用点:`collection-question-pool.ts:847` / `:849``rangeNarrowHint`)。
## 2. 根因
- 5 条断言:BUG-689 改了交付文案、BUG-690 加了公开字段,但两处"锁契约"的测试没同步。
- 文案:把固定两候选场景的句子复用到任意候选数的场景。
## 3. 决策记录
| 决策 | 内容 |
| --- | --- |
| D1 | **`exitAppendCalls()` 的短语表加入 BUG-689 的新交付文案**(「收到 … 这 N 分钟」「按现有信息分不开」「说出来我接着算」这一组)。这些确实是出口载体(它们就是交付旁白本身),加入合规。**但不得再次放宽 `assert.equal(gates.length, 1)` 的"恰好一条"语义**(BUG-688 的防复发条),也不得把参考题确认语「只微调排序」加回去。 |
| D2 | **`rectification-decision-authority.test.ts``birth_time_source` 字段**,保持深比较(不得改成部分匹配来绕过)。公开字段集合变化必须被这条测试挡住,这是它存在的意义。 |
| D3 | **文案按实际候选数出话。** 候选数 = 2 才可以说「这两分钟」;> 2 说「这几个候选」或直接复述范围;候选数未知时不说这半句。不得在同一段话里出现互相矛盾的数字。 |
| D4 | **研究文档追加勘误(不删原文)**`docs/research/precision_gate_2026_09_14.md` 的 M1b 里,V1 与 V2 在三档半径上的数字与 V0 **完全相同**,而该节自己写明「V0 采集误走了生产计分、没有打上分盘标签」;V3 有差异说明机制能生效,因此 **V1/V2 大概率未被真正应用,其 `no_benefit` 判定作废,标为「未测」**。V3(加 D60,±10 命中 0.80→0.70)的结论可信,保留。重跑与否另行决定,本单只做勘误。 |
| D5 | 不改打分、判据、置信度与确认门控;不改 BUG-689/690 的既有行为(交付卡照出、来源标签分档)。 |
## 4. 硬红线
1. `tsc --noEmit` 0 错;`npm run lint` 0 error**`npm test` 失败数必须回到基线 27 条**,且不得靠弱化断言达成;`next build` 通过且 `/``○ Static`
2. 新增/修改断言必须是行为断言;改既有断言按 §7.3 写「原值 / 新值 / 原因」三栏。
3. 不得回退 BUG-688 恢复的两条断言语义。
4. 文案改动对照 `frontend/docs/VOICE.md`;改 UI 的提交同时更新 `frontend/DESIGN.md`
## 5. 任务分解
### 任务 1 · 文案按候选数出话(P0)
- `user-copy.ts:176``rangeDeliveryCollectClosed` 改成函数或参数化模板,接收候选数;`collection-question-pool.ts:847/:849` 两个调用点传入 `candidateCount`
- 验收标准:
- 行为单测:候选数 = 2 → 文案含「这两分钟」;候选数 = 4 → **不含**「这两分钟」,且与前半句的候选数一致(用正则同时校验两处数字);候选数未知 → 不出现该半句。
- 回归:邀请语的其余部分(不限领域、日期优先例子、年月例子)不变。
### 任务 2 · 两处断言跟上(P0)
- `rectification-exhaustion-exit-20260906.test.ts``exitAppendCalls()` 按 D1 加短语;四条恢复绿。
- `rectification-decision-authority.test.ts` 按 D2 补字段;一条恢复绿。
- 验收标准:`npm test` 失败数 = 27,且 `assert.equal(gates.length, 1)` 与「不含只微调排序」两条仍在。
### 任务 3 · 研究文档勘误(P1)
- 按 D4 在 `docs/research/precision_gate_2026_09_14.md` 的 M1b 追加勘误段,并把总表里 V1/V2 的判定从 `no_benefit` 改成 `not_measured`(原值保留在勘误里)。
- 同步更新 `docs/research/rectification_minute_resolution_closure_2026_09_14.md` 的索引段,注明 M1b 的 V1/V2 未测。
### 任务 4 · 记录
- `docs/BUG_HISTORY.md` 新增 **BUG-692**`resolved`):现象写「交付邀请语说『这两分钟』但同段话写着 4 个候选;同时 5 条契约断言未随文案与字段更新」;防复发条:**文案里出现的数字必须来自同一份数据,不得硬编码;改用户可见文案或公开字段时,必须同步跑 `npm test` 并把失败数与基线比对。**
- `CHANGELOG.md` 一行;`PROGRESS-rectification-invite-copy-fix-20260915.md``docs/testing/` 清单补一条:交付卡上"候选数"与"这两分钟/这几个候选"的说法必须一致。
## 6. 让步顺序
1. 任务 2 最优先(门禁红着不能发布)。
2. 任务 1 必做(用户可见的数字矛盾)。
3. 任务 3 可延后但不得省略。
## 7. 开工前置命令
```bash
git fetch origin --prune
git worktree add -b codex/rectification-invite-copy-fix-20260915 \
.worktrees/rectification-invite-copy-fix-20260915 origin/staging
cd .worktrees/rectification-invite-copy-fix-20260915
ln -s /workspace/Jyotisha/.venv .venv
cd frontend && npm ci
npx tsx --test tests/rectification-exhaustion-exit-20260906.test.ts tests/rectification-decision-authority.test.ts # 先复现 5 条红
```
## 8. BUG 编号起点
- 起点 **BUG-692**(当前最大号 690691 已被 `TASK-rectification-record-conflict-copy-20260914.md` 预留)。