Files
Jyotisha/docs/tasks/PROGRESS-consult-card-affliction-data-20261001.md
T
Jesse_ChenandClaude Opus 5.5 4c8889027f docs: progress, bug history, changelog for consult card affliction data
TASK-consult-card-affliction-data-20261001 T5/T6: BUG-1154~1159 (1158 functional
classification source, investigating; 1159 yoga list is the packet candidate
set, investigating), progress record with size table, T4 diagnosis and T5
findings, BLOCKED entry, task index status.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N4f2nya58RoRu4yEmJgRGE
2026-10-01 23:59:23 +08:00

145 lines
15 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# PROGRESS · 数据卡补相位、同宫、燃烧,瑜伽按领域分流(2026-10-01,三单之一)
- 任务书:`docs/tasks/TASK-consult-card-affliction-data-20261001.md`(origin/staging `9b937c4a`)
- 执行:Claude fork 子代理(直接执行模式,产品授权)
- 分支 / worktree:`codex/consult-card-affliction-data-20261001` / `.worktrees/consult-card-affliction-data-20261001`,基线 `9b937c4a`(任务书写的 `2d620fb4` 之后只多了任务书与排查记录两个文档提交)
- BUG 编号:开工核对最大 BUG-1153;本单用 1154~1159(1158 = T5 核对结论,1159 = T4 诊断中查出的瑜伽清单问题)
- 代码提交:`19802a48`(文档另一提交)
- 预检:`python3 scripts/pre_work_check.py --remote-timeout 8 --command-timeout 45` 全部 ok;已读 `docs/research/pre_work_error_ledger.md`
## 环境
- 无项目 `.venv`(仓内 `.venv` 是悬空软链),Python 一律用本机 `python3` 3.13.5(user site 带 pyswisseph)。
- Node 22.14(`/exec-daemon/node`)跑前端;`frontend/node_modules` 用 `cp -al` 硬链接副本(真目录,Turbopack 可构建,已 gitignore,未提交)。
- 快速门内部的 `npm test` 步骤走系统 Node 20,70 条失败(Node 22 才支持的模块 mock 等);前端全量另用 Node 22 跑,结论以 Node 22 为准。
- 无 Docker:24 条数据库 / 部署套件失败,与基线逐条同名。
- 无模型凭据:模型读卡后的真实回答不在本单验收范围(第三单名人回测)。
## 交付门
| 项 | 基线 `9b937c4a` | 本分支 |
| --- | --- | --- |
| `tsc --noEmit` | 0 错 | 0 错 |
| `npm run lint` | 0 error / 126 warning | 0 error / 126 warning |
| `npm test`(Node 22,提交后终跑) | 4,868(pass 4,803 / fail 24 / skip 41 / cancelled 0) | 4,878(pass 4,813 / fail 24 / skip 41 / cancelled 0) |
| 失败名单 | 24 条,全是数据库 / 部署类 | 与基线逐条同名(`comm` 无差) |
| 测试名单 | — | 缺 0、新增 10(全部来自新文件) |
| `next build` | `/` ○ Static | `/` ○ Static |
| 首屏 gzip(`index.html` 引用 29 个脚本 gzip-9 求和) | 566,193 B | 566,193 B(0%) |
| Python 定向 `tests/test_consultation_native_layers.py` | 7 | 12 passed |
| 快速门 Python 段 | — | 1,041 passed / 1 skipped(含新增 5 条;快速门整体因内部 Node 20 的 `npm test` 退出 1,见环境) |
| `tests/test_api_server_growth_contract.py` | — | 通过(`jyotish_api_server.py` 0 行改动) |
时序抖动:`consult-evidence-lookup-20260927.test.ts`「a lookup does not reset the answer clock」在中间一次全量跑里报 `empty_answer` ≠ `answer_truncated`(70 秒假时钟下的竞态),同分支其余两次全量跑通过、单文件连跑 3 次 15/15 通过;本单没有改答题钟或该测试的任何依赖。
## 实现
| 任务 | 落点 |
| --- | --- |
| T1 引擎层(BUG-1154) | `scripts/consultation_native_layers.py` 新增 `build_graha_drishti`:七颗行星调 `aspects.calc_house_aspects`,输出 `planets[星].aspects_houses / aspected_by / combust`、`houses[N].aspected_by`;罗睺、计都只作被照对象。燃烧:把完整报告 Step 5 Shadbala 块里的内联规则提成 `jyotish_engine.COMBUSTION_ORBS` + `is_combust()`(容许度、比较式原样),完整报告与本层都调它。`_guard` 包裹 |
| T1 附带(T3 年运字段) | `build_slow_transits` 增加 `saturn_from_moon_house`(行运土星星座距本命月亮星座的整宫宫距) |
| T4 引擎侧(BUG-1157) | 新增 `build_yoga_domains` 与固定表 `YOGA_PACKET_DOMAINS`(按 Raman 包文件,用 `rule_id` 对照),每条带 `name / hit / domain` |
| 投影 | `frontend/src/mastra/consultation-workflow.ts`:`graha_drishti`、`yoga_domains` 进本命投影各自白名单;行运白名单加 `saturn_from_moon_house` |
| T2 卡片 base(BUG-1155) | `consultation-evidence-card.ts` `baseNatal`:行星行加 `aspected_by`、`conjunct_with`(同 `house` 选择)、`combust`(仅 true);相位层缺失记 `base.aspects`。领域段宫位行加 `aspected_by` |
| T3(BUG-1156) | parents roles 加 `lord_rows` / `significator_rows`;D12 同号宫加 `lord`、`lord_sign`;health `[1, 6, 8, 12]`、education `[4, 5, 9]`;年运卡抄 `saturn_from_moon_house` |
| T4 卡片 | 规格新增 `yogaTags`;parents、children 打开 yogas;yogas 段 `{names, hits, claim_boundaries}` |
| golden | `JYOTISH_API_CHART_CACHE_TTL_SECONDS=0 PYTHONHASHSEED=0 python3 scripts/research/capture_consult_evidence_card_golden.py` 重生;去掉新键后与旧 golden 逐值比对 0 处差异 |
| 测试 | 新文件 `frontend/tests/consult-card-affliction-data-20261001.test.ts`(10 条);`tests/test_consultation_native_layers.py` 新增 5 条 |
## 与任务书的偏差(请验收时逐条判断)
1. **相位层挂在 `chart.consultation_native_layers.graha_drishti`,不在 `chart.modules`。** 该模块的既有约定是不写 `modules`(主题报告按 `modules` 数量计 `full_reading_module_count`,不能动),所有本地附加层都在这里,投影也从这里读。
2. **燃烧不是「透传」。** 普通对话的排盘路径根本没有 `combust` 字段(golden 三张盘行星行都没有)。做法是把完整报告的内联规则原地提成函数,两处共用;没有写回 `chart.planets` 行(不改既有输出),值放在相位层里。
3. **宫位相位放在领域段的宫位行,没放 base。** 两种 base 方案都试过:base `house_aspects`(空宫省略)时乔布斯 timing 卡「契约+卡」12,005 > 12,000;放进 `base.natal.houses` 更大。领域宫位行只给本领域选中的宫,读宫时就在手边。代价:某领域没选的宫,卡上看不到它被谁照(落了星的宫可从落星的 `aspected_by` 读到)。
4. **为守住 12,000 字符,压缩了两处既有格式(任务书 D6「先压缩格式」):** `antardashas_in_mahadasha` 从 `{lord,start,end}` 改为 `[主星, 起, 止]`;D9 行的 `vargottama` 只在 true 时出现。新增的 `aspected_by`、`conjunct_with` 空时不出现,`combust` 只在 true 时出现。没有删任何字段的信息。
5. **yogas 段去掉 `count`、加 `hits`。** 原 `count` 是引擎全量条数,分流后与名单对不上;`hits` 是引擎 `hit` 原值,见 T4 诊断第一条。
6. **`functional` 标签** benefic / malefic / neutral 由卡写,进 `EVIDENCE_CARD_LABELS`(同「母亲 / 父亲」的先例)。D12 宫主用卡内 `SIGN_LORDS` 常量(与 `scripts/functional_benefics.py` 同一张表)。
7. **T4 验收「子女卡含 Puthra 类」**:golden 的 family 路由与 annual 路由都有子女包,测试用 annual 路由(20 条全包)对五个领域逐条核对。这些名字大多是**未命中**的规则候选,不是成立的瑜伽,见下。
## 改动的既有断言(原值 / 新值 / 原因)
| 文件 | 原值 | 新值 | 原因 |
| --- | --- | --- | --- |
| `consult-evidence-card-20260927.test.ts`「the card names what else…」 | career 卡 `supplementable_sections` 不含 `yogas`(false) | 含(true) | T4:卡上只放本领域标签的瑜伽,完整清单仍只能一次查阅拿到 |
| 同文件「every card value is…」白名单 | `EVIDENCE_CARD_LABELS` 四条 | 同一来源多 benefic / malefic / neutral,断言本身不变 | T3 父母卡宫主与代表星行的功能吉凶 |
| `consult-evidence-card-v2-20260927.test.ts`「every base section carries the engine's D9 summary」 | 每行 deepEqual `pick(row, [d9_sign, d9_dignity, vargottama])` | `vargottama` 为 false 时期望里去掉该键;另加一条断言卡上 `vargottama === true` 与引擎一致 | D6 字符预算 |
三个 12,000 字符断言(`consult-evidence-card-20260927`、`consult-evidence-card-v2-20260927`、`consult-condensed-checklist-20260927`)一条未改。
## 卡片体量(字符,`JSON.stringify` 长度;golden 三张盘)
「契约+卡」= 工具返回去掉 `methodology`(`consult-evidence-card-v2` 的口径);「含清单」= 整个返回(`consult-condensed-checklist` 的口径)。annual / timing 用各自路由的 golden,其余领域用 family 路由。
| 盘 / 领域 | 契约+卡 基线 | 本分支 | 差 | 含清单 基线 | 本分支 | 差 |
| --- | ---: | ---: | ---: | ---: | ---: | ---: |
| 乔布斯 / career | 7,358 | 7,233 | -125 | 9,989 | 9,864 | -125 |
| 乔布斯 / marriage | 7,904 | 7,941 | +37 | 10,612 | 10,649 | +37 |
| 乔布斯 / wealth | 7,378 | 7,385 | +7 | 9,950 | 9,957 | +7 |
| 乔布斯 / health | 7,206 | 7,412 | +206 | 10,993 | 11,199 | +206 |
| 乔布斯 / education | 6,329 | 6,477 | +148 | 8,368 | 8,516 | +148 |
| 乔布斯 / migration | 6,270 | 6,330 | +60 | 8,309 | 8,369 | +60 |
| 乔布斯 / family | 6,352 | 6,424 | +72 | 8,388 | 8,460 | +72 |
| 乔布斯 / parents | 6,518 | 7,379 | +861 | 8,555 | 9,416 | +861 |
| 乔布斯 / children | 6,152 | 6,321 | +169 | 8,190 | 8,359 | +169 |
| 乔布斯 / annual | 9,514 | 9,751 | +237 | 11,550 | 11,787 | +237 |
| 乔布斯 / timing | 8,552 | 8,555 | +3 | 11,471 | 11,474 | +3 |
| 乔布斯 / general | 7,911 | 7,859 | -52 | 9,948 | 9,896 | -52 |
| 奥巴马 / career | 7,299 | 7,120 | -179 | 9,930 | 9,751 | -179 |
| 奥巴马 / marriage | 7,653 | 7,662 | +9 | 10,361 | 10,370 | +9 |
| 奥巴马 / wealth | 7,462 | 7,398 | -64 | 10,034 | 9,970 | -64 |
| 奥巴马 / health | 7,134 | 7,319 | +185 | 10,921 | 11,106 | +185 |
| 奥巴马 / education | 6,380 | 6,456 | +76 | 8,419 | 8,495 | +76 |
| 奥巴马 / migration | 6,318 | 6,320 | +2 | 8,357 | 8,359 | +2 |
| 奥巴马 / family | 6,373 | 6,396 | +23 | 8,409 | 8,432 | +23 |
| 奥巴马 / parents | 6,549 | 7,398 | +849 | 8,586 | 9,435 | +849 |
| 奥巴马 / children | 6,188 | 6,311 | +123 | 8,226 | 8,349 | +123 |
| 奥巴马 / annual | 9,355 | 9,501 | +146 | 11,391 | 11,537 | +146 |
| 奥巴马 / timing | 8,629 | 8,577 | -52 | 11,548 | 11,496 | -52 |
| 奥巴马 / general | 7,894 | 7,799 | -95 | 9,931 | 9,836 | -95 |
| 泰勒 / career | 7,244 | 7,167 | -77 | 9,875 | 9,798 | -77 |
| 泰勒 / marriage | 7,970 | 8,064 | +94 | 10,678 | 10,772 | +94 |
| 泰勒 / wealth | 7,432 | 7,466 | +34 | 10,004 | 10,038 | +34 |
| 泰勒 / health | 7,090 | 7,333 | +243 | 10,877 | 11,120 | +243 |
| 泰勒 / education | 6,334 | 6,527 | +193 | 8,373 | 8,566 | +193 |
| 泰勒 / migration | 6,291 | 6,369 | +78 | 8,330 | 8,408 | +78 |
| 泰勒 / family | 6,356 | 6,469 | +113 | 8,392 | 8,505 | +113 |
| 泰勒 / parents | 6,518 | 7,364 | +846 | 8,555 | 9,401 | +846 |
| 泰勒 / children | 6,142 | 6,362 | +220 | 8,180 | 8,400 | +220 |
| 泰勒 / annual | 9,623 | 9,882 | +259 | 11,659 | 11,918 | +259 |
| 泰勒 / timing | 8,568 | 8,604 | +36 | 11,487 | 11,523 | +36 |
| 泰勒 / general | 7,811 | 7,800 | -11 | 9,848 | 9,837 | -11 |
最大值:契约+卡 9,882(上限 12,000);含清单 11,918(elizabeth_taylor/annual,上限 12,000,余量 82)。
**提醒第二单**:年运「含清单」只剩 82 字符(泰勒),timing 约 480。第二单若给年运、时运加中文清单,必须先在卡或清单上再省,或由产品重新定 12,000 的口径。
## T4 诊断:Sasa、落陷取消、Gajakesari 为什么不在卡上
对三张公开盘直接调用 `yoga_expansion.detect_all_yogas` + `yoga_engine.detect_yogas`(即 `_compute_yogas_api` 的两个检测器):
| 盘 | 检测器能出的大格局(节选) | 卡上 yogas(family 路由) | 其中命中 |
| --- | --- | --- | --- |
| 乔布斯 | Gajakesari、Raja Yoga 多条、Matrunasa、Saraswati、Amala(49 条) | 8 条母亲 / 子女 / 兄弟规则 | 0 |
| 奥巴马 | Sasa、Neechabhanga Raja、Budhaditya、Matrunasa(60 条) | 同 8 条 | Matrunasa |
| 泰勒 | Gajakesari、Hamsa (Trikona)、Saraswati、Eka / Bahu Puthra(61 条) | 同 8 条 | 0 |
三层原因(代码已核实,BUG-1159):
1. **卡上的名字是「规则候选」,不是「成立的瑜伽」。** `modules.yogas.yogas` = Raman 支持包里本路由成员规则的 `hits + misses`(`raman_support_observations.sieve_yogas_for_routes`),卡原来只抄名字不抄 `hit`。乔布斯 family 路由 8 条全部未命中,模型却看到 8 个瑜伽名。本单在卡上加了 `hits`。
2. **大格局不在任何 Raman 包里。** Sasa / Neecha Bhanga / Gajakesari 即使被检测到,也只进 `raman_support.yogas.ungoverned_detected`,不进 `modules.yogas`。这是「只放 governed_support_only_candidate_ready 的规则」的治理筛选,按任务书与 AGENTS §8.4 不放宽。
3. **规则引擎只在 `chart.yogas` 为空时才跑。** `jyotish_api_server.py` 普通对话 yogas 块:`chart.yogas` 有内容就直接用它,`if not compact:` 才调 `_compute_yogas_api`。乔布斯、泰勒的排盘结果自带 1~2 条扩展瑜伽(Amala、Saraswati / Kemadruma),于是完整检测没跑,乔布斯本可命中的 Matrunasa 也成了未命中;奥巴马 `chart.yogas` 为空,检测才跑,所以只有他有命中。命中与否取决于一个不相关的条件。
不是 Raman 筛选的条数上限(筛选没有上限,family 路由正好 3 个包 8 条规则)。第 2、3 条要改都涉及治理范围或 `jyotish_api_server.py`,交产品决定(BLOCKED.md)。
## T5 核对:功能吉凶分类的出处(只核不改,BUG-1158 investigating)
- 出处:`scripts/functional_benefics.py` `derive_functional_benefic_malefic`,`SOURCE = "strict_functional_benefic_malefic_v1"`,2026-06-28 `09817b96`「Bridge functional benefic malefic layer」引入;模块里没有引用任何典籍、流派或参考文件。
- 规则:三方宫 {1,5,9}、角宫 {1,4,7,10}、难宫 {3,6,8,11,12};同时主三方与角宫(日月除外)→ yogakaraka 且吉;只主三方 → 吉;主难宫且不含 1 宫 → 凶;其余(含只主角宫)→ 中性;8 宫主是日月时免凶。
- 由此:1 宫同时算三方和角宫,**除日月外的命主一律是 yogakaraka**(泰勒火星 1+6、奥巴马土星 1+2、乔布斯水星 1+10);**角宫主一律中性**,没有「凶星主角宫转吉」,天蝎上升的太阳(10 宫主)因此是中性;火星同时主 6 宫,因含 1 宫不算凶。
- 与常见 BPHS 列表的差别:yogakaraka 通常指同时主一个角宫与一个三方宫、且不靠命宫的行星(天蝎上升没有);天蝎上升常列功能吉星为太阳、月亮、木星。是否算缺陷、按哪派改,交产品与占星顾问;本单未改分类,父母卡的 `functional` 原样取自这一层。
## 未做 / 交给后两单
- 提示词(`frontend/src/mastra/index.ts` 的数据卡说明)还没讲新字段(`aspected_by`、`conjunct_with`、`combust`、`lord_rows`、`hits`、`saturn_from_moon_house`、子运短数组)——属第二单(读法与清单)。
- 模型读新卡后的真实回答、名人回测——第三单。