merge origin/staging into narrower delivery (只碰文档, issue #77)
This commit is contained in:
@@ -0,0 +1,92 @@
|
||||
# 婚恋合盘规则:从业者共识调研(2026-10-17)
|
||||
|
||||
用途:`docs/tasks/TASK-marriage-match-p1-20261017.md` 的规则口径 `practitioner_consensus_v1` 的出处。
|
||||
|
||||
起因:占星师复核第一版(只按 B. V. Raman《Muhurtha》定口径)时指出,这些规则不能只按一本书定,参与的信息很多,不能粗暴下断语,不要刻板。所以改为调研印度占星从业者公开资料,按共识程度分档。
|
||||
|
||||
## 读法与局限
|
||||
|
||||
- 分档:**广泛公认**(几乎所有来源一致)、**常见**(多数采用,细节有出入)、**少数 / 地区性**、**有争议**(来源互相矛盾或明说无依据)。
|
||||
- 公开资料大多是商业占星站或计算器站,彼此转录,很少注明出处;经典出处(Muhurta Chintamani、Jataka Parijata、Jyotirnibandha、Kala Prakasika)多是二手转引。分档只说明从业者有多常用,不说明对不对。
|
||||
- 没找到 K.N. Rao、Sanjay Rath、PVR Narasimha Rao、Komilla Sutton 对 Kuja / Papasamya 的一手原文。注意:jagannathhora.com 不是 PVR 的站点(PVR 本人站点是 vedicastrologer.org),引用时不能当作 PVR 的观点。
|
||||
- AstroSage、Prokerala、ClickAstro 的规则页这次没取到(404 或没有方法细节)。
|
||||
|
||||
## 1. 火星冲克(Kuja / Mangal Dosha)
|
||||
|
||||
| 规则 | 分档 | 来源 |
|
||||
| --- | --- | --- |
|
||||
| 犯宫 1/2/4/7/8/12 | 常见 | [Drik Panchang](https://www.drikpanchang.com/jyotisha/mangal-dosha/mangal-dosha-calculator.html)、[r-astro](https://r-astro.com/glossary/mangal-dosha)、[Daily Mirror LK](https://www.dailymirror.lk/print/jyotisha-news/Myths-and-Misconceptions-about-Kuja-Dosha/312-157122) |
|
||||
| 犯宫 1/4/7/8/12(不含 2) | 常见(另一主流版本) | [onlinejyotish](https://www.onlinejyotish.com/articles/marriage-matching/english/kuja-dosha-nivarana.php)、[dekhopanchang](https://dekhopanchang.com/learn/modules/13-3) |
|
||||
| 犯宫 2/4/7/8/12(不含 1) | 少数(Raman《Muhurtha》1969,pp. 91–92) | 上游书库 |
|
||||
| 南北印差异:哪一派不看 1 宫、哪一派不看 2 宫 | 有争议(各站说法相反) | Drik Panchang、dekhopanchang |
|
||||
| 从上升、月亮、金星三处同查 | 广泛公认 | Drik Panchang、onlinejyotish;Raman |
|
||||
| 三处权重 | 少数,没有公认数值(只有一家厂商博客给 1 / 0.5 / 0.25;Raman 给的次序与它相反) | [roxyapi](https://roxyapi.com/blogs/porutham-vs-gun-milan-rajju-vedha-papasamyam) |
|
||||
| 化解:火星本垣(白羊、天蝎)或入旺(摩羯) | 广泛公认 | 几乎所有来源 |
|
||||
| 化解:木星与火星同宫或木星相位火星 | 广泛公认 | onlinejyotish(引 Jataka Parijata)、Daily Mirror、dekhopanchang;Raman 只写同宫 |
|
||||
| 化解:水星 / 月亮 / 金星与火星同宫或相位;吉星落角宫 | 常见(多写作「减弱」) | Daily Mirror、[jagannathhora](https://jagannathhora.com/mangal-dosha-cancellation-rules/) |
|
||||
| 化解:宫 × 星座例外(2 双子/处女、4 白羊/天蝎、7 巨蟹/摩羯、8 射手/双鱼、12 金牛/天秤) | 常见,星座略有出入 | [astrosight](https://astrosight.ai/doshas/mangal-dosha-cancellation-rules)、[aaps](https://aaps.space/blog/mangal-dosha-cancellation/)、Daily Mirror;Raman |
|
||||
| 化解:巨蟹或狮子上升(火星为 Yogakaraka) | 常见 | jagannathhora、onlinejyotish |
|
||||
| 化解:火星在动星座 | 常见,出处说法不一 | onlinejyotish(Jataka Chandrika)、jagannathhora(Jataka Parijata) |
|
||||
| 化解:火星落巨蟹(落陷) | 有争议 | onlinejyotish 引 Garga;jagannathhora 标 debated |
|
||||
| 化解:火星逆行、燃烧 | 有争议 | jagannathhora |
|
||||
| 化解:火星在狮子或水瓶 | 少数 / 写法不一 | dekhopanchang、Daily Mirror;Raman |
|
||||
| 28 / 30 岁后减弱 | 少数,多站明说无经典依据 | jagannathhora、vedicmarga、astrojagriti |
|
||||
| 两人都有则相抵(要求程度相当) | 广泛公认 | onlinejyotish(Dosha-samya)、dekhopanchang、jagannathhora;Raman |
|
||||
| 一方有、另一方同类宫位有土星 / 罗睺等凶星可平衡 | 常见(Papasamya 思路) | 匹配讲义(Scribd),只有二手资料 |
|
||||
| 轻重分两档:部分(anshik)/ 完全(poorna) | 常见(口语说法) | [Wikipedia](https://en.wikipedia.org/wiki/Mangala_Dosha)、[shubhpanchang](https://shubhpanchang.com/jyotisha/mangal-dosh) |
|
||||
| 百分比分级(12 宫 50%、1 宫 60%、2/4 宫 80%、7/8 宫 100%,叠加凶星可到 150–250%) | 少数,单站自定 | Drik Panchang |
|
||||
|
||||
## 2. 婚姻宫压力(Papasamya / Dosha Samya)
|
||||
|
||||
| 规则 | 分档 | 来源 |
|
||||
| --- | --- | --- |
|
||||
| 计入火星、土星、太阳、罗睺;计都有的算有的不算 | 常见(以南印为主) | roxyapi、[泰米尔匹配讲义](https://www.scribd.com/document/331807497/Match-Making) |
|
||||
| 从上升、月亮、金星数 1/2/4/7/8/12 宫 | 常见 | 同上 |
|
||||
| 女方总数不得多于男方 | 常见(南印习惯;带性别不对称,产品不采用) | 同上 |
|
||||
| 加权(太阳减半、7/8 宫加倍、三处系数) | 有争议,没找到可信来源;roxyapi 明说各派权重不同、经典没有公布分表 | roxyapi |
|
||||
| 星体旺弱影响轻重 | 常见 | 匹配讲义 |
|
||||
|
||||
## 3. 性情(Yoni Koota)
|
||||
|
||||
| 规则 | 分档 | 来源 |
|
||||
| --- | --- | --- |
|
||||
| 14 种动物,同类 4 分、死敌 0 分 | 广泛公认 | [onlinejyotish](https://www.onlinejyotish.com/articles/marriage-matching/english/yoni-kootam.php)(引 Muhurta Chintamani)、[jagannathhora](https://jagannathhora.com/yoni-koot-yoni-milan-explained/)、[AstroVed](https://www.astroved.com/articles/yoni-porutham) |
|
||||
| 七对死敌:牛—虎、象—狮、马—水牛、犬—鹿、猫—鼠、蛇—獴、羊—猴 | 广泛公认 | 同上三家 |
|
||||
| 中间档 3 / 2 / 1 的归属 | 有争议(各注本不同) | onlinejyotish、jagannathhora |
|
||||
| 南印只判合格 / 不合格,北印打 0–4 分 | 常见 | roxyapi、AstroVed |
|
||||
| 蛇—鼠相仇的南北差异 | 未找到依据(标准表里蛇的死敌是獴,鼠的死敌是猫);PyJHora 的南印敌对表里有这一对 | — |
|
||||
|
||||
没找到权威网页公布完整的 14 × 14 表。实现用版本化的表,与 PyJHora `YoniArray`、上游 vendored 的 dashaflow `matchmaking.py` 交叉核对。
|
||||
|
||||
## 4. 月宫距离(Bhakoot)例外
|
||||
|
||||
| 规则 | 分档 | 来源 |
|
||||
| --- | --- | --- |
|
||||
| 两人月宫同一主星 | 广泛公认 | [onlinejyotish](https://www.onlinejyotish.com/articles/marriage-matching/english/bhakoota-kootam.php)、[astrosight](https://astrosight.ai/doshas/bhakoot-koota-dosha-cancellation)、[jagannathhora](https://jagannathhora.com/bhakoot-dosha-complete-guide/);Raman p. 81 |
|
||||
| 两颗主星互为朋友 | 常见(2/12 引 Kala Prakasika,6/8 引 Muhurta Pradipa) | 同上 |
|
||||
| 5/9 较轻,或看男女方向 | 常见;方向规则属少数 | onlinejyotish |
|
||||
| 九分盘主星相同或友好 | 少数 | astrosight |
|
||||
| 脉或月主友谊满分可抵 | 少数(只有商业站) | — |
|
||||
|
||||
## 5. 脉(Nadi)例外
|
||||
|
||||
| 规则 | 分档 | 来源 |
|
||||
| --- | --- | --- |
|
||||
| 同一月亮星座、不同星宿 | 广泛公认(引 Jyotirnibandha) | [onlinejyotish](https://www.onlinejyotish.com/articles/marriage-matching/english/nadi-kootam.php)、[jagannathhora](https://jagannathhora.com/nadi-dosha-complete-guide/) |
|
||||
| 同一星宿、不同月亮星座 | 广泛公认 | 同上、[vedicmarga](https://vedicmarga.com/nadi-dosha-calculator/) |
|
||||
| 同一星宿、不同 pada | 常见(有来源注明不那么普遍);Raman 用 pada 重算表 | jagannathhora、astrosight;Raman pp. 86–87 |
|
||||
| 月宫主星或九分盘主星友好 | 少数(引 Muhurta Ganapati);Raman 也列了月宫同主、主星友好 | onlinejyotish、[daanyam](https://daanyam.in/blog/nadi-dosha-meaning-cancellation-remedies) |
|
||||
| 豁免星宿名单 | 有争议(Narada Samhita 与 Piyushdhara 两份名单不一致) | onlinejyotish、daanyam |
|
||||
| 只对特定种姓严格 | 少数,产品不采用 | onlinejyotish |
|
||||
|
||||
## 6. 36 分的分量与措辞
|
||||
|
||||
- 各来源一致:36 分只看月亮;第 7 宫、宫主、D9、大运必须另看。高分也可能不顺,低分配上好的整盘也可能顺([shreekundli](https://www.shreekundli.com/blog/marriage-matchmaking/36-guna-matching-not-enough-kundli-milan)、[shubhpanchang](https://performance.shubhpanchang.com/blog/kundali-matching-compatibility-beyond-love-and-destiny))。
|
||||
- 18 分是常见及格线,但各站分别用 18 / 25 / 27 / 28。
|
||||
- 多个来源批评对火星冲克过度恐惧和误用。像「若干年内婚姻结束」这类宿命化说法正是要避开的。
|
||||
|
||||
## 产品采用(摘要,细则见任务书)
|
||||
|
||||
- 默认用广泛公认的规则;常见、有争议的规则也列出来,并标注分档。
|
||||
- 轻重只用文字(未见 / 轻 / 明显),不给百分比,不出加权总分。
|
||||
- 不采用:性别不对称的比较、种姓规则、28 / 30 岁之说参与判断(只列出、标「有争议」)。
|
||||
@@ -334,6 +334,7 @@
|
||||
| `TASK-rectification-refresh-r3-r4-20260913.md` | `PROGRESS-rectification-refresh-r3-r4-20260913.md` | 刷新阶段 R3(MIN_BOUNDARY_DAYS 45→30)+ R4(pratyantar 与 D9/D10 上升 Narayana);首轮出题不变。即使放宽仍有 0 题例子,定向补事另线保留(BUG-664/665) | 已实现 `ab1ade59`,已部署;2026-09-13 验收通过(实现单由执行方自拟,无产品决策记录段;收益口径见研究文档) | `codex/rectification-refresh-r3-r4-20260913` |
|
||||
| `TASK-upstream-sync6-20261007.md` | [PROGRESS-upstream-sync6-20261007.md](PROGRESS-upstream-sync6-20261007.md) | **上游同步第六轮(`23be1807`)**:10-05 五个计算修正一行未合——D5/D6/D8/D11 映射(乔布斯盘四张分盘星座全不同)、Vimsopaka 权重、Yogini 顺序与出生余额、Panchadhikari 宫位参照、Narayana 并列、特殊上升、出生秒数、Neecha Bhanga 两条件、首段大运子运、岁差被覆盖;逐项对照原书核实;最先做 | 已验收(门禁补修 `2df6ee72`,已部署 staging) | [PROGRESS-upstream-sync6-20261007.md](PROGRESS-upstream-sync6-20261007.md) |
|
||||
| `TASK-upstream-sync7-20261014.md` | [PROGRESS-upstream-sync7-20261014.md](PROGRESS-upstream-sync7-20261014.md) | **上游同步第七轮(BUG-1318 起)**:婚恋评级断语改证据档位、DK「婚姻质量 X/100」改对;KP 宫头到宫头判宫;瑜伽宫主排序去重;api_server 大运年长 365.25;星历路径只核查。不动校正打分。Grok 执行(agent 循环) | 待验收 | `codex/upstream-sync7-20261014`(BUG-1318~1321 已改;BUG-1322 星历路径核查中,未改代码) |
|
||||
| `TASK-upstream-sync8-20261017.md` | — | **上游同步第八轮(BUG-1380 起)**:按作者修复分支 caf1ed4e 移植——星宿拆解第一大运小运、星宿边界、Sandhi、Pinda、Bhava Bala、Argala 裁决、KP 边界、Avastha 一批、Saham 弧方向、Gulika / Hindu 日出。不动校正打分(回放逐字节相同)。Grok 执行(agent 循环) | 待领取 | issue #80 |
|
||||
| `TASK-beta-main-path-20261014.md` | `PROGRESS-beta-main-path-20261014.md` | **内测主路径**:BUG-1063 他人报告 worker 读档案(逐列只读授权 + test:db);对话与报告「AI 生成,仅供参考」标识与免责;BUG-1080/283 状态;状态板按事实清账;冒烟清单 `docs/testing/beta-smoke-20261014.md`。与发布单并行 | 第 1 次打回后已修,待验收 | `codex/beta-main-path-20261014` |
|
||||
| `TASK-beta-main-path-fix-20261014.md` | `PROGRESS-beta-main-path-20261014.md` | **#73 第 1 次打回**:`fca62fda` 内容通过;与 #63 删除的旧报告视图有代码冲突,接受删除即可 | 待验收 | `codex/beta-main-path-20261014` |
|
||||
| `TASK-release-path-production-20261014.md` | `PROGRESS-release-path-production-20261014.md` | **发布通路 + 生产首发**:产品 10-14 授权改生产工作流(发布 SHA = 最近门禁成功提交 + 其后纯文档);63 个迁移清单与演练脚本、首发 runbook;生产拒绝测试验证码。Grok 不 dispatch 生产工作流 | 第 2 次打回后续修 | `codex/release-path-production-20261014`(BUG-1348、BUG-1349) |
|
||||
@@ -499,3 +500,5 @@
|
||||
| `TASK-api-server-service-extract-20261013.md` | — | API 单体第一阶段:拆出不带 HTTP 的计算类,生产伪造 handler 归零 | 待领取(排队:dasha-unify) | `codex/api-server-service-extract-20261013` |
|
||||
| `TASK-data-layer-types-20261013.md` | `PROGRESS-data-layer-types-20261013.md` | 数据访问层改用自己的 DataClient 类型第一阶段(BUG-1351;任务书预留的 1343 已被更大编号越过) | 待验收 | `codex/data-layer-types-20261013` |
|
||||
| `TASK-contracts-helpers-dedupe-20261013.md` | — | 前后端契约与小工具去重第一阶段 | 待领取(排队:frontend-dead-code、consult-route-split) | `codex/contracts-helpers-dedupe-20261013` |
|
||||
| `TASK-people-archive-limit-20-20261017.md` | — | 星盘档案上限 5→20 人(触发器新迁移 + 常量 + 文案;婚恋合盘前置单) | 待领取 | `codex/people-archive-limit-20-20261017`;动表,需 test:db |
|
||||
| `TASK-marriage-match-p1-20261017.md` | — | 婚恋合盘第一期:独立页、任意两人、从业者共识口径(分档并列)、按报告扣点(BUG-1370 起) | 排队(等上限单合入) | `codex/marriage-match-p1-20261017`;动表 |
|
||||
|
||||
@@ -0,0 +1,130 @@
|
||||
# 任务书:婚恋合盘第一期(2026-10-17)
|
||||
|
||||
## 基线与顺序
|
||||
|
||||
- `origin/staging` = `f95eb670b`(开工前 `git fetch origin --prune`,以最新 `origin/staging` 为准)
|
||||
- 分支:`codex/marriage-match-p1-20261017`;工作树:`.worktrees/marriage-match-p1-20261017`
|
||||
- **前置**:`TASK-people-archive-limit-20-20261017.md` 必须先合入 staging。两单都改 `components/people/people-page.tsx`,本单在它之后从最新 `origin/staging` 开分支。
|
||||
- 原型(v4,规则已按共识口径改):https://claude.ai/artifact/Tq6vhXFMnGitDZhJdamaHe 。原型里的人名、分数、宫位全是虚构示例。
|
||||
|
||||
## 现状实证(按符号定位)
|
||||
|
||||
| # | 事实 | 位置 |
|
||||
| --- | --- | --- |
|
||||
| 1 | 唯一入口是档案页他人行的「和我合盘」,跳 `/?synastry=<id>`;只能「本人 × 他人」 | `components/people/people-page.tsx`(`和我合盘`)、`components/people-home-links.tsx` 的 `SynastryDeepLink`(挂在 `app/(app)/page.tsx`) |
|
||||
| 2 | 结果没有界面:结果卡随 `chart-library-panel.tsx` 在 d08ffdc0a 删除;现在只往聊天输入框塞一句草稿问题。`use-synastry.ts` 返回的 `synastryReportCard` / `synastryHistory` / `setSynastryRelationshipType` 无人渲染;`globals.css` 里 `synastry-report-card` 样式成孤儿;`page.tsx` 开机仍拉合盘历史 | `hooks/use-synastry.ts`、`lib/home-profile.ts` 的 `buildSynastryQuestion`、`lib/home-cloud-sync.ts` |
|
||||
| 3 | 不看性别:永远把本人当男方 | `app/api/synastry/route.ts`:`male_moon: moonLongitude(selfChart)`、`female_moon: moonLongitude(partnerChart)` |
|
||||
| 4 | 网页路径从不算火星冲克:Python `/api/synastry` 只收两个月亮度数,`calculate_ashtakoot` 拿不到整盘,`kuja_*`、`LagnaHouse7` 恒缺 | `scripts/offline_compute_mixins.py` 的 `SynastryMixin._compute_synastry` |
|
||||
| 5 | 火星冲克有三套互相矛盾的规则:`scripts/ashtakoot.py` 的 `calc_kuja_dosha`(只从上升数 2/4/7/8/12,五颗星按旺弱打 100/80/50 分,`match_kuja_dosha` 女方重判不合、男方重可容忍);`scripts/yogas_doshas.py` 的 `calc_mangal_dosha`(1/2/4/7/8/12);`references/relationship-astrology-guide.md` §5.3 又一套 | 同左 |
|
||||
| 6 | 36 分的三处简化:性情只给 4/2/0;月宫距离没有主星例外;脉的化解只有「月宫距离有分 + 同绳无碍」一条,没有 pada 重算 | `scripts/ashtakoot.py` 的 `calc_yoni`、`calc_bhakoot`、`calculate_ashtakoot` 里的 exceptions 段 |
|
||||
| 7 | `scripts/synastry.py` 是旧副本:`calc_ashtakoot` 把互控写死 2.0;星宿下标不取模(360° 越界);只被 CLI `synastry`、`tests/run_all.py`、`tests/test_open_source_integrations.py` 用 | `scripts/synastry.py`;退役建议见 `docs/research/antigravity_round23_synastry_module_retirement_decision_2026_06_25.md` |
|
||||
| 8 | 文档虚报:`references/quick-reference-guide.md`、`references/technique-capability-matrix.md`、`scripts/jyotish_engine.py` 头注释称已覆盖 Papasamya / Mangal 匹配,代码没有 | 同左 |
|
||||
| 9 | 合盘不扣点,只有每小时 8 次限流(`request-rate-limit.ts` 的 `synastry` 桶);无缓存 | `app/api/synastry/route.ts` |
|
||||
|
||||
相关历史(开工时按 §5 检索并读完):BUG-466(合盘历史只认云端)、BUG-1030(「设为默认」让合盘把别人叫成「我」)、BUG-1333(两张盘并行算 + 跳过外部概览)、BUG-736、BUG-189。
|
||||
|
||||
## 根因
|
||||
|
||||
合盘一直是挂在别的面板上的附属功能:计算只拿月亮度数,界面跟着旧面板一起删了,规则从几个来源拼来、互相打架,没有一处定过口径。
|
||||
|
||||
## 决策记录(产品负责人 2026-10-17)
|
||||
|
||||
| # | 决定 |
|
||||
| --- | --- |
|
||||
| D1 | 合盘做成独立功能:侧栏一项「**婚恋合盘**」,独立页面,页面标题「婚恋合盘」。档案里**任意两个人**都能合(包括两个都不是本人) |
|
||||
| D2 | 第一版**只做恋爱 / 婚姻**,不给选关系类型;旧的 `relationshipType`(business / family / general)分支删除 |
|
||||
| D3 | **一次合盘按一次报告扣点**(`report.full` 的定价)。同一对人、两人出生资料都没改、规则版本没变时,再次打开直接读已保存的结果,不扣点 |
|
||||
| D4 | 八项**逐项展示**,不做大号总分;历史列表不挂分数 |
|
||||
| D5 | **不考虑同性**:男方女方按档案性别定;两人性别相同或有一人没填时,按选择顺序第一个人当男方,不提示、不互换平均(推翻同日早先「互换取平均」的说法) |
|
||||
| D6 | 副标题定稿:「看这段感情往后的走向,和两人之间的助力与考验。」页面任何地方不写「合不合」「会不会在一起」 |
|
||||
| D7 | 新增星盘入口放在两个选人下拉的**最底一行**「+ 新增星盘」,本页弹出与星盘档案同一张新建表,保存后自动选进这一格;档案满时这一行变灰 |
|
||||
| D8 | 「开始合盘」按钮居中,点数说明在按钮正下方 |
|
||||
| D9 | **规则口径定为「从业者共识 + 分歧并列」`practitioner_consensus_v1`**(2026-10-17 第二版)。占星师复核意见:这些规则不能只按一本书定,参与的信息很多,不能粗暴下断语,不要刻板。所以不再以 Raman《Muhurtha》一书为准,改为按印度占星从业者公开资料的共识分档:**广泛公认的作默认,常见的、有争议的都列出来并注明分档**。**推翻**同日第一版的 `raman_muhurtha_v1`,以及现有 `calc_kuja_dosha` 的五星合分、旺弱打分表、`match_kuja_dosha` 的性别不对称阈值。旧打分与性别不对称不得出现在新功能里,也不作为并列口径展示(产品 10-17 同意) |
|
||||
| D10 | **规则有分歧时并列展示**:每条命中的规则都标出分档(广泛公认 / 常见 / 有争议),并写明按另一派结果会变成什么,不悄悄只选一个。轻重一律用文字,不出百分比,也不出伪精确分数 |
|
||||
| D11 | 第二期(本单不做、不留占位):两人大运同步「什么时候顺」、就这对关系开对话、导出报告、非婚恋关系 |
|
||||
|
||||
### 规则口径 `practitioner_consensus_v1`
|
||||
|
||||
调研记录:`docs/research/marriage_match_practitioner_consensus_2026_10_17.md`(与本任务书同批推送,逐条附来源链接)。公开资料多为商业站互相转录,经典出处多是二手转引。所以分档只说明「从业者有多常用」,不说明「对不对」。
|
||||
|
||||
**火星冲克(Kuja / Mangal Dosha)**:只看火星。
|
||||
|
||||
| 项 | 默认 | 同时列出 |
|
||||
| --- | --- | --- |
|
||||
| 参照点 | 从上升、月亮、金星三处分别数,逐处列出「从哪里数、落第几宫」。**不给权重** | — |
|
||||
| 犯宫 | 1、2、4、7、8、12(多数采用) | 每处触发都注明「不计 2 宫的版本(1/4/7/8/12)下是否仍算」「不计 1 宫的版本(2/4/7/8/12,Raman)下是否仍算」 |
|
||||
| 化解:广泛公认 | 火星本垣(白羊、天蝎)或入旺(摩羯);木星与火星同宫或木星相位火星 | — |
|
||||
| 化解:常见 | 水星 / 月亮 / 金星与火星同宫或相位;宫 × 星座例外(2 宫双子/处女、4 宫白羊/天蝎、7 宫巨蟹/摩羯、8 宫射手/双鱼、12 宫金牛/天秤,各家星座略有出入);巨蟹或狮子上升(火星为 Yogakaraka);火星在动星座 | 写明「常见,各家写法不一」 |
|
||||
| 化解:有争议 | 火星落巨蟹(落陷)、逆行、燃烧;火星在狮子或水瓶;28 / 30 岁后减弱(多处明说无经典依据) | 写明「有争议」,不参与轻重判断,只列出 |
|
||||
| 单人轻重(文字) | **未见**:三处都没触发,或每处触发都被广泛公认的条件化解;**轻**:触发只被常见条件化解,或只在某一宫位版本下成立;**明显**:至少一处触发没有任何广泛公认或常见的化解 | 页面脚注写明:这是计算层的归纳,不是定论,要结合整盘看 |
|
||||
| 两人比较 | 两人都「明显」或都「轻」→ 相互抵消(广泛公认,前提是程度相当);一方「明显」、另一方「未见」→ 需要留意,并提示看婚姻宫压力是否平衡。**不分男女** | — |
|
||||
|
||||
**婚姻宫压力(Papasamya)**:多为南印做法。火星、土星、太阳、罗睺落在从上升、月亮、金星数的 1、2、4、7、8、12 宫,逐处列出;计都单列一行,标「部分派别计入」。两人比较只写「大致均衡 / 一方明显偏重」。**不出加权总分**(各派权重不同,经典没有公布分表)。南印习惯里「女方不得多于男方」的比较带性别不对称,不采用,脚注说明。单独一节,不叫火星冲克。
|
||||
|
||||
**八项配对(36 分)**
|
||||
|
||||
| 项 | 默认 | 同时列出 |
|
||||
| --- | --- | --- |
|
||||
| 性情 Yoni | 同类 4、七对死敌 0(牛—虎、象—狮、马—水牛、犬—鹿、猫—鼠、蛇—獴、羊—猴),广泛公认。中间档 3 / 2 / 1 用一张版本化 14 × 14 表计分(以 PyJHora `YoniArray` 对照写入、注明出处),页面用文字写「友好 / 中性 / 略不合」 | 注明「中间档各家表不同」;南印只判是否死敌,并列一行「南印:是 / 否死敌」 |
|
||||
| 月宫距离 Bhakoot | 原始分照算照显示,并标类型(2/12、5/9、6/8)。两人月宫同一主星、或两主星互为朋友 → 例外成立(广泛公认 / 多数采用),单独标出;**不改原始分** | 九分盘主星友好、其他项满分可抵:标「部分占星师接受」 |
|
||||
| 脉 Nadi | 原始分照算。例外(广泛公认):同一月亮星座不同星宿;同一星宿不同月亮星座。多数采用:同一星宿不同 pada | 月宫主星友好:标「少数」;豁免星宿名单:标「有争议」,并写明出自哪份名单 |
|
||||
| 合计 | 表尾并列两个数:原始合计、计入广泛公认例外后的合计。**不显示及格分档**:常见及格线是 18,但各家分别用 18 / 25 / 27 / 28,脚注写「满分 36,常见及格线 18,各家不一」 | — |
|
||||
|
||||
`ashtakoot.py` 现有的附加项(Mahendra、Stree Deergha、Vedha、Rajju、BadConstellations)保留展示,例外按上面同样的分档标注。
|
||||
|
||||
**结论措辞**:三句话总述的落点只用三档:「助力多于考验」「有几处需要留意,建议结合整盘细看」「考验较多,建议请占星师细看」。火星冲克一方「明显」另一方「未见」时,至少落到第二档。总述以各自婚姻征象(D1 第 7 宫、D9、UL、DK)为主,36 分只作一层参考。
|
||||
|
||||
## 硬红线
|
||||
|
||||
1. `scripts/jyotish_api_server.py` 不增长(类方法数、`__new__` 伪造点、行数护栏):新计算放新模块(建议 `scripts/marriage_match.py`),主文件只做薄注册。
|
||||
2. `app/(app)/page.tsx` 的 `Home()` 状态数不得增长;本单删掉 `SynastryDeepLink` 与开机拉合盘历史,只会减少。
|
||||
3. 新功能里不得出现:五星合分、任何百分比或 100/80/50 之类的火星冲克分数、Papasamya 加权总分、按性别判轻重、「合 / 不合」「相合」「会不会在一起」「适合 / 不宜结婚」「分离」「寿命」。
|
||||
4. 生产运行时不得 import PyJHora(只作测试对照,许可证边界);验收会屏蔽 PyJHora 模拟生产。
|
||||
5. 合同测试的 fixture 用真实引擎输出(golden)。所有示例与测试只用虚构人物或公开名人。
|
||||
6. 扣点:先预留、算失败或超时**释放不扣**;读已保存结果不预留。用现有 `authorizeUsage` / `completeUsage` 及其释放路径,记账 metadata 标明 `kind: "marriage_match"`。
|
||||
7. 一次等待一次揭幕:等待只有一屏,结果整页一起出现;揭幕后无 spinner / 骨架。
|
||||
8. 加表 / 加列可以同轮,不得删旧列(AGENTS §7.6);动表必须真跑 `npm run test:db`。
|
||||
9. 删人:删档案里的人时,这个人参与的合盘一并删除;删前确认句在「N 个对话和 M 份报告」后加上「K 份合盘」。
|
||||
|
||||
## 任务分解
|
||||
|
||||
| # | 内容 | 验收标准 |
|
||||
| --- | --- | --- |
|
||||
| T1 | **引擎**:新模块实现 `practitioner_consensus_v1`:火星冲克(三参照点 × 三种宫位版本 × 命中的化解条件及其分档)、婚姻宫压力、八项(Yoni 表、Bhakoot / Nadi 例外分档)、单人婚姻征象(复用 `relationship_analysis.analyze_relationship`:7 宫主、金星、D9、UL、DK)、D9 对照(两人 D9 上升、D9 金星、D9 上升相隔几宫)。输入两份出生资料 + 性别,一次请求内算完(占重计算并发位)。每条规则带 `consensus: broad / common / disputed` 和来源键,来源键对应调研记录里的条目 | 新 pytest:每条化解条件至少一例且分档正确;宫位三版本差异各一例;单人「未见 / 轻 / 明显」与两人比较各至少一例;有争议的条件不改变轻重;Yoni 14 × 14 与 PyJHora 对照全等(测试里可 import PyJHora,缺时 skip 并记录),七对死敌为 0;Bhakoot / Nadi 例外不改原始分;至少 20 对虚构出生资料的八项原始分与 PyJHora North 方法对照,差异逐条解释 |
|
||||
| T2 | **Python 接口**:新端点(如 `POST /api/marriage_match`)薄注册;旧 `/api/synastry` 保留给 MCP / CLI 兼容但不再被网页调用 | `tests/test_api_server_growth_contract.py` 绿;端点 golden 一份进 `frontend/tests/fixtures/` |
|
||||
| T3 | **退役与文档纠错**:删 `scripts/synastry.py`,CLI `synastry` 改走新模块或删除(同步 `SKILL.md` 命令表、`tests/run_all.py`、`tests/test_open_source_integrations.py`);`ashtakoot.py` 的 `calc_kuja_dosha` / `match_kuja_dosha` 标为旧版、不被新功能调用;删掉三处 Papasamya / Mangal 匹配虚报 | 全量 pytest 与基线逐条比对无新增失败;`git grep "synastry.calc_ashtakoot"` 0 命中 |
|
||||
| T4 | **数据**:`synastry_reports` 加列——两人的人物引用(本人用约定值,他人用 `chart_profiles.id`)、两人出生资料指纹、规则版本 `rules_version`、结构化结果;旧行不迁移、不显示 | `npm run test:db`:同一对人同指纹第二次读到旧行;任一人改出生资料后指纹不同;删人后其合盘行消失 |
|
||||
| T5 | **Next 接口**:重写 `app/api/synastry/route.ts`(或新路由,旧的删):收两个人物 id → `loadSubjectBirth` 两次 → 查已保存(命中即返回,不扣点)→ 预留 `report.full` → 调 T2 → 存 → 结算;性别按 D5;保留产品开关 `compatibility` 与限流桶;删掉 `relationshipType` 与 business / family / general 分支 | 路由测试覆盖:命中缓存不扣点;计算失败释放不扣;两个 id 相同 400;不属于本人的 id 拒绝;同性 / 缺性别按顺序定男方 |
|
||||
| T6 | **页面**:侧栏「婚恋合盘」;`/marriage-match`(路由名可议,写进 DESIGN)选人页(两个自定义下拉,底行「+ 新增星盘」复用星盘档案新建表;居中按钮;点数来自定价不写死;之前的合盘列表只列「人名 × 人名 · 日期」,点开不扣点);结果页按原型 v4:三句话总述 → 各自的婚姻征象 → 八项配对(含例外绿字 / 另一派灰字、两个合计)→ 火星冲克(每人逐处列出触发与化解,化解条件带分档标签;两人对比)→ 婚姻宫压力 → 脚注(口径来源、分档含义、「计算层归纳不是定论」) | 渲染测试:两个状态(两人火星冲克相当 / 一方明显)的 golden 渲染;20 人时下拉可滚动;手机 390 px 无横向滚动;`next build` 后 `/` 仍 Static,首屏 gzip ±2% |
|
||||
| T7 | **三句话总述**:由服务端按结构化结果确定性拼句(不调模型),讲各自征象、相处的助力与考验、八项合计只作一层参考;落点只用「结论措辞」的三档,第二、三档讲清原因 | 单测覆盖两种状态;文案进 VOICE |
|
||||
| T8 | **清旧入口**:档案页「和我合盘」改跳新页并预选两人;删 `SynastryDeepLink`、`use-synastry.ts` 中无人用的部分、`buildSynastryQuestion` 草稿路径、孤儿 CSS、`page.tsx` 开机拉合盘历史 | 按 AGENTS §7.8 grep 源码文本合同测试同轮改,三栏说明 |
|
||||
| T9 | **记录**:调研记录已由 Claude 写好,执行方只需在 PROGRESS 引用;DESIGN.md、VOICE.md(新文案、删人确认句、侧栏名)、CHANGELOG、BUG_HISTORY(下节编号)、`docs/testing/marriage-match-p1-20261017.md` 真人清单(选人、新增星盘、扣点与再次打开不扣、删人连带删除、手机宽) | 文档齐 |
|
||||
|
||||
## 让步顺序
|
||||
|
||||
先保 T1–T5(算对、存对、扣对);T6 不可省;T7 若来不及可先用固定模板句但不得出现红线 3 的词;T3 的 CLI 改写可降为「删 `synastry.py` + CLI 命令删除」。任何一项过不了红线就停下写进 PROGRESS,不得放宽口径。
|
||||
|
||||
## 开工前置命令
|
||||
|
||||
```bash
|
||||
git fetch origin --prune
|
||||
git worktree add -b codex/marriage-match-p1-20261017 .worktrees/marriage-match-p1-20261017 origin/staging
|
||||
cd .worktrees/marriage-match-p1-20261017
|
||||
git log --oneline -5 -- frontend/src/lib/subject-birth.ts # 确认上限 20 人那单已在
|
||||
grep -n "BUG-1[0-9][0-9][0-9]" docs/BUG_HISTORY.md | tail -3
|
||||
python3 scripts/pre_work_check.py --remote-timeout 8 --command-timeout 45
|
||||
```
|
||||
|
||||
验证:全量 `pytest tests -n 4` 与开工基线逐条比对;`run_quality_gate.py --profile quick`;前端 `tsc --noEmit`、`npm run lint`、`npm test`(含 grep 源码文本合同测试)、`npm run test:db`、`npm run build`。
|
||||
|
||||
## BUG 编号
|
||||
|
||||
从 **BUG-1370** 起(在途的 #77 已用 BUG-1367,它的修复单可能再占几个号;开工时核对最大号,冲突则整体顺延):
|
||||
|
||||
| 建议编号 | 事实 |
|
||||
| --- | --- |
|
||||
| BUG-1370 | 合盘不看性别,本人恒为男方(实证 3) |
|
||||
| BUG-1371 | 网页合盘从不计算火星冲克(实证 4) |
|
||||
| BUG-1372 | 旧 `synastry.py` 互控写死 2.0 / 星宿下标越界(实证 7) |
|
||||
| BUG-1373 | 结果卡随旧面板删除,合盘只剩聊天草稿(实证 2) |
|
||||
| BUG-1374 | 文档虚报 Papasamya / Mangal 匹配已实现(实证 8) |
|
||||
@@ -0,0 +1,62 @@
|
||||
# 任务书:星盘档案上限 5 人 → 20 人(2026-10-17)
|
||||
|
||||
## 基线
|
||||
|
||||
- `origin/staging` = `f95eb670b`(开工前 `git fetch origin --prune`,以最新 `origin/staging` 为准)
|
||||
- 分支:`codex/people-archive-limit-20-20261017`;工作树:`.worktrees/people-archive-limit-20-20261017`
|
||||
- 本单是**婚恋合盘第一期**(`TASK-marriage-match-p1-20261017.md`)的前置单,两单都改 `components/people/people-page.tsx`,必须串行:本单先合入 staging,合盘单再开工。
|
||||
|
||||
## 现状实证(按符号定位)
|
||||
|
||||
上限「本人 + 4 个他人 = 5」写在下面这些地方,缺一处就会出现「界面让加、服务端拒绝」或反过来:
|
||||
|
||||
| 层 | 位置 | 现值 |
|
||||
| --- | --- | --- |
|
||||
| 数据库触发器 | `public.chart_profiles_guard_limit()`,最后一次定义在 `frontend/supabase/migrations/20260925030000_chart_subject_trust_and_limit.sql`(开工时 `grep -l chart_profiles_guard_limit frontend/supabase/migrations` 确认没有更晚的重定义) | `if others >= 4 then raise exception 'subject_limit_reached'` |
|
||||
| 常量 | `frontend/src/lib/subject-birth.ts`:`MAX_OTHER_SUBJECTS`、`MAX_SAVED_SUBJECTS` | 4、5 |
|
||||
| 接口文案 | `frontend/src/app/api/chart-profiles/route.ts`:`SUBJECT_LIMIT_MESSAGE` | 「最多保存 5 个人的星盘」写死 |
|
||||
| 页面文案 | `frontend/src/components/people/people-page.tsx`:`LIMIT_COPY` | 同上写死 |
|
||||
| 文案规范 | `frontend/docs/VOICE.md` 星盘档案两段(「还可以保存 N 个人」「最多保存 5 个人的星盘」) | 5 |
|
||||
| 自动测试 | `frontend/tests/people-archive-view.test.tsx`(限额句断言)、`frontend/tests/database-chart-subject.test.ts`(第五个人被拒) | 5 |
|
||||
| 真人清单 | `docs/testing/people-archive-p1-20260924.md`、`docs/testing/people-ephemeris-ui-20260926.md` | 5 |
|
||||
|
||||
## 决策记录
|
||||
|
||||
- 产品负责人 2026-10-17:档案上限从 5 人改为 **20 人(含本人,即他人最多 19)**。
|
||||
- 扣点不变:建档不扣点,各功能照常扣(与 2026-09-24 定稿一致);`profile.extra` 计费键**不启用**。
|
||||
- 数字只在一处定义:文案用常量拼出,不再写死「5」或「20」。
|
||||
|
||||
## 硬红线
|
||||
|
||||
1. 新增一个迁移文件(`frontend/supabase/migrations/20261017xxxxxx_chart_profiles_limit_20.sql`)重定义 `chart_profiles_guard_limit()`,阈值改为 `others >= 19`;**不改**旧迁移文件,不动其它表、不动 advisory lock 与 `role` 检查逻辑。
|
||||
2. 迁移与代码同一提交;生产部署前先跑迁移(写进 PROGRESS 与 CHANGELOG)。
|
||||
3. 不改人物表结构、不加列。
|
||||
4. 测试数不得减少;改断言写「原值 / 新值 / 原因」三栏(AGENTS §7.3)。
|
||||
|
||||
## 任务分解
|
||||
|
||||
| # | 内容 | 验收标准 |
|
||||
| --- | --- | --- |
|
||||
| T1 | 新迁移:触发器阈值 19 | `npm run test:db` 中 `database-chart-subject.test.ts` 改为「第 20 个他人(共 21 人)被拒、第 19 个他人可存」,两条都绿 |
|
||||
| T2 | 常量 `MAX_OTHER_SUBJECTS = 19`、`MAX_SAVED_SUBJECTS = 20`;接口与页面限额句改为由常量拼出「最多保存 {MAX_SAVED_SUBJECTS} 个人的星盘」 | `git grep -n "5 个人"` 在 `frontend/src` 0 命中;`people-archive-view.test.tsx` 断言新文案 |
|
||||
| T3 | 人多时的列表:档案页列表、标题旁人名切换(`subject-switcher.tsx` / `current-subject-switcher.tsx`)、聊天的 `chat-profile-picker.tsx` 在 20 人时可滚动、不撑出屏幕 | 新增渲染测试:20 人时列表容器有限高 + 纵向滚动;手机宽 390 px 不出现横向滚动(写进真人清单) |
|
||||
| T4 | VOICE、DESIGN(若 T3 动了样式)、两份真人清单里的 5 改为 20;CHANGELOG 一条 | 文档 grep 无残留「5 个人」 |
|
||||
|
||||
## 让步顺序
|
||||
|
||||
T1+T2 必须一起交;T3 若列表已能滚动,只补测试即可;T4 不可省。
|
||||
|
||||
## 开工前置命令
|
||||
|
||||
```bash
|
||||
git fetch origin --prune
|
||||
git worktree add -b codex/people-archive-limit-20-20261017 .worktrees/people-archive-limit-20-20261017 origin/staging
|
||||
cd .worktrees/people-archive-limit-20-20261017
|
||||
grep -l chart_profiles_guard_limit frontend/supabase/migrations/*.sql
|
||||
```
|
||||
|
||||
验证:`./node_modules/.bin/tsc --noEmit`、`npm run lint`(0 error)、`npm test`(失败名单与基线逐条一致)、`npm run test:db`(Windows 已知失败名单之外无新增)、`npm run build` 后 `/` 仍 Static。
|
||||
|
||||
## BUG 编号
|
||||
|
||||
本单是产品需求,不新增 BUG 编号。
|
||||
@@ -0,0 +1,73 @@
|
||||
# TASK · 生时校正交付区间收窄 · 修复单(issue #77,第 1 次打回)
|
||||
|
||||
- 日期:2026-10-17
|
||||
- 被验提交:`56a3c081455d948b2f9dd54be8dd697ecad23447`(分支 `codex/rectification-narrower-delivery-20261016`)
|
||||
- 原任务书:`docs/tasks/TASK-rectification-narrower-delivery-20261016.md`(下称「原单」)
|
||||
- 执行方:Grok,在**同一分支**追加提交;`origin/staging` 前进时用 `git merge origin/staging`,不 rebase
|
||||
- BUG 编号:沿用你已登记的 BUG-1367~1369;新发现的缺陷从开工时 `docs/BUG_HISTORY.md` 最大号 +1 起
|
||||
|
||||
## 验收结论(Claude,Linux)
|
||||
|
||||
T1 的方向对,代码质量整体可以;但原单让步顺序写明**最少交 T0+T1**,T0 没交,T1 又有两处会让显示比真实范围更窄的缺陷,所以打回。T2、T3 没做是允许的(按让步顺序),本单不要求。
|
||||
|
||||
| 项 | 结论 | 证据 |
|
||||
| --- | --- | --- |
|
||||
| tsc / lint | 通过 | 0 错;0 error、123 条原有 warning |
|
||||
| 前端全量 `npm test` | 通过 | 5030 条(基线 5024),失败 25 条与基线逐名一致(另 1 条只在 Docker 下能跑的已知项) |
|
||||
| Python 显示单测 | 通过 | `tests/test_rectification_living_display_intervals.py` 4 passed |
|
||||
| 越界 / 隐私 | 通过 | 只动了原单 T1 范围内的文件;无个人资料 |
|
||||
| **T0 基线回放** | **未通过** | 没产出 `docs/research/rectification_narrower_delivery_baseline_2026_10_16.json` |
|
||||
| **T1 显示成员与交付区间一致** | **未通过** | 见 F2 |
|
||||
| **T1 golden 验收** | **未通过** | 用的是手造卡片,原单要求一例 ±60 回放(见 F3) |
|
||||
| T1 Python 侧 | 部分 | 见 F4 |
|
||||
|
||||
## F1 · 补 T0,并用同一套回放量 T1(必做)
|
||||
|
||||
你在进度里说现有回放脚本不记「真值在不在交付区间」、也不翻题,这是事实;**补这两项正是 T0 的工作内容**,不是阻塞理由。
|
||||
|
||||
做法:
|
||||
|
||||
1. 在研究脚本里扩展(不改生产代码):`frontend/tests/research/rectification-segment-persisted-replay.ts` / `scripts/research/varga_resolution_persisted_replay.py` 之一(选你更顺手的,进度里写明),增加:
|
||||
- 参数:窗口 `±10/±30/±60`;答题模式 `all_correct`、`flip_1`、`flip_3`、`flip_5`(第 N 道点选题按反向作答);轮数上限沿用生产默认(当前 8),**不得**用 6。
|
||||
- 每例输出:真值分钟;交付时的 `credible_range` / `credible_intervals`(决策包络);分段显示区间(T1 的 `livingDisplayFromCandidates` 同口径);两者是否包含真值;实际剩余分钟数;显示宽度;问题数。
|
||||
2. **T0**:在原单开工 SHA(`712a0fd2`)上跑 77 例 × 3 档 × 4 模式,落 `docs/research/rectification_narrower_delivery_baseline_2026_10_16.json`,写清复跑命令。
|
||||
3. **T1 判定**:在本分支上跑同一套,落 `docs/research/rectification_narrower_delivery_t1_2026_10_17.json`。按原单 §4 红线 2 比较「分段显示包含真值」与基线「包络包含真值」:
|
||||
- 全对:每档例数 ≥ 基线 −1;
|
||||
- 翻 1/3/5:每档比例 ≥ 基线 −5 个百分点。
|
||||
过不了就按原单 §6 撤回 T1 对应出口,不放宽红线。
|
||||
4. Windows 磁盘不够或 Docker 起不来时,按 `docs/research/` 盘型口径研究的「无 Docker 验收法」(预编译 PG17)跑;仍跑不了就**停下回报**,不要只交代码。
|
||||
|
||||
## F2 · 显示成员与交付区间成员不一致,可能把还活着的时段藏掉(必做)
|
||||
|
||||
`frontend/src/lib/rectification-agentic/core/candidate-window.ts::livingDisplayFromCandidates` 自己重算「谁还活着」,与交付区间的权威口径 `core/credible-range.ts::stillValidCandidates` / `unionStillValidIntervals` 有两处分歧:
|
||||
|
||||
1. **取整后比门槛。** 交付卡(`rectification-range-delivery.tsx`)和只读范围行(`rectification-agentic-chat.tsx`)传进来的是解析后的 `RectificationCandidate`,只有 `relativeSupport`,它是 `inference-adapter.ts` 里 `Math.round(posterior_score)` 再夹到 0–100 的整数。拿它比 `MIN_SEPARATION_LEAD = 8` 会在边界上出错:峰值 7.6、候选 0.4,真实差 7.2(在区间内),取整后差 8(被当成出局)。
|
||||
2. **缺区间的候选被悄悄丢掉。** 某个活着的候选没有 `cluster_intervals` 时,新函数直接跳过它,而 `unionStillValidIntervals` 遇到这种情况返回空、由调用方退回旧口径。结果是显示比真实范围窄,真值可能正落在被丢掉的那段里。
|
||||
|
||||
修法要求(实现方式你定,结果必须满足):
|
||||
|
||||
- 显示成员**必须与 `stillValidCandidates(candidates, lead)` 完全相同**,用原始 `posterior_score` 比较,不用取整值。推荐在写盘处(有 `InferenceCandidate` 的地方)算好分段显示区间并随结果持久化,前端只读,不在 UI 侧重算;若改为持久化,读旧结果时缺字段就退回旧标题。
|
||||
- 任一活着的候选缺 `cluster_intervals` → 整体退回旧的包络标题(与 `unionStillValidIntervals` 同规则)。
|
||||
- 新增测试:① 边界例(峰值 7.6 / 候选 0.4 → 两者都在显示里);② 一个活着的候选缺区间 → 退回旧标题;③ 对同一组候选,分段显示的成员集合 == `stillValidCandidates` 的成员集合(可用 golden 输入批量断言)。
|
||||
|
||||
## F3 · T1 验收要用回放产物,不用手造卡片(必做)
|
||||
|
||||
原单 T1 验收第 2 条:「用 golden 中一例 ±60 回放得到的候选构造交付卡,标题段数与实际剩余分钟数和回放一致」。AGENTS §7.4 也要求合同 fixture 来自真实引擎响应。F1 跑完后,从 ±60 结果里挑一例「有大于 4 分钟空档」的,落到 `frontend/tests/fixtures/`(只存候选分数与区间,不存出生资料;`fixtureProvenance` 写命令与 SHA),替换或补充 `rectification-living-display-20261016.test.ts` 里的手造输入。手造用例可以保留做边界测试。
|
||||
|
||||
## F4 · Python 侧新函数没有任何调用方(必做,小)
|
||||
|
||||
`scripts/rectification/living_display_intervals.py` 只被它自己的测试引用。原单 D1 要求报告里的范围也按分段显示;进度里写「技能报告的不可分宽度仍是决策包络」。二选一并写进进度:
|
||||
|
||||
- a. 把报告(Python 侧用户可见的范围句)接到这个函数上,补一条测试;
|
||||
- b. 如果报告范围完全由前端传入、Python 侧没有用户可见出口,就删掉这个文件和它的测试,并在进度「口径」表里写明报告范围由哪一处决定。
|
||||
|
||||
会话标题仍用数据库函数里的单段包络:原单禁止本轮改表,**这一项接受**,保持进度里的说明即可。
|
||||
|
||||
## 不要做
|
||||
|
||||
- 不做 T2、T3(让步顺序允许后交);不改 `MIN_SEPARATION_LEAD`、`SCORE_DELTA` 等原单红线 1 的任何一项。
|
||||
- 不改既有断言来迁就新显示;要改的按「原值 / 新值 / 原因」写。
|
||||
|
||||
## 回报
|
||||
|
||||
issue #77 回报新 SHA,表格里写:T0 与 T1 的三档 × 四模式包含率对照、实际剩余分钟与显示宽度中位数、F2 三条新测试结果、F4 选了 a 还是 b。
|
||||
@@ -0,0 +1,132 @@
|
||||
# TASK · 上游同步第八轮:上游 10-16 通知答复分支 + 10-08 以来四项计算修正(2026-10-17)
|
||||
|
||||
- 日期:2026-10-17
|
||||
- 来源:
|
||||
- 10-16 产品要求复查上游 Skill 仓(GitHub `732642856/yinduzhanxing`,本机 `/workspace/yinduzhanxing`)。上游 `0337b77f → 3c2dad95` 共 14 个提交,其中 8 个是计算修正。
|
||||
- 我们把对方仍存在的 7 处代码问题和 5 个口径问题写成通知 `docs/research/upstream_notice_2026_10_16.md`(staging `9b750915`)发给 skill 作者。
|
||||
- 10-17 作者在分支 `codex/upstream-notice-20261016`(`caf1ed4e`)修复并逐条答复,答复见上游 `docs/research/upstream_notice_reply_2026_10_16.md`。
|
||||
- 产品 10-17 决定直接按该分支出本单。
|
||||
- 执行方:**Grok(Windows)**,分支 `codex/upstream-sync8-20261017`,只推这个分支
|
||||
- 验收:Claude(Linux)
|
||||
- BUG 编号:**BUG-1380 起**。写作时 `docs/BUG_HISTORY.md` 最大号为 BUG-1366;在途单已占用 BUG-1367~1369(窄交付)和 BUG-1370~1374(婚恋合盘)。开工时再核对一次最大号,冲突则整体顺延。
|
||||
|
||||
## 1. 基线
|
||||
|
||||
- 基线 commit:`origin/staging` `53608d8b`。我方核对时用的是 `1eb504d3`,两者之间 `scripts/` 无改动。sync7(BUG-1318~1322)的代码已在其中。
|
||||
- 上游参照:分支 `origin/codex/upstream-notice-20261016` 的 `caf1ed4e`(10-17)。
|
||||
- **注意:该分支未合入上游 main。** 上游 main(`3c01a214`)与它从 `97dea658` 分叉,main 上缺 Argala 裁决、Avastha 并存条件和 dasha_analyzer 修复。
|
||||
- 本单一律以 `caf1ed4e` 为准,不参照上游 main。
|
||||
- 取上游:仓库是公开 GitHub,执行方可以加 remote 后 `git fetch` 读 diff(见 §9)。下表每项写了上游提交号,只按语义移植,**不整文件覆盖**;我方文件和上游已经分叉,补丁不能直接 apply。
|
||||
|
||||
## 2. 事故实证(`53608d8b`,按符号定位)
|
||||
|
||||
| 项 | 上游提交 | 我方现状 |
|
||||
| --- | --- | --- |
|
||||
| T1 星宿拆解第一大运小运 | `8643bc9a`(上游测试 `test_first_remaining_md_is_not_repartitioned_into_new_ads`) | `scripts/nakshatra_dasha.py::calc_nakshatra_dasha_breakdown` 把 `first_remaining`(出生时剩余年数)交给 `_calc_vimshottari_antardasha_full`,等于把剩余段当完整大运重新切 9 段。用例:月亮在 Ashwini 中点,当前小运应为 Rahu,我方给 Ketu。结果经 `modules.nakshatra_dasha.vimshottari_nak_breakdown` 进完整报告与数据包 |
|
||||
| T2 星宿边界 | `3c2dad95` 第①部分、`8643bc9a`、`9e04f0db`(只取 `lon_to_nakshatra`) | `jyotish_engine.py::cmd_dasha` 与 `dasha_analyzer.py::lon_to_nakshatra` 都是 `idx = int(m/ns)` 和 `progress = (m%ns)/ns` 分开算。月亮恰在星宿起点时,两者不一致。上游 27 起点参数化测试在我方挂 16/27:第一大运余额 0,整段大运被跳过 |
|
||||
| T3 Sandhi 假交接 | `3c2dad95` 第②部分(按我方数据形状改写) | `jyotish_engine.py::_calc_dasha_sandhi` 把第一段小运被裁到出生日的 `start` 当成交接。我方第一大运 `start` 本来就是出生前的真实交接时刻(BUG-1268),所以上游「跳过第一大运起点」那条**不搬**。默认参考时刻带墙钟时分,没归零到当天 0 点 |
|
||||
| T4 Yoga Pinda | `30b43643` | `scripts/ashtakavarga.py::calc_yoga_pinda` 只取本座 bindu ×4× 行星权重,没做 Trikona / Ekadhipatya 削减,也没做十二座、七曜求和。我方已有标准削减链 `ashtakavarga_shodhana.sodhita_chain`(BUG-1209) |
|
||||
| T5 Bhava Bala | `a4d4a249` | `scripts/bhava_bala.py`:Dig 表里人象与四足共用一张,且多一个 vanaspati 档;摩羯前半归成水象;Sputa 用阶梯表,不是 BPHS 分段公式,也没有火、木、土的特殊相位;吉星取了水星而不是月亮。报告 Bhava Bala 三分量表与咨询卡每宫 `bhava_bala` 都受影响 |
|
||||
| T6 Argala | `e7301feb`、`86935c0a`、`4f1536f2` | `scripts/argala.py::calc_argala_for_reference`:<br>• 计都所在宫没反向数;<br>• 同数直接判阻挡;<br>• H9 当次级 Argala;<br>• `net_result` 按有星宫数比,不按成对比;<br>• `_summarize_argala` 用占位式 Rajayoga 排序。<br>下游:`consultation_native_layers.build_argala`、`consult_card_domain_facts` 的 `worksheets.advanced_systems.argala` |
|
||||
| T7 KP 分区 | `8eec9a54` | `scripts/kp_system.py::get_kp_lords` 与上游修复前逐字相同:浮点累加 sub-sub 区间,与 120° 取余混用,star / pada / sub 在边界上落在不同半开区间。按角秒扫一圈,129.6 万点中 499 处不同,全在精确边界上 |
|
||||
| T8 Avastha | 上游 `e628118d`(09-24,只取 `avastha_calculator.py` 与相关测试)、`7d545039`、`f75a6e77`、`ac565836`(Shayanadi 接线) | `scripts/avastha_calculator.py` 停在 `e628118d` 之前:<br>• `_is_friend_sign` / `_is_enemy_sign` 恒 False;<br>• 旺、落只认精确点 ±5°;<br>• Bala 无奇偶宫翻转,Jagrat 按宫位,交点星未排除;<br>• 标签是落陷→Vikala、燃烧→Khala、友→Mudita、敌→Dina;<br>• Shayanadi 是按星座元素的启发式,没有 PVR 公式,也没有接线。<br>上游 `7d545039` 的 dignity 用例在我方 21 败 3 过 |
|
||||
| T9 Saham 例外弧方向 | `ce9fed15` | `scripts/tajika.py::_calc_formula_saham` 检查「上升是否在第一→第二操作数的顺行弧上」,不在就 +30°。PVR §28.8.1 p394 的规则是检查**第三操作数 C** 是否在 **B→A** 顺行弧上,不在则 +30°。我方 `references/saham_rules.json` 7 条公式第三项都是上升,所以两种判法近乎互补:**大量 Saham 结果会差 30°** |
|
||||
| T10 日出相关 | `9f9f16b3`(只取 `gulika.py`)、`872eaecf`(只取 `saham_daynight.py` 日窗口)、上游 `BIT_HINDU_RISING` 口径 | `scripts/gulika.py` 夜晚结束用 `sunrise + 1.0`,不是真实的下一次日出。`scripts/saham_daynight.py::determine_daytime` 从 jd−1 查日出日落,晚于出生就整减 1.0 天,也没有 Hindu rising 口径。**该函数同时被生时校正使用**(`active_rectification_event_engine.py` 里 `saham_daynight.determine_daytime`,用于 Hora / Ghati 起点) |
|
||||
|
||||
## 3. 根因
|
||||
|
||||
我方前七轮同步按上游提交标题筛选,只搬了被点名的修正。上述算法边界和来源口径问题,有的是两边同源的旧写法(T1、T2、T6、T7、T9、T10),有的是我方从未跟进上游 09-24 以后的改写(T5、T8)。T1 是 BUG-1268 修 `cmd_dasha` 时漏掉的同类函数。
|
||||
|
||||
## 4. 决策记录(产品授权)
|
||||
|
||||
1. **10-17 产品决定:直接按作者修复分支 `caf1ed4e` 出单**,不等上游合 main。
|
||||
2. 作者 10-17 口径答复,本单照此实现:
|
||||
- **Khala**:取 Science of Light 定义(落陷 = Khala;燃烧 = Kopa;友 Shanta、中性 Dina、敌 Duhkhita)。同时成立的条件**全部保留展示**(如擢升与燃烧并存);旧单标签顺序只作兼容字段,并标明「无经典出处」。大友、凶星同宫条件标「未计算」。
|
||||
- **日出**:不强制全站统一。Saham 昼夜、Gulika、Shayanadi 改用 Hindu rising(日面中心、不计折射);Panchanga 维持现有配置。
|
||||
- **Argala 同数**:只按 Rath p363 前两级比较,即先比占星数,同数再比水星、木星、宫主的合相 / 星座相位关联;仍平手的保留 `unresolved`,**不得**用 Shadbala 或其他常数顶替。第 3 宫「两颗以上凶星」门槛保留为参数敏感候选。
|
||||
- **Bhava Bala 吉星**:固定月亮、木星、金星,水星中性。结果里注明这是具名实现 `jyotishganit_mirrored_equal_house_v2` 的契约,**不写成经典定论**。
|
||||
- **Pinda**:按 PVR §12.7 表 28–29(处女座 6),以 PVR 例 43 = 152 校验;同主一占一空且同值时,按 Raman 15(c) 清空空宫。不向 PyJHora 常数靠拢。
|
||||
3. **10-16 产品范围:本单不改生时校正打分。** 日出口径只跟作者改的几处。凡是会改变校正输出的移植,一律保住校正路径原行为(见 §5 红线 1)。
|
||||
4. 用户可见变化已知并接受:
|
||||
- 报告 Avastha 表与咨询卡措辞会变;
|
||||
- Pinda 数值约 ×3、强弱排序会变;
|
||||
- Bhava Bala 每宫约 ±10%、排序会变;
|
||||
- 年运 Saham 不少会差 30°;
|
||||
- 咨询层 Argala 会出现「待定」。
|
||||
5. 不搬:
|
||||
- `c3346847`:我方没有 `formation_status`,燃烧降级已由 sync5 处理;
|
||||
- `raman_sahams.py`:我方无此表;
|
||||
- 上游 `ac23c2ee` / `8abbfd91` / `c74fd96c` 研究工具;
|
||||
- `001033df` 测试环境隔离;
|
||||
- 分支上其余提交(年运计算域、D12 联动、英文报告、完整解读元数据、Narayana Rath seed `6b9cd74e`、交付 pin 等)。这些另行评估,**本单不碰**。
|
||||
- 上游 `9e04f0db` 把 `dasha_analyzer` 整体转调原生时钟、保留时分秒:会改变校正打分,本单**只取 `lon_to_nakshatra` 边界部分**,其余记入进度记录待研究。
|
||||
|
||||
## 5. 硬红线
|
||||
|
||||
1. **生时校正输出逐字节不变。**
|
||||
- 校正打分读 `dasha_analyzer.lon_to_nakshatra / build_dasha_timeline / build_antardasha`、`saham_daynight.determine_daytime`、`kp_system.get_kp_lords`。
|
||||
- T2 只许改变「恰在星宿起点」那几个浮点点的结果。
|
||||
- T7 只许改变精确边界点。
|
||||
- T10 必须让校正调用点保持现有日出口径与日窗口:例如 `determine_daytime` 新增显式参数,默认值即现行为,只有 Saham / Gulika / Shayanadi 调用方传新口径;或者校正侧显式固定旧口径。具体写法执行方定,结果必须相同。
|
||||
- 验收:改动前后各跑一次 `scripts/research/reported_offset_sweep.py` 与 `scripts/research/sealed_holdout_rerun.py`(用法同 sync6),结果 JSON 除时间戳外逐项相同。若有任何差异,**停下回报**,不得自行重新冻结(ERR-110)。
|
||||
- `tests/test_sealed_holdout_contract_freshness.py` 等冻结身份测试必须保持绿。
|
||||
- 不得改 `sealed_holdout_rerun.PRODUCTION_FILES` 所列文件。
|
||||
2. `scripts/jyotish_api_server.py` 不得增长(`tests/test_api_server_growth_contract.py`)。本单应当不需要改它。
|
||||
3. golden 由真实引擎重新生成,不手造。改任何既有断言写「原值 / 新值 / 原因」三栏(AGENTS §7.3)。前端合同测试里的 golden(如 `consult-evidence-card-golden.json`)同样由引擎重生。
|
||||
4. Argala 的 `unresolved` / `strength_comparison_required` / `mixed` 不得在下游被压成 `none` 或「无」。
|
||||
5. 不改数据库、不改 workflow、不提升 main、不推 staging;只推 `codex/upstream-sync8-20261017`。
|
||||
6. 不写真实用户资料;示例只用公开名人盘(如乔布斯 AA)或虚构盘。实测数字段落推送前跑 `tests/test_repo_privacy_markers.py`。
|
||||
|
||||
## 6. 任务分解
|
||||
|
||||
每项一个提交,提交说明写上游提交号与 BUG 号。
|
||||
|
||||
| 项 | 内容 | 验收 |
|
||||
| --- | --- | --- |
|
||||
| T1 | 星宿拆解第一大运:小运从**完整大运真实起点**排,再裁到出生之后;复用 `cmd_dasha` 已有逻辑,不另写一套 | 移植上游 `tests/test_nakshatra_native_dasha_clock.py::test_first_remaining_md_is_not_repartitioned_into_new_ads` 通过(Ashwini 中点 → 当前小运 Rahu) |
|
||||
| T2 | `cmd_dasha`、`dasha_analyzer.lon_to_nakshatra` 以及其他按 `int(m/ns)` + `m%ns` 分开算的星宿定位,改为同一个量一次算出序号与进度,并按上游 `8643bc9a` 的统一边界语义(不吞掉真实邻点) | 移植上游 27 起点参数化测试 `test_native_vimshottari_exact_star_birth_balance`,**27/27 通过**;另加一条:月亮在起点左右相邻浮点数时,序号分别为前、后星宿;红线 1 的校正回放相同 |
|
||||
| T3 | Sandhi:小运交接用 `unclipped_start_datetime` 判断,第一段被出生裁剪的小运起点不算交接;默认参考时刻归零到当天 0 点 | 移植上游 `tests/test_dasha_sandhi_birth_clip.py`,按我方数据形状改写(第一大运 `start` 在出生前),三栏说明改写处;出生 30 天的虚构盘 Sandhi 表不再出现出生日假交接 |
|
||||
| T4 | Pinda 改按 PVR §12.7:削减**复用 `sodhita_chain`**,十二座 × 星座权重(处女 6)+ 行星权重,求七曜;Raman 15(c) 同值清空空宫。更新报告表头说明 | 移植上游 `tests/test_ashtakavarga_pinda_source.py`;PVR 例 43 = 152;报告 Sodhita 表与 Pinda 用同一份削减结果(加一条断言);`yoga_pinda_summary` 的 golden 由引擎重生 |
|
||||
| T5 | Bhava Bala Dig 表、摩羯前后半、BPHS Sputa 分段公式、火木土特殊相位、吉星集合(月木金,水中性);结果带方法名与 `claim_boundary`(上游最后一个元数据 hunk 我方缺 `status`,按我方结构补) | 移植上游 `tests/test_bhava_bala_vendor_profile.py`;`test_report_longform_gaps2` 等报告断言按三栏更新;BUG-1210 记录补关联 |
|
||||
| T6 | Argala:<br>• 计都宫反向数、源对边界、H9 不当次级(`e7301feb`);<br>• 同数按决策 2 的两级裁决,**复用我方 `narayana_dasha.select_narayana_seed_sign` 已有实现**,不移植后续层(`86935c0a`);<br>• 解释文本与裁决一致(`4f1536f2`);<br>• 待定状态透传到 `consultation_native_layers` 与 `consult_card_domain_facts` | 移植上游 `tests/test_argala_source_boundaries.py`、`tests/test_argala_strength_adjudication.py`;新增下游测试:同数仍平手时咨询层与咨询卡显示待定,不显示「无 / 被阻挡」 |
|
||||
| T7 | `get_kp_lords` 改为边界安全的整数 / 精确分区(`8eec9a54`)。新版对 None、bool、字符串、NaN/inf 抛 `ValueError`:先 grep 调用点(`active_rectification_questions.py`、`flexible_birth_time_profile.py`、`rectification/kp_cusp_observation.py`、`cmd_kp`),确认没有依赖旧 `TypeError` 的 try/except,有就同步改 | 移植上游 `tests/test_kp_exact_angular_boundaries.py`;20 万随机经度新旧结果 0 差异;红线 1 回放相同 |
|
||||
| T8 | Avastha 一批:<br>• 友敌座判定、旺落按星座、Bala 奇偶翻转、Jagrat 按尊贵、交点星排除(`e628118d` 的 avastha 部分);<br>• Deeptadi 标签按决策 2(`7d545039`);<br>• 并存条件全部保留(`f75a6e77`);<br>• PVR Shayanadi `calculate_pvr_shayanadi` 移植并在主链接线:传月亮经度、上升经度、**实际前一次日出(Hindu rising)以来小时数**(`ac565836`);<br>• 报告 Avastha 表、`report-fact-tables.ts`、咨询卡 avastha 行、`pl9_reader_export` 的 Markdown 表跟着改字段 | 移植上游 `tests/test_avastha_dignity_regressions.py`(7d545039 与 f75a6e77 版)、`tests/test_shayanadi_pvr.py` 通过;主链输出里 Shayanadi 的 `method_status` 不再是 `simplified_heuristic`;中英文报告各一例快照(公开盘) |
|
||||
| T9 | Saham 例外:改为 C 在 B→A 顺行弧上、不在则 +30°;两个入口(`_calc_formula_saham` 与 trace)都改,规则说明同步改 `references/saham_rules.json` 的描述字段 | 移植上游 `tests/test_saham_directed_operand_contract.py` 与 `tests/test_tajika.py` 的改动(`ce9fed15`);构造 C 在 A→B 弧上的例子,新旧结果差 30°;年运报告快照按三栏更新 |
|
||||
| T10 | 日出:<br>• `gulika.py` 两处夜晚结束改用真实 `next_sunrise`;<br>• `saham_daynight` 增加 Hindu rising 口径与真实相邻事件日窗口(`872eaecf`),只给 Saham 昼夜、Gulika、Shayanadi 用;<br>• 校正调用点行为不变(红线 1) | 移植上游 `tests/test_saham_daynight.py` 的四季 × 四时用例(Hindu 口径)通过;新增测试:校正调用 `determine_daytime` 的结果与改前逐字节相同;高纬度冬季例子 Gulika 夜段终点等于真实次日日出 |
|
||||
|
||||
## 7. 让步顺序
|
||||
|
||||
- **不可让**:红线 1。
|
||||
- **尽量不让**:T1、T2,二者是确定的错误,影响儿童用户的当前小运。
|
||||
- **可让**:
|
||||
- T8 体量最大,可拆为 T8a(判定与标签)和 T8b(Shayanadi 接线)先后交。
|
||||
- T10 若在不动校正路径的前提下改动面超预期,可只交 Gulika 部分,Hindu rising 写清卡点。
|
||||
- T6 的下游透传若牵动前端过多,可先交引擎层,下游写清卡点。
|
||||
- 次序建议:T1 → T2 → T3 → T7 → T4 → T5 → T6 → T9 → T10 → T8。T8 依赖 T10 的 Hindu 日出。
|
||||
|
||||
## 8. 验收门(执行方自测 + Claude 复验)
|
||||
|
||||
- Python:`ruff`、`py_compile`、定向测试;**全量 pytest 与基线逐名对比**(引擎数值改动,快速门曾漏过报告测试,BUG-1220);快速门 `scripts/run_quality_gate.py --profile quick`;冻结身份测试绿;隐私标记测试。
|
||||
- 校正回放:红线 1 的前后两次结果 JSON 附在进度记录。
|
||||
- 碰到前端(T6 / T8 极可能):tsc / lint / `npm test`(失败名单与基线逐名相同)/ build。
|
||||
- 文档:
|
||||
- `docs/BUG_HISTORY.md`(BUG-1380 起,每项一号);
|
||||
- `CHANGELOG.md`(用户可见:Avastha 措辞、Pinda、Bhava Bala、Saham、Argala 待定);
|
||||
- `docs/tasks/PROGRESS-upstream-sync8-20261017.md`;
|
||||
- `docs/tasks/README.md` 状态。
|
||||
|
||||
## 9. 开工前置
|
||||
|
||||
```
|
||||
git fetch origin --prune
|
||||
git status -sb
|
||||
git worktree add -b codex/upstream-sync8-20261017 .worktrees/upstream-sync8-20261017 origin/staging
|
||||
cd .worktrees/upstream-sync8-20261017
|
||||
git remote add upstream-skill https://github.com/732642856/yinduzhanxing.git # 已有则跳过
|
||||
git fetch upstream-skill codex/upstream-notice-20261016
|
||||
git log --oneline -1 FETCH_HEAD # 应为 caf1ed4e
|
||||
```
|
||||
|
||||
读上游改动:`git show <提交号>`,以及作者答复 `git show caf1ed4e:docs/research/upstream_notice_reply_2026_10_16.md`。
|
||||
|
||||
开工时核对 `origin/staging` 是否仍为 `53608d8b`。若已前进,以最新 staging 为基,进度记录写明。
|
||||
Reference in New Issue
Block a user