Compare commits

...
3 changed files with 178 additions and 4 deletions
+2 -1
View File
@@ -523,11 +523,12 @@
| `TASK-report-english-han-leak-20261021.md` | `PROGRESS-report-english-han-leak-20261021.md` | #89 个人报告英文版约 4 成整份丢弃:漏译汉字源头补英文孪生字段、修吃空格;200 张固定种子回归 + 快速门 smoke(复发自 BUG-1272);中文逐字节不变 | 已合入 staging | `codex/report-english-han-leak-20261021` |
| `TASK-chart-dasha-yogini-20261021.md` | — | #88 星盘页大运右栏切换 Chara / Yogini,Yogini 补小运(按比例,内部核对,页面注明未经外部软件核对);Ashtottari 另立单(起运表与 PyJHora 8/12 宿不一致) | 已合入 staging | `codex/chart-dasha-yogini-20261021` |
| `TASK-full-data-parity-1-20261021.md` | — | #91 完整数据版补齐(一):A 段渲染(中文附录改中文源、71 小节归 6 章、导出星座名)→ B 段引擎(Yogi 点、标准大运子运、Kalachakra 简化子运、年运三年全展开、36 个月星历、解释补长);不设大小上限 | A 段第 1 次打回,修复单见下行 | `codex/full-data-parity-1-20261021` |
| `TASK-full-data-parity-2-20261021.md` | — | #92 完整数据版补齐(二):研究型推运附录(Tithi Ashtottari、Yoga / Nakshatra Pravesha、Karana 等,口径换成我方真恒星)、四种星座大运第三层、Kalachakra 第三层(简化模型)、Niryaana Shoola 子运只在有书面出处时做、D81 / D108 / D144 研究型分盘;全部标研究口径,不进对话卡与校正;不设大小上限 | 排队(等 #91 合入) | `codex/full-data-parity-2-20261021` |
| `TASK-goel-jaimini-strength-20261022.md` | `PROGRESS-goel-jaimini-strength-20261022.md` | #94 搬上游公开的 Goel Jaimini 强度与 Brahma / Maheshwara / Rudra(4 个上游原样文件,按 #81 决策 A 先例根目录预算 448→452;来源串改书目引用);只做计算、不改报告;冻结身份不变 | 已合入 staging | `codex/goel-jaimini-strength-20261022` |
| `TASK-chart-subject-table-fix-20261022.md` | `PROGRESS-chart-subject-table-fix-20261022.md` | **#86 第 1 次打回**:报告所有表被强制单行(打印跑出纸面);保存他人复制了档案页代码且已分叉;点编辑框内边距会丢修改 | 已合入 staging | `codex/chart-subject-table-20261021` |
| `TASK-full-data-parity-3-20261022.md` | — | #93 完整数据版补齐(三):「独立年度方法参考」正式环境调 PyJHora(子进程隔离;装上后其余输出逐字节不变,7 个换路径开关钉死);输入默认用本地时间与正确年份(D6 待产品确认) | 待领取(等 #91 合入) | `codex/full-data-parity-3-20261022` |
| `TASK-synastry-staging-fix-fix-20261022.md` | `PROGRESS-synastry-staging-fix-fix-20261022.md` | **#85 第 1 次打回**(T7~T11 主体通过):新地址没登记进路由清单致快速门红;CHANGELOG 与 T11 矛盾;侧栏点亮测试是空断言 | 已合入 staging | `codex/synastry-staging-fix-20261021` |
| `TASK-report-english-han-leak-fix-20261022.md` | `PROGRESS-report-english-han-leak-fix-20261022.md` | **#89 第 1 次打回**:改了冻结的校正打分文件 `jaimini.py`;测试的 PyJHora 屏蔽没传到子进程(测的不是生产那份报告,也是慢的原因);缺英文时留空藏住漏洞 | 已合入 staging | `codex/report-english-han-leak-20261021` |
| `TASK-full-data-parity-1-fix-20261022.md` | `PROGRESS-full-data-parity-1-fix-20261022.md` | **#91 A 段第 1 次打回**:新六章 69 节里 16 节在三张虚构盘上整节「未判定」,其中 12 节数据在资料包里、是读错了字段;测试抓不到整节未判定;新六章绕过了报告口径替换;中文附录悄悄丢列和瑜伽条目要量出来 | 本地完成,待验收 | `codex/full-data-parity-1-20261021` |
| `TASK-full-data-parity-1-b-fix-20261023.md` | `PROGRESS-full-data-parity-1-b-20261023.md` | **#91 B 段打回(本单累计第 3 次,交产品定执行方)**:T9 解释补长不在让步清单却没做(行星一章 4,574 字符,目标约 8,970);D8 后两年缺整宫、Tajika、Tripataki、Saham 轨迹、年主依据 | 需拍板 | `codex/full-data-parity-1-20261021` |
| `TASK-full-data-parity-1-b-fix-20261023.md` | `PROGRESS-full-data-parity-1-b-20261023.md` | **#91 B 段打回(第 3 次,产品 10-23 选 A 交回 Grok,并新增 K3 72 年返照表)**:T9 解释补长不在让步清单却没做(行星一章 4,574 字符,目标约 8,970);D8 后两年缺整宫、Tajika、Tripataki、Saham 轨迹、年主依据 | 待执行 | `codex/full-data-parity-1-20261021` |
| — | `PROGRESS-full-data-parity-1-fix2-20261022.md` | **#91 A 段第 2 次打回**(Claude 口头修复单 F1~F4):11 节只印「未判定」和键名改读真实记录;测试只认非第一列真实值、禁止键名格;中文瑜伽组合句由中文源给出(BUG-1418);六章降为 `##`、节 `###`(BUG-1419) | 本地完成,待验收 | `codex/full-data-parity-1-fix2-20261022` |
@@ -2,14 +2,14 @@
- 被验提交:`d74760b10`(分支 `codex/full-data-parity-1-20261021`,B 段 T4~T10)
- 原任务书:`TASK-full-data-parity-1-20261021.md`
- 执行方:待产品定(见 issue #91 的 escalate 评论)。同一分支继续,开工前 `git merge origin/staging`(不 rebase)。
- 执行方:Grok(产品 10-23 选 A,放开第 3 次打回的熔断;见 issue #91 scope-final 评论)。同一分支继续,开工前 `git merge origin/staging`(不 rebase)。
- BUG 编号:本分支 Yogi 用的 BUG-1421 已被 #95 占用(staging 当前最大号 1423)。合并时改成当时最大号 +1,CHANGELOG、PROGRESS 同步。
## 验收结论(Claude,Linux,屏蔽 PyJHora,0 号虚构盘先英文后中文)
做对了的:Yogi / Ava Yogi 改为原生计算,不再整盘 `blocked`;标准大运表出了子运,没有规则的体系写明「本体系未提供子运」,Kalachakra 标「简化模型」、主运不换;年运附表六节出现;从报告月起 36 个月 × 9 星,报告口径与 KP 口径各 324 行;新模块都在 `scripts/annual_native/`,根目录文件数不变;没碰冻结打分文件;没有导入 `jhora`;新增的异常处理都记日志带原因;「六维力量合计为未列出」已修。生成:英文 1,263,805 字符、中文 753,562 字符,合计约 24 秒,远低于 180 秒。
**未通过的两项:**
**未通过的项(K1、K2 为验收发现,K3 为产品 10-23 新增,K4 为全量 pytest 发现):**
## K1 · T9 解释补长没做,但它不在让步清单里(必修)
@@ -33,9 +33,28 @@ D8 要求「当年 + 后两年,**每一年都有**」全套。现在 2027、20
验收:0、1、9 号盘中英两版,三年里每一年上面每一项都出现且有数值;加一条结构测试逐年断言。
## K3 · 72 年逐年返照表要补(产品 10-23 新增,必修)
产品 10-23 决定:上游「Lifetime Annual Return Chart Data」要补,上轮把它当让步跳过不算。按 10-21 定稿「大小不设上限、只记录」:
- 用我方年返函数逐年算出生起 72 年(与上游同口径的年数),每年一行:年返时刻、年盘上升、年主、Muntha,以及九星黄经;黄经仍走本系统真恒星计算(红线 1)。
- 中英各一张表,归在「年运附表」章。
- 补完后在 PROGRESS 记:单份生成时长(先英文后中文)、中英字符数与字节数、资料包 JSON 大小。
- 单份生成超过 180 秒(前端等待上限)就停下回报,**不得截断、不得自行缩年数**。
验收:0 号虚构盘中英两版各 72 行;任取一年的太阳黄经与我方排盘函数同刻结果差 ≤ 1e-6°;生成时长写进 PROGRESS。
## K4 · 全量 pytest 多出两条真失败(必修)
Claude 在 Linux 上跑全量 pytest(`-n 3`,屏蔽 PyJHora),与 staging 基线逐条比,多出 5 条;单独重跑后 3 条是本机负载偶发,下面 2 条是真失败:
1. `tests/test_annual_tajika_pack.py::test_builds_annual_tajika_pack_contract`:年运包的键列表变了(第 10 位 `annual_houses` 插在 `mudda_dasha` 之前,末尾多两个键)。新键一律加在原有键之后,不改原有顺序;断言按 AGENTS §7.3 写「原值 / 新值 / 原因」三栏。
2. `tests/test_report_longform_gaps2.py::test_auxiliary_dasha_headings_render_from_native_modules`:`ValueError: yogini antardasha failed for Mangala: 'full_years'`(`KeyError: 'full_years'`)。`dasha_children.enrich_master_family` 写回的 Yogini 行少了下游要用的 `full_years`,阅读页的 Yogini 子运会整段失败。修在 `enrich_master_family`:只加子运字段,不删、不改原有字段;加一条测试:enrich 前后每个体系每行的原有键与值逐项相同。
验收:这两条通过;全量 pytest 与 staging 基线逐条相同。
## 可以接受的偏差(记录在案)
- 72 年生命周期年返不做:在让步清单里。
- 现居地八年总览只在资料包带现居地坐标时出:现居地读取在 `_annual_payload_from_args` 里到不了,打开会改已有年运数值。保持不动,Claude 另行评估。
- 年度北印度图盘面板不新做:阅读页已用算好的黄经印成文字表(「Annual Chart Numeric Data」三年都有)。
- 三年星历不走 `kp_monthly_transits`:那条旧路径是视位置,违反红线 1;改用本系统真恒星黄经是对的。
@@ -0,0 +1,154 @@
# 任务书:完整数据版补齐(二)——研究型推运附录、星座大运第三层与研究型分盘,标注研究口径(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. 开工前置命令
```bash
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 起**。本单以补功能为主,只有发现缺陷才占号。