docs: BUG-1053 record, progress, real-device checklist, changelog and board row

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017eEAG8HD3mm8gsKXgk8uU8
This commit is contained in:
Jesse_Chen
2026-09-27 01:04:27 +08:00
co-authored by Claude Opus 5.5
parent eef0cb7486
commit 3f8e180238
5 changed files with 232 additions and 0 deletions
+30
View File
@@ -14156,3 +14156,33 @@
- 相关记录:BUG-1038(登录返回存根与 `bootstrapSelectionFromLookup` 来源参数,本条推翻其存根部分)、BUG-599(裸 `/` 不自动开校正、默认落咨询,本条收紧为空白首页)、BUG-1015(`?new=1` 新建意图与恢复不抢落点,规则被推广)、BUG-1040(暖返回,同规则、首帧无加载环不变)、BUG-989 / BUG-929 / BUG-1001(首问前不落库、空草稿不进列表)、BUG-705(`?c=` lookup 不变)、BUG-936(首屏兜底不变)。
- 复发自:无(产品规则变更 + BUG-1038 / BUG-599 规则叠加的组合路径)。
- 修复版本:`codex/home-landing-blank-20260927`(本地提交,未推送)。
## BUG-1053 | 普通咨询用户看到的回答没看过星盘:本命路径由看不到计算结果的第二个流来写
- 状态:resolved(本地修复 `codex/consult-single-pass-answer-20260927`,待部署 staging;真机清单待产品走)
- 首次发现 / 最近更新:2026-09-27 / 2026-09-27
- 影响面:`POST /api/consult` 本命路径(`runAgenticConsultation` 的 natal 分支,含首页「深入看今日」入口);`frontend/src/lib/stream-agent-response.ts`(`consumeAttempt` / `publishFindings` / `composeOnce` / `finishPass4`);`frontend/src/lib/consultation-thinking-plan.ts`(`consultationComposePrompt`);`frontend/src/mastra/consultation-tools.ts`(时间常数)。申报时段与无出生分钟路径没有 compose,不受本缺陷影响,但一并改为同一套取答规则与时钟。生产(`7b620c7a`,08-16)没有这条路径,**不受影响**。
- 用户现象:staging 上本命提问的回答与盘面对不上。gpt-5.6-luna 直接写「没有父母主题的盘面证据」;DeepSeek 写得像模像样,但上升、月亮、宫位等「盘面事实」并非来自本轮计算。**2026-08-23 以来 staging 上 DeepSeek 的本命回答可能引用过没有根据的盘面事实。**
- 触发条件:任何一轮本命咨询(每轮都会触发,与问题内容无关)。
- 根因:三段式里的第三段是瞎写的。
1. 主工具循环调用 `run-jyotish-consultation` 后,下一步模型**看得到**约 4 万 token 的计算结果,也写了回答,但这段正文在 `consumeAttempt` 里被 `drainSpoken` 整段丢弃。
2. 随后 `composeAnswer` 另开一个 `agent.stream`,输入只有 `[...baseMessages, { user: consultationComposePrompt() }]`(`toolChoice: "none"`、`maxSteps: 1`)。本命路径的 `baseMessages` 只有历史 + 本轮问题,从不追加工具结果;Agent 在两次 stream 之间没有记忆。
3. `interpretFindings` 只回思考计划的 id、没有文本,所以 compose 提示词里的「判断依据」恒为空,却写着「服务器计算已经完成」。用户看到的回答就是这个没看过星盘的流写的。`continueAfterLength` 同样只拿历史 + 已写正文,续写也是盲的;只有保留工具的 `retryForAnswer` 能重新取回同请求缓存。
4. 顺带:「深入看今日」入口的用户轮要求三节(今日趋势 / 适合推进 / 一个行动),compose 提示词却强制本命四标题,两条指令互相矛盾。
- 引入:`04463e9a`(2026-08-23,「sliced compose」:compose 前丢弃主循环正文);BUG-944(`94c1e81f`)把分段写作改为一次成文时保留了这个结构。
- 为什么测试没拦住:compose 相关测试全部是手造的生成器流,没有一条断言「写回答的那次模型调用看到了什么」。`consultation-agentic-runtime.test.ts` 的「composeAnswer drains leftover first-stream text and writes one body」反而把「丢掉看过证据的正文」当成期望行为锁住。BUG-1051 的回归只看结束方式,同样不看 compose 的输入。
- 修复(产品 2026-09-27 决策 D1–D3):
- D1 删掉第三段:删除 `composeAnswer` / `interpretFindings` / `publishFindings` / `composeOnce` / `drainSpoken`、`consultationComposePrompt` / `consultationSectionPrompt`(后者自 BUG-944 起已是死代码)、`AGENT_SLICE_MAX_STEPS`、`ThinkFinding`。主循环在工具结果之后的那一步写回答,正文保留。
- 取答边界:新选项 `stepScopedAnswer`(本命、申报时段)。按 Mastra 的 `step-start` / `tool-call` / `step-finish` 分步:一步里的正文先扣住,出现 Markdown 标题或满 160 字才放出;这一步如果调用了工具,扣住的正文整段丢弃;计算结果到手之前的正文沿用原规则(不进回答、只留作降级材料)。所以工具前后的过程说明都进不了回答。
- 写作要求搬家:原 compose 提示词里的「开场无标题、一次写完四个二级标题、不写统一参数与技法审计表、不写思考过程」改由主循环看到的用户轮携带(`natalAnswerShapeInstruction()`;「深入看今日」入口 `dailyAnswerShapeInstruction()`),并加一句「拿到本轮计算结果后直接写回答,只用结果里的盘面事实」。系统提示里的 VOICE §7 开场形态与四标题规则不变。
- 续写有据:`streamAgentResponse` 记下计算工具的结果,`continueAfterLength(output, evidence)` 由 `consultationContinueMessages()` 把它作为一条用户消息放在已写正文之前(申报时段已预计算的包已在 `baseMessages` 里,不重复)。
- Pass 4 整篇被拒:原先的 compose 重写改为带 `PASS4_RETRY_HINT` 的 `retryForAnswer`(保留工具、命中同请求缓存);已放出过句子时仍就地丢弃、不重写(BUG-950)。
- 时间预算:`createConsultationRunClock()` 一轮两只钟。工具与申报时段预计算仍用 110 秒的 `toolSignal`(每领域 31 秒、领域墙钟 65 秒不变);模型循环的 `loopSignal` 在计算结果到手之前跟随工具阶段,到手后(`onAnswerPhase`)交给 70 秒答案时钟(`CONSULTATION_ANSWER_TIMEOUT_MS`,由 `CONSULTATION_COMPOSE_TIMEOUT_MS` 改名),续写与回答重试共用同一只答案钟。计算刚好在 110 秒前完成、消费端还没看到时,由 `answerReady` 判断交接而不是掐断。最坏仍是 110 + 70 = 180 秒,`maxDuration` 240 不变。
- BUG-1051 保持:结算只认写回答那一步的 `stop`。Mastra 循环在一步以 `other` / `unknown` / 无工具调用的 `tool-calls` 结束后会再跑一步,所以结束原因取「最后一个写出正文的步」而不是整条流的 `finish`;`length` → 续写;其余非 `stop` 且有正文 → `answer_truncated`、不扣点、记 `compose-abort`(名字保留,现指写回答那一步)。
- D2 观测:`composeFinishReason` / `composeAborted` / `answerVisibleChars` 名字不变,含义改为「写回答那一步」,仍只有枚举 / 布尔 / 计数。
- 验证:新增 `frontend/tests/consult-single-pass-answer-20260927.test.ts`(15 条,真实 `getJyotishAgent` + 真实 skill 绑定 + 真实计算工具 + 记录提示词的假模型,计算数据来自 `fixtures/consultation-workflow-report-blocked-repairs-golden.json`):写回答的调用提示里有工具结果与 golden 盘面数值;工具结果之后只有一次模型调用;工具前、工具之间的过程说明不进回答;四标题与无标题开场保留;`length` 续写提示里有计算结果;`content-filter` / `tool-calls` / `other` / `unknown` 截断不扣点;答案钟掐断 → 截断、`compose-abort`;工具阶段到期不掐写回答;空回答走带工具的回答重试且不重复宣布计算;Pass 4 整篇被拒带提示重试;路由源码合同。修复前用同一套真实 Agent 复现:3 次模型调用,只有第 2 次提示里有工具结果,用户看到的是第 3 次写的。既有 compose 用例改写并附「原值 / 新值 / 原因」(`consultation-agentic-runtime` 6 条、`consult-answer-truncation-20260926` 全文件、`consultation-thinking-plan` 2 条、`consultation-workflow-contract` 3 条、`consultation-stream-recovery` 1 条、`application-billing-contract` 1 条)。数字见 `docs/tasks/PROGRESS-consult-single-pass-answer-20260927.md`。
- 未做(D3 范围外):约 4 万 token 的工具结果瘦身与按领域选技法、家庭拆父母 / 子女、43 行审计表。真实供应商下写回答步的耗时、`composeFinishReason` 分布与盘面引用是否对得上,需部署后按 `docs/testing/consult-single-pass-answer-20260927.md` 复核。
- 防复发:用户可见正文必须由看过本轮证据的那次模型调用写出。新增任何写回答的流,都要有「这次调用的提示里有工具结果」的真实 Agent 回归(记录提示词的假模型),不得只断言结束方式或正文形状。续写、重试这类新流必须显式带上证据或保留工具。
- 相关记录:BUG-612(分段写作再调工具,同一 compose 结构)、BUG-942 / BUG-943 / BUG-944(三通道重做,保留了丢弃主循环正文的结构)、BUG-1051(写回答时钟与结算规则,本单沿用并搬进主循环)、BUG-305、BUG-937(主循环开 thinking,不得用非 `auto` 的 toolChoice)。
- 复发自:无(新缺陷)。
- 修复版本:待提交