merge origin/staging into report chart layout fix

Keep BUG-616/617 after 614/615 and before 618–620.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Jesse_Chen
2026-09-09 18:46:18 +08:00
co-authored by Cursor
36 changed files with 1005 additions and 171 deletions
+80
View File
@@ -9526,6 +9526,38 @@
- 复发自:无
- 修复版本:待发布
## BUG-614 | 三列卡把「还没对照」显示成 0 和没有窗口
- 状态:resolved
- 首次发现:2026-09-09
- 最近更新:2026-09-09
- 影响面:`scripts/rectification/refinement_packet.py``column_times_for_compare`)、`frontend/src/lib/rectification-agentic/v9/divergence-panel.ts``rectification-range-delivery.tsx``user-copy.ts`
- 用户现象:区间卡第 2、3 列写「强相关 0 · 有关联 0 · 弱关联 0」,三列都写「未来一年没有明显的窗口」;相同性格句每列重复一遍。
- 触发条件:推断层后验前三与引擎分数前三不是同一组分钟;客户端按列时间查 `event_dasha_ledger_by_time` / `prospective_windows_by_time` 找不到键。
- 根因:`column_times_for_compare` 只取引擎分数前三,卡片列按后验前三投影。缺键时投影把空表当成 0 次吻合、把缺窗口当成「没有窗」。
- 修复:`columns` 改为引擎 `candidate_times` 去重全集(上限 9)。客户端缺键写 `fit: null` / `windows: null`,灰字「这一分钟还没对照」,不得回退成 0。经历对照改成「N 件里 M 件对得上」;无窗写「未来一年没有明显的时段」。三列共有的性格句只出现在卡顶一次。
- 验证:`tests/test_rectification_v5_services.py::test_compare_ledgers_cover_all_engine_candidate_times``frontend/tests/rectification-range-delivery-20260907.test.ts` 后验前三与引擎前三不同时 `fit` 非 null,缺键 DOM 出现「这一分钟还没对照」、不出现 `0 · 0 · 0`
- 防复发:`set(ledgers) == set(candidate_times)`;用户可见文案禁用「强相关 / 有关联 / 弱关联」;列内不得再出现 `<h3>`「经历对照 / 往后 12 个月」。
- 相关记录:BUG-597、BUG-615、`TASK-rectification-compare-card-polish-20260909.md`
- 复发自:BUG-597(三列对照的 by_time 只覆盖引擎前三)
- 修复版本:待发布
## BUG-615 | 交付旁白被证据轮裁句裁成一句
- 状态:resolved
- 首次发现:2026-09-09
- 最近更新:2026-09-09
- 影响面:`frontend/src/lib/rectification-agentic/v9/collect-prompt.ts``agent-run.ts`
- 用户现象:交付轮助手正文只剩「校正到这里可以收口了。」一类单句,BUG-595 定的三句(范围、经历与吻合率、边界句)被裁掉。
- 触发条件:访谈收口出区间卡;该轮 `action === "evidence"`,模型写了三句以上。
- 根因:BUG-606 的 `trimEvidenceTurnBody`(超过两句只留首句)对所有 evidence 轮生效。交付也走 evidence 轮。
- 修复:先跑 `persistNextInterviewIfIdle`。仍有下一问时继续裁到一句;该函数返回 `terminalNote` 时保留 ≤3 句。裁剪不得发生在 idle 之前,否则交付四句会先被裁掉。裁完与流式正文不同时发 `answer.delta replace`,气泡跟落库同一段。
- 验证:`frontend/tests/rectification-v9-agent.test.ts` 交付轮模型写四句 → 落库三句;普通证据轮三句 → 一句。`frontend/tests/rectification-collect-prompt.test.ts``trimSpokenTurnForInterview`
- 防复发:`agent-run` 必须在 idle 之后调用 `trimSpokenTurnForInterview(answerText, interviewIdle?.terminalNote === true)`。不得把交付轮重新裁成一句。
- 相关记录:BUG-606、BUG-595、BUG-614、`TASK-rectification-compare-card-polish-20260909.md`
- 复发自:BUG-606(证据轮裁句没有把交付轮排除)
- 修复版本:待发布
## BUG-616 | 报告页 22 张北印盘叠在同一位置
- 状态:resolved
@@ -9557,3 +9589,51 @@
- 相关记录:BUG-616、`TASK-report-md-page-20260906.md``TASK-report-chart-layout-fix-20260909.md`
- 复发自:无(09-06 直渲结构在星盘进入后才变成可感知卡顿)
- 修复版本:待发布
## BUG-618 | 采集题「没有 / 记不清」浮在输入框上方,离问题太远
- 状态:resolved
- 首次发现:2026-09-09
- 最近更新:2026-09-09
- 影响面:`rectification-agentic-chat.tsx` 口述采集快捷回答、`globals.css` `.rectification-collect-replies`
- 用户现象:口述采集时,「没有」「记不清」两个按钮贴在底部输入框上方,和问题气泡分开,看起来像多余的条。
- 触发条件:`collect_spoken` 焦点激活且未 busy。
- 根因:BUG-605 把快捷回答挂在 `composer-wrap` 输入框上方,没有跟选择题卡一样嵌进同一条助手气泡。
- 修复:两个按钮改到问题 `afterAnswer` 里,紧挨题干;composer 不再渲染它们。点选仍走原来的「没有 / 记不清」短路。
- 验证:`frontend/tests/rectification-spoken-collect.test.ts`(按钮在 afterAnswer,不在 composer-wrap)。
- 防复发:采集快捷回答不得回到 composer。选择题卡继续用嵌入卡,口述采集用 `rectification-collect-reply`
- 相关记录:BUG-605
- 复发自:无
- 修复版本:待发布
## BUG-619 | 生时校正时间轴比对话内容更贴边
- 状态:resolved
- 首次发现:2026-09-09
- 最近更新:2026-09-09
- 影响面:`globals.css` `.rectification-timeline` 水平内边距
- 用户现象:校正对话上方的时间轴比下面的候选卡、助手气泡更靠屏幕外边,左右对不齐。
- 触发条件:打开生时校正,尤其是已出现三列候选卡时。
- 根因:条用 `space-5` / 窄屏 `space-4`,对话列是 `space-8` / `space-4` 再加头像让位 `--assistant-content-inset`;条又不在 `.message-list` 里,继承不到该变量。
- 修复:条的内边距改为对话沟槽加头像让位;背景和底边发丝线仍拉满。高度不变。
- 验证:`frontend/tests/rectification-timeline-20260909.test.ts`
- 防复发:时间轴水平内边距必须含 `--assistant-content-inset`,不得写回贴边的 `space-5`
- 相关记录:无
- 复发自:无
- 修复版本:待发布
## BUG-620 | 点「更像这个」后三列卡消失,收尾句贴左不对齐
- 状态:resolved
- 首次发现:2026-09-09
- 最近更新:2026-09-09
- 影响面:`rectification-agentic-chat.tsx` 区间交付卡、`verified_idle` 收尾句、`globals.css` `.rectification-pending-note`
- 用户现象:点「更像这个」后三列时间卡忽然消失,底下出现未对齐的「已采用 HH:MM,新建对话即按这个时间排盘。」
- 触发条件:交付卡出现后点其中一列「更像这个」;尤其是没有后续核对题、`next_user_action``start_consultation` 时。
- 根因:`showSelectionCards``!busy` 整张卸卡;采用请求把对话标成 busy。收尾句用未定义样式的 `.rectification-pending-note` 直接挂在消息列表里,没有助手列让位。采用后若 live offer 锚点被清掉,卡也不再回到原消息。
- 修复:采用中或已采用时 busy 不再卸卡;用 resultId 锁住首次出示卡片的那条消息。收尾句改到卡片下方,样式与卡片同一条左边线。已采用列按钮保持按下并禁用。不恢复输入框上方状态条。
- 验证:`frontend/tests/rectification-adopt-cards-stay-20260909.test.ts``frontend/tests/rectification-candidate-offer-anchor.test.ts`
- 防复发:交付卡不得因采用 busy 卸载;`verified_idle` 不得使用无 inset 的裸段落;不得把采用状态写回 composer。
- 相关记录:BUG-595、BUG-619
- 复发自:无
- 修复版本:待发布
@@ -0,0 +1,52 @@
# PROGRESS · 三列对比卡修正与减法(BUG-614/6152026-09-09
工作树:`.worktrees/rectification-compare-card-polish-20260909`
分支:`codex/rectification-compare-card-polish-20260909`
任务书:`docs/tasks/TASK-rectification-compare-card-polish-20260909.md`
基线:任务书写 `origin/staging` @ `365ad799`;本 worktree 按开工时的 `origin/staging` `3005e36d`(任务书本身)切出。合入前 rebase 到当时的 `origin/staging`(含 `17b36f3a` 咨询 BUG-612/613、`584a56bd` 报告图布局 brief、`ca921c3f` 采集按钮/时间轴/已采用列,BUG-618~620)。已采用列继续 `disabled={busy || adopted}`,不把 BUG-618 冲掉。
本单状态:**待验收**。合入 staging 时更新落点 SHA。
预检:本机已跑 `python3 scripts/pre_work_check.py --remote-timeout 8 --command-timeout 45`(含 `diagnose_external_engine_adapters.py --json`),远端可见性 `verified`。前端用 worktree 里指向主仓的 `frontend/node_modules` 符号链接。
未改:采用 RPC、各道门槛、`SCORE_DELTA`、四选项合同、时间轴、Skill 版本 / `references/conversation-strategy.md`
## 做了什么
- **BUG-614** `column_times_for_compare(..., limit=9)` 覆盖引擎 `candidate_times` 去重全集。客户端 `lookupByTime` 缺键 → `fit: null` / `windows: null`,灰字「这一分钟还没对照」,不再把空表渲染成 `0 · 0 · 0`
- **BUG-615** `trimSpokenTurnForInterview``persistNextInterviewIfIdle` **之后**执行:仍有下一问裁到一句;`terminalNote` 保留 ≤3 句。不得在 `streamAttempt` 里先裁。裁完若与流式正文不同,再发一条 `answer.delta` `replace`,气泡与落库一致。
- **卡片减法** 两列及以上共有性格句提到卡顶并改写成「两个/三个时间的…都在…」;列内 `fit_line` / `window_line`;无 `<h3>`;禁用「强相关 / 有关联 / 弱关联」。
- **右栏** `VedicChartSvg` 北印星盘;宫位表与换升时刻默认 `<details>`(summary「换升时刻 · N 个」);显示层并入同一折叠。换分钟只高亮变化宫,无动画。
## 三栏
| 用例 | 原值 | 新值 | 理由 |
| --- | --- | --- | --- |
| 引擎 5 个候选、卡片后验前三与引擎前三不同 | 后验列查不到键 → `0 · 0 · 0` / 「没有窗口」 | `by_time` 含全部候选分钟;列 `fit`/`windows` 有数 | 决策 1:按引擎候选集算,不是按卡片前三 |
| `by_time` 缺某一列的键 | 空数组当 0、当没有窗 | `fit === null`,DOM「这一分钟还没对照」 | 没算 ≠ 没有 |
| 三列 D10 同在巨蟹 | 三列各写一遍 | 卡顶一句「三个时间的事业盘都在巨蟹座:…」 | 相同句只写一次 |
| 交付轮模型写 4 句 | BUG-606 裁成 1 句 | `terminalNote` 时留 3 句 | 决策 2BUG-595 三句口径 |
| 普通证据轮 3 句 | 1 句 | 仍 1 句 | BUG-606 采集轮不变 |
| 右栏本命 | 宫位表常驻 | 北印星盘 + 宫位表折叠 | 读屏仍可打开表 |
| 右栏换升时刻 | 逐分钟常驻列表 | 默认折叠「换升时刻 · N 个」 | 时间轴已表达同一件事 |
## 测试
- `frontend` `./node_modules/.bin/tsc --noEmit`exit 0
- `npm run lint`0 error / 107 warning(仓库既有 warning,无新增 error
- 任务书切片 `tsx --test tests/rectification-*.test.ts tests/agent-voice-copy-contract.test.ts`(排除 database):**1063 passed / 0 failed**
- 本单针对性:`rectification-v9-agent.test.ts` 交付 4→3 句、证据 3→1 句;`rectification-range-delivery-20260907.test.ts` 后验前三有 `fit`、缺键「还没对照」;`rectification-board-model.test.ts` 北印星盘 + 换升默认折叠
- `.venv/bin/python -m pytest tests/test_rectification_v5_services.py::RectificationV5ServicesTest::test_compare_ledgers_cover_all_engine_candidate_times``test_compare_returns_ledger_and_windows_by_candidate_time`**2 passed**。同文件 `test_block_scan_seven_events_finishes_within_fifteen_seconds` 本机 41s 超 15s 预算,与本单无关(既有壁钟断言,见 BUG-570 P2)
- 浏览器真人走查:无登录态,未见真实交付卡/右栏像素
## 偏离
1. 任务书基线 `365ad799`worktree 从已推任务书的 `3005e36d` 切出。未把后续 staging 提交 rebase 进来。
2. 代表分钟缺 `by_time` 键时,经历 ledger 仍可回退到该分钟自己的 `eventDashaLedger`(不是填 0);窗口没有回退。缺键列只要 `windows == null` 仍显示「还没对照」。
3. 单列不把性格句提到卡顶(任务书写的是三列共有)。
4. 浏览器真人走查:本会话无登录态,未见真实交付卡/右栏像素。合同测试覆盖 DOM 字符串,不把它们写成已经看见真实会话。
5. 裁句后补一条 `answer.delta replace`。任务书只要求 idle 之后裁句;不补这条的话流式气泡会停在未裁正文。
## 环境缺口
无登录态、无生产/staging 走查。不把合同测试写成已经看见真实像素。
+1 -1
View File
@@ -87,7 +87,7 @@
| `TASK-rectification-timeline-fix-20260909.md` | `PROGRESS-rectification-timeline-fix-20260909.md` | 时间轴修复单:宽度读数改含两端分钟数(与 BUG-593 报告/卡片一致);标记改读推断层候选全集,被淘汰分钟留在原地变空心(客户端投影只含 active,DESIGN §10 描述在真实数据下画不出) | 已验收通过 | `92e3d5e7`BUG-602603 |
| `TASK-rectification-conversation-economy-20260909.md` | `PROGRESS-rectification-conversation-economy-20260909.md` | 对照竞品后产品拍板三条:开场三句讲做法 + 一次收多件(推翻 opening brief「不要一次说完/不举例」与 SKILL L52);采集题「没有 / 记不清」按钮(不做示例骨架条);每轮只留一句(方法句进活动记录、点选旁白去领先落后、证据轮正文一句复述 + 服务端裁剪);Skill 10.0.19 | 已验收通过(2 条 P3 备注) | `aa7ccb30` + `1453fb16`BUG-604606Skill 10.0.19 |
| `TASK-consultation-daily-empty-answer-20260909.md` | `PROGRESS-consultation-daily-empty-answer-20260909.md` | 首页「深入看今日」计算完成却 `empty_answer`:入口定的 `timing` 被模型改成 `general``canonicalDomainPlan` 以模型为准),分段写作标题与今日格式错位,分段 `maxSteps=1` 且工具仍可调 → 模型在分段里再调工具、零正文;思考流按 chunk 过滤漏出缺词英文 | 待验收 | `codex/consultation-daily-empty-answer-20260909`BUG-612613);走查 `docs/testing/consultation-daily-empty-answer-20260909.md` |
| `TASK-rectification-compare-card-polish-20260909.md` | `PROGRESS-rectification-compare-card-polish-20260909.md` | 三列卡两列经历对照 0、三列无未来窗:引擎按引擎前三算 by_time,卡片按推断前三查表,键不匹配(BUG-614);交付旁白被 BUG-606 裁成一句(BUG-615);设计减法:相同性格句只写一次、经历对照说人话、删小标题、右栏本命宫位改北印星盘、换升时刻默认折叠 | 待执行 | `codex/rectification-compare-card-polish-20260909`BUG-614615 |
| `TASK-rectification-compare-card-polish-20260909.md` | `PROGRESS-rectification-compare-card-polish-20260909.md` | 三列卡两列经历对照 0、三列无未来窗:引擎按引擎前三算 by_time,卡片按推断前三查表,键不匹配(BUG-614);交付旁白被 BUG-606 裁成一句(BUG-615);设计减法:相同性格句只写一次、经历对照说人话、删小标题、右栏本命宫位改北印星盘、换升时刻默认折叠 | 待验收 | `codex/rectification-compare-card-polish-20260909`BUG-614615 |
### 聊天主链路与首页
@@ -84,11 +84,13 @@
期望:
- 交付轮只见一张卡:范围、对照了 N 件经历、至多三列并排(相对可能性、性格处事、经历对照、往后 12 个月、「更像这个」)、底部边界句
- 点「更像这个」即采用;已采用列按钮显示「已采用」,其它列仍可点改选
- 交付轮只见一张卡:范围、对照了 N 件经历、至多三列并排。相同性格句只出现在卡顶一次。每列是时间、相对可能性、有差别的性格句、人话经历对照(「N 件里 M 件对得上」)、下一个时段或「未来一年没有明显的时段」、「更像这个」底部边界句。列内没有小标题。
- 某一列还没对照时只见灰字「这一分钟还没对照」,不见「强相关 0 · 有关联 0 · 弱关联 0」,也不把「没算」写成「没有窗口」
- 点「更像这个」即采用;卡片留在原处,被点的列显示「正在采用…」再变成「已采用」并禁用,其它列仍可点改选
- 采用后的收尾句跟卡片同一列,不要单独贴左,也不要出现在输入框上方
- 卡片下方「查看验证报告」默认收起,打开后是真正的表格
- 助手正文只有三句(范围、经历与吻合率、边界句),不含「排盘用」「方法1」或 Technique Audit
- 不见「相对支持度」「当前推荐」「采用此时间」「按这个范围用」「再补一件经历」「都不像」「说不好」
- 不见「相对支持度」「当前推荐」「采用此时间」「按这个范围用」「再补一件经历」「都不像」「说不好」「强相关」「有关联」「弱关联」
- 输入框上方没有「先这样,先看当前范围」,也没有采用后状态条
## 6. 七领域问完后下一问必须是职业题或直接出区间卡
@@ -166,6 +168,6 @@
- 这一条消息只触发一次候选比较,账本写入三件
- 下一问不再是已经说过的那三个领域
- 只报一件时也只比较一次,下一问是既有逐领域采集,正文没有「还有吗 / 还能想起别的吗」;第一道逐领域题干末尾可以有一次「想到别的也可以一起说」
- 口述采集输入框上方有「没有」「记不清」,没有「先这样」
- 口述采集问题下方有「没有」「记不清」,没有「先这样」,输入框上方不再挂这两个按钮
- 每轮助手正文一句复述(可另接一句范围变化);气泡里没有「本轮对照了…」,也没有「很有帮助 / 很有价值 / 很有分量 / 特别有用」