Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017eEAG8HD3mm8gsKXgk8uU8
5.1 KiB
TASK · 恒星黄道经度少扣章动:所有行星偏约 0.005°,大运日期差 2–3 天(2026-10-08)
- 基线:
origin/staging(写作时16782634,已部署795b8845)。 - 分支 / worktree:
codex/ephemeris-nutation-20261008/.worktrees/ephemeris-nutation-20261008 - 串行:与
TASK-report-full-data-fix2-20261008可以并行开工;谁后合入 staging,谁 rebase 后重跑 Python 全量与报告定向测试。两单都会让报告 golden 变化。 - BUG 编号:本单是 BUG-1275(已在
docs/BUG_HISTORY.md记为 investigating)。
1. 事故实证
Claude 2026-10-08 验收报告时,用乔布斯公开盘(1955-02-24 19:15 PST,Lahiri,平均交点)对比:
| 来源 | 月亮恒星黄道经度 | 土星余额后第一个大运(水星)起点 |
|---|---|---|
| 我方引擎(报告「本命盘行星原始位置」) | 344.52°(内部 344.51652) | 1958-03-19 |
上游 23be1807 同盘导出 |
344.51° | 1958-03-22 |
Swiss Ephemeris FLG_SIDEREAL(标准做法,本机直接算) |
344.51148 | — |
差值 0.00504°,正好等于这一时刻的黄经章动 Δψ(swe.calc_ut(jd, swe.ECL_NUT) 第 3 项 = 0.0050426°)。
2. 根因
scripts/jyotish_engine.py 的 _calc_sidereal_planets_for_jd 以及 _sidereal_calculation_profile 的 legacy 档:行星用默认标志算含章动的热带视位置,再减 swe.get_ayanamsa(jd),而后者是不含章动的平岁差。两边口径不一致,所有行星统一多出 Δψ(|Δψ| 最大约 17.2″ ≈ 0.0048°,随年份在正负之间变化)。
影响:
- 所有行星、交点的恒星黄道经度同方向偏移 Δψ;落在星座 / 星宿 / 分盘边界附近的星会换格。
- Vimshottari 等以月亮度数起算的大运:0.005° ÷ 13.333° × 大运年数 ≈ 2–3 天。
- 上升点若用另一条路径计算(例如带
FLG_SIDEREAL的宫位),行星与上升之间会有 Δψ 的相对误差,需在 T0 核实。 - 我方 2026-10-07 记录过「虚构盘大运与独立计算差约 2 天」,当时被误判为岁差版本差异;其实也是本条(见
docs/tasks/PROGRESS-upstream-sync6-20261007.md的 Claude 验收段,本单关闭时补一句更正)。
同一写法的其他调用点(T0 逐一核实是否同样不一致):jyotish_engine.py 中 get_ayanamsa( / get_ayanamsa_ut( 共约 10 处(约第 828、841、12350、13006、13371、13583、13620、13714、13805 行附近,按符号定位);bhava_chalit.py、domain_calculation_service.py、daily_guidance_service.py、shadbala.py、western_chart_engine.py(西洋盘用热带黄道,可能不受影响,要核实)。
3. 决策记录(产品 2026-10-08)
- 单独开一单尽快修。
- 按标准恒星黄道算法改:行星与岁差使用同一口径(
FLG_SIDEREAL,或get_ayanamsa_ex_ut取与行星同标志的岁差)。PyJHora 只作对照答案,不进运行时。 - 修正后所有日期都会微移;生时校正按版本规则升级并重跑评测。
4. 硬红线
- 修正后,三张公开盘(乔布斯、奥巴马、爱因斯坦)与虚构盘的九星恒星黄道经度,与 Swiss Ephemeris
FLG_SIDEREAL的差 ≤ 1e-6°;Lahiri、Raman、KP 三种岁差都测。PyJHora 4.8.7 的对照答案离线冻结成 fixture,差值写进进度记录。 position_mode的mean/apparent两档语义不变;legacy档如果就是这条错误本身,改正并在进度记录写明;不得新增第四档绕开。- 生时校正:同一输入分数会变 → 升
rectification-v5-matrix-scoring-12;记忆化 golden 出新版本、旧版冻结;研究记录按 ERR-110 重新冻结;历史校正记录仍能只读打开(BUG-621);v5 77 例评测逐格报告,任一格下降超过 1 个百分点就停下报产品。 - 引擎数值一变就跑 Python 全量,失败名单 ⊆ 基线(Linux 62 条)。golden 一律用真实引擎重生成;改断言写三栏。
- 运行时不得导入
jhora(快速门的导入扫描);验收在无 PyJHora 环境跑。 - 不改 workflow、不提升 main、不动迁移(除非版本字面量需要,届时按 sync5 先例只改守卫一行并真跑
test:db)。
5. 任务分解
| # | 内容 | 验收标准 |
|---|---|---|
| T0 | 盘点所有「热带位置 − 岁差」的调用点,逐个标「一致 / 不一致 / 不适用(热带西洋)」;核实上升点与宫头走哪条路径 | 进度记录里有调用点表 |
| T1 | 修正不一致的调用点 | 红线 1 |
| T2 | 下游:报告、对话卡、日运、Bhava Chalit、Shadbala 的 golden 重生成 | 每份 golden 变化列表(哪些星换了星座 / 星宿 / 分盘) |
| T3 | 生时校正 | 红线 3 |
| T4 | 记录 | BUG-1275 改为 resolved(附验证);CHANGELOG.md(用户可感知:大运日期可能前后移动 2–3 天);进度记录;状态板 |
6. 验收口径
ruff、py_compile、快速门、Python 全量失败名单 ⊆ 基线、npm test 失败名单与基线相同、next build / Static。部署后核对 /api/health 的 deployment.gitCommit、/login 200、未登录 /api/account 401。