Files
Jyotisha/docs/tasks/TASK-full-data-parity-2-20261021.md
T

17 KiB
Raw Blame History

任务书:完整数据版补齐(二)——研究型推运附录、星座大运第三层与研究型分盘,标注研究口径(agent 循环 issue #92,2026-10-21)

基线

  • 写作基线:初稿 bd3ce0e7b(10-21),定稿 origin/staging = d03a8bc86(10-23)。开工时以 #91(TASK-full-data-parity-1-20261021)A、B 两段及其修复单 TASK-full-data-parity-1-b-fix-20261023 都合入后的 origin/staging 为准;#91 未合入不得开工。 两单改同一批渲染文件(scripts/pl9_full_data_export.py、scripts/report_render/、scripts/rashi_dasha_report.py)。#91 B 段已建好 scripts/annual_native/ 子包(含 tithi_pravesh.py、dasha_children.py、report_ephemeris.py)与 report_render/parity_chapters.py 的中英字段标签表,本单接着用,不另起一套。
  • 分支:codex/full-data-parity-2-20261021;工作树:.worktrees/full-data-parity-2-20261021。执行方 Grok(Windows + Docker),只推这个分支。
  • 上游参照(只读,放仓库外):https://github.com/732642856/yinduzhanxing.git main(258e08e3)的计算模块;交付版分支 codex/customer-export-frozen-20261016(1d549fe9)的 customer-export/registry/delivery_timing_supplement.py 与 delivery_evidence_appendix.py::auxiliary_dasha_markdown。不得复制该分支的个案文件(见 #91 任务书「基线」)。
  • 关联:BUG-1275(真恒星口径)、BUG-1393 / 1283(Niryaana Shoola 不编子运)、TASK-rashi-dashas-native-20261008(星座大运出处表)、TASK-report-full-data-fix-20261008 红线 4(customer_timing_supplement 不搬)。

1. 现状实证(Claude,Linux,bd3ce0e7b,屏蔽 PyJHora)

1.1 上游两章的体量

产品 10-21 上传的上游英文交付版(真实个人资料,只统计字符数,不入库):

上游章节 字符 表行 占全文
Additional Native Timing Calculations(补充推运计算数据) 2,424,694 36,752 52%
Auxiliary Dasha Subperiods(辅助大运次小运数据) 713,444 9,402 15%

1.2 「补充推运计算数据」:计算我方全部没有

上游由 scripts/customer_timing_supplement.py::build_customer_timing_supplement(main)产出,交付版的 delivery_timing_supplement.py::timing_supplement_markdown 渲染。资料包键 worksheets.timing_and_predictive_systems.customer_timing_supplement,我方资料包里没有。

方法族 上游计算模块(行数) 我方
Tithi Ashtottari 本命,顺 / 逆两口径 tithi_ashtottari.py(296) 无
Tithi Ashtottari 年度,三年内每对 300~400 天回归 × 顺逆 × 角度 / 时间余额 同上 + annual_pravesha.py(540) 无
Yoga Vimshottari 本命 yoga_annual_dasha.py(176) 无
Saptavarga 宫主关系(Sripati 输入) aayu_sripati_periods.py(834) 无
Buddhi Gati buddhi_gati.py(185) 无
Kaala kaala_dasha.py(172) 无
Sudasa(另有一条「已确认起点」固定为 blocked) sudasa.py(585) 无
Varnada JSS(两个备选起点分开) varnada_dasha.py(349) 无
Yoga / Nakshatra Pravesha:参考年内全部回归 + 每个回归的后继分支 + 360 Tithi 年 annual_pravesha.py、pravesha_return_year.py(417) 无
Karana 年度三种(Julene Louis 主星表 / PVR 角宫主星 / PVR 360 Tithi 年) karana_annual_dasha.py(535)、tithi_pravesh.py(236,#91 会先搬) 无
当前周期定位 以上结果查询 无

连带依赖:conditional_dashas.py(193)、nakshatra_annual_dasha.py(96)、satabdika_annual.py(90)、transit_search.py(210)、pravesha_year_basis_diagnostic.py(91)。原生部分合计约 5,000 行。依赖链里的 pyjhora_canonical_adapter.py(356)、specialized_dasha_external_replay.py(1,545)是 PyJHora 对照,不搬。「三年逐月星历」在 #91 已做。

口径问题:这些模块取经度用 FLG_MOSEPH(Moshier 星历,不是我方的 Swiss Ephemeris 星历文件),参数 longitude_profile='apparent',可选 'true_position'(FLG_TRUEPOS,几何位置);customer_timing_supplement 全部传 'apparent';Karana 一路还写死 position_mode='apparent'。三者都不是我方 BUG-1275 之后的口径(Swiss Ephemeris + 真岁差,等价 FLG_SIDEREAL)。

1.3 「辅助大运次小运数据」:我方只到第二层

体系 我方现状(scripts/rashi_dashas_native.py::calculate_rashi_dashas,虚构盘实测) 上游
Sthira 主运 12 / 子运 144 / 次小运 0 次小运 1,728
Drig 12 / 144 / 0 同上
Shoola 12 / 144 / 0 同上
Navamsha 12 / 144 / 0 同上,带次小运规则说明
Niryaana Shoola 只出主运(pvr_niryaana_shoola_v1);三层平手时本轮不上表(这张虚构盘即如此) 子运 + 次小运

星座大运在渲染时才算(rashi_dasha_report.py::render_rashi_dasha_chapter),不在资料包 worksheets 里;对话卡读的 read_full_data_domain 只拿 worksheets,所以现在不会进对话卡。

1.4 研究型分盘(10-21 产品从 #91 移入)

上游交付版「Alternative Divisional Calculation Profiles」(3,569 字符)与「Research High-Division Raw Data」(941 字符,D81 / D108 / D144 等)由 delivery_research_vargas.py::research_varga_markdown 渲染。上游函数直接跑在我方数据上能出 4,643 字符(英文),数据来自我方 varga_research_high、varga_extended、varga_full,只缺渲染。我方现有报告结构化附录里已有少量 D81 / D108 / D144 行(英文 3 处),本单统一到研究口径章节下。

1.5 体量估算与现有上限

项 数
#91 B 段实测(0 号虚构盘,Linux,屏蔽 PyJHora) 英文 1,263,805 字符、中文 753,562 字符;资料包 JSON 14.1 MB;先英文后中文合计约 24 s。#91 修复单还会加解释补长、后两年全套与 72 年返照表,开工时以合入后的实测为准
本单再加约 3.1 M 字符 / 每种语言
预计每种语言 英文约 4.5 M 字符以上,中文按比例;生成时长必须先按 T1 实测外推
快照(中文 + 英文 + 事实表,存一行) 约 10~15 MB

代码里的上限(全部按符号定位):

上限 位置 数值
前端等引擎出稿 frontend/src/lib/personal-report-longform-generate.ts ENGINE_TIMEOUT_MS 180 s(中英两份一起算)
快照存储 personal_report_sections.payload(jsonb,迁移 20260830020000_personal_report_sections.sql) 应用层无上限;PostgreSQL 单值约 255 MB
阅读页 personal-report-markdown-view.tsx FULL_DATA_CHAPTER_PAGE_CHARS 全文超 20 万字符按二级标题一章一页;单章没有上限,240 万字符的一章会整页渲染;打印时全部章节一起渲染
每次打开报告 app/api/reports/[reportId]/route.ts → readLongformSnapshot 读整行快照(中英两份 + 事实表),看中文也会把英文一起读出来
请求体 jyotish_api_server.py MAX_REQUEST_BYTES 2 MiB,只限请求,不限响应
REPORT_DOCUMENT_MAX_BYTES 1.5 MiB personal-report-contract.ts 只管封面文档,不含 Markdown,不受影响

2. 根因

上游交付版的这两章依赖上游的原生推运模块,我方从未移植(Kalachakra 子运已在 #91 B 段以「简化模型」补到第二层);研究型分盘只差渲染;customer_timing_supplement 当时因视位置被红线挡住(TASK-report-full-data-fix-20261008 红线 4),挡住的是口径,不是这些方法本身。

3. 决策记录

# 决定 来源
E1 补上游「补充推运计算数据」(各方法变体)与「辅助大运次小运数据」(四种星座大运第三层,Niryaana Shoola 见 E7,Kalachakra 见 E8) 产品,issue #92;10-21 定稿
E1b D81 / D108 / D144 研究型分盘与「其他分盘口径的计算数据」从 #91 移入本单,同样标研究口径 产品 2026-10-21
E2 三章(补充推运、辅助次小运、研究型分盘)开头写明「研究口径:依赖所选方法,未经外部软件核对」,英文「Research basis: method-dependent; not checked against external software.」;已知与 PyJHora 不一致的体系逐个标出 产品,issue #92
E3 这些数据不进对话卡、不进校正打分 产品,issue #92
E4 位置用我方引擎口径;上游 customer_timing_supplement 用的视位置设置不得照搬。本条改写 TASK-report-full-data-fix-20261008 红线 4「customer_timing_supplement 仍不搬」为:方法可以搬,口径换成我方 产品,issue #92
E5 大小不设上限,只记录字符数 / 字节数 / 生成时长;碰到前端等待(ENGINE_TIMEOUT_MS 180 s)或存储 / 接口硬上限就停下回报,不得截断 产品 2026-10-21
E6 阅读页没有单章上限:240 万字符的一章会整页渲染。渲染时按方法族拆成多个二级标题(不是体量上限,是为了能翻页),拆法写进 PROGRESS Claude(执行细节)
E7 Niryaana Shoola 子运与第三层:只在有书面出处时做(书名 + 页码)。照上游实现核对其出处;找不到就不上这一层,并在报告该体系标题下与 PROGRESS 写明原因,不得自编规则(BUG-1393、#84)。Claude 10-23 先查过:上游 main 的 scripts/niryaana_shoola_dasha.py 只产主运,原文写着「Its child-period rule is not independently specified」;上游交付版里那几行子运来自未公开的冻结引擎,不能当出处。所以除非 T0 找到书面规则,默认结果是不做 产品 10-23(issue #92 scope-final)
E8 Kalachakra 补到第三层,不改现有结果:#91 B 段已出 Kalachakra 主运与子运(标「简化模型」);本单只加第三层边界,同样标「简化模型 / Simplified model」。现有主运、子运对 3 张虚构盘逐项不变;第三层与上游规则对不上就停下回报,不自行调整 产品 10-23(issue #92 scope-final)

4. 硬红线

  1. 口径:新模块取经度一律经我方排盘函数(Swiss Ephemeris + 真岁差,与 tests/test_sidereal_nutation_frame.py 同框架)。删去 FLG_MOSEPH、FLG_TRUEPOS、'apparent' 参数与交点偏移;回归点求根也用我方函数。新增测试:每个方法族在出生时刻用到的日、月经度与 core_chart.planets.*.degree_raw 差 ≤ 1e-6°;任取一个 Tithi 回归时刻,日月角距与目标 Tithi 角差 ≤ 1e-6°。
  2. 隔离(E3):本单产出不写进资料包 worksheets,放在单独的键(例如 packet["research_timing"])或像星座大运一样在渲染时计算。测试:(a) read_full_data_domain 对 3 张虚构盘的输出不含本单任何键,对话卡逐字节不变;(b) 用语法树断言 scripts/rectification*、scripts/birth_time*、校正打分入口不导入本单新模块;(c) 校正打分 golden 不变。
  3. PyJHora:运行时不得导入 jhora。「与 PyJHora 不一致」的标注来自离线对照:脚本放 scripts/research/,只在执行方本机跑,结果存成 JSON 提交,pytest 不导入 jhora(BUG-1275 的做法)。
  4. 增长冻结:不改 scripts/jyotish_api_server.py;scripts/*.py 根目录 452 个已到 ROOT_PY_BUDGET = 452,新模块进子包(例如 scripts/research_timing/,或并入 #91 的 scripts/annual_native/),不得调高预算;SILENT_EXCEPT_BUDGET 不增加,每个方法族失败要记日志并给出具体原因,不得把导入失败包成 blocked 了事。
  5. 引擎输出变化:验收必须全量 pytest 与开工基线逐条比对;四种星座大运的主运与子运、#91 已出的 Kalachakra 主运与子运对 3 张虚构盘逐行不变。
  6. 不编周期:上游注明「不提供次小运」「不推造小运」的方法照样不提供;blocked 的分支(如 Sudasa 已确认起点)只写原因,不上空表。
  7. 不截断(E5):不设大小上限;只有中英合计生成超过 180 s 前端等待,或存储 / 接口报错(写入失败、请求或响应被拒),才停止接线、推分支、在 PROGRESS 写清实测数和卡在哪一步,等产品决定;不得删行、抽样或降精度来压体量。
  8. 中英文各自从源字段生成,英文汉字 0(#89 的 200 盘测试照跑);中文卫生门(#91 新加的两条)照跑。
  9. 不动数据库结构;不改 .gitea/;不推 main;只用虚构盘与公开名人盘。

5. 任务分解

# 内容 验收标准
T0 盘点:逐个方法族列出上游函数、输入、出处、口径参数,以及要改成我方函数的地方;Niryaana Shoola 子运出处(E7);四种星座大运次小运规则的出处(接 TASK-rashi-dashas-native-20261008 T0 的规则表) PROGRESS 一张表,每格有出处或 blocked
T1 先量再接:搬两个最重的方法族(Tithi Ashtottari 年度、Yoga / Nakshatra Pravesha 后继分支),先只算不渲染,对 3 张虚构盘量耗时和输出行数,按上游行数比例外推整章大小与时长;外推超过 180 s 就停(红线 7) PROGRESS 有实测与外推;未碰硬上限才继续
T2 其余方法族搬进子包,改口径(红线 1),每族一个测试:固定虚构盘的周期边界 golden 来自我方引擎实跑,不手造 各族测试通过;红线 1 两条口径测试通过
T3 渲染「补充推运计算数据」:章首 E2 文字;按方法族分二级标题(E6);当前周期定位表;中英双语字段标签 3 张虚构盘中英文出现;英文汉字 0
T4 「辅助大运次小运数据」:Sthira / Drig / Shoola / Navamsha 次小运(按 T0 出处);Niryaana Shoola 按 E7;Kalachakra 第三层按 E8;章首 E2 文字,每个体系写所用规则 主运、子运逐行不变(含 Kalachakra);各体系次小运条数写进 PROGRESS;Niryaana 若不做,标题下有原因句
T4b 研究型分盘(E1b):渲染「其他分盘口径的计算数据」与 D81 / D108 / D144 原始数据,中英双语,章首 E2 文字;现有结构化附录里的零散 D81 / D108 / D144 行并入该章,不重复 3 张虚构盘中英文出现;全文 D81 / D108 / D144 只在研究口径章节出现
T5 PyJHora 离线对照(红线 3):10 张以上虚构盘,逐体系逐层比对,不一致的在报告该体系标题下标「与 PyJHora 不一致:差在起点 / 方向 / 年数 / 子运划分」 对照 JSON 与汇总表进 PROGRESS;报告标注与 JSON 一致
T6 隔离测试(红线 2 的 a、b、c) 全部通过
T7 量测与文档:Linux(Claude 复测)与 Windows 生成时长;中英 Markdown 字符与字节;快照 JSON 大小;打开报告接口的响应大小与耗时;阅读页章数与最大一章。BUG_HISTORY(若有缺陷)、CHANGELOG、PROGRESS、docs/testing/full-data-parity-2-20261021.md(真机:生成、翻到两章、中英切换、打印预览、导出) 实测数齐全;未碰硬上限,或已按红线 7 停下

6. 验收分工

检查 Grok 自跑 Claude 验收
改到的与新增的 Python 测试文件,含 test_sidereal_nutation_frame、test_rashi_dashas_native、test_full_data_domain_reader、test_report_english_edition、test_python_hygiene_budget、test_api_server_growth_contract、test_runtime_jhora_import_scan 必跑(工作树 .venv),屏蔽 PyJHora 再跑一次 复验
前端 tsc、lint、改到的测试文件 动了前端才跑 复验
Python 快速门 不跑 以 Claude 为准
Python 全量 pytest 与基线逐条比对 不跑 以 Claude 为准
前端全量 npm test、npm run build 不跑 以 Claude 为准
生成时长与体量(Linux,屏蔽 PyJHora) Windows 数照报 以 Claude 的 Linux 数判是否碰 180 s

7. 让步顺序

不让步:红线 1、2、7,E2 章首说明,英文汉字 0。时间不够时依次让出:T5 的覆盖盘数(不少于 5 张)→ Karana 三种中的 PVR 360 Tithi 年 → Tithi Ashtottari 年度的「时间余额」分支。让出的写进 PROGRESS。

8. 开工前置命令

git fetch origin --prune
git log origin/staging --oneline | grep -i "full-data-parity-1" | head   # 确认 #91 两段都已合入
git worktree add -b codex/full-data-parity-2-20261021 .worktrees/full-data-parity-2-20261021 origin/staging
cd .worktrees/full-data-parity-2-20261021
git -C ../yinduzhanxing-ref fetch origin main codex/customer-export-frozen-20261016
git -C ../yinduzhanxing-ref show 258e08e3:scripts/customer_timing_supplement.py | head -60
grep -n "FLG_MOSEPH\|FLG_TRUEPOS\|apparent" ../yinduzhanxing-ref/scripts/{annual_pravesha,pravesha_return_year,karana_annual_dasha,tithi_ashtottari}.py
ls scripts/*.py | wc -l     # 452 = ROOT_PY_BUDGET,新文件不得放根目录
grep -oE "^## BUG-[0-9]+" docs/BUG_HISTORY.md | sort -u | sort -t- -k2 -n | tail -1

9. BUG 编号

定稿时 staging 最大号 BUG-1423,#91 修复单合入时还会占号,开工时核对最大号 + 1 起。本单以补功能为主,只有发现缺陷才占号。