docs(bugs): renumber this branch's records after a concurrent push claimed 270 and 271
Independent Staging Quality Gate / validate (push) Successful in 7m43s
Independent Staging Quality Gate / publish (push) Successful in 8m46s

The rebase also applied staging's fix-version edit to the wrong record,
because every record ends with the same boilerplate line; the follow-up
chip record is back to an uncommitted candidate.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Jesse_Chen
2026-08-18 15:47:19 +08:00
parent 52f3c04b3b
commit 3c9b0bb32b
+38 -38
View File
@@ -3982,7 +3982,7 @@
- 首次发现:2026-08-18
- 最近更新:2026-08-18
- 影响面:`/` 首页“今日星语”卡片、首页 hero 的问候与标题、`/api/daily-starlanguage` 的失败归因与超时预算、Onboarding Agent 生成的欢迎语。
- 后续修正:本记录「Agent 欢迎语落到 hero 说明行」的处置已被 BUG-270 推翻——该说明行经用户评审判定为累赘并删除,`onboarding.greeting` 因此重新回到无渲染点状态,处理见 BUG-270
- 后续修正:本记录「Agent 欢迎语落到 hero 说明行」的处置已被 BUG-272 推翻——该说明行经用户评审判定为累赘并删除,`onboarding.greeting` 因此重新回到无渲染点状态,处理见 BUG-272
- 用户现象:staging 上出生资料完整的账号打开首页,“今日星语”卡片一直显示“正在结合你的星盘写今天的星语。”,永远不出现 Agent 写的文案。同一次反馈里还问到:首页那三个问题是不是写死的,以及首页标题“今天想先理清什么?”为什么没换成登录后按时段问候的形式。
- 触发条件:`birth_time_status``candidate``accepted``confirmed` 且已有可用出生时间的任何账号打开首页。也就是说,越是资料完整的账号越必然命中。
- 根因:三处独立问题,都在同一屏上。
@@ -3992,43 +3992,7 @@
- 修复:守卫改成 `!hydrated || !profileComplete || !personalChartAvailable`,与卡片渲染个人内容的条件对齐,并在服务端报 unavailable 时延迟 5 秒重试一次后才落到失败态,卸载时清理定时器。路由给 `/api/chart``.catch()`,把生成结果改成判别联合,失败原因区分 `chart_unavailable` / `model_unavailable` / `agent_generation_failed``engineTimeoutMs` 提到 20 秒、`agentTimeoutMs` 提到 45 秒,仍在 `maxDuration = 60` 之内。问候收敛成一套:`createStartGreeting` 拆出 `createStartGreetingParts`,返回 `{salutation, question}`hero 第一行用 salutation、`h1` 用 question,选中变体在离开首页时重抽;删除 `starter-prompt.ts``greetingForHour`。客户端不再覆盖 Agent 欢迎语,`onboarding.greeting` 落到 hero 说明行并保留原静态文案作为兜底。
- 验证:线上先证明后端是好的——带登录 Cookie 直接调 staging `/api/daily-starlanguage`,冷路径 30.6 秒返回真实 `{trend, action, caution}`,第二次 1.6 秒命中 `agent_cache``/api/health` 确认部署 SHA 就是 `origin/staging` 头部,`jyotishApi` 检查为 ok,因此排除部署落后与引擎不可用。新增 4 条回归:每日星语请求条件必须与 `personalChartAvailable` 一致且源码中不得再出现 `birthTimeDisplayState(profile)`、失败必须重试一次且清理定时器、`/api/chart` 必须带 catch 且三种失败原因各自可辨、两个超时预算有下限断言;hero 断言 salutation/question 拆分与 Agent 欢迎语落点,并禁止 `starterPrompt`/`createStarterPrompt`/`greetingForHour` 复活。前端非数据库套件 1711/1724 通过,13 个失败全部是本机 Docker/PostgreSQL fixture(与 BUG-265 同一类环境失败,与本次无关);`tsc --noEmit` 与改动文件 ESLint 清洁。未做的验证:**没有在浏览器里看过修好后的首页**——本机没有 Python 引擎与模型密钥,无法起完整栈,卡片从 `pending``ready` 的实际观感、重试是否够用、以及 hero 换行后的排版都要等 staging 发布后确认。
- 防复发:一个界面元素的「取数条件」必须和它的「渲染条件」写成同一个表达式,不能一边用 `personalChartAvailable` 渲染、一边用另一个语义相反的谓词决定是否请求。删除兜底文案时必须回头检查被兜底遮住的空状态路径是否本来就是坏的——BUG-265 删兜底是对的,但没有验证删掉之后真实账号能不能拿到内容,代价是上线即空转。同一个概念(这里是「登录后的问候」)不允许存在多套并行实现,否则改动必然落在没被渲染的那一套上。Agent 生成的字段如果没有渲染点,就不要生成,更不能在客户端覆盖后还继续消耗 token。
- 相关记录:BUG-265(本次修复的直接前序:Agent 化改造正确但守卫未同步,且其「待跟进」已经预告了首屏等待态问题)、BUG-201(每日星语 effect 依赖完整 Profile 对象的既有决定,本次沿用其引用保持策略,未改依赖形状)、BUG-200(首页文案第一人称与真实性边界)、BUG-270(本次 hero 说明行处置的后续推翻)
- 复发自:无
- 修复版本:`a12f5797`staging
## BUG-270 | 首页 hero 第三行重复问候被删除,真实性边界随之迁移;onboarding 契约去掉无渲染点的欢迎语并扩展到全部十个主题
- 状态:resolved(本地修复,待提交与发布)
- 首次发现:2026-08-18
- 最近更新:2026-08-18
- 影响面:`/` 首页 hero 文案层级、主题区小标题承载的出生时间边界声明、Onboarding 起点加载文案、`/api/onboarding` 的 payload 契约与缓存版本、onboarding 生成超时预算、首页十张主题卡的文案来源。
- 用户现象:BUG-269 把 Agent 欢迎语放进 hero 说明行后,用户评审首页时指出这一行「有点累赘」,要求删掉整段 `starter-hero-note`。同一次反馈里还指出「首页可不是三个问题啊,有好多问题」,并追问首页标题是否由 Agent 生成(答:不是,来自 `onboarding-client.ts` 的本地时段变体表,5 个时段 × 3 条问句)。
- 触发条件:任何账号打开首页;hero 连续三行都在做同一件事(称呼、提问、再一次欢迎并再问一次「想从哪里开始」)。
- 根因:两处独立问题。
1. hero 的信息层级在 BUG-269 之后变成三行同义内容。`starter-greeting` 已经完成称呼、`h1` 已经完成提问,Agent 欢迎语在句式上又重复了这两件事,因此第三行没有新增信息。但这一行同时是「无可用出生分钟」账号的真实性边界声明所在(BUG-200 约束,`starter-questions.test.ts` 有断言钉住),直接整段删除会连边界声明一起删掉。
2. 首页主题卡渲染的是 `consultationDomainRegistry` 的全部十个域,而 `/api/onboarding``suggestions``career`/`marriage`/`timing` 的固定三元组。页面按主题 id 逐个 `find`,找不到就回落到 registry 的静态 `prompt`,因此其余七个域(wealth、health、education、migration、family、annual、general)恒定是写死文案,个性化只覆盖三分之一的入口,而界面上十张卡看起来完全同级,用户无法分辨哪些是为自己生成的。加载态文案「根据你的资料整理三个起点。」也与实际渲染的十张卡不符。
- 修复:分两步。
1. 界面收敛:删除 `starter-hero-note` 元素及其两处 CSS 规则,hero 收敛为称呼加提问两行。出生时间边界声明迁到主题区小标题,按 `personalChartAvailable` 分支——读者正要挑主题时才看到这句限制,位置比 hero 更贴近实际动作。加载态文案改为「根据你的资料整理今天的起点。」,不再声明具体条数。
2. 契约收敛(用户评审后决定,同一分支内完成):`onboarding.greeting` 从 Agent 契约里彻底移除——schema、fallback、prompt、客户端响应校验与 `OnboardingContent` 类型全部不再有这个字段,不再为无渲染点的内容付费。`suggestions``career`/`marriage`/`timing` 的固定三元组改成按 `consultationDomainIds` 顺序覆盖全部十个域,校验用 refine 钉住「长度与顺序都必须与 registry 一致」,于是首页十张卡全部是 Agent 写的,静态 `prompt` 退回纯兜底角色。fallback 直接由 `generalGuidedJyotishTopics` 派生,避免手写十条又与 registry 漂移。生成十条比三条显著更慢,预算随之上调:路由 `maxDuration` 30→60 秒、服务端生成超时 18→45 秒、客户端单次请求超时 25→50 秒。缓存版本 `ayanam-onboarding-v4``v5`,让所有存量 v4 payload 重新生成一次。
- 验证:`onboarding-presentation.test.ts` 的 hero 断言改为同时检查 `page.tsx``globals.css` 中不再出现 `starter-hero-note`,避免只删元素留下死样式;`starter-questions.test.ts` 的边界声明断言从「文件里存在这句话」收紧为「这句话出现在主题区小标题且受 `personalChartAvailable` 分支控制」,防止下一次挪动文案时悄悄丢掉。契约部分新增 5 条回归:只覆盖三个域的旧形态响应必须整体拒绝并落到覆盖全域的兜底、主题顺序被交换必须拒绝(否则问题会挂到错误的主题标签下)、fallback 自身必须能通过 payload schemaregistry 里的 prompt 一旦不再第一人称就会被这条抓住)、prompt 与 payload/client 源码中不得再出现 greeting 字段、路由必须把 registry 主题列表发给 Agent。客户端请求超时断言从 25 秒下限改到 45 秒下限,与服务端生成预算对齐。全量套件 1720/1729 通过,9 个失败全部是本机 Docker/PostgreSQL fixture(与 BUG-265、BUG-269 同一类环境失败);`tsc --noEmit` 清洁,ESLint 仅存量 4 条 warning`next build` 成功。未做的验证:**没有在浏览器里看过改动后的首页**,也没有真实调用过新契约的生成——本机没有模型密钥,十条问题的实际生成耗时是否落在 45 秒预算内、十张卡的文案是否彼此重复、以及 hero 删掉第三行后的留白与边界声明在窄屏的折行,都要等 staging 发布后确认。若线上出现大量 `fallback`,第一嫌疑就是 45 秒预算仍然不够。
- 防复发:删除一个 UI 元素前必须先确认它有没有在承载与自身样式无关的合规或真实性文案——`starter-hero-note` 表面是装饰性说明行,实际是 BUG-200 边界声明的唯一落点。删元素时同步删样式,并用测试同时钉住两个文件,否则死 CSS 会在下一次改版时被误当作现有设计复用。声明数量的文案(「三个起点」)不要写死在与数据源无关的地方,数量必须跟着 registry 走。Agent 契约里的字段数量变化必须同步三件事:缓存版本、生成超时预算、客户端请求超时;只改 schema 不改预算的结果是全量用户静默落到 fallback,而 fallback 看起来是「正常内容」,不会报错。契约收紧时要用 refine 校验「集合与顺序」而不是只校验单项,否则模型少写几项或错位映射都能通过。
- 相关记录:BUG-269(本次推翻其 hero 说明行处置)、BUG-200(首页真实性边界声明的原始约束,本次迁移未削弱)、BUG-271(同一轮评审的下一项删除)
- 复发自:无
- 修复版本:本地未提交候选
## BUG-271 | 回答后输入框上方的三条推荐问题实际使用率极低且从未由 Agent 生成,整条链路删除
- 状态:resolved(本地修复,待提交与发布)
- 首次发现:2026-08-18
- 最近更新:2026-08-18
- 影响面:会话内 `composer-suggestions` 追问按钮、`/api/consult` 写入的 assistant 消息字段、`consultation-reply-metadata``agent-reply` 的解析契约、会话写入 schema、`composer-wrap` 相关样式与 DESIGN.md 的对应条目。
- 用户现象:用户实际测试后反馈「Agent 回答后用户输入框上方的三个推荐问题」使用频率很少,要求删除,并要求 Agent 也不再生成这三个问题。
- 触发条件:任何咨询会话收到 assistant 回复之后,输入框上方固定出现三条按钮。
- 根因:这里有一个与用户预期不同的事实——**这三条问题从来不是 Agent 生成的**。`createConsultationReplyMetadata` 按会话主题从写死的十主题三元组里取一组,服务端总是把它塞进 `parseAgentReply` 的 metadata 参数,而 metadata 分支优先级高于模型输出(`metadata?.suggestions ?? …`),因此模型即便真的输出了 `AYANAM_SUGGESTIONS` 也会被覆盖;Prompt 本身还明确禁止模型产出隐藏元数据块。同一份三元组表被完整复制在 `agent-reply.ts``consultation-reply-metadata.ts` 两处。也就是说,界面上看起来「个性化」的追问入口,实际是按主题查表的十组固定文案,与用户的具体问题、星盘证据都无关——这正是使用率低的合理解释。附带发现:`chooseConversationSuggestion` 里针对「先完成生时校正」这一条的生时校正跳转分支在当前链路下不可达,因为服务端 metadata 恒定覆盖,三元组里从不含这条文案。
- 修复:删除渲染点(`composer-suggestions` 块)、派生状态 `activeSuggestions`、点击处理 `chooseConversationSuggestion` 与常量 `rectifyBeforeConsultationSuggestion`、客户端 `readSuggestions` 与三处 `suggestions` 写入(send、本地预览、预览会话种子)。服务端 `consultationReplyMetadataSchema` 收缩为只有 `title``.strict()``createConsultationReplyMetadata` 不再需要 `theme` 入参,两份 `fallbackSuggestions` 表全部删除。`parseAgentReply``parseAgentReplyBody` 在失去 suggestions 后返回形状完全相同,合并为单一 `parseAgentReply(value, metadata?)`,生时校正改调这一个入口。`ChatMessage` 去掉 `suggestions` 字段;但会话写入 schema 的 `suggestions` **有意保留为可选**——该 schema 是 `.strict()` 的,发布瞬间仍在运行旧 bundle 的客户端会继续带上这个字段,拒绝整个写入等于丢掉用户那条消息,代价远大于留一个被忽略的字段。`stripAgentReplyMetadata` 同样保留剥离 `AYANAM_SUGGESTIONS` 注释的能力,因为删除前写入的历史回答里仍带着这个块,不剥离会把原始 HTML 注释显示给用户。CSS 删除 8 处 `.composer-suggestions` 规则(含混合选择器中的片段与两个媒体查询内的规则),Prompt 里「follow-up suggestions 由服务端生成」改为只提标题,DESIGN.md 对应条目改写为「回答不提供追问建议」并记录原因。
- 验证:新增/改写回归共 6 条:会话内不得再出现 `composer-suggestions``activeSuggestions``chooseConversationSuggestion` 且 CSS 同步无残留、metadata schema 必须拒绝 `suggestions` 字段(防止 chips 从元数据侧回流)、两个库文件与 consult 路由中不得再出现主题三元组或 suggestions 写入、历史遗留的 `AYANAM_SUGGESTIONS` 块必须被剥离且不得复活成字段、输入框与正文之间不得再有会改变高度的兄弟节点(原 chip 行会在流式过程中撑高 composer)、生时校正入口在失去 chip 跳转后仍可从首页卡片进入。全量 1716/1721 通过,5 个失败全部是本机 Docker/PostgreSQL migration fixture`tsc --noEmit` 清洁,ESLint 仅存量 4 条 warning`next build` 成功。未做的验证:**没有在浏览器里确认删掉 chip 行后会话底部的留白与滚动锚点表现**,尤其是 BUG-263 里「跳到最新」按钮的定位曾依赖 chip 行带来的高度变化,需要发布后目视确认按钮位置仍然合理。
- 防复发:不要把查表得到的固定文案摆在会让用户以为是个性化生成的位置——这类「假个性化」入口既消耗界面空间又必然低使用率,而且因为看起来正常,不会有人报 bug。同一份兜底数据不允许在两个模块各存一份副本,否则删除时必然漏掉一处。删除一个可选字段时要区分「输出契约」与「输入契约」:输出侧应当立刻停止产出,输入侧在旧客户端与历史数据仍可能带上它时必须继续宽容接收,否则发布窗口内会丢用户数据。当两个函数因为字段删除而返回形状相同时应当合并,但要意识到其中一个可能是某个历史 Bug(此处 BUG-179)刻意建立的隔离措施,合并前必须确认该措施防的问题已经在结构上不可能发生。
- 相关记录:BUG-179(曾因通用解析器的三条建议兜底污染生时校正,本次删除使其隔离措施不再必要)、BUG-263(「跳到最新」按钮定位曾受 chip 行高度影响)、BUG-249(草稿隔离验证里包含推荐问题填入路径)、BUG-270(同一轮评审的上一项删除)
- 相关记录:BUG-265(本次修复的直接前序:Agent 化改造正确但守卫未同步,且其「待跟进」已经预告了首屏等待态问题)、BUG-201(每日星语 effect 依赖完整 Profile 对象的既有决定,本次沿用其引用保持策略,未改依赖形状)、BUG-200(首页文案第一人称与真实性边界)、BUG-272(本次 hero 说明行处置的后续推翻)
- 复发自:无
- 修复版本:`a12f5797`staging
@@ -4065,3 +4029,39 @@
- 相关记录:BUG-268(同为「诊断量算出来就丢」,本条是「诊断量压根没被创建」)、BUG-258(同为失败时回执信息不足)、BUG-255(同为模型参数被拒白扔步数,当时的修法是把互斥字段从 schema 里删掉)
- 复发自:无
- 修复版本:`b5bcbaed`staging
## BUG-272 | 首页 hero 第三行重复问候被删除,真实性边界随之迁移;onboarding 契约去掉无渲染点的欢迎语并扩展到全部十个主题
- 状态:resolved(本地修复,待提交与发布)
- 首次发现:2026-08-18
- 最近更新:2026-08-18
- 影响面:`/` 首页 hero 文案层级、主题区小标题承载的出生时间边界声明、Onboarding 起点加载文案、`/api/onboarding` 的 payload 契约与缓存版本、onboarding 生成超时预算、首页十张主题卡的文案来源。
- 用户现象:BUG-269 把 Agent 欢迎语放进 hero 说明行后,用户评审首页时指出这一行「有点累赘」,要求删掉整段 `starter-hero-note`。同一次反馈里还指出「首页可不是三个问题啊,有好多问题」,并追问首页标题是否由 Agent 生成(答:不是,来自 `onboarding-client.ts` 的本地时段变体表,5 个时段 × 3 条问句)。
- 触发条件:任何账号打开首页;hero 连续三行都在做同一件事(称呼、提问、再一次欢迎并再问一次「想从哪里开始」)。
- 根因:两处独立问题。
1. hero 的信息层级在 BUG-269 之后变成三行同义内容。`starter-greeting` 已经完成称呼、`h1` 已经完成提问,Agent 欢迎语在句式上又重复了这两件事,因此第三行没有新增信息。但这一行同时是「无可用出生分钟」账号的真实性边界声明所在(BUG-200 约束,`starter-questions.test.ts` 有断言钉住),直接整段删除会连边界声明一起删掉。
2. 首页主题卡渲染的是 `consultationDomainRegistry` 的全部十个域,而 `/api/onboarding``suggestions``career`/`marriage`/`timing` 的固定三元组。页面按主题 id 逐个 `find`,找不到就回落到 registry 的静态 `prompt`,因此其余七个域(wealth、health、education、migration、family、annual、general)恒定是写死文案,个性化只覆盖三分之一的入口,而界面上十张卡看起来完全同级,用户无法分辨哪些是为自己生成的。加载态文案「根据你的资料整理三个起点。」也与实际渲染的十张卡不符。
- 修复:分两步。
1. 界面收敛:删除 `starter-hero-note` 元素及其两处 CSS 规则,hero 收敛为称呼加提问两行。出生时间边界声明迁到主题区小标题,按 `personalChartAvailable` 分支——读者正要挑主题时才看到这句限制,位置比 hero 更贴近实际动作。加载态文案改为「根据你的资料整理今天的起点。」,不再声明具体条数。
2. 契约收敛(用户评审后决定,同一分支内完成):`onboarding.greeting` 从 Agent 契约里彻底移除——schema、fallback、prompt、客户端响应校验与 `OnboardingContent` 类型全部不再有这个字段,不再为无渲染点的内容付费。`suggestions``career`/`marriage`/`timing` 的固定三元组改成按 `consultationDomainIds` 顺序覆盖全部十个域,校验用 refine 钉住「长度与顺序都必须与 registry 一致」,于是首页十张卡全部是 Agent 写的,静态 `prompt` 退回纯兜底角色。fallback 直接由 `generalGuidedJyotishTopics` 派生,避免手写十条又与 registry 漂移。生成十条比三条显著更慢,预算随之上调:路由 `maxDuration` 30→60 秒、服务端生成超时 18→45 秒、客户端单次请求超时 25→50 秒。缓存版本 `ayanam-onboarding-v4``v5`,让所有存量 v4 payload 重新生成一次。
- 验证:`onboarding-presentation.test.ts` 的 hero 断言改为同时检查 `page.tsx``globals.css` 中不再出现 `starter-hero-note`,避免只删元素留下死样式;`starter-questions.test.ts` 的边界声明断言从「文件里存在这句话」收紧为「这句话出现在主题区小标题且受 `personalChartAvailable` 分支控制」,防止下一次挪动文案时悄悄丢掉。契约部分新增 5 条回归:只覆盖三个域的旧形态响应必须整体拒绝并落到覆盖全域的兜底、主题顺序被交换必须拒绝(否则问题会挂到错误的主题标签下)、fallback 自身必须能通过 payload schemaregistry 里的 prompt 一旦不再第一人称就会被这条抓住)、prompt 与 payload/client 源码中不得再出现 greeting 字段、路由必须把 registry 主题列表发给 Agent。客户端请求超时断言从 25 秒下限改到 45 秒下限,与服务端生成预算对齐。全量套件 1720/1729 通过,9 个失败全部是本机 Docker/PostgreSQL fixture(与 BUG-265、BUG-269 同一类环境失败);`tsc --noEmit` 清洁,ESLint 仅存量 4 条 warning`next build` 成功。未做的验证:**没有在浏览器里看过改动后的首页**,也没有真实调用过新契约的生成——本机没有模型密钥,十条问题的实际生成耗时是否落在 45 秒预算内、十张卡的文案是否彼此重复、以及 hero 删掉第三行后的留白与边界声明在窄屏的折行,都要等 staging 发布后确认。若线上出现大量 `fallback`,第一嫌疑就是 45 秒预算仍然不够。
- 防复发:删除一个 UI 元素前必须先确认它有没有在承载与自身样式无关的合规或真实性文案——`starter-hero-note` 表面是装饰性说明行,实际是 BUG-200 边界声明的唯一落点。删元素时同步删样式,并用测试同时钉住两个文件,否则死 CSS 会在下一次改版时被误当作现有设计复用。声明数量的文案(「三个起点」)不要写死在与数据源无关的地方,数量必须跟着 registry 走。Agent 契约里的字段数量变化必须同步三件事:缓存版本、生成超时预算、客户端请求超时;只改 schema 不改预算的结果是全量用户静默落到 fallback,而 fallback 看起来是「正常内容」,不会报错。契约收紧时要用 refine 校验「集合与顺序」而不是只校验单项,否则模型少写几项或错位映射都能通过。
- 相关记录:BUG-269(本次推翻其 hero 说明行处置)、BUG-200(首页真实性边界声明的原始约束,本次迁移未削弱)、BUG-273(同一轮评审的下一项删除)
- 复发自:无
- 修复版本:本地未提交候选
## BUG-273 | 回答后输入框上方的三条推荐问题实际使用率极低且从未由 Agent 生成,整条链路删除
- 状态:resolved(本地修复,待提交与发布)
- 首次发现:2026-08-18
- 最近更新:2026-08-18
- 影响面:会话内 `composer-suggestions` 追问按钮、`/api/consult` 写入的 assistant 消息字段、`consultation-reply-metadata``agent-reply` 的解析契约、会话写入 schema、`composer-wrap` 相关样式与 DESIGN.md 的对应条目。
- 用户现象:用户实际测试后反馈「Agent 回答后用户输入框上方的三个推荐问题」使用频率很少,要求删除,并要求 Agent 也不再生成这三个问题。
- 触发条件:任何咨询会话收到 assistant 回复之后,输入框上方固定出现三条按钮。
- 根因:这里有一个与用户预期不同的事实——**这三条问题从来不是 Agent 生成的**。`createConsultationReplyMetadata` 按会话主题从写死的十主题三元组里取一组,服务端总是把它塞进 `parseAgentReply` 的 metadata 参数,而 metadata 分支优先级高于模型输出(`metadata?.suggestions ?? …`),因此模型即便真的输出了 `AYANAM_SUGGESTIONS` 也会被覆盖;Prompt 本身还明确禁止模型产出隐藏元数据块。同一份三元组表被完整复制在 `agent-reply.ts``consultation-reply-metadata.ts` 两处。也就是说,界面上看起来「个性化」的追问入口,实际是按主题查表的十组固定文案,与用户的具体问题、星盘证据都无关——这正是使用率低的合理解释。附带发现:`chooseConversationSuggestion` 里针对「先完成生时校正」这一条的生时校正跳转分支在当前链路下不可达,因为服务端 metadata 恒定覆盖,三元组里从不含这条文案。
- 修复:删除渲染点(`composer-suggestions` 块)、派生状态 `activeSuggestions`、点击处理 `chooseConversationSuggestion` 与常量 `rectifyBeforeConsultationSuggestion`、客户端 `readSuggestions` 与三处 `suggestions` 写入(send、本地预览、预览会话种子)。服务端 `consultationReplyMetadataSchema` 收缩为只有 `title``.strict()``createConsultationReplyMetadata` 不再需要 `theme` 入参,两份 `fallbackSuggestions` 表全部删除。`parseAgentReply``parseAgentReplyBody` 在失去 suggestions 后返回形状完全相同,合并为单一 `parseAgentReply(value, metadata?)`,生时校正改调这一个入口。`ChatMessage` 去掉 `suggestions` 字段;但会话写入 schema 的 `suggestions` **有意保留为可选**——该 schema 是 `.strict()` 的,发布瞬间仍在运行旧 bundle 的客户端会继续带上这个字段,拒绝整个写入等于丢掉用户那条消息,代价远大于留一个被忽略的字段。`stripAgentReplyMetadata` 同样保留剥离 `AYANAM_SUGGESTIONS` 注释的能力,因为删除前写入的历史回答里仍带着这个块,不剥离会把原始 HTML 注释显示给用户。CSS 删除 8 处 `.composer-suggestions` 规则(含混合选择器中的片段与两个媒体查询内的规则),Prompt 里「follow-up suggestions 由服务端生成」改为只提标题,DESIGN.md 对应条目改写为「回答不提供追问建议」并记录原因。
- 验证:新增/改写回归共 6 条:会话内不得再出现 `composer-suggestions``activeSuggestions``chooseConversationSuggestion` 且 CSS 同步无残留、metadata schema 必须拒绝 `suggestions` 字段(防止 chips 从元数据侧回流)、两个库文件与 consult 路由中不得再出现主题三元组或 suggestions 写入、历史遗留的 `AYANAM_SUGGESTIONS` 块必须被剥离且不得复活成字段、输入框与正文之间不得再有会改变高度的兄弟节点(原 chip 行会在流式过程中撑高 composer)、生时校正入口在失去 chip 跳转后仍可从首页卡片进入。全量 1716/1721 通过,5 个失败全部是本机 Docker/PostgreSQL migration fixture`tsc --noEmit` 清洁,ESLint 仅存量 4 条 warning`next build` 成功。未做的验证:**没有在浏览器里确认删掉 chip 行后会话底部的留白与滚动锚点表现**,尤其是 BUG-263 里「跳到最新」按钮的定位曾依赖 chip 行带来的高度变化,需要发布后目视确认按钮位置仍然合理。
- 防复发:不要把查表得到的固定文案摆在会让用户以为是个性化生成的位置——这类「假个性化」入口既消耗界面空间又必然低使用率,而且因为看起来正常,不会有人报 bug。同一份兜底数据不允许在两个模块各存一份副本,否则删除时必然漏掉一处。删除一个可选字段时要区分「输出契约」与「输入契约」:输出侧应当立刻停止产出,输入侧在旧客户端与历史数据仍可能带上它时必须继续宽容接收,否则发布窗口内会丢用户数据。当两个函数因为字段删除而返回形状相同时应当合并,但要意识到其中一个可能是某个历史 Bug(此处 BUG-179)刻意建立的隔离措施,合并前必须确认该措施防的问题已经在结构上不可能发生。
- 相关记录:BUG-179(曾因通用解析器的三条建议兜底污染生时校正,本次删除使其隔离措施不再必要)、BUG-263(「跳到最新」按钮定位曾受 chip 行高度影响)、BUG-249(草稿隔离验证里包含推荐问题填入路径)、BUG-272(同一轮评审的上一项删除)
- 复发自:无
- 修复版本:本地未提交候选