Files
Jyotisha/docs/tasks/TASK-chat-markdown-list-20260918.md
T
Jesse_ChenandClaude Opus 5 fa21cf46a8 docs(tasks): 补 BUG-964 思考条与正文间距 56px 的实测根因
Chrome 实测 gapPx=56:.consultation-thinking-report 的 grid gap 24px
加首个 h2 的 margin-top 32px。后者源于 globals.css:415 的「首元素清零」
被 2353 行会话作用域规则按特指度压掉(0,2,0 对 0,4,1),在真实会话里
从未生效。另一条路径 message-stage-and-answer 只有 8px。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0193vBv6w5MV2cifdTUu9H5P
2026-09-18 09:47:50 +00:00

109 lines
7.4 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 · 回答正文的列表渲染(2026-09-18 第六轮)
> 基线:`origin/staging` @ `ea0280c1`(代码部分 = 已部署的 `877128ce`)。
> 触发:产品在 staging 真机看申报时段回答,反馈「排版没对齐、看起来很难受」。
> BUG 编号起点:`docs/BUG_HISTORY.md` 当前最大号 **BUG-958**;`TASK-contract-degraded-pass4-20260918.md` 已占 959~961,本单占 **BUG-962 ~ BUG-964**。
## 0. 复现方式(已在本机用真实构建复现)
1. 取 staging 真实一轮的回答原文(申报时段 / 「未来半年我事业如何?」)。
2. 用仓库自己的渲染管线跑:`renderChatMarkdown(answer)`(`src/components/chat-markdown-view.tsx`)。
3. 用 `next build --webpack` 产物里的 CSS chunk 套上 `.message-markdown` 容器,headless Chrome 截图。
产出的 HTML(节选,**这是渲染器真实输出**):
```html
<h2>先回答你的问题</h2>
<p>这是你出生窗口内的稳定结构,不是某一分钟的盘。……</p>
<ul class="markdown-list">
<li><p><strong>你这半年的事业是「外刚内不承」</strong>:表面硬气是真的硬——……</p></li>
<li><p><strong>推的是火星</strong>:事情由你自己起动、自己顶上去。……</p></li>
<li><p><strong>所以别去应火星的「硬顶」,也别去应土星弱位的「拖」。去扮演太阳的「署名」</strong>:……</p></li>
</ul>
<ul class="markdown-list"><li>口头承诺一律补一条确认消息</li>……</ul>
```
模型写的是**三段散文**,渲染出来变成了**三条列表项**,而且和结尾真正的行动清单用同一种样式。
## 1. BUG-962(P1)聊天正文的列表没有项目符号
`src/app/globals.css:1336-1349` 的 `.markdown-list` 设了 `display: grid`、`gap`、`padding-inline-start: 1.35em`,**但没有恢复 `list-style`**。项目是 Tailwind v4,`@import "tailwindcss"` 的 preflight 把 `ul, ol` 的 `list-style` 清成 `none`。
结果:所有列表项只是「往右缩进一段的孤行」,看不出是清单;正文段落靠左、列表块缩进,页面出现两级左边界——这就是产品说的「没对齐」。
已验证:在同一份编译 CSS 上加一行 `list-style: disc` 后,`display: grid` 下 `::marker` 正常渲染,**不需要改布局方式**。
**要求**:
1. `.message-markdown .markdown-list` 恢复项目符号:`ul` 用 `disc`、`ol` 用 `decimal`;`::marker` 颜色取次级文字色(不要纯黑)。
2. 顺带核对同一文件里其它被 preflight 清零又没恢复的列表(`personal-report-markdown-view` 走的是另一套样式,本单不动)。
3. 验收标准:新增一条渲染测试断言 `.markdown-list` 的计算样式 `list-style-type !== "none"`(或源码级断言该选择器块内含 `list-style`);进度记录附改前改后截图。
## 2. BUG-963(P1)散文被自动提升成列表
`src/lib/chat-definition-lists.ts` 的 `promoteDefinitionLists`:连续 ≥2 个「X:Y」形式的段落会被改写成 `- **X**:Y` 列表。
它是 BUG-356(2026-08-23)的修复,当时要治的是「行运 / 适合推进这类**并列短项**被挤成一坨段落」。但 BUG-943(今天)把本命正文改成四标题口语体之后,正文散文**本来就长这样**——「你这半年的事业是 X:……」「推的是火星:……」——于是整段正文被误判成并列项。
现在的判据太松:
- `DEFINITION_LINE = /^(.{2,80}?)[::](.+)$/` 的 term 允许含句号,所以「……也别去应土星弱位的「拖」。去扮演太阳的「署名」」整串都成了 term;
- body 只要求 `length >= 4`,一段一百多字的多句散文照样算「解释」。
**要求**(收紧,不是删除——BUG-356 的场景要继续工作):
1. term 不得含句末标点(`。!?;!?;`)与换行。
2. body 必须是**单句**:不含句末标点,或仅以一个句末标点收尾。
3. body 长度上限(建议 ≤ 40 个字符,实现方可按 BUG-356 的真实样例校准),超过就是散文,不提升。
4. 三条**全部**满足才提升,且仍要求连续 ≥2 段。
5. 验收标准:
- 回归 fixture 用**两份真实正文**:BUG-356 的并列短项(仍然提升)与本轮申报时段回答(**不再提升**,保持三个 `<p>`);
- `chat-definition-lists.test.ts` 既有断言若需改动,写「原值 / 新值 / 原因」三栏。
## 3. BUG-964(P1)思考条与正文之间空 56px
产品第二条反馈:「思维链和正文中间间隔好大」。用同一套 harness 量了(Chrome `getBoundingClientRect`):
```
{"gapPx":56,"h2MarginTop":"32px","reportGap":"24px","listStyle":"none"}
```
56px 由两段叠成:
| 来源 | 值 |
| --- | --- |
| `.consultation-thinking-report { gap: var(--space-6) }`(`globals.css:1197-1200`) | 24px |
| 正文首个 `<h2>` 的 `margin-top` | 32px |
第二段是个**被静默覆盖的规则**:`globals.css:415` 写着 `.message-markdown > *:first-child { margin-top: 0 }`,本意就是让首元素不带外边距;但 `globals.css:2353` 的 `.conversation:not(.is-empty):not(.is-rectification) .message-markdown h2 { margin: var(--space-8) 0 var(--space-3) }` 特指度更高(0,4,1 对 0,2,0),**在真实会话里首元素清零从来没生效过**。任何以标题开头的助手回答都多出 32px。
对照:另一条不带 timeline 的路径 `.message-stage-and-answer { gap: var(--space-2) }` 只有 8px,两条路径差 48px。
**要求**:
1. 让首元素清零在会话作用域里也生效(加一条同作用域的 `> *:first-child { margin-top: 0 }`,或把 2353 那条改成 `* + h2` 形态)——不要靠 `!important`。
2. `.consultation-thinking-report` 的 `gap` 从 24px 降到 12px 量级,与另一条路径同一口径(两条路径的间距必须由同一个 token 决定,不得再各写各的)。
3. 顺带:会话里 `.markdown-list` 的 `gap: var(--space-4)`(16px)比正文行距还大,三条行动看起来像三个段落;降到 8px 量级。
4. 验收标准:同一 harness 复测,思考条底与正文首标题之间 ≤ 16px;进度记录附改前改后截图与实测数字。
## 4. 硬红线
1. `tsc --noEmit` 0 错、`npm run lint` 0 error、`npm test` 失败数不超过基线 `877128ce` 实测的 31 条且清单一致;测试总数不低于 3501。
2. 同一提交更新 `frontend/DESIGN.md`:写明聊天正文里「列表有符号」「散文不自动变列表」「思考条与正文的间距由同一 token 决定」三条口径,以及判据阈值。
3. 不改 `next build` 后 `/` 的 `○ Static`;首屏 gzip 变化在 ±2% 内(本轮只动 CSS 与一个 lib,预期接近 0)。
4. 不得顺手改个人报告页的 Markdown 样式(那是另一套,未收到反馈)。
## 5. 开工前置
```bash
git fetch origin --prune
git worktree add -b codex/chat-markdown-list-20260918 \
.worktrees/chat-markdown-list-20260918 origin/staging
cd .worktrees/chat-markdown-list-20260918/frontend
npm test 2>&1 | grep -E "^# (tests|pass|fail)" # 开工基线:tests 3501 / pass 3455 / fail 31
```
截图复现法(本单验收要用同一套):把真实回答喂给 `renderChatMarkdown`,套 `next build` 产物里的 CSS chunk,用 headless Chrome 截 `.message-markdown`。
收工:`docs/tasks/PROGRESS-chat-markdown-list-20260918.md`(附改前改后截图与 gap 实测值)+ `docs/BUG_HISTORY.md`(BUG-962~964)+ `frontend/DESIGN.md`,与代码同一批推 `staging`。