Files
Jyotisha/docs/tasks/TASK-upstream-sync2-fix-20260909.md
T

110 lines
9.8 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.
# TASK · 上游同步二修复单(网页婚恋路径拿不到大运 / 围栏失败会打断报告)— 2026-09-09
- 基线:`origin/staging` @ `04ad3325``TASK-upstream-sync2-20260909` 实现,已验收;`TASK-report-chart-render-20260909` 实现 `2fdcb14f` 同批在 staging)。
- 分支:`codex/upstream-sync2-fix-20260909`worktree `.worktrees/upstream-sync2-fix-20260909`
- 验收结论摘要(`04ad3325`):定向 Python 176 通过;quick 门 708 通过 / 1 失败(`test_shadbala_endpoint_returns_ranked_planet_strength`,验收机缺 `timezonefinder`,环境缺口);真实 `pl9-export` 时间系统表 5 + 10 行正确;api_server 11300 行(上限 11363)。前端(`2fdcb14f`):tsc 0 错、lint 0 error、`npm test` 2991 / 2949 通过 / 28 失败(无 Docker 基线同 28/ 14 跳过;`next build --webpack` `/` Static`globals.css` gzip 35290 → 35630+0.96%)。
## 1. 事故实证
### P1 · 网页咨询路径的婚恋三层分类永远没有大运命中
`04ad3325` 起本地 API`scripts/jyotish_api_server.py --port 5299`)对 `/api/consultation_workflow``theme=marriage`,虚构出生 1990-06-15 10:30 北京)实测:
| 观察 | 值 |
| --- | --- |
| `thematic_report.themes.marriage.evidence` | `D1-7th-house``Spouse-status-yoga``DK-UL-Dasha timing``Romantic-activation` |
| `Romantic-activation.details.hits` | `[]`(只有 `natal_structure: ["7H_Moon"]` |
| `Relationship-formation` / `Legal-marriage` | 不出现 |
| `thematic_report.themes.marriage.timing.dasha_period` | `Saturn-Unknown` |
| `chart.modules.dasha` 的键 | `current_md / remaining_years / total_years / start_date / periods / birth_balance / …`**没有** `maha_dasha` / `antar_dasha`,也没有 `vimshottari_analysis``current_md` 是出生时大运(Rahu),不是当前 |
| `chart.modules.dasha_sub_periods.current` | `{"mahadasha": {"lord": "Saturn", …}, "antardasha": {"lord": "Jupiter", …}}`(正确的当前 MD/AD |
链路:`_thematic_dasha_info`L6555)只从 `chart['dasha']``dasha['vimshottari_analysis']['current']``maha_dasha` / `antar_dasha`;咨询路径 `full_reading_used=false``dasha = full_modules.get('dasha')`L5425)是 chart 模块的 `dasha`,没有 `vimshottari_analysis`。于是传进 `analyze_relationship``dasha_info` 只有 `current_md`(出生 MD),`MD_AD_KEYS = ('maha_dasha','mahadasha','antar_dasha','antardasha','bhukti')` 一个都对不上 → `event_class_split.*.hits` 恒空。
**后果**:任务书 §2 的核心目标(按 MD/AD 把心动 / 成对 / 领证分开)在网页聊天路径上是空转,只剩本命结构观察;同时 `report_orchestrator.py` L701 那句「婚姻相关宫位与 karaka 将被激活,是缔结或调整伴侣关系的关键期」仍随 `timing.dasha_period``Saturn-Unknown`)无条件输出——这正是 BUG-608 要拆掉的合并式「婚恋机会」,只是换了个文件。
### P2 · 围栏构造在 try 外,任何一张分盘出 ValueError 会让整份长报告 500
`scripts/jyotish_engine.py` `_render_south_chart`L4226):`render_south_indian_chart``try` 内,失败返回 `_图盘生成失败_`;但紧接的 `build_chart_block(...)``try` 外,`resolve_chart_id` / `_sign_name``raise ValueError('chart id missing' / 'ascendant sign missing')`。分盘 `Ascendant` 行的 `sign` 不在英文 12 星座内(例如引擎某分盘输出 `sign_idx` 而无 `sign`、或中文星座名)时,`render_pl9_markdown` 整体抛错,`/api/reports/<id>/professional-reference``pl9-export` 一起失败。22 张 golden 都是正常路径,没有覆盖这个分支。
### P3 · `/api/health` 的 `version` 写死 `6.9.14`
`scripts/jyotish_api_server.py` L3402 `'version': '6.9.14'`L7000 另一处 `6.9.15`),`jyotish_vedic.__version__` 已是 `6.9.16`。健康检查报的 Skill 版本与实际不符(`5d35731f` 引入,非本轮回归,顺带修)。
## 2. 根因
- P1`_thematic_dasha_info` 是为 `/api/thematic_report` 走 full reading 时写的,前提是 `dasha``vimshottari_analysis`;咨询路径 09-06 起改为复用 chart 模块后这个前提就没了,但当时只影响一句 legacy `timing`,没人发现。BUG-608 把 `dasha_info` 接上后,这条断链第一次有了产品后果。
- P2:任务书 §5 任务 1 写「失败路径不加围栏」,执行方理解为「SVG 失败不加」,没把围栏自身的失败纳入。
- P3:版本字符串散落三处,没有从 `jyotish_vedic.__version__` 读。
## 3. 决策记录
| 决策 | 内容 |
| --- | --- |
| D1 | `dasha_info` 的当前 MD/AD/PD 一律从 `chart.modules.dasha_sub_periods.current``_consultation_dasha_sub_periods` L1432,按请求参考日切出)取;缺失时再回退 `vimshottari_analysis`;两者都缺时**不**从 `dasha.periods` 手算——日期只许来自引擎已切好的边界。 |
| D2 | `report_orchestrator.py` 婚恋主题的 `activation_description` 改为按 `event_class_split` 出句:有 `legal_marriage` MD/AD 命中才可写「缔结」;只有 `romantic_activation` 时写「感情被激活的观察期,不等于领证」;没有命中时不出「关键期」句,`timing` 保留日期但 `activation_description` 写「本期无婚恋事件类命中」。`Saturn-Unknown` 这种 AD 缺失时不得拼 `-Unknown`,改用 MD 单独显示。 |
| D3 | 围栏失败只丢围栏、保留 SVG;不新增用户可见文案。 |
| D4 | 三处版本字符串统一读 `jyotish_vedic.__version__`。 |
不推翻 `TASK-upstream-sync2-20260909` 任何红线。
## 4. 硬红线
1. `scripts/jyotish_api_server.py` 净增 ≤ 15 行(当前 11300,上限 11363);`_thematic_dasha_info` 改动就地,不新增 handler。
2. `/api/consultation_workflow` 契约只增不改;`thematic_report.themes.marriage.timing` 现有键保留。
3. `relationship_analysis.py` / `relationship_event_class_evidence.py` 不改逻辑;P1 只修喂数。
4. 前端不动。
## 5. 任务分解
### 任务 1 · 喂正确的 MD/ADP1)
- `_thematic_dasha_info(chart, dasha)`:先读 `chart.get('modules', {}).get('dasha_sub_periods', {}).get('current')`,映射 `mahadasha.lord → maha_dasha``antardasha.lord → antar_dasha``pratyantardasha.lord → pratyantar_dasha`(若存在);再按原逻辑回退 `vimshottari_analysis`
- 新测试 `tests/test_thematic_dasha_info_source.py`:构造 chart(含 `dasha_sub_periods.current` Saturn/Jupiter)与无 `vimshottari_analysis` 的 dasha → 返回 `maha_dasha='Saturn', antar_dasha='Jupiter'`;无 `dasha_sub_periods` 但有 `vimshottari_analysis` → 走回退;两者都无 → 不含 `maha_dasha`
- 端到端:`tests/test_relationship_event_class_evidence.py` 加一条走 `_derived_marriage_evidence` 的用例,输入来自真实 `/api/consultation_workflow` 响应(把本轮实测的 1990-06-15 虚构盘响应存为 `tests/golden/upstream_sync2/consultation_marriage_1990_fictional.json`,只保留 `chart.modules.dasha / dasha_sub_periods / planets / ascendant``thematic_report.themes.marriage`),断言 `Romantic-activation``Relationship-formation` 至少一条 `details.hits` 非空(Saturn MD / Jupiter ADJupiter 为该盘 7L 或 DK 之一时命中;若该盘不命中,换一个命中的虚构出生并写明)。
验收:新测试绿;重跑本单 §1 的 curl,`hits` 非空、`timing.dasha_period` 不再含 `Unknown`
### 任务 2 · 婚恋 activation 句按事件类出(P1 后半)
- `scripts/report_orchestrator.py` L701 附近:婚恋主题 `activation_description``event_class_split` 派生(见 D2);`dasha_period` 在 AD 缺失时只写 MD。
- 测试:`tests/test_report_orchestrator_marriage_timing.py`(或就近既有文件)三例:仅 romantic → 含「不等于领证」;legal MD/AD 命中 → 可含「缔结」;无命中 → 不含「关键期」「缔结」。
验收:`grep -n "缔结或调整伴侣关系的关键期" scripts/report_orchestrator.py` 只在 legal 分支出现。
### 任务 3 · 围栏失败不打断报告(P2)
- `_render_south_chart``build_chart_block``try/except Exception`,失败返回 `svg`(不带围栏),并 `logging.warning` 一次(不含地名 / 用户串)。
- `tests/test_report_chart_block.py` 加一条:`ascendant_row={'sign': '白羊'}``render_pl9_markdown` 不抛、Markdown 含 `<svg` 且该处无 ```jyotish-chart。
### 任务 4 · 版本字符串(P3)
- L3402、L7000、L7120 三处改为 `jyotish_vedic.__version__`fallback 后缀保留);`tests/test_api_server_security.py` 或就近健康检查测试断言 `version == __version__`
### 任务 5 · 记录
- `docs/BUG_HISTORY.md`**BUG-609**P1,关联 BUG-608、BUG-555 咨询复用 chart 模块)、**BUG-610**P2,关联 BUG-607)、**BUG-611**P3)。
- `docs/tasks/PROGRESS-upstream-sync2-fix-20260909.md``CHANGELOG.md` 一条(婚恋 activation 句按事件类出)。
- `docs/testing/upstream-sync2-20260909.md` 补一条:staging 上问「我什么时候会结婚」,回答里的大运名要与页面时间轴当前 MD/AD 一致,且不出现 `Unknown`
## 6. 让步顺序
1. 任务 4P3)。
2. 任务 2 的「AD 缺失只写 MD」可先只做 `Unknown` 不拼。
3. **不可砍**:任务 1、任务 2 主体、任务 3、任务 5。
## 7. 开工前置命令
```bash
git -C /workspace/Jyotisha status -sb | head -1
git fetch origin --prune
git worktree add -b codex/upstream-sync2-fix-20260909 .worktrees/upstream-sync2-fix-20260909 origin/staging
cd .worktrees/upstream-sync2-fix-20260909
.venv/bin/python -m pytest tests/test_relationship_event_class_evidence.py tests/test_report_chart_block.py tests/test_consultation_workflow_domains.py -q # 基线
.venv/bin/python scripts/jyotish_api_server.py --port 5299 & # 复现 §1 的 curl
```
## 8. BUG 编号起点
`docs/BUG_HISTORY.md` 当前最大 `BUG-608`;本单 **BUG-609 / 610 / 611**,开工时重新核对。