Compare commits

...
3 changed files with 238 additions and 5 deletions
@@ -0,0 +1,89 @@
# TASK:默认前后 30 分钟改为研究情景:个人报告、年运、合盘(2026-11-15)
- Gitea:#280
- 分支:`codex/default-window-scenario-20261115`,从 staging 的本任务书提交切出。
- Bug 编号:BUG-1891(BUG-1890 已由生时纠正 #279 占用)。开工时核对 `docs/BUG_HISTORY.md` 末尾;已被占用就顺延,并在 PROGRESS 写明。
- 负责验收:Claude(jyotisha-3f)。
- 同时在做:
- #279(生时纠正,BUG-1890):改生时纠正页面,以及 `frontend/src/lib/personal-report-longform-birth.ts` 的回退逻辑。本单不碰这个文件。
- #281(合盘第 3 批,BUG-1892):会改 `synastry-full-sections.ts` 和 `synastry-full-technical.ts` 的附录部分。各改各的函数,后合入的负责 rebase。
任务书没写到的取舍,不得写成"产品决定"或"裁定",一律标「需拍板」。不得修改或删除既有断言来让测试通过。确需修改的,在 PROGRESS 逐条写明原值、新值和原因。
## 背景
- 占星师 2026-11-15 合盘裁定 Q6:没有自报误差时,前后 30 分钟只能算研究情景,不是已知的出生区间,不能据此认证稳定;稳定只在检查过的范围内成立。
- 产品负责人 2026-11-15:个人报告、年运、合盘、生时纠正一起改。生时纠正页面由 #279 做,本单做三个报告。
- 规则见 `references/product_runtime_contract.md` M 节(本任务书同一提交)。
- 现状举例(不全,开工先盘点):
- `scripts/report_render/birth_precision_window.py` `birth_window_label_zh`:「没有误差信息,按前后各 30 分钟」。
- `scripts/report_render/upstream_sync_chapters.py:121-123`:`stable` →「稳定」,`stable_across_window` →「窗口内稳定」。
- `scripts/report_render/audit_chapters.py:544`:stability 显示「稳定」。
- `scripts/report_render/evidence_grade.py:238-243`:`purpose_stability == "stable"` 时不加「需说明」。
- `frontend/src/lib/annual-report-generate.ts:195, 781`,`frontend/src/components/annual/annual-report-page.tsx:254`:年运的误差说明。
- `frontend/src/lib/synastry-full-technical.ts:190`:合盘附录「误差内稳定」。
- `scripts/marriage_match_service/birth_precision.py`:合盘每人的 window_label。
## 要做的
### 1. 盘点
- 找出三个报告里所有向用户显示"稳定 / 不变 / 已确认"类判断的地方,包括页面、导出(.md)、写作输入和追问对话材料。
- 只看依赖出生时间窗口的判断,跟星座含义无关的「稳定」不算。
- 在 PROGRESS 列表写清:位置、现文案、窗口来源、改后文案。
### 2. 文案
窗口来源决定写法;内部状态码(`stable`、`stable_across_window`、`varies` 等)不改。
| 窗口来源 | 没有变化时写 |
| --- | --- |
| `default_unknown_30` | 按前后 30 分钟试算,没有变化(没有填写误差,这只是试算,不能确认稳定) |
| `user_stated` | 在填写的误差范围内没有变化 |
| `rectified_range` | 在生时纠正选定的区间内没有变化 |
| `confirmed_minute` | 维持现状 |
- 括号里那句,同一页面或导出只出现一次,放在误差来源那一行;其余地方用前半句。
- `birth_window_label_zh` 默认来源改为「没有填写误差,按前后各 30 分钟试算」。
- 会变的层照常写候选值,不改。
- 写作输入里,研究情景下没有变化的层,用同样的说法。提示词加一条:不得写成「稳定」「已确认」「不会变」。
### 3. 等级
- **个人报告**:窗口来源是 `default_unknown_30` 时,`purpose_stability` 不得为 `stable`。改成新值 `default_window_scenario`,并进入 `must_disclose`,等级上限不变。
- **年运**:`scripts/annual_service/evidence_grade.py` 里,默认窗口下状态为 `stable` 的依赖:
- 仍算可用,不因此降为 D,也不因此提高等级;
- 加进 `must_disclose`,标识写成 `default_window_scenario:<依赖 id>`;
- 前端 `DEPENDENCY_LABELS` 和「需说明」的显示写成「××按前后 30 分钟试算」。
- 两处都要在 PROGRESS 写明 grades 的 sha256 会变,以及旧报告怎么显示。旧快照照常显示,不报错。
### 4. 不改的
- 窗口怎么取(#224)不改;`personal-report-longform-birth.ts` 不碰。
- 生时纠正页面、选盘页不碰(#279)。
- 冻结文件、她的 `skills/**`、`references/**`(M 节已由本提交写好)、`consult-preset-prompts.ts` 不碰。
- 不调用 DeepSeek。
## 测试
- `tests/test_default_window_scenario_20261115.py`、`frontend/tests/default-window-scenario-20261115.test.tsx`。
- 用合成数据覆盖:
- 个人报告、年运、合盘,三种窗口来源各一条,文案符合上表;
- 默认窗口下,没有出现「稳定」「误差内稳定」「窗口内稳定」「已确认」;
- 个人报告默认窗口:`purpose_stability` 不是 `stable`,`must_disclose` 有对应项;
- 年运默认窗口:`stable` 依赖进了 `must_disclose`,cap 和改前相同;
- 旧快照照常显示;
- 用户可见文字没有「·」、字段名或下划线。
## 要改的文件
- 第 1 节盘点到的文件(上面列的那些)。
- `docs/BUG_HISTORY.md`,只在末尾追加。
- `docs/tasks/PROGRESS-default-window-scenario-20261115.md`。
## 验收标准
1. PROGRESS 盘点表完整;验收时我会用 grep 抽查。
2. 公开名人盘,三个报告各一份,都没填误差:误差来源那一行写明「只是试算」,没有一处把默认窗口写成稳定。
3. 年运和个人报告的等级上限与改前一致,只多出「需说明」。
4. tsc、eslint(0 错)、`npm test`(基线失败除外)、quick gate 全部通过。
+130
View File
@@ -0,0 +1,130 @@
# TASK:合盘第 3 批:十节结构、加载她的写作文件、附录可见范围(2026-11-15)
- Gitea:#281
- 分支:`codex/synastry-b3-20261115`,从 staging 的本任务书提交切出。
- Bug 编号:BUG-1892。开工时核对 `docs/BUG_HISTORY.md` 末尾;已被占用就顺延,并在 PROGRESS 写明。
- 负责验收:Claude(jyotisha-3f)。
- 同时在做:#280(默认窗口改为研究情景,BUG-1891),会改 `synastry-full-technical.ts` 的误差文案和 `birth_precision.py` 的 window_label。各改各的函数,后合入的负责 rebase。
任务书没写到的取舍,不得写成"产品决定"或"裁定",一律标「需拍板」。不得修改或删除既有断言来让测试通过。确需修改的,在 PROGRESS 逐条写明原值、新值和原因。
## 背景
- 占星师 2026-11-15 回复了合盘八问。网站要遵守的规则已写进 `references/product_runtime_contract.md` L 节(本任务书同一提交,替换了 11-14 的暂行版)。
- 本单做 L 节里的这几项:
- 用户章节(Q7)
- 附录可见范围(Q1)
- 两个事件状态的中文(Q4 的翻译部分)
- 逐条等级的依赖表草稿(Q2 的第一步)
- 以下几项不在本单:
- 研究扫描、公开化、法律婚严格路径、首次接触(第 4 批)
- 逐层误差(Q6)、Raman 主动开启(Q8)(第 5 批)
- 逐条等级的实现:等她审完依赖表再做
## 要做的
### 1. 十节用户结构(她 Q7)
- 用她 `skills/jyotish-full-synastry-reading/references/customer-report-shape.md`「Required User-Facing Sections」的 10 节,中英文都改:
1. 结论总纲
2. 各自带入关系的需求
3. 情绪安全与相处感受
4. 吸引与亲密
5. 沟通、冲突与修复
6. 关系如何推进
7. 共同生活的收益与压力
8. 能不能稳定走下去
9. 关系应期
10. 现实建议
- 英文标题取她 `validate_bilingual_synastry_delivery.py:21` 的 `EN_HEADINGS`,第 10 节写 `Practical Advice`。
- 现在用作标题的内部判断顺序(命局承诺、配偶与婚姻承载、两盘交感、能否久处、辅助证据与边界),以后只作内部推理,不作用户标题。
- **section_id**:
- 用稳定的 id 绑定标题。现有 9 个 id 保留给旧报告。
- 需要新 id 时,新建 migration 放宽 `chat_sessions_synastry_section_check`,在 PROGRESS 写明映射。
- 新快照写 `structure: "skill_v3"`。`skill_v2` 和更早的报告按原来的顺序和标题显示,不报错。
- **每节的写作说明**:照她 report-shape 对该节的要求重写 `SECTION_TASKS`。逐项要求都要写进去:第 3 节的六段法,第 4 节的四个问题,第 8 节在 D9 双人互动已经算出时要交代它对 D1 结论是强化、补充还是构成条件。
- **每节的证据**:`SECTION_BRIEFS` 按新节重排,对应她 `reader_section_brief[].section` 的 id。原来「辅助证据与边界」一节的传统配对材料,归到第 8 节或附录,在 PROGRESS 写明归到哪里。
- 第 9 节「关系应期」的内容本单不改(第 4 批),只换标题和位置。
### 2. 加载她的写作文件
- 每次写作时,把她的文件放进提示词:中文用 `SKILL.md`、`references/chinese-synastry-writing-contract.md`、`references/customer-report-shape.md`;英文把中文写作合同换成 `english-synastry-writing-contract.md`。
- 快照记录 `actually_loaded`:每个文件的路径和 sha256。复用 `synastry-full-create.ts` 的 `SKILL_SNAPSHOT_SHA256` 做法;文件变了就要能看出来。
- 她的文件里写「私有证据包不得附进客户稿」,这条已被她 11-15 Q1 改掉。在提示词里写明:附录由程序生成,模型不写附录,正文照她的写作合同写。
- 我们自己的 `ZH_SYSTEM` / `EN_SYSTEM` 与她的文件重复或冲突的句子,删掉或改成引用她的。每条删改在 PROGRESS 写原值、新值和原因。
### 3. 移植她的单语交付检查
- 把她 `validate_bilingual_synastry_delivery.py` 里适用于单语的检查,移植到我方合盘 gate:
- 第一句从双方的体验切入(`ZH_AFFECTION_OPENING_TERMS`);
- 不能用分析者口吻开头(`ZH_ANALYST_LED_OPENERS`);
- 温暖与空间都要覆盖(`ZH_AFFECTION_SECTION_WARMTH_TERMS` / `BOUNDARY_TERMS`);
- D9 已算出时第 8 节要提到 D9;
- 10 个固定标题;
- 篇幅门槛(`ZH_SECTION_MIN_CHARACTERS`、`ZH_READER_MIN_CHARACTERS`,英文对应);
- `READER_BANNED_TERMS`。
- 常量从她的脚本导入或逐字复制,并注明来源行号。她的检查器缺第 10 节,我方按 10 节检查,并在注释里写明以她 11-15 Q7 为准。
- 失败时和年运一样:先重写一次,仍不过的照现有规则处理。不得在页面上显示「没有通过核对」(11-13 业主规则)。
### 4. 附录可见范围(她 Q1)
- 补充方法(Western synastry/composite/Davison、Shukuyo、Prashna)在「技法执行情况」里单独成组,分三类:
- 已执行,并用于结论:写名称、来源传统、在本报告里的作用;
- 已执行,但没有用于结论:单独列出,写「已计算,未用于结论」;
- 没有执行:写「未执行」和原因,不得写成已计算。Prashna 没有真实提问时刻盘的,写「暂不能判断:没有提问时刻盘」。
- 来源传统用中文写,例如「西方占星」「日本宿曜」,不得写成印度占星依据。
- 现有检查里禁止附录出现补充方法名的断言(包括 `report-no-web-wording-20261109.test.ts` 等),改成只在正文和追问对话里禁止。每条改动写原值、新值和原因。正文仍不点名补充方法;她要求用户明确只要印度体系时不加入补充推论,现状本来就不加,保持不变。
- 工程字段名、路径、令牌不进附录(现有检查保留)。
### 5. 事件状态的中文(她 Q4 翻译部分)
- `synastry-full-timeline.ts` `PAIR_STATUS`:
- `not_established`:「本证据链尚未建立」/ "This evidence chain is not established yet"。
- `one_sided`(以及 `one_sided_or_incomplete`,如有):「单侧或证据不完整」/ "One-sided or incomplete evidence"。
- 不得写成「不会发生」「不成立」「另一方没有激活」。旧报告重新显示时也用新文字。
### 6. 逐条等级依赖表草稿(她 Q2,只写文档)
- 新建 `docs/synastry-claim-dependencies-draft-20261115.md`。按她 Q2 的 7 类结论,把她写的每项依据落到 dossier 的字段路径,并标出现在是否已经算出:
- 情绪安全
- 吸引/亲密
- 沟通/修复
- 关系推进
- 共同生活
- 长期稳定
- 关系应期
- 每行写:结论类型、她写的依据、字段路径、当前状态(已算出 / 部分 / 没有)、缺的话是哪里缺。
- 只写文档,不写代码,不改等级逻辑。她审完再做。
### 7. 不改的
- 冻结文件、她的 `skills/**`、`references/**`(L 节已由本提交写好)、`consult-preset-prompts.ts` 不碰。
- 不改事件扫描、四类事件、断言标签、误差逻辑、Raman 显示。
- 不调用 DeepSeek。测试用桩写手。真实样例由验收方生成。
## 要改的文件
- `frontend/src/lib/synastry-full-sections.ts`、`synastry-full-generate.ts`、`synastry-full-timeline.ts`(只限第 5 节)、`synastry-full-technical.ts`(只限附录分组)、`synastry-report-view.tsx`、合盘 gate 所在文件。
- 新 migration(如需新 id)。
- 测试:`frontend/tests/synastry-b3-20261115.test.tsx`、`tests/test_synastry_b3_20261115.py`(如有后端改动)。覆盖:
- 新快照 10 节,中英标题对;
- 9 节应失败,只有标题没有正文应失败;
- 开头不是体验时失败;
- D9 已算出而第 8 节没提 D9 时失败;
- `actually_loaded` 有三份文件和 sha256;
- 旧 `skill_v2` 快照照常显示;
- 附录补充方法分三类;
- Prashna 写暂不能判断;
- 正文不点名补充方法;
- 两个状态的中文;
- 用户可见文字没有「·」、字段名或下划线。
- `docs/synastry-claim-dependencies-draft-20261115.md`
- `docs/BUG_HISTORY.md`,只在末尾追加
- `docs/tasks/PROGRESS-synastry-b3-20261115.md`
## 验收标准
1. 公开名人盘一对,用桩写手:页面和快照是 10 节,标题与她的 report-shape 一致;附录补充方法分三类;状态中文正确。
2. 合成测试覆盖上面列出的每种情况。
3. 依赖表草稿 7 类都有,字段路径能在公开名人盘的 dossier 里找到。
4. tsc、eslint(0 错)、`npm test`(基线失败除外)、quick gate 全部通过。
+19 -5
View File
@@ -353,10 +353,24 @@ evidence_card.backstage records, for the backend only, that global web evidence
- 研究方法(Yoga/Nakshatra Pravesha)只作观察,不进必需。
- 本条不减少她要求执行的任何技法,也不把「需说明」项写成结论依据。
## L. 合盘的暂行做法(产品 2026-11-14,待占星师裁定)
<!-- 产品对她合盘子 skill(skills/jyotish-full-synastry-reading,7a773d13)的暂行落地,不是她的方法。依据:2026-11-14 合盘差距盘点;产品负责人 2026-11-12「计算依据附录照实列网上资料核对、真实案例校准两行」、2026-11-13 出生时间误差规则(#224)。下列各条在她裁定前暂行,裁定后按她的改。 -->
## L. 合盘的落地做法(产品 2026-11-14,按占星师 2026-11-15 合盘八问裁定修订)
<!-- 依据:占星师 2026-11-15《合盘八问裁定回复》(Q1–Q8);产品负责人 2026-11-12「计算依据附录照实列两行核验」、2026-11-15「按候选时间逐层算出并列给用户不算在报告里分支」「前后 30 分钟只是研究情景,个人报告、年运、合盘、生时纠正一起改」。她的源仓(skills/jyotish-full-synastry-reading)尚未按裁定修改;源仓和网站冲突时,以她 11-15 的裁定为准,并在回执里写明。 -->
- 技法执行情况分两栏:「计算」照她回执的状态写;`ready_for_comparison` 写「输入已齐」,不写「已执行」(她 SKILL.md:105-107)。「在本报告中」是产品的 v1 映射:executed、ready_for_comparison 写「供写作参考」,parameter_sensitive、partial 写「只作观察」,blocked、not_applicable 写「未使用」并附理由。
- 附录照实列「网上资料核对:未完成」「真实案例校准:未完成」两行。正文不提。
- 出生时间误差:每人用自报误差,没填按前后 30 分钟。某人的 D1 上升、D9 上升或月亮星宿在误差内会变时,只把这个人一侧依赖它的层,以及用到这一侧的两盘对照,标为参数敏感,并在附录写明;另一人不受影响。是只封一侧还是整层都封,待她裁定(合盘问题 6)。
- 以下沿用现状,待她裁定,不算产品规则:附录显示的回执方法名(问题 1)、模型自选的 6 个断言标签(问题 2)、产品自写的逐类激活扫描和四类事件(问题 3–5)、Raman 默认并列显示(问题 8)。
- 附录照实列「网上资料核对:未完成」「真实案例校准:未完成」两行。正文和追问对话不提。
- 可见范围(她 Q1):合盘和个人报告、年运一样,结构是结论、主题叙述、证据附录。附录列参数与实际日期、必要的原始结构和周期边界、实际执行和使用情况、冲突、两行核验状态。补充方法(西方合盘、星宿文化、卜卦)实际执行了,附录写名称、来源传统和作用;执行了但没用于结论的单独列;没执行的不得写成已计算。补充方法不得写成印度占星依据,也不提高应期精度。卜卦没有真实提问时刻盘的,标 blocked。工程日志、令牌、私有路径、其他客户资料不进客户稿。旧的禁词和附录检查器跟着改,不得用删掉依据的办法通过检查。
- 断言标签和证据等级(她 Q2):保留她的 6 个断言标签和真实调用状态,另加 A–D 等级上限,两轴分开,不从标签换算等级。等级上限由后端按她给的依赖表定,模型只能写到上限或更低;依赖在写作前冻结。没有对得上的案例不得给 A/B;无关层缺失不把整篇降为 D。依赖表落到字段路径后交她审。
- 计数(她 Q3):Vimshottari 和 Narayana 保留两条调用记录,但不算两张独立票;同一事件的 MD/AD/PD 和衍生指标不重复计。两人对同一事件都要通过 promise、activation、manifestation、label 门控;通过也只算 `candidate_alignment_requires_event_history`。
- 产品扫描(她 Q4):保留为具名、带版本的「研究扫描」,去掉「满两条线=多线」。研究候选不能绕过门控成为双人事件;和她的 gate 冲突时页面写明。`not_established` 写「本证据链尚未建立」,`one_sided_or_incomplete` 写「单侧或证据不完整」。
- 事件类别(她 Q5):首次接触、心动、成为伴侣、公开化、法律婚姻分开,不合并接触和心动。公开化的社会轴没有书证规则前,公开化判定标 blocked,保留原始结构。年度层的 Tajika、太阳回归、Muntha 不是三张独立票。
- 出生时间误差(她 Q6):只把变化一侧依赖它的层及用到这一侧的两盘结论标出,另一人不受影响。逐层核对(DK、UL、宫位、大运等),不因时间不稳机械认定每层都变。各候选分支已经算出且能展示差异的,用 parameter_sensitive;缺输入、分支没算或关键依赖没有结果的,用 blocked 并写原因。按候选时间算出并列给用户,不替用户选,不算在报告里分支(产品 2026-11-15)。默认前后 30 分钟按 M 节。
- 用户章节(她 Q7):按 customer-report-shape 的 10 节,包括「十、现实建议」。内部判断顺序不作用户标题。
- Raman(她 Q8):`raman_muhurtha_v1` 由用户主动开启「比较其他流派」后才显示,记录选择和口径;不取较高分裁定关系。配对口径和岁差是两个参数。缓存键含两人的输入版本、计算日期、误差范围、计算与配对口径、依赖和规则版本。
## M. 默认前后 30 分钟只是研究情景(产品 2026-11-15)
<!-- 依据:占星师 2026-11-15 合盘 Q6「没有自报误差时 ±30 分钟只能标研究情景,不是已知出生区间,不能据此认证稳定;稳定性只在已检查范围内成立」;产品负责人 2026-11-15「个人报告、年运、合盘、生时纠正一起改」。生时纠正页面由 #279 处理。 -->
- 用户没填误差时,前后 30 分钟(`default_unknown_30`)是研究情景,不是已知的出生区间。窗口怎么取不变(#224)。
- 在研究情景里没有变化的层,用户可见文字写「按前后 30 分钟试算,没有变化」,不写「稳定」「误差内稳定」「已确认」。有自报误差或纠正区间时,写「在填写的范围内没有变化」或「在纠正选定的区间内没有变化」;稳定只在检查过的范围内成立。
- 等级:研究情景下没有变化的依赖,不因此判为 D,也不因此提高等级;它进入「需说明」,写明是按前后 30 分钟试算。个人报告的 purpose_stability 在研究情景下不得为 `stable`。
- 会变的层照常写候选值,不受本节影响。