Преглед изворни кода

docs(harness): 记下「草稿被最终文本整段替换」为已接受行为

用户 2026-09-21 报:卡片下方先渲染一大段正文,随后整段消失变成另一段。

取证结论(不改代码):
- DMS 里那一轮的存储内容与用户所见一致(卡片 + 降级答复 + notices + 参考资料);
  用户贴文中看着粘连的地方,DMS 里是正常 \n\n 分隔;第 2、3 条内容相同也是后端给的。
- 复现同一问法:answer_end.status=completed,但 concat(answer_delta) 不是 answer_end.text 的前缀,
  公共前缀 175/1494 = 11.7%。差异是最终版给标题补序号、把纯文本换成 markdown 链接。
- 契约明确要求覆盖草稿(「绑定真实链接,随最终替换出现」「不能用 text 覆盖…不能只保留草稿」)。

用户拍板:接受现状。记录进 tech-debt-tracker 新增的「已知且已接受的行为」一节(A1),
写清现象、契约依据、实测数据、以及「要根治需后端在流式阶段就带上链接」。
本轮无代码改动。

Co-Authored-By: Claude Code <noreply@anthropic.com>
gongtianxiao пре 1 дан
родитељ
комит
b0658fd443
3 измењених фајлова са 50 додато и 0 уклоњено
  1. 24 0
      harness/docs/exec-plans/tech-debt-tracker.md
  2. 26 0
      harness/progress.md
  3. 0 0
      harness/tools/_answer-dump.txt

+ 24 - 0
harness/docs/exec-plans/tech-debt-tracker.md

@@ -104,3 +104,27 @@
 ## 已还
 
 (还清后从上面移到此处,保留一行说明怎么还的,便于追溯)
+
+---
+
+## 已知且**已接受**的行为(不是债,勿当 bug 修)
+
+### A1. 流式草稿会被最终文本**整段替换**
+
+- **现象**(用户 2026-09-21 报):卡片下方先渲染出一大段正文,随后**整段消失**,
+  变成另一段(可能是更短的降级答复)。
+- **为什么会这样(契约要求,不是渲染 bug)**:
+  - `token-streaming.md`:「完整校验后**绑定真实链接,随最终替换出现**」;
+    「`answer_end` 无论 status 是 completed 还是 fallback,**均用 text 覆盖已有内容**……
+    **不能只停止光标而保留草稿**」
+  - 实测复现(同一问法):草稿 1494 字 → 最终 1943 字,**公共前缀只有 175 字(11.7%)**——
+    最终版给标题补了序号(`### 高新技术企业认定…` → `### 一、高新技术企业认定…`)、
+    把纯文本渠道换成了 markdown 链接(`- 国家高新技术企业认定管理工作网先行注册…` →
+    `- [查看办事指南](https://zwdt.sh.gov.cn/…)`)。**链接只在最终校验后才绑定**,草稿必然没有。
+  - `status: fallback` 那一类更直接:草稿被判不可用 → 换成降级答复
+    (「已查到相关资料,但这次未能完成答复整理。您可以查看下方原文资料,或稍后重试。」)
+- **客户端能做的只有缓解、改不了「内容会变」**:曾评估过 ①加提示 ②渲染层保留公共前缀行只重建
+  分歧点之后 —— 实测公共前缀仅 11.7%,②收益很小。**用户 2026-09-21 决定接受现状**。
+- **复核方式**:抓一轮 `/api/chat` 原始载荷,比对 `concat(answer_delta)` 与 `answer_end.text`
+  的**公共前缀长度**(`harness/tools/probe-answer-tail-timing.mjs` 可改造成此用途)。
+- **若要根治**:得后端在流式阶段就带上最终链接、或减少降级 —— 属后端侧决定。

+ 26 - 0
harness/progress.md

@@ -3451,3 +3451,29 @@ F073 之后正文是**即时渲染**的(流式期间打字机关着),但**
 只有单行那处生效 → 结果 `anchorLargeBlockTop` 引用了**未定义的常量**,
 而 `npm run build` **照样通过**(Vite 不做类型检查)。改用 Edit 工具重做,并用
 `vue-tsc` 复核。教训:**多行替换必须核对生效处数**,且构建通过 ≠ 代码正确。
+
+### 续 16:查清「草稿被整段替换」并决定接受(用户 2026-09-21 拍板 A)
+
+**用户描述**:卡片下方先渲染出一大段正文,随后**整段消失**,变成另一段。
+
+**取证(不猜)**:
+1. 从 DMS 1889 按 `c_answer` 搜到那一轮并落盘:存储内容 = 卡片 + 降级答复
+   (「已查到相关资料,但这次未能完成答复整理…」)+ notices + 参考资料,与你看到的一致;
+   你贴的「`3. …?- 需求拆解失败…`」看着粘连,DMS 里其实是正常 `\n\n` 分隔(复制时丢的);
+   第 2、3 条内容完全一样也是**存储里就是这样**(后端给的),不是重复渲染。
+2. 复现同一问法抓原始载荷:`answer_end.status = completed`,但
+   **`concat(answer_delta)` 不是 `answer_end.text` 的前缀** —— 公共前缀只有 **175 / 1494 = 11.7%**。
+   差异内容:最终版给标题补了序号(`### 高新技术企业认定…` → `### 一、…`)、
+   把纯文本渠道换成 markdown 链接(`- 国家高新技术企业认定管理工作网…` →
+   `- [查看办事指南](https://zwdt.sh.gov.cn/…)`)。
+3. 契约本来就写着:「完整校验后**绑定真实链接,随最终替换出现**」;
+   「`answer_end` 无论 status 是 completed 还是 fallback,均用 text 覆盖已有内容……
+   **不能只停止光标而保留草稿**」。
+
+**结论**:草稿被替换是**后端设计 + 契约要求**,不是渲染缺陷。
+**用户选择 A:接受现状**,不改代码。
+
+**记录位置**:`harness/docs/exec-plans/tech-debt-tracker.md` 新增「已知且**已接受**的行为」
+一节(A1),写清了现象、契约依据、实测数据与「若要根治得后端改」,避免以后重复排查。
+
+**本轮无代码改动**,只更新 harness 记录。

Разлика између датотеке није приказан због своје велике величине
+ 0 - 0
harness/tools/_answer-dump.txt


Неке датотеке нису приказане због велике количине промена