Compare commits

...
5 changed files with 246 additions and 0 deletions
+46
View File
@@ -0,0 +1,46 @@
# #260 开工前补充:做成动态题库,一直问到收敛(2026-11-14,Claude)
本文件补充 `TASK-rect-adaptive-20261114.md`。两份冲突时,以本文件为准。
## 产品负责人的意见(2026-11-14)
现在这套是固定题:一共 5 道,答完是什么就是什么。用户每答一题,系统其实就多知道了一些,应该据此更新后面的题,动态加题或减题,直到收敛。
## 改法:取代任务书第 1 条的「一题一题按固定顺序问」,以及第 4 条的「再确认 X 盘」入口
1. **每张盘准备多道候选题。** 每张关键盘不止一道题,候选题包括:
- D9:感情开始、结婚、分开,各算一个类别。
- D10:入职或升职、换工作或离职、创业或开店,各算一个类别。
- D2:收入明显增加、较大的支出或损失,各算一个类别。
- 同一类别里,可以用第二突出的年龄段再出一道题。
- D1:外表、胎记。
- D6、D8:补充题。补充题每张盘最多一道。
所有候选题都由 #241 已有的打分方式生成,不得新增评分规则。D6、D8 的事件题仍要等占星师定义,本单不加。
2. **每答完一题,就重新挑下一题。**
- 先拿当前时间段,算出每张关键盘还剩几种可能。
- 在还没问过的候选题里,选「最能把剩下的可能分开」的那一道。分得开的程度可以用信息量或最大分组数来衡量,具体怎么算写进 PROGRESS。
- 并列时,先选事件题,再按 D1 → D9 → D10 → D2 → D6 → D8 的顺序选。
- 已经定下来的盘,不再出它的题。
3. **什么时候停**:下面任何一条满足就停。
- 六张关键盘都已经定下来。
- 剩下的候选题都分不开剩下的可能。这时照实把那几张盘标为「还没定」。
- 问满 **12 题**。
- 用户点了「先到这里」。
4. **页面**
- 进度改为「已确认 n / 6 张盘」,配一条细进度条,不再写「第 n 题,共 N 题」。
- 结果页去掉「再确认 X 盘」入口:没定的盘会在停下前自动接着问到底。
- 首页的「继续」只对两种情况开放:中途点了「先到这里」的记录,以及旧的 v1 记录。点了之后,从已保存的那一段接着动态问。
5. **记录**:每道题都写进 `rounds`(或 v2 的 `asked`)。内容包括题目 id、它要区分的那张盘、用户的回答、答完后时间段的变化。不记原文以外的推断。
## 验收补充
- 测试盘(±15 分钟和 ±30 分钟各一组,用合成答案):
- 题目会根据前面的回答变化。同一张盘答了「记不清」后,会换一类事件或换一个年龄段再问。
- 收敛后会自动停下。
- 总题数不超过 12。把实际题数记进 PROGRESS。
- 单测要覆盖:
- 下一题的选择规则,包括并列时的顺序;
- 已经定下的盘会被跳过;
- 四种停止条件;
- 「记不清」之后会换题。
+26
View File
@@ -0,0 +1,26 @@
# #260 开工前补充 2:首页(当前使用)只留结果,不留「继续」和历史(2026-11-14,Claude)
本文件补充 `TASK-rect-adaptive-20261114.md` 和 `FIX-rect-adaptive-0.md`。几份文件冲突时,以本文件为准。
## 产品负责人的意见(2026-11-14,看了真机首页)
- 「继续」没有用。上次答过的题,再进去还是同样的题,用户只会给同样的答案。不能让用户为了凑出一个结果去改答案:那是用户的生日,不是系统的生日。
- 「已定 4 张盘,提到 2 件事」这类统计不需要显示。用户只要看到上次拿到的时间。
- 既然选中了代表时刻,首页就要把代表时刻显示出来。只显示时间范围没有用。
- 不需要历史列表(「历史 2 次」)。
## 改法(`ChartChoiceHome`,即 `chart-choice-page.tsx` 约 1091–1175 行)
1. **主标题改成代表时刻。** 大字显示代表时刻,比如 `05:01`;有秒就显示秒,比如 `05:01:12`。紧接着下面一行小字显示 `范围 04:59:43–05:15:00`。
2. **删掉这一行:** 「代表时刻 05:01,你填的是 05:00」。刻度尺上的 `▲ 05:00` 已经标出了用户填的时间。
3. **刻度尺和六张盘的行保持不变。** 没定的盘照实写「还没定(05:07:55 换)」。
4. **删掉「还有 n 张盘没定」和「继续」按钮。** 同时删掉首页上 `onResume` 这条入口,v1 旧记录和「先到这里」停下的记录也一样。按照 FIX-0,答题时已经一路问到收敛;剩下没定的盘就是没定,不再提供重答入口。想重来就点「重新纠正」。
5. **整块删掉「历史 / n 次」列表**,包括 `chart-choice-history`、旧记录的打开入口和 `historySubline`(「已定 n 张盘,提到 n 件事」)。后端照常保存历史记录,只是不再显示,接口不改。
6. **底部两个按钮保持不变:** 「看星盘」和「重新纠正」。
7. **结果页**也删掉事件计数句:「你提到 n 件有日期的事,n 件和这一段的大运对得上」,以及「你提到的事,n 件」这个标签。结果页只说时间、各盘、哪些还没定。
## 验收
- 截图:一条已全部定下的记录、一条有两张盘没定的记录,宽度 390 和 1280 各一张。
- 首页上不出现以下文字:「继续」「历史」「件事」「你填的是」。
- 测试改为断言以上四个字串都不出现,并断言代表时刻显示为主标题。
+72
View File
@@ -0,0 +1,72 @@
# #260 补充 3:按上游方法对齐动态题库(2026-11-14,Claude)
本文件补充 `TASK-rect-adaptive-20261114.md`、`FIX-rect-adaptive-0.md` 和 `FIX-rect-adaptive-1.md`。几份文件冲突时,以本文件为准。
产品负责人的规定:生时纠正跟上游占星师的方法走,不能自己另起一套。本文件里列出的上游依据都在 `/workspace/yinduzhanxing`(5fb8379c):
- `references/birth-time-rectification-decision-tree.md`
- `scripts/active_rectification_questions.py`
- `scripts/active_rectification_selector.py`
- `scripts/active_rectification_candidates.py`
- `scripts/active_rectification_events.py`
## 1. 题目按「事件领域」出,不按「一张盘一道题」出
上游的题库是按生活领域写的,每个领域绑定一张主分盘(见 `QUESTION_BINDINGS` 和决策树第 4 节)。一道题只要能把当前剩下的候选时间段分开,就有用,不管它属于哪张盘。我们的 6 张关键盘(D1、D9、D10、D2、D6、D8)只用来判断什么时候停,不决定问什么。
候选题按领域准备。年龄沿用产品规则,从 18 岁起问:
| 领域 | 主分盘 | 题目内容(示例) | 可靠度(上游 `DOMAIN_RELIABILITY`) |
|---|---|---|---|
| 学业 | D24 | 升学、毕业、读研、换专业 | 1.0 |
| 搬迁 | D4 | 搬家、离乡、出国、长期异地 | 0.95 |
| 感情 | D9 | 开始恋爱、结婚、分开 | 0.95 |
| 工作 | D10 | 入职、换工作、创业、职责明显加重 | 0.9 |
| 公开身份 | D10 / A10 | 升职、作品公开、身份变化 | 0.82 |
| 钱财 | D2 | 收入明显增加、较大支出或损失 | 0.8 |
| 子女 | D7 | 孩子出生 | 0.85 |
| 父母 | D12 | 父母的重大变故 | 0.75 |
- 每道题的选项年龄段,仍然用现有的 `_dasha_score` / `_varga_score`(Vimshottari MD/AD/PD + Narayana MD/AD)算出来。领域对应的宫位和事件星,用 `astrologer.EVENT_CATEGORIES`;没有的类别,从上游 `active_rectification_event_engine.py` 补上。
- **D30 健康题,这一轮不做。** 上游规定:只有用户有明确的健康事件时才用,而且要等候选窗口收窄以后才能问(`_question_gating`,候选数 ≤ 24)。这件事需要产品负责人拍板,这一轮不要做。
- 主盘(D1)的外貌和胎记题保留,仍然只在 D1 线存在时问(上游 advanced 第二阶段「外貌和胎记预筛」)。
- **删掉 D6 / D8 的「哪种更像你」补充题。** 上游的生时纠正里没有这类题。D6 和 D8 只能靠事件题顺带定下来;定不下来,照实标「还没定」。
## 2. 选下一题的打分,照搬上游 `_score_question`
在 FIX-0 的「最能把剩下可能分开」之外,再加上上游的几个分量:
- 分开程度 × 3
- 可靠度 × 2.5
- 用户答题的省力程度 × 1.5
- 领域多样:同一领域问过一次,再问时扣 1.5(`_question_domain_priority`),另外再扣 1(`_score_question`)
- 最高分低于门槛就停(上游门槛是 `best < 4.0`,停止原因 `no_answer_can_improve_separation`)。我们的分值尺度不同时,在 `docs/tasks` 里写清楚换算方法。
FIX-0 的「最多 12 题」继续保留,作为产品上限。上游没有这个数字,题库本身只有 8 个领域。
## 3. 结果要带上游的把握分级
依据上游 `active_rectification_events.py` 约 325–357 行:
- **低:** 有日期的事件少于 3 件;或者领域少于 2 个;或者选中的段宽超过 15 分钟;或者领先幅度不到 10%。
- **高:** 事件至少 4 件,领域至少 3 个,段宽不超过 5 分钟,领先幅度至少 20%。
- **其余为中。**
- **Narayana 降级:** 如果 Vimshottari 支持选中的段,但 Narayana 在这一段是反对的,把握最高只能是低(上游 `score_answers` 里 `downgrade_reasons` 的 narayana 一项)。
显示方式:首页和结果页的代表时刻旁边,只放一个词「把握 高 / 中 / 低」。FIX-1 第 7 条删的是事件计数句,**把握分级要保留**。
有日期的事件少于 3 件时,结果只叫「倾向」。这是之前已经定下的规则,不变。
结果永远不说「已验证」:上游是 `claim_status=candidate`、`not_birth_time_truth`。档案里的出生时间也不改,这一条维持现状。
## 4. 验收新增:用 77 个公开案例做回放(不调模型)
- 用 holdout v5 的 77 个 AA 案例(脚本参照 `docs/research/artifacts/rectification-width-funnel-2026-10-16/seg_placebo.py`)。用每个案例已知的、有日期的事件,模拟用户回答新流程。
- 报告以下几项,写在 `docs/tasks/rect-adaptive-replay.md`:
- 选中的段包含真实时间的比例;
- 随机选一段的比例;
- 直接用用户填的时间所在段的比例(11-06 的基线是 19% / 20% / 34%);
- 平均问了几题;
- 各种停止原因的占比;
- 把握高 / 中 / 低各占多少,以及每一档的实际命中率。
- 结果不好也要如实报告,不许调参调到好看。上线与否由产品负责人看完数字再决定。
+33
View File
@@ -0,0 +1,33 @@
# #260 补充 4:加上健康题(D30),按上游门槛来问(2026-11-14,Claude)
产品负责人 11-14 拍板:要加健康题。本条取代 FIX-2 第 1 节里「D30 健康题这一轮不做」那一句。
上游依据:
- `references/birth-time-rectification-decision-tree.md` 第 4 节和第 6 节:D30 只在有明确的健康事件时使用。
- `scripts/active_rectification_questions.py` 里 `health_crisis_or_low_period` 的绑定:event_categories health / loss,dasha_tracks Vimshottari + Narayana + Transit。
- `scripts/active_rectification_selector.py` 的 `_question_gating`:候选窗口收窄以后才能问。
## 怎么问
1. **领域:** 健康 / 意外,主分盘 D30,可靠度 0.72(上游 `DOMAIN_RELIABILITY`)。年龄段的算法和其他事件题一样:用 `_dasha_score` / `_varga_score` 算出来,宫位和事件星按上游 health 类别(6、8 宫,参照 `active_rectification_event_engine.py`)。
2. **门槛:**
- 至少答过一道非健康的事件题,并且当前剩下的候选段不止一段,才能问;
- 第一题永远不能是健康题;
- 整个流程里健康题最多问 1 道。
3. **题面用中性语言,** 只问发生过什么:「你在哪个年龄段有过比较大的健康变故,比如手术、住院、意外受伤?」不写疾病名称,不写「危机」「灾」这类字眼。
4. **选项:** 年龄段(带年份)、「都没有」,外加一个与「记不清」同样大小的「不想回答」。选「不想回答」等同于「记不清」,不算作否定。
5. **展开后的细项按钮:** 手术 / 住院 / 意外受伤,三选一,加上年份。
6. **隐私:**
- 健康答案只用于这次纠正打分,不写进报告和咨询的上下文,不显示在首页,也不进日志原文;
- 记录里只存年份和类别,不存自由文字。
7. **D30 不加入 6 张关键盘。** 结果页和首页不出现 D30 这一行。健康题的作用只是帮忙把候选段分开。
## 验收补充
- 回放报告里单列一行:有健康题和没有健康题时的选中率对比。
- 测试覆盖以下几点:
- 第一题不是健康题;
- 健康题最多 1 道;
- 「不想回答」不影响打分;
- 健康答案不出现在报告或咨询的输入里。
+69
View File
@@ -0,0 +1,69 @@
# TASK:生时纠正改为边答边缩小;年龄选项带年份;选中样式重做;结果页去掉「对不上」「再补几件事」和回测说明(2026-11-14)
- Gitea:#260(接 #239)
- 分支:`codex/rect-adaptive-20261114`,基于 staging `cbc7fdccf58674b81cdac36bf6cbb36116fce5ec`
- Bug 编号:BUG-1881
- 验收:Claude(jyotisha-e6)
不得自行写「产品决定/裁定」;任务书没写到的取舍,一律选需拍板。不得修改或删除既有断言来让测试通过;确需修改的,写明原值、新值和原因。
## 产品负责人真机反馈(2026-11-14)
1. 旧记录的首页上,时间尺的「分界 04:59:42」和「存 05:00」叠在一起。
2. 年龄选项只写「20 岁」,用户还得自己去算是哪一年。
3. 选中后整块涂上暗红,深色模式下很难看。
4. 结果页列出四条「你的回答有一处对不上……」,用户看了也没法处理。原话:「你就告诉对不上,你有解决办法吗?你没有啊,那你说这个有啥用」。
5. 「再补几件事」点进去,问的还是那 5 道题,没有用。
6. 「这个方法有多准」(77 个案例)整段不要。
## 要做的
### 1. 引擎:边答边缩小(`scripts/chart_choice/`,接口 `chart_answers`)
- 按 D1 → D9 → D10 → D2 → D6 → D8 的顺序**一题一题来**。每答完一题,就用这个答案把当前时间段缩小(取交集)。
- 下一题**只列出在当前时间段里还可能的选项**;年龄段按这几种可能重新算。某张盘在当前段里只剩一种可能,**直接跳过,不出题**。
- 「都没有」「记不清」不缩小时间段,这张盘照旧记为「还没定」。
- 因为每题只给还可能的选项,正常作答不会再出现冲突。万一出现(例如改答案后),冲突只记进后台的 `conflict`,**接口不再返回给页面展示**。
- 接口改成一题一请求:带上已答的内容,返回下一题,或者返回结果。前端「第 n 题,共 N 题」里的 N,按当前预计还要问的题数动态显示。
- D6、D8 的补充题也照此处理。通常前面几题答完,它们已经被定下来,不会再问。
### 2. 年龄选项带年份
- 选项写成「20 岁(2017 年前后)」「27–28 岁(2024–2025 年)」。年份按出生日期折算,跨两年时写成年份区间。
- 展开后「哪一年」的默认值,取这个年龄段的第一年(已经是这样,保留)。
### 3. 选中样式(浅色、深色都按这个)
- 选中的选项块**不再整块换底色**:底色和其他选项一样,外加 1.5px 的强调色描边(用 inset ring,不占布局),选项文字和迷你时间带改成强调色。
- 展开后,「什么事」的按钮未选中时只有 1px 细边框、透明底,选中时填实心强调色加白字。「哪一年」的加减器也只用细边框,不加底色块。
- 深色模式下,所有底色用 `--color-surface-dark*` 这套 token,不要叠半透明的红。
- 展开动画照旧。
### 4. 结果页
- 删掉所有「你的回答有一处对不上……」这类句子。
- 「依据」只留一行,写对得上的事件,例如「2020 年入职或升职、2023 年收入明显增加,和这段时间的大运对得上。」有日期的事少于 3 件时,在同一句末尾加「先作参考」,不另起一行。
- **「再补几件事」改成按条件显示。** 只有当某张盘还没定,**并且**引擎还有一道**没问过的新题**能区分它(例如另一个事件类别,或第二个年龄段)时,才显示「再确认婚恋盘」这类入口,点进去只问这道新题。没有新题就不显示。引擎接口要返回 `followups: [{chart, question_id}]`。
- **整段删掉「这个方法有多准」**。页面上不再出现 77 个案例和那组百分比。顶部标题照旧写「按你的回答,出生时间在 X 到 Y 之间」。
- 结果页和首页的六张盘那几行保持现状,不变。
### 5. 时间尺标签不重叠
- 所有时间尺(首页的旧 v1 记录、范围页、答题页、结果页)都要处理:两个标签离得太近时,一个放在尺上方,另一个放在尺下方。下方已有端点时间时,靠近的那个端点时间隐藏。
- 首页的旧 v1 记录(「线后这张盘」那种)要专门修好这一处。
## 验收
- 测试盘(±15 分钟、±30 分钟各一组):
- 实际出题数要比修订五更少(写进 PROGRESS);
- 正常作答不出现冲突;
- 年龄选项带年份;
- 选中样式浅色、深色各截一张图;
- 结果页没有冲突句、没有回测说明,「再确认 X 盘」只在有新题时出现;
- 首页 v1 记录的时间尺标签不再重叠。
- 单测要覆盖:
- 答完上一题后,下一题的选项被正确缩小;
- 某张盘只剩一种可能时被跳过;
- 改答案后冲突只出现在后台;
- `followups` 在有新题时出现、没有新题时为空。
- 质量门、前端测试、tsc、eslint 全部通过。截图先给产品负责人看过,才能标 `待真机`。