# TASK · 报告与聊天标注「判断不了的分盘」(2026-10-01) ## 基线 - `origin/staging` @ `00420f89`(写作时 head;开工时以最新 `origin/staging` 为准)。盘型口径(BUG-1115~1117、1131)已在其中。 - 分支 `codex/rectification-chart-tier-caveats-20261001`,工作树 `.worktrees/rectification-chart-tier-caveats-20261001`。 - **串行 / 并行**:与 `TASK-rectification-message-cleanup-20261001.md` 文件不重叠,可并行。与 `TASK-consult-plain-answer-20261001.md`:本单**不改** `frontend/src/app/api/consult/route.ts`、`frontend/src/mastra/product-voice.ts`、`consultation-evidence-card.ts`、`consultation-thinking-plan.ts`;若确需改动这些文件,排在该单合入之后并在 PROGRESS 写明。 - 不动冻结计分文件、引擎计分、盘型交付逻辑;**不改数据库结构**。 ## 事故实证(产品 2026-10-01 对比旧版 / 新版时发现) Claude 用 v5 77 例回放「采纳推荐后读到的盘对不对」(`docs/research/varga_resolution_impl_replay_2026_09_30.json` 同口径;脚本见 PROGRESS): | 窗口 | 卡片对 D9 / D10 的说法 | 采用后存下分钟的 D9 / D10 对的例数 | | --- | --- | --- | | ±10 | 74 人给推荐(D9 对 65、D10 对 64),3 人「分不开」 | 68 / 66 | | ±30 | 只对 18 / 24 人推荐,其余「分盘分不开」 | 50 / 52 | | ±60 | 全部 blocked(「分盘解读需要更准的出生时间」) | 27 / 28 | 卡片已经如实说「判断不了」,但**报告和聊天不读这个结论**,照样按存下的那一分钟读 D9 / D10 下结论。Claude 只读调研(`origin/staging` @ `a8820f2c`): - 报告:`lib/personal-report-route-core.ts::resolveReportBirthClock`(accepted / confirmed 用 `active_birth_time`)→ `resolveReportBirthTimeSensitivityInput` → 只传时分;长报告 `lib/personal-report-longform-birth.ts` 构造 `/api/professional_report_reference` 载荷,带 `birth_time_accuracy`、`candidate_range`、`time_source`,无分盘可判性;`lib/personal-report-generation.ts` 的 `birthTimePolicy` 是整份报告级标签,`demoteThemesMissingRequiredCharts` 已存在。 - 聊天:`lib/consultation-route-service.ts`(`persistedConsultationMode`、`declaredBirthAccuracyFromProfile`、accepted 时 `loadCandidateRange`);`lib/consultation-birth-time-mode.ts::applyBirthTimeModeToWorkflowContext` 只对 `unverified_birth_time` 设 `birth_time_notice` / `answer_policy`。 - 可用数据:采用时写入的 `profiles.active_birth_provenance` 已含 `contract: "segment-v1"`、`case_id`、`result_id`(`20261001010000_rectification_segment_adoption.sql`);每次服务端读资料都会带出(`lib/server-owned-birth-profile.ts`),但没人解析。分盘档位在该 result 的 `decision_receipt.inference_state.segment_summary.charts[].tier`。 ## 根因 盘型口径只改了校正交付卡;采用后下游(报告、聊天)仍只拿一个分钟,不知道哪些分盘被判为不可判。旧版同样如此(旧版连卡片都不提示)。 ## 决策记录(产品 2026-10-01) - **D1 数据源**:仅当 `active_birth_provenance.contract === "segment-v1"` 时,按其 `result_id` 读该次结果的 `segment_summary`;`tier ∈ {blocked, indistinct}` 的分盘记为「不可判分盘」。`tentative`(倾向)不标注。旧采用(非 segment-v1)、未校正资料、读取失败 → 行为与现在完全相同(读取失败要记服务端日志,不阻断报告 / 聊天)。 - **D2 聊天**:不可判分盘进入 `answer_policy`(如 `unreliable_vargas: ["D9"]`)与一句 `birth_time_notice`;Agent 不得据这些分盘下结论;用户的问题主要依赖它(婚恋问 D9、事业问 D10)时,回答里用一句大白话说明「你的出生时间范围较宽,D9 判断不了,下面只看本命盘和大运」,不展开技术细节,不拒答。文案对照 `frontend/docs/VOICE.md`。 - **D3 报告**:不可判分盘相关的章节 / 表格(该分盘的盘图、分盘解读段、依赖它的主题结论)顶部加一行固定提示「出生时间范围内这张盘的上升会变,这一节仅供参考」;依赖它的主题按现有 `demoteThemesMissingRequiredCharts` 降级。**不删除**分盘图与表(专业读者仍可看)。 - **D4 不改数据库**:读已有字段;新增一个服务端读取 helper,报告与聊天共用。 - **不做**:不改校正交付卡、不改采用规则(D7 已验证无更优变体)、不追溯修改已生成的旧报告(新生成才带提示)。 ## 硬红线 1. 非 segment-v1 资料的报告载荷与聊天上下文**逐字节不变**(用虚构旧资料做 A/B 快照测试)。 2. 读取失败不得让报告生成或聊天失败;不得在前端拿 `case_id` / `result_id` 直接查(服务端读,owner 校验)。 3. 不改数据库结构;`npm run test:db` 若涉及新查询路径须真查(AGENTS §7.6;无 Docker 时写环境缺口并给产品本地清单)。 4. Python 侧若需接收新字段(`professional_report_reference`),只加可选参数、不改既有输出;`run_quality_gate.py --profile quick` 与基线逐条一致;`jyotish_api_server.py` 不增长。 5. 前端:tsc 0、lint 0 error、npm test 失败清单与基线逐名一致且名单 0 丢失、`/` Static、首屏 gzip ±2%。 6. 隐私:fixture 只用公开名人或虚构盘;报告提示文案不含任何内部 id。 ## 任务分解 - **T1 服务端读取 helper(BUG-1138)**:`lib/rectification-adopted-chart-tiers.ts`(命名可调):输入服务端资料行,输出 `{ unreliable: ("D9"|"D10"|"D1")[], source: "segment-v1" } | null`;owner 校验;单测覆盖 segment-v1 / 旧采用 / 未校正 / 结果缺失 / summary 损坏五种。 - **T2 聊天接入(BUG-1138)**:在 `consultation-route-service.ts` 读资料处调用 T1,经 `consultation-birth-time-mode.ts` 写入 `answer_policy` 与 `birth_time_notice`;提示文本在 birth-time-mode 常量处新增,不改 `consult/route.ts`。验收:虚构 segment-v1 资料(D9 blocked)问婚恋 → 上下文含不可判 D9 与提示;旧资料上下文快照不变。 - **T3 报告接入(BUG-1139)**:经 `resolveReportBirthTimeSensitivityInput` / `personal-report-longform-birth.ts` 传 `unreliable_vargas`;章节级提示与主题降级按 D3。验收:虚构 segment-v1 资料生成报告,D9 / D10 相关章节顶部有提示、图表仍在;旧资料载荷逐字节不变;长报告 Python 侧(如需)只加可选字段。 - **T4 记录**:`docs/BUG_HISTORY.md`(BUG-1138~1139)、`CHANGELOG.md`、`frontend/docs/VOICE.md`(提示句)、`frontend/DESIGN.md`(报告章节提示样式)、`docs/testing/rectification-chart-tier-caveats-20261001.md` 真机清单(±60 窗口校正并采用 → 聊天问婚恋 → 看到一句说明;生成报告 → D9 章节有提示)、`docs/tasks/PROGRESS-rectification-chart-tier-caveats-20261001.md`、`docs/tasks/README.md`。 ## 让步顺序 T1 > T2 > T3 > T4 之外的截图。T1 + T2 可先合入;T3 若涉及 Python 长报告改动较大,可拆后续单并在 PROGRESS 写明。 ## 开工前置命令 ```bash git fetch origin --prune export PATH=/exec-daemon:$PATH && node -v # 22.x git worktree add -b codex/rectification-chart-tier-caveats-20261001 .worktrees/rectification-chart-tier-caveats-20261001 origin/staging cd .worktrees/rectification-chart-tier-caveats-20261001/frontend && npm ci ./node_modules/.bin/tsc --noEmit && npm run lint npm test 2>&1 | grep -E "^(not )?ok [0-9]+ - " | sed -E 's/^(not )?ok [0-9]+ - //' | sort > /tmp/tier-caveat-names-base.txt cd .. && PYTHONHASHSEED=0 python3 scripts/run_quality_gate.py --profile quick 2>&1 | tail -5 ``` ## BUG 编号 开工时核对 `docs/BUG_HISTORY.md` 最大号(写作时 `BUG-1131`;`1132`~`1134` 被 consult-plain-answer 预留,`1135`~`1137` 被 message-cleanup 预留)。本单:**BUG-1138**(聊天不读分盘可判性)、**BUG-1139**(报告不读分盘可判性)。号冲突顺延。关联 BUG-1115~1117、BUG-1131、BUG-690。