docs(tasks): sync2 + chart-render acceptance — fix brief for web-path dasha_info (BUG-609)
This commit is contained in:
@@ -0,0 +1,109 @@
|
||||
# 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/AD(P1)
|
||||
|
||||
- `_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 AD:Jupiter 为该盘 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. 任务 4(P3)。
|
||||
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**,开工时重新核对。
|
||||
Reference in New Issue
Block a user