From 04a70923f16947ccc0a7b2a9a6256c826243c976 Mon Sep 17 00:00:00 2001 From: Jesse_Chen Date: Sun, 18 Oct 2026 15:19:45 +0800 Subject: [PATCH] =?UTF-8?q?docs(tasks):=20synastry=20report=20=E2=86=92=20?= =?UTF-8?q?chat=20brief?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 5.5 (1M context) Claude-Session: https://claude.ai/code/session_014Ad9rqAB8pXXvyzh7f4X8v --- docs/tasks/README.md | 1 + .../TASK-synastry-report-chat-20261018.md | 72 +++++++++++++++++++ 2 files changed, 73 insertions(+) create mode 100644 docs/tasks/TASK-synastry-report-chat-20261018.md diff --git a/docs/tasks/README.md b/docs/tasks/README.md index 6f53ea20..870daa74 100644 --- a/docs/tasks/README.md +++ b/docs/tasks/README.md @@ -504,3 +504,4 @@ | `TASK-marriage-match-p1-20261017.md` | #79 | 婚恋合盘引擎(搬上游 bde5d615:marriage_match + 合盘证据包;35 分七项、不分男女;第六版不扣点、不做页面)(BUG-1370 起) | 待执行(不再等 #78) | `codex/marriage-match-p1-20261017`;动表 | | `TASK-full-reading-module-parity-20261018.md` | #81 | full-reading 补齐上游 5 个模块(西占层文件没搬致永远 blocked、Navamsha / Niryaana 用我们自己的实现填键、Lagna Vargottamamsa / Pushkara / Punarphoo)(BUG-1375 起) | 待执行(可与 #78 并行) | `codex/full-reading-module-parity-20261018` | | `TASK-synastry-full-report-20261018.md` | #82 | 婚恋合盘:选人页 + 完整合盘报告(关系画像九节:结论+折叠的分析逻辑+关系时间线+技术依据摘要;英文按需;计费键 synastry.full) | 排队(等 #78、#79、#81) | `codex/synastry-full-report-20261018`;动表 | +| `TASK-synastry-report-chat-20261018.md` | — | 从合盘报告某一节进入对话问依据(绑定报告与节、对话里可用术语、只依据已存计算结果、计费照普通对话) | 待用户过目后提 issue(排在 #82 后) | `codex/synastry-report-chat-20261018`;动表 | diff --git a/docs/tasks/TASK-synastry-report-chat-20261018.md b/docs/tasks/TASK-synastry-report-chat-20261018.md new file mode 100644 index 00000000..7b19b201 --- /dev/null +++ b/docs/tasks/TASK-synastry-report-chat-20261018.md @@ -0,0 +1,72 @@ +# 任务书:从合盘报告进入对话问依据(2026-10-18) + +## 基线与顺序 + +- `origin/staging` 以开工时最新为准(`git fetch origin --prune`)。 +- 分支:`codex/synastry-report-chat-20261018`;工作树:`.worktrees/synastry-report-chat-20261018`。 +- **前置**:`TASK-synastry-full-report-20261018.md`(#82)合入后开工。本单读 #82 存下的合盘报告与每节分析逻辑。 +- **上线**:与 #79、#82 一起提升到 `main`。#82 的「对哪一段想再问清楚?」入口在本单合入前隐藏,本单负责打开它。 +- 原型(v13,报告末尾的入口):https://claude.ai/artifact/Tq6vhXFMnGitDZhJdamaHe + +## 现状实证(按符号定位) + +| # | 事实 | 位置 | +| --- | --- | --- | +| 1 | 对话只能绑一个人:`chat_sessions.chart_profile_id / chart_profile_name / chart_profile_role`;人物选择器单选 | 迁移 `20260830010000_chat_session_chart_profile_binding.sql`;`components/chat-profile-picker.tsx`、`lib/chat-profile-picker-model.ts` | +| 2 | 会话已有「类型 + 外键」的先例:`session_type`(`consultation` / `birth_time_rectification`)+ `rectification_case_id`,非普通会话锁定人物选择器 | 迁移 `20260721110000_chat_session_surface_metadata.sql`;`lib/rectification-in-chat*.ts`、`chatSessionSubjectLocked` | +| 3 | 建会话:`POST /api/sessions`,`chatSessionCreateSchema` 为 `.strict()`、`session_type` 是枚举;服务端用 `authoritativeSessionBinding` 校验绑定 | `app/api/sessions/route.ts`、`lib/chat-session-write-contract.ts`、`lib/consultation-subject-resolver.ts` | +| 4 | 「新会话 + 预填问题」只有 `continueInNewChat` 一处(`setDraft(prompt.question)`);地址栏只认 `c=` 与 `new=1` | `hooks/use-session-management.ts`、`lib/chat-session-url.ts` | +| 5 | 每轮对话固定先调 `run-jyotish-consultation`(单人本命),再按同源卡回答;证据查阅工具只认固定的 `EVIDENCE_LOOKUP_SECTIONS` | `mastra/index.ts`(`jyotishInstructions`)、`mastra/consultation-tools.ts`、`lib/consultation-evidence-card.ts` | +| 6 | 入口枚举 `consultationEntrypointSchema`(`daily_starlanguage` / `birth_time_rectification` / `guided_topic`);有入口时跳过闲聊分类 | `lib/consultation-entrypoint.ts`、`lib/consultation-smalltalk.ts` | +| 7 | 计费:每轮 `POST /api/consult` 预留 `chat.standard`;开会话不扣点 | `lib/consult/settlement.ts` | +| 8 | 护栏:`Home()` 的 `useState` ≤ 36、`useRef` ≤ 37;普通对话提示词 + 卡 ≤ 20,000 字符(含方法论 ≤ 26,000) | `frontend/tests/home-shell-growth-contract.test.ts`;`consult-card-full-source-20261007.test.ts` 等 | + +## 决策记录(产品负责人 2026-10-18) + +| # | 决定 | +| --- | --- | +| G1 | 合盘报告正文是关系语言,**印度占星的依据要能讲给用户听,引导到对话里**(产品 10-18)。入口只在报告末尾一处:「对哪一段想再问清楚?」列出第一到八节标题(含关系时间线),选一节进入对话 | +| G2 | 点一节 → 新建一个**绑定这份合盘报告和这一节**的对话,输入框预填「合盘报告里『<节名>』这一段,在我们两人的盘里依据是什么?」(英文报告用英文),**由用户自己点发送**,不自动发出 | +| G3 | 对话里**可以用印度占星术语**(星曜、宫位、分盘、大运),这是它和报告正文的分工;仍守 VOICE 的口吻,判断禁词照旧(合不合、注定、必然、灵魂伴侣等);不替两人做决定 | +| G4 | 回答**只依据这份报告已经存下的计算结果**(证据包快照、每节分析逻辑、时间线分段、技术依据摘要),不在对话里重新排盘、不新增结论;问到报告没覆盖的内容,如实说明这份合盘没算到,并建议回到各自的盘单独问 | +| G5 | 计费照普通对话:每轮 `chat.standard`,开会话不扣点 | +| G6 | 对话侧栏里这类会话标题写「A × B · 合盘追问」;当前人物是两人中任意一个时都显示;人物选择器锁定显示「A × B」 | +| G7 | 报告被删或任一人被删:报告随之删除(#82),这些会话保留文字记录,但不能再继续提问,输入框处显示「这份合盘已删除」 | + +## 硬红线 + +1. `scripts/jyotish_api_server.py` 不动;`app/(app)/page.tsx` 的 `Home()` 状态数不增长(新逻辑进 hook / lib)。 +2. 普通单人对话的提示词、同源卡、工具集**一字不改**;合盘追问用独立的提示与工具,独立的长度上限测试(提示 + 本节材料 ≤ 20,000 字符)。 +3. 证据只从本人拥有的报告里读(服务端按 `user_id` 校验,行级安全照旧);不把出生日期、出生地、经纬度放进提示。 +4. 改既有断言写三栏;动表必须真跑 `npm run test:db`;只加列、加枚举值,不删旧列。 +5. 合盘追问会话不进入单人对话的记忆与上下文继承(`continued_from_session_id`、`context_summary` 不跨类型)。 + +## 任务分解 + +| # | 内容 | 验收标准 | +| --- | --- | --- | +| T1 | **数据**:`chat_sessions.session_type` 加 `synastry_report`;加 `synastry_report_id`(指向 `personal_reports.id`,删除时置空并标记会话只读)与 `synastry_section`(节键)。`chatSessionCreateSchema`、`authoritativeSessionBinding` 同步:该类型必须带本人拥有的 `synastry_full` 报告 id 与合法节键 | `test:db`:他人报告 id 被拒;节键非法被拒;删报告后会话仍在、标记只读 | +| T2 | **入口**:#82 阅读页「对哪一段想再问清楚?」的节按钮 → 建会话 → 跳到 `c=` 并预填问题(G2);去掉 #82 里的隐藏开关 | 渲染测试;点按钮不调用 `/api/consult`、不扣点 | +| T3 | **对话链路**:`POST /api/consult` 遇到 `synastry_report` 会话,走独立分支:不调 `run-jyotish-consultation`;用新的合盘追问提示(建议 `mastra/synastry-report-chat.ts`)+ 一个只读工具「读取合盘报告某节材料」(返回该节结论、分析逻辑、对应证据条目;时间线节返回分段与两人大运;可另取技术依据摘要);入口枚举加 `synastry_report`,跳过闲聊分类;计费照 `chat.standard` | 单测:不调用单人排盘;工具只能读本会话绑定的报告;问报告外的内容时回答里有「这份合盘没算到」类说明(用固定样例走一遍) | +| T4 | **侧栏与选择器**:标题「A × B · 合盘追问」;两人任一为当前人物时显示;选择器锁定显示「A × B」;只读会话的输入框状态(G7) | 渲染测试 | +| T5 | **记录**:DESIGN.md(入口与只读态)、VOICE.md(合盘追问的口吻与术语边界)、CHANGELOG、`docs/testing/synastry-report-chat-20261018.md` 真人清单(从报告进对话、预填不自动发、追问两轮、问报告外问题、删报告后只读、英文报告进对话) | 文档齐 | + +## 让步顺序 + +T1–T3 必须一起交;T4 若来不及,侧栏先按第一个人显示,写进 PROGRESS;不得为赶工复用单人对话的提示或工具。 + +## 开工前置命令 + +```bash +git fetch origin --prune +git worktree add -b codex/synastry-report-chat-20261018 .worktrees/synastry-report-chat-20261018 origin/staging +cd .worktrees/synastry-report-chat-20261018 +git log --oneline -5 -- frontend/src/components/personal-report # 确认 #82 已合入 +grep -n "BUG-1[0-9][0-9][0-9]" docs/BUG_HISTORY.md | tail -3 +``` + +验证:前端 `tsc --noEmit`、`npm run lint`、`npm test`(含 grep 源码文本合同测试与 Home 增长护栏)、`npm run test:db`、`npm run build`(`/` 仍 Static,首屏 gzip ±2%)。真实模型回答(无模型凭据时)写成环境缺口,部署后由 Claude 在 staging 用名人合盘走一遍。 + +## BUG 编号 + +本单是产品需求;只为执行中发现的真实缺陷新增编号,起点为开工时最大号 + 1。