Files
Jyotisha/docs/tasks/PROGRESS-consult-career-yoga-functional-20261002.md
T

22 KiB
Raw Blame History

PROGRESS · 事业题看行业与名声、开场守「只说迹象」、功能吉凶典籍对照表、传统格局上卡(2026-10-02)

  • 任务书:docs/tasks/TASK-consult-career-yoga-functional-20261002.md
  • 执行方式:产品负责人要求子代理直接执行(Claude 子代理);只 commit、未 push。
  • 基线:origin/staging 8e978cab(任务书提交;代码同 6987875b)
  • 分支 / worktree:codex/consult-career-yoga-functional-20261002 / .worktrees/consult-career-yoga-functional-20261002
  • T1 触发硬红线 3,已停:T1 单独放在分支 codex/consult-career-yoga-functional-t1-20261002(1d039429,未合入本分支),交产品决定。本分支不含 T1,回测与 golden 都按不含 T1 的代码生成。
  • BUG 编号:开工核对最大号 BUG-1173;本单 BUG-1174~1177(T2~T5),更新 BUG-1158 / 1159 / 1164 / 1167 / 1168。

开工预检

python3 scripts/pre_work_check.py --remote-timeout 8 --command-timeout 45:status pass;唯一 ok: false 是 .venv 不存在(本机用系统 python3,已知环境缺口)。

T1 功能吉凶 BPHS 第 34 章对照表(BUG-1158)— 已实现、未合入(硬红线 3)

出处

  • EN:公开英文译本「Brihatparāśarahorāśāstra」第 34 章「Yoga Karakas」第 13、19–44 颂(vedpuran.net 流传的 PDF,印地语术语版,文件内未署译者;不是 R. Santhanam 原版排印,因此代码与本文都不写成 Santhanam)。
  • SA:enjoylearningsanskrit.com「bṛhat-pārāśara-horā-śāstram chapter 34」梵文原颂 + 逐词英译,颂号与 EN 一致。
  • 两份都逐颂读完(第 1–46 颂),没有凭记忆填格。每格的出处写在 scripts/functional_benefics.py BPHS_CH34_TABLE 的注释和 citations 字段里。

填格规则

  1. 该上升的颂里点名 pāpa / malefic → 凶;śubha / auspicious → 吉;sama / samaphala / madhyaphala → 中性。
  2. yogakaraka(决策 D1①):只认同一颗星同时主一个角宫(4、7、10)和一个三方宫(5、9)(第 13 颂),且该上升的颂没有判它为凶。命主不因主 1 宫成为 yogakaraka。
  3. 颂里点名「成对」给 raja yoga 的(如天秤「月亮与水星」),记在 raja_yoga_pairs,不算 yogakaraka。
  4. 颂里没有给吉凶判词的星、或 EN 与 SA 意思不一致的格,保留公式值并标 formula_fallback(公式同 v1,只是 1 宫只算三方宫、不算角宫;8 宫主为日月时按第 7 颂判中性)。

12 上升旧值 / 新值

上升 旧值(v1 公式)YK / 吉 / 凶 / 中 新值(BPHS ch.34)YK / 吉 / 凶 / 中 出处 formula_fallback
白羊 火 / 木火日 / 水土 / 月金 — / 木火日 / 水土金 / 月 v19–22 月
金牛 土金 / 水土金 / 木火月 / 日 土 / 水土日 / 木火月金 / — v23–24 火、水
双子 水 / 水土金 / 火日 / 木月 — / 水土金 / 木火日 / 月 v25–26 月、水、土
巨蟹 火 / 木火月 / 水土金 / 日 火 / 木火月 / 水土金 / 日 v27–28 土
狮子 火 / 木火日 / 水月土金 / — 火 / 木火日 / 水土金 / 月 v29–30(YK 依第 13 颂) —
处女 水 / 水土金 / 火月日 / 木 — / 水土金 / 木火月 / 日 v31–32 土
天秤 土金 / 水土金 / 木日 / 火月 土 / 水土 / 木火日 / 月金 v33–34(YK 依第 13 颂) 月
天蝎 火 / 木火月 / 水土金 / 日 — / 木月 / 水土金 / 火日 v35–36 日
射手 木 / 木火日 / 土金 / 水月 — / 火日 / 土金 / 木水月 v37–38 水、土
摩羯 土金 / 水土金 / 木火 / 月日 金 / 水土金 / 木火月 / 日 v39–40 土
水瓶 土金 / 水土金 / 木火月 / 日 金 / 土金 / 木火月 / 水日 v41–42 日
双鱼 木 / 木火月 / 土日金 / 水 — / 木火月 / 水土日金 / — v43–44 木

(木 = 木星,火 = 火星,日 = 太阳,月 = 月亮,水 = 水星,金 = 金星,土 = 土星。)

验收要求逐条:白羊无 yogakaraka 火星 ✔;金牛 / 天秤只有土星 ✔;巨蟹 / 狮子只有火星 ✔;摩羯 / 水瓶只有金星 ✔。tests/test_functional_benefics_bphs_table.py 锁 12 上升全部格子、每格出处、yogakaraka 必须同时主角宫与三方宫。

交产品与占星顾问复核的格(formula_fallback 与歧义)

  1. 金牛水星:EN「Budh is somewhat inauspicious」,SA「budhas tv alpa-śubha-pradaḥ」(给的好处少)——两个译法相反,保留公式值(吉)。
  2. 双子:第 25 颂「eka eva kaviḥ śubhaḥ」(只有金星吉),但没判水星(命主)、土星(9 宫主)为凶——保留公式值(吉);若按「只有金星吉」应改中性。
  3. 射手土星:第 37 颂「eka eva kaviḥ pāpaḥ」(只有金星凶),又说土星是 killer——保留公式值(凶),与「只有金星凶」字面冲突。
  4. 只被点名为 maraka(killer)、没有吉凶判词的:金牛火星、巨蟹土星、水瓶太阳——保留公式值。
  5. 只出现在「成对 yoga」里的:天秤月亮、天蝎太阳、射手水星、双鱼木星(命主)——保留公式值;对应的对子记在 raja_yoga_pairs(处女金+水、天秤月+水、天蝎日+月、射手日+水、双鱼火+木)。
  6. 狮子火星、天秤土星的 yogakaraka:该上升的颂只说「吉」,yogakaraka 依第 13 颂(同一颗星主角宫与三方宫)推出,没有逐上升点名。
  7. 水瓶第 41 颂 SA 行尾带「bṛhaspatiḥ」,EN 只译金星为唯一 raja yoga 星;同颂判木星为凶,按金星唯一处理。
  8. 天秤金星(命主兼 8 宫主)判中性、天蝎火星(命主兼 6 宫主)判中性、射手木星(命主)判中性、金牛金星(命主兼 6 宫主)判凶:都是颂的原文,与 v1「命主一律吉」不同,属已知变化。
  9. 另一套实现 scripts/yoga_engine.py functional_malefics() / functional_benefics()(瑜伽规则引擎内部用)不读本模块,本单未改,口径仍是旧的;是否统一交产品决定。

生时校正回归门(硬红线 3)

命令:python3 scripts/research/holdout_v5_baseline.py --dataset v5 --out-dir <scratchpad>(v5 77 例;改前在 origin/staging 一次性 worktree 跑,改后在 1d039429 一次性 worktree 跑,只差 T1)。

指标 ±10 改前 → 改后 ±30 改前 → 改后 ±60 改前 → 改后
引擎先验头名(sweep top1) 0.1818 → 0.1688(−1.3 pp) 0.0779 → 0.0779 0.0649 → 0.0649
覆盖(sweep coverage) 1.000 → 1.000 1.000 → 1.000 1.000 → 1.000
六题回放头名(sweep replay_top1) 0.6364 → 0.5974(−3.9 pp) 0.4935 → 0.4675(−2.6 pp) 0.2597 → 0.2857(+2.6 pp)
线上区间回放头名(cluster_width top1) 0.6753 → 0.6364(−3.9 pp) 0.4935 → 0.5195(+2.6 pp) 0.3247 → 0.3896(+6.5 pp)
线上区间覆盖(cluster_width coverage) 0.987 → 0.987 0.987 → 0.987 0.974 → 0.974
区间宽度中位(cluster_width) 15 → 13 35 → 35 63 → 65

结论:±10 的头名掉 1.3~3.9 个百分点、±30 六题回放掉 2.6 个百分点,超过 1 个百分点,按红线停在 T1。覆盖不变;±60 反而上升。逐例看,±10 六题回放是 8 例丢、5 例得(净 −3),±30 是 5 丢 3 得,±60 是 5 丢 8 得——属于换牌式的波动,与 09-29 研究「42 个特征在 77 例上多为噪声」一致,但红线按数字执行。T1 提交保留在 codex/consult-career-yoga-functional-t1-20261002,交产品决定:①接受这次波动合入;②只合入「yogakaraka 必须同时主角宫与三方宫」这一条、吉凶表另议;③不合入。

T2 瑜伽检测不跳过(BUG-1174)

  • scripts/consultation_native_layers.py 新增 collect_consultation_yogas / merge_detected_yogas:规则引擎(yoga_expansion.detect_all_yogas + yoga_engine.detect_yogas)每次都跑,与 chart.yogas 按归一化名字合并去重,再进 Raman 筛选;规则引擎抛错时保留 chart.yogas(原先 chart.yogas 非空时本就不跑)。
  • scripts/jyotish_api_server.py:删掉 if not compact: 分支,改为调用上面的函数(+2 / −18 行,tests/test_api_server_growth_contract.py 过;类方法数不变)。
  • tests/test_consultation_yoga_detection_merge.py:锁「chart.yogas 非空时规则引擎仍运行」、去重、引擎失败退回、服务端源码里不再有 if not compact:。

改前 / 改后 modules.yogas 的 hits(四条路由的并集;三位 golden 名人即前三位):

名人 改前 hits 改后 hits
Steve Jobs — Matrunasa、Sunaphaa、Vosi
Barack Obama Matrunasa、Sunaphaa、Vosi、Ubhayachara、Dharidhra、Swaveeryaddhana 同左(排盘本无自带瑜伽,原先就跑了规则引擎)
Elizabeth Taylor — Bahu Puthra、Eka Puthra、Matrunasa、Anaphaa、Vosi、Ubhayachara、Swaveeryaddhana
Marilyn Monroe — Matrunasa、Sunaphaa、Anaphaa、Duradhara、Vosi、Ubhayachara、Swaveeryaddhana
Judy Garland — Eka Puthra、Matrunasa、Anaphaa、Dharidhra、Swaveeryaddhana
Édith Piaf — Eka Puthra、Matrunasa、Sunaphaa
Frida Kahlo Matrunasa、Dharidhra 同左
George W. Bush — Matrunasa、Anaphaa、Vosi、Ubhayachara、Dharidhra、Swaveeryaddhana
Zinedine Zidane — Matrunasa、Vosi、Ubhayachara、Swaveeryaddhana

观察(未改,不在本单范围):泰勒、齐达内的排盘自带「Kemadruma Yoga」(月亮两侧无星),规则引擎同时判出 Anaphaa / Vosi / Ubhayachara(月亮或太阳两侧有星)——两套检测器对同一张盘结论相反,现在两条都会进到模型可见的数据里。建议另开单核对。

T3 传统格局栏(BUG-1175)

  • 引擎:build_traditional_yogas(_guard 包裹)从 raman_support.yogas 的 hits + ungoverned_detected 里按封闭名单取成立项,挂 consultation_native_layers.traditional_yogas = {status, source, label, names}。名单按引擎实有名称对齐:Ruchaka、Bhadra、Hamsa、Malavya、Sasa(含 Shasha)、Gajakesari、Neecha Bhanga Raja(引擎名 Neechabhanga Raja Yoga / … (Kendra))、Budha-Aditya(引擎另有同一组合的「Surya-Budha Yoga」,并成一行)。名单内每个格局引擎都有检测器,没有新写检测器。
  • 投影:consultation-workflow.ts 新增 traditional_yogas 白名单(status / reason / source / names;label 由卡片自己写)。
  • 卡片:general、career、wealth 三张卡加 traditional_yogas: {label, names},label 固定为 EVIDENCE_CARD_LABELS.traditionalYogas「传统格局,本站未验证,只作参考」;没有成立项就不出现。
  • 通用读法第 8 行:「traditional_yogas 只用来说明力量,不单独下结论,不算受冲,也不抵消受冲。」
  • 各名人检测结果(golden 实测):Jobs Gajakesari;Obama Sasa、Neecha Bhanga Raja、Budha-Aditya;Taylor Hamsa、Gajakesari、Budha-Aditya;Monroe Budha-Aditya;Garland Bhadra;Piaf Budha-Aditya;Kahlo 无;Bush 无;Zidane Budha-Aditya。
  • 验收:frontend/tests/consult-career-yoga-functional-20261002.test.ts(奥巴马综合卡含 Sasa、Neecha Bhanga Raja;乔布斯、泰勒含 Gajakesari;只有三张卡带;空时不出现;标签原文)。数据卡 12,000 / 18,000 字符断言原样通过。

T4 事业清单(BUG-1176)

career 清单第 1 行后加任务书定稿的两行(原文,未改字)。清单 7 → 9 行。

T5 开场规则(BUG-1177)

natalAnswerShapeBody 第一句换成定稿句;合同测试锁句并断言不再有「第一句就是结论」。另:product-voice.ts ANSWER SHAPE 第 1 条(系统提示里的同一条开场规则)补一句「开场的结论只说哪条线顺、哪条线有压力迹象,不替用户断定在不在身边、几段感情、有没有病,不写程度结论」——任务书 T5 只点名 natalAnswerShapeBody,但系统提示里同一规则仍写「第一句就是结论」,不补会与 D5 冲突;原句保留,既有合同测试 /开场一到三句人话,第一句就是结论/ 不受影响。VOICE §7 ① 同步。

改动的既有断言

文件 · 测试 原值 新值 原因
consult-affliction-reading-20261001.test.ts「T1: the shared reading is the first section…」 CONDENSED_SHARED_READING_LINES.length === 7 === 8 T3 定稿给通用读法加一行(BUG-1175)
同文件「T3: career, marriage and wealth each carry their affliction line」 三份清单 5–8 行 marriage / wealth 5–8 行,career 5–9 行 T4 定稿给事业清单加两行(BUG-1176)
consult-condensed-checklist-20260927.test.ts「each condensed list is 5–8 lines」 三份 5–8 行;全部清单 2–8 行 career 上限 9,其余不变 同上
T1 分支(未合入)tests/test_mcp_strict_workflow_functional_layer.py source == "strict_functional_benefic_malefic_v1" "bphs_ch34_table_v1" D1 推翻 v1 公式

T6 回测(BUG-1167 补记)

  • 评分表 docs/research/consult_biography_backtest_rubric.json 版本 2026-10-02:9 位事业项加 expected_field(按任务书)与 public: true,how_to_score.career_field 写明「行业对」与「专业 / 幕后误判」的判法。T1 未合入,乔布斯事业 expected_signals「10 宫主水星是 yogakaraka」保持原样。
  • golden:两份都用 capture 脚本重新生成(PYTHONHASHSEED=0 JYOTISH_API_CHART_CACHE_TTL_SECONDS=0),同一代码两次输出逐字节相同;未手改。
  • 命令:--repeats 2 --concurrency 4 --correction barack_obama,marilyn_monroe,judy_garland,edith_piaf,72 份 + 8 份纠正,失败 0。逐份阅读评分,结果见 docs/testing/consult-affliction-backtest-20261001.md「改动后(第三轮)」。
通过线(任务书 T6) 第三轮 达到
事业「行业对」≥ 14 / 18 3 / 18(其中 1 份弱) 否
「专业 / 幕后」误判 ≤ 3 / 18 12 / 18 否
对照组严重误报 0 0 是
对照组轻度误报 ≤ 2 3 否
严重冲突总数 ≤ 5 / 72 15 / 72(事业 12、父母 3) 否
其余领域不比第二轮差 父母持平(严重 3);婚姻持平(误报 1 → 0,读反 0 → 1 轻);健康持平略好(读反 1 → 1,误报 3 → 2,全部轻) 是(持平)
禁句 0 0 是

读出来的主因:模型确实按 T4 的「星的本性」取行业了,但这几张盘上 10 宫、10 宫主、AmK 落到的是水星 / 木星 / 土星(分析、顾问、组织),按清单的对照表本来就推不出「表演 / 竞技 / 政治」;「公众型」的几条依据(太阳或 10 宫主强在角宫、AL / A10 落角宫)在乔布斯、布什、齐达内盘上也不成立。也就是说,按 D4 定稿的对照表,这批盘的行业和公众性从盘面读不出来——不是模型没照做,是对照表与这批名人的生平对不上。要过线需要产品与占星顾问决定事业口径(例如 D10、AL 落 10 宫、入旺星的权重),不是改措辞。开场规则(T5)有效:对照组开场下结论的轻度误报 6 → 3。

门禁

项 基线(origin/staging 一次性 worktree) 本分支
tsc --noEmit — 0 错
npm run lint — 0 error / 126 warning
npm test(Node 22) 4,898 项:pass 4,833 / fail 24 / cancelled 0 / skip 41 4,904 项:pass 4,839 / fail 24 / cancelled 0 / skip 41;失败名单与基线逐条同名(24 项都是需要 Docker / PostgreSQL / 部署环境的套件)
next build / ○ Static / ○ Static
首屏 gzip(预渲染 index.html 引用的 /_next/ 脚本 gzip-9 求和,同法实测) 952,189 B 952,189 B(0%)
Python 定向 — test_consultation_yoga_detection_merge.py、test_consultation_native_layers.py、test_api_server_growth_contract.py、test_active_rectification_events.py、test_report_longform_parity.py、test_cli_smoke.py、test_consultation_consumer_context.py、test_api_server_security.py 全过;test_consult_evidence_card_research.py::test_source_parsers_keep_family_split_gap 失败,基线同样失败(与本单无关)
快速门 run_quality_gate.py --profile quick(系统 python3 + Node 22) — pytest 1,041 passed / 1 skipped;门内 npm test 与上行相同(24 项环境失败),门禁总状态因此为 failed
隐私标记 — tests/test_repo_privacy_markers.py 在快速门内通过

环境:frontend/node_modules 用硬链接拷贝(Turbopack 拒绝工作树外软链),未提交;模型 key 只从环境变量读,没有写入文件、日志或提交;模型输出在 scratch/consult-biography-backtest/round3-20261002/(gitignore)。

第二轮:产品 10-02 决定后的改动

A. yogakaraka 窄修(BUG-1158 部分)

  • 产品决定:只合入「yogakaraka 须同时主 4/7/10 之一与 5/9 之一,1 宫不计入」;吉 / 凶 / 中性分组不变(命主仍为吉)。提交 ffafa28b,SOURCE = strict_functional_benefic_malefic_v2(jyotish_engine.py、jyotish_api_server.py 两处 blocked 兜底字符串、mcp_server.py 同步改名)。
  • 12 上升 yogakaraka 旧 → 新:白羊 火 → 无;金牛 土金 → 土;双子 水 → 无;巨蟹 火 → 火;狮子 火 → 火;处女 水 → 无;天秤 土金 → 土;天蝎 火 → 无;射手 木 → 无;摩羯 土金 → 金;水瓶 土金 → 金;双鱼 木 → 无。吉 / 凶 / 中性分组 12 上升逐格与 v1 相同(脚本逐格比对)。
  • 生时校正 v5 77 例(改前 81f6e513、改后 ffafa28b,各在一次性 worktree 跑):
指标 ±10 ±30 ±60
引擎先验头名 0.1818 → 0.1818 0.0779 → 0.0779 0.0649 → 0.0649
六题回放头名 0.6364 → 0.6364 0.4935 → 0.4935 0.2597 → 0.2597
线上区间回放头名 0.6753 → 0.6753 0.4935 → 0.4935 0.3247 → 0.3247
覆盖(区间) 0.987 → 0.987 0.987 → 0.987 0.974 → 0.974
宽度中位 15 → 15 35 → 35 63 → 63

逐项相同,未触发红线(生时校正打分只读吉凶分组,不读 yogakaraka)。

  • 测试:新增 tests/test_functional_yogakaraka_kendra_trikona.py;tests/test_mcp_strict_workflow_functional_layer.py 两处 source 断言:原值 strict_functional_benefic_malefic_v1 / 新值 ..._v2 / 原因:产品 10-02 yogakaraka 定义改动。
  • T1 分支保持原表不动,只追加复核清单 docs/research/bphs_ch34_functional_table_review_2026_10_02.md(c66c122a)。更正:待复核的 formula_fallback 格是 15 个,首次回报写成 14 个。

B. 上游 e9beae6b 移植(未执行,权限)

协调方随后要求改为移植上游 /workspace/yinduzhanxing e9beae6b 的 functional_benefics.py(原样)、pancha_mahapurusha.py(原样)、yoga_engine.py 局部与 references/functional-role-profile.md。已核对:我方两份文件与上游改动前版本逐字节相同。但本会话的自动权限判定以「Untrusted Code Integration」拒绝了从另一仓库原样拷入代码,按规则没有用别的办法绕过,移植未做,需要用户在权限设置里放行后再执行。因此主分支仍是 A 的窄修;回退方案里的 pancha_mahapurusha 修复(同样来自上游)也未做。career_analysis.py、jyotish_api_server.py 的上游改动按指示不移植。另记:上游的 references/functional-role-profile.md 若移植,references/ 是 Skill 包(硬红线 5),应放 docs/research/ 并改 rule_reference。

C. 事业「不猜行业,问用户」(BUG-1176 决策日志)

  • CAREER_FIELD_ASK_RULE 定义在 consultation-thinking-plan.ts,事业清单第 1 行引用(取代「先讲一生事业形态:公众型还是幕后型」与第一轮加的两行);AL 一行去掉「落 10 宫 = 公众形象就是事业」;CAREER_FOLLOW_UP_RULE 进追问轮形状。VOICE §8 同步。事业清单 9 → 7 行,第一轮放宽的「career 5–9 行」断言改回原值 5–8。
  • 改动的既有断言:consult-no-presupposition-20261001.test.ts(原值:career[0] 以「先讲这张盘一生的事业形态」开头、含「受冲只说阻力和代价,不改写事业形态」/ 新值:以 CAREER_FIELD_ASK_RULE 开头、含「不替用户断定他做哪一行、是公众型还是幕后型」/ 原因:产品 10-02 决定);consult-condensed-checklist-20260927.test.ts「the writer's prompt carries…」(原值:career 必含「事业形态」/ 新值:必含「不替用户断定他做哪一行」/ 同上)。
  • 回测脚本加 --correction-domain、--correction-texts(每位名人一条追问)。
  • golden 用 capture 脚本重生成(yogakaraka 变化),两次逐字节相同。评分表:how_to_score.career_field 改为第四轮口径,pass_lines_career_round4;乔布斯事业 expected_signals 不再说水星是 yogakaraka。

D. 第四轮回测(详表见测试文档「改动后(第四轮)」)

通过线 第四轮 达到
事业行业 / 类型与生平冲突 ≤ 1 / 18 9 / 18 否
事业段末请问一句 ≥ 16 / 18 18 / 18 是
严重冲突总数 ≤ 5 / 72 12 / 72(事业 9、父母 3) 否

事业追问(足球运动员 / 演员 / 政治家 × 2)6 / 6 按真实职业读、不编依据。新出现禁句 1 处(Piaf 健康 r2);3 份全篇两处请求。

门禁(第二轮)

项 结果
tsc 0 错
lint 0 error / 126 warning
npm test(Node 22) 4,905 项:pass 4,840 / fail 24 / cancelled 0 / skip 41;失败名单与基线逐条同名
build / ○ Static;首屏 gzip 952,189 B(0%)
Python 定向 yogakaraka、mcp 功能层、瑜伽合并、native layers、生时校正事件、报告长文、cli smoke、consumer context、api security、增长合同、隐私标记全过

提交

主分支 codex/consult-career-yoga-functional-20261002(未 push):c74bfcc0、dd817c8e、5af6b222、81f6e513、ffafa28b、6a02e5e9 及本文档提交。T1 分支 codex/consult-career-yoga-functional-t1-20261002:1d039429、c66c122a。