合并推进后的 origin/staging,带上 #85、#88、#94。

开工时 staging 是 9a0d5e11。合并期间远端又快进到 0034333b。不带上这三次合入,后面无法快进推送。

Co-Authored-By: Grok (agent loop)
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
jesse-ux
2026-10-22 09:59:47 +08:00
co-authored by Grok (agent loop) Cursor
63 changed files with 5111 additions and 131 deletions
+80
View File
@@ -37016,6 +37016,86 @@
- 复发自:无。
- 修复版本:分支 `codex/synastry-staging-fix-20261021`。
## BUG-1404 | 合盘报告两侧空白滚不动
- 状态:resolved(待 staging 真机复测)
- 首次发现:2026-10-21(产品负责人真机)
- 最近更新:2026-10-21
- 影响面:合盘报告阅读页
- 用户现象:鼠标停在报告两侧空白处滚动时,报告不动。停在中间正文上可以滚。
- 触发条件:桌面宽度下打开一份已写好的合盘报告,指针放在 720px 正文栏以外的空白处滚动。
- 根因:`.synastry-report` 自己是滚动口,宽度又是 `min(720px, 100%)`。两侧空白属于外层 `.chat-panel`(`overflow: clip`),滚轮到不了中间这一栏。个人报告是整宽的 `.personal-report-reader` 在滚,内文再居中。
- 修复:新增整宽的 `.synastry-report-scroll`,高度 100%、纵向滚动,和 `.personal-report-reader` 同一做法。`.synastry-report` 只保留居中和排版,不再带 `height: 100%` 和 `overflow`。打印时外层改为 `height: auto`、`overflow: visible`,长报告不会被裁成一页。
- 验证:`frontend/tests/synastry-full-report.test.ts` 锁定外层整宽滚动、内栏没有 `height: 100%` / `overflow: auto`、阅读页用这个外层包住报告,以及打印解锁。
- 防复发:上述样式与源码断言。不要把滚动再放回宽度受限的 `.synastry-report`。
- 相关记录:issue #85。
- 复发自:无。
- 修复版本:分支 `codex/synastry-staging-fix-20261021`。
## BUG-1405 | 合盘报告打开后侧栏变成「我的报告」
- 状态:resolved(待 staging 真机复测)
- 首次发现:2026-10-21(产品负责人真机)
- 最近更新:2026-10-21
- 影响面:婚恋合盘报告的地址、报告中心卡片、选人页的「开始合盘」和「之前的合盘」
- 用户现象:点「开始合盘」之后,侧栏当前项从「婚恋合盘」变成「我的报告」。浏览器标题也是「个人报告」。
- 触发条件:从选人页进入一份合盘,或从报告中心打开合盘卡片。地址是 `/reports/报告`。
- 根因:合盘和个盘共用个人报告阅读页。侧栏按地址前缀点亮,「我的报告」是 `/reports`。任务书原先只要求跳进阅读页,没有给合盘单独的地址。
- 修复:新增 `/synastry/报告`,仍用原来的阅读页,文档标题是「婚恋合盘 · Jyotisha」,`?lang=` 保留。选人页的「开始合盘」和「之前的合盘」、报告中心的合盘卡片改走这个地址。旧的 `/reports/报告` 打开合盘时换成新地址,不另留一条历史。新地址若打开的是个人报告,换回 `/reports/报告`。左上角「‹ 婚恋合盘」不变。打印样式只在打印时收起侧栏。侧栏本来就用地址前缀点亮 `/synastry`,所以新地址仍是「婚恋合盘」。
- 验证:`frontend/tests/synastry-report-surface.test.ts`。旧地址带 `lang=en` 换成 `/synastry/报告?lang=en`;个人报告留在 `/reports`;新页面标题和 `surface="synastry"`;选人页和报告中心的链接;侧栏对 `/synastry/` 前缀点亮。失败态带上报告类型,个人报告的失败断言从「没有 reportType」改为带上 `personal_full`。
- 防复发:上述测试。不要把合盘再链回 `/reports/报告`。
- 相关记录:issue #85。BUG-1404。
- 复发自:无。
- 修复版本:分支 `codex/synastry-staging-fix-20261021`。
## BUG-1406 | 合盘正文开头重复节标题
- 状态:resolved(待 staging 真机复测)
- 首次发现:2026-10-21(产品负责人真机)
- 最近更新:2026-10-21
- 影响面:合盘报告各节正文,中文和英文
- 用户现象:节标题下面,正文又用同一句话开头,标题等于出现了两次。
- 触发条件:模型把这一节的标题写进正文开头。保存和质检都没有拦住。
- 根因:每一节单独生成,提示里有节名,但保存前不剥离开头的标题,质检也不把这件事当成失败。
- 修复:正文以该节标题开头(可重复一次,后面是空白)时,质检记 `repeated_heading` 并只重写这一节。重写提示写明不要以节标题开头。通过之后,保存前再剥掉开头重复的标题。中文和英文同一条规则。标题后面紧接着别的字、不是空白也不是再来一遍标题时,不剥,避免误伤。
- 验证:`frontend/tests/synastry-full-report.test.ts`:正文以「沟通与理解」开头时先重写,保存结果不再以这个标题开头;英文标题同样剥掉;「沟通与理解力」不剥。`tests/test_synastry_full_reader_gate.py`:同一中文样例和英文「Communication and Understanding」被质检判为失败。
- 防复发:上述两条。不要只在页面上藏起来,生成和质检都要认。
- 相关记录:issue #85。
- 复发自:无。
- 修复版本:分支 `codex/synastry-staging-fix-20261021`。
## BUG-1407 | 合盘两人顺序和选人页相反
- 状态:resolved(待 staging 真机复测)
- 首次发现:2026-10-21(产品负责人真机)
- 最近更新:2026-10-21
- 影响面:合盘等待页、报告标题、报告中心卡片、追问对话标题
- 用户现象:选人页先选甲、再选乙。等待页是甲 × 乙。写完之后,报告标题、报告中心卡片和追问对话标题变成乙 × 甲。
- 触发条件:先选的那个人,编号排在后选的那个人后面。已经写好的报告保留当时的顺序。再生成一份时按这次的选人顺序(BUG-1408)。
- 根因:去重用的一对编号按编号从小到大存放。生成时把较小的编号当成甲、较大的编号当成乙。等待页读的是选人页当场记下的顺序,所以只有等待页是对的。
- 修复:创建时另存选人顺序(先选的人、后选的人)。生成按这个顺序加载两个人,报告标题、卡片摘要和追问标题都用这个顺序。去重用的编号排序不变。没有这份顺序的旧报告仍按原来的编号顺序。等待页本来就是选人顺序,没有改。
- 验证:`frontend/tests/synastry-display-order.test.ts`:先选的人编号更大时,标题和追问标题仍是甲 × 乙;等待页句子是甲在前。`frontend/tests/database-synastry-full-create.test.ts`:请求先是本人、后是另一人时,存下的顺序是本人在前,而去重编号仍是另一人在前。
- 防复发:上述两条。生成不要再把较小的编号直接当成甲。
- 相关记录:issue #85。
- 复发自:无。
- 修复版本:分支 `codex/synastry-staging-fix-20261021`。
## BUG-1408 | 同一对人不能再生成一份合盘
- 状态:resolved(待 staging 真机复测)
- 首次发现:2026-10-21(产品负责人)
- 最近更新:2026-10-21
- 影响面:婚恋合盘的「开始合盘」、点数、之前的合盘
- 用户现象:同一对人已经有一份写好的合盘,再点「开始合盘」会打开上一份,不能新写。
- 触发条件:两人、出生资料和规则版本都没变,上一份状态是 ready。
- 根因:创建时把 ready 和 generating 都当成可复用,并且数据库不允许同一对有第二份 ready。这是 #82 决策 E3。产品在 K6 推翻了复用这一部分。
- 修复:只有 generating 才打开原来那份、不扣点。ready 时新建一份并再扣 `synastry.full`,旧报告保留。去掉只允许一份 ready 的索引。引擎结果仍落在原来的 `synastry_reports` 一行上,报告正文按新的一份重写。选人页在点数说明下写出已经合过几次、再生成会另扣多少点;正在生成时不写这句。
- 验证:`frontend/tests/database-synastry-full-create.test.ts`:generating 时第二次仍是原 id、点数不变;写成 ready 后再建得到新 id、点数再减。`frontend/tests/database-synastry-full-report.test.ts`:同一对可以留下两份 ready。`frontend/tests/synastry-full-report.test.ts`:已有两份且不在生成中时,渲染出「这两人已经合过 2 次,再生成会另扣 19 点」。
- 防复发:上述三条。不要把 ready 再当成复用,也不要把那条唯一索引加回来。
- 相关记录:issue #85。推翻 #82 决策 E3 的复用部分。BUG-1407。
- 复发自:无。
- 修复版本:分支 `codex/synastry-staging-fix-20261021`。
## BUG-1409 | 导出弹窗把「没有英文」写成常驻说明,选中态没有主题色
- 状态:resolved(待 staging 真机复测)
@@ -0,0 +1,206 @@
上游 `5fb8379c` 原文;我方 Niryaana 选择器在 `scripts/rashi_dashas_native.py`;书稿未入库
# Goel Jaimini public calculation module
## Scope and entry points
`scripts/goel_jaimini_strength.py` publishes the existing frozen runtime's
position-only arithmetic, with input validation and explicit blocked points.
It contains no customer identity, birth record, report, private fixture, or
runtime dependency on a frozen directory. The historical frozen-engine
publication receipt remains true: its complete payload is not published.
Public functions:
- `calculate_goel_strength(planet_longitudes, node_occupancy_policy=...)`
- `build_goel_chart_evidence(planet_longitudes, ascendant_longitude)`
Both accept already calculated sidereal longitudes in degrees, in `[0, 360)`.
Supply exactly Sun, Moon, Mars, Mercury, Jupiter, Venus, Saturn, Rahu and Ketu;
nodes must be opposite. The builder also requires a finite numeric Ascendant.
No ayanamsa, node mode, birth time or ephemeris is inferred. The caller owns
those upstream settings. Invalid inputs raise `ValueError`; equal seven-karaka
degrees block the calculation instead of inventing a ranking.
The native `jaimini --mode special` / `--mode all` commands and `full-reading`
now expose `goel_full_strength` and `goel_special_points`. The builder's
`strength` and `special_points` keys map to those two report keys. Existing
eight-karaka and other Jaimini profiles remain independent.
## Sources and page numbering
V. P. Goel, *Predicting through Jaimini Astrology*, Chapter 1, printed pp10–17
(PDF file pages14–21). Local source:
`V. P. Goel, Predicting through Jaimini Astrology`.
Transcription SHA256:
`0a8eb5e6de409d5d8ae6684be927b1273acdc5fa72a7f1c36c31de33907341a6`.
Line numbers below refer to that transcription, not printed line numbers.
| Calculation | Printed pages | PDF pages | Transcription locator |
|---|---|---|---|
| Dignity values and natural friendship | 10–11 | 14–15 | L461 onward |
| Seven-karaka rank; Kendriya, Kartari, Adhipati | 11–12 | 15–16 | L510–553 |
| Sign permanent and karaka components | 13 | 17 | L558–593 |
| Sthana, aspect roles, sign-lord strength | 14 | 18 | L598–632 |
| Worked planetary/sign totals | 15 | 19 | L636–697 |
| Brahma and Maheshwara; first Rudra rule | 16 | 20 | L701–727 |
| Rudra malefic-contact exception | 17 | 21 | L731–736 |
| Mercury/Jupiter as sign lord: double role credit | 103 | 107 | L4359–4389 |
The p103 clarification occurs in Goel's **short method** chapter. Only its
explicit double-role explanation is used to clarify the three-role reading
of p14. The short method's different weights are NOT mixed into this full
method. Numeric reproduction of p15 also checks this role convention.
Degree-specific Moolatrikona ranges reuse the existing named
`raman_manual_degree_mt_exaltation_first_v1` profile from
`scripts/trikona_raman.py`: B. V. Raman, *A Manual of Hindu Astrology*,
section29, printed p12. Goel provides the score categories; this auxiliary
profile supplies degree ranges. Exaltation is checked first. This is an
explicit method choice, not a claim that all Goel/Raman conventions coincide.
## Formula contract
Planet total is dignity + karaka + kendriya + kartari + adhipati.
- Dignity: exalted60, Moolatrikona45, own30, friend22.5, neutral15,
enemy7.5, debilitated3.75; natural friendship, not compound friendship.
- Seven classical planets ranked by degree within sign: 60,45,30,22.5,15,7.5,3.75.
Nodes never receive these karaka points.
- Kendra / Panaphara / Apoklima from AK: 60 / 30 / 15.
- Kartari: 60 when the planet is in an odd sign and both adjacent signs have
occupants; nodes count in this component under both occupancy policies.
- Adhipati: 60 for a qualifying odd-sign lord with a malefic conjunction or
Jaimini rasi aspect. All classical planets except Moon own an odd sign.
This implementation declares Sun/Mars/Saturn/Rahu/Ketu malefics and excludes
self-contact; phase-dependent Moon and conditioned Mercury are not added.
Sign total is permanent + occupying karaka points + Sthana + aspect roles
+ sign-lord total. Movable/fixed/dual permanent values are15/30/60.
Sthana is zero if empty, otherwise45+15*n. Jupiter, Mercury and sign lord are
three roles worth60 each; if one planet fulfills two roles it can earn120.
Conjunction and aspect qualify a role once, not twice. Aspects are Jaimini
sign aspects, not Parashari planetary aspects.
Special points:
- Brahma first checks AK's eighth lord occupying AK's eighth. Otherwise it
compares Lagna/seventh Goel totals and selects the strongest non-Saturn
6/8/12 lord from the stronger anchor. The Saturn exclusion belongs to the
fallback branch; it is not silently applied to the first override.
- Maheshwara is AK's eighth lord; if exalted, compare AK's twelfth lord.
Saturn is allowed.
- Rudra compares Lagna's second/eighth lords. The weaker candidate wins when
it alone has malefic contact; when both have contact the stronger wins.
The frozen convention treats conjunction and rasi aspect as contact;
the p17 exception itself says “aspect” and its discussion adds association.
Retain this declared convention when porting rather than hiding it.
- Equal final scores remain `blocked`; no silent degree or list-order tie-break.
## Node discrepancy and default
Printed p14 explicitly includes Rahu and Ketu in Sthana. The p15 worked
totals reproduce when they are excluded from **that component only**.
`include_nodes_text` is the default because it follows the explicit rule.
`exclude_nodes_worked_example` is the reproducibility alternative, retained
under `strength.worked_example_node_exclusion` by the builder.
This switch does NOT remove nodes from Kartari or malefic contacts and does
not give them karaka points. For the published example, excluding nodes gives
Virgo281.25 / Pisces363.75; including them gives296.25 /378.75. The other ten
sign totals and all seven planet totals agree between policies. This is an
observed text/table discrepancy, not proof of the author's intended erratum.
## Relation to 9f08b57b and 258e08e3
These are **different algorithms**:
| Field / producer | Comparison | Method / use |
|---|---|---|
| `lagna_seventh_strength` | First/seventh Goel numeric totals | Goel Brahma/Sthira-related explicit selector evidence |
| Historical `niryaana_shoola_strength` | Same first/seventh totals | Deprecated frozen-export alias only |
| `select_niryaana_shoola_start_sign` | Second/eighth | PVR Ayur ordered comparison: occupancy, all-planet rasi aspects, exalted-occupant presence |
`9f08b57b` implements the last row and `258e08e3` explicitly includes both
nodes in its occupancy/aspect counts. Those changes are already on main.
This publication does not replace them. The legacy alias now carries
`deprecated: true`, `comparison: lagna_vs_seventh`, and `not_for` metadata.
Use the canonical new key for Goel totals; use the existing PVR selector for
Niryaana. Sthira's existing explicit-input short selector is a separate
contract: do not label Goel full weights as the Chapter5 short weights, and
do not infer that publishing these points automatically executes Sthira Dasha.
## Portable synthetic example
```python
from scripts.goel_jaimini_strength import build_goel_chart_evidence
positions = dict(Sun=29., Moon=58., Mars=87., Mercury=116.,
Jupiter=145., Venus=174., Saturn=203., Rahu=245., Ketu=65.)
result = build_goel_chart_evidence(positions, 0.)
```
This is deliberately invented positional data, not a real birth chart.
| Planet | Dignity | Karaka | Kendriya | Kartari | Adhipati | Total |
|---|---:|---:|---:|---:|---:|---:|
| Sun | 60 | 60 | 60 | 0 | 0 | 180 |
| Moon | 60 | 45 | 30 | 0 | 0 | 135 |
| Mars | 7.5 | 30 | 15 | 60 | 60 | 172.5 |
| Mercury | 7.5 | 22.5 | 60 | 0 | 0 | 90 |
| Jupiter | 22.5 | 15 | 30 | 60 | 60 | 187.5 |
| Venus | 3.75 | 7.5 | 15 | 0 | 60 | 86.25 |
| Saturn | 60 | 3.75 | 60 | 0 | 0 | 123.75 |
AK=Sun. Lagna=367.5; seventh=225. Brahma=Jupiter; Maheshwara=Mars;
Rudra=Mars. Gemini Sthana=75 (alternative60); Sagittarius Sthana=60
(alternative0). The existing PVR Niryaana selector instead selects Taurus.
`tests/test_goel_jaimini_strength.py` contains these literal expectations,
the printed p15 totals without birth identity, branch checks, input rejection,
blocked points and native entry wiring. Run:
```bash
python3 -m pytest -q tests/test_goel_jaimini_strength.py tests/test_niryaana_shoola_dasha.py
```
Status: source-bounded wired, with one published numerical table replay and
synthetic arithmetic regression. No predictive-case validation, global
closure, PL9 parity or automatic change to a frozen customer pin is claimed.
Verification:166 tests passed across `test_goel_jaimini_strength`,
`test_niryaana_shoola_dasha`, `test_sthira_brahma_goel_short_method`,
`test_trikona_raman_native`, `test_jaimini`, `test_jaimini_source_identity`
and `test_bphs_validation_runtime`. This includes the real full-reading CLI
and its Goel output, as well as the existing PVR Niryaana behavior.
## Current-window exploration and publication boundary
Started from main258e08e3 in an isolated `codex/goel-publication` worktree;
the original workspace was on customer-export-r32-release with unrelated
dirty files, all preserved. Checked all six existing linked worktree paths,
branch/recent-commit status, tracked file inventory, producer/CLI/report/test
searches and the two whole-machine sweep records. WorkBuddy skill is a
symlink to the primary repository; its registry remains a separate authority.
The configured r32 runtime supplies the reviewed position-only Goel module;
its hash was235fc8f90718b6da45af0ee1edc2a7c195be92664ff55bbb7b8e0398b605b33d.
The archived 10-16 publication receipt confirms the full payload was excluded.
The separately inspected local 10-16 r2 engine has neither this named module
nor the two Goel output fields; therefore the archive date must not be used
as proof of that report's actual generating pin. This extraction is from
the inspected r32 source, not a claim that the omitted r2 payload contained it.
Repository APIs/renderers remain consumers of the native engine, not a second
implementation. No external engine code or book pages are republished here.
Pre-work check passed, including external adapter diagnostics and remote
visibility; direct `git ls-remote origin refs/heads/main` returned258e08e3.
The broader governance audit separately flags `main_worktree_dirty` and
`remote_head_unverified`; the former is real and preserved, and the latter
does not certify publication despite the successful direct visibility check.
Capability authority snapshot and governance audit were invoked;
the former's historical customer examples are not authority for this module.
The reused chains are Goel position arithmetic, Raman dignity helpers,
Jaimini rasi aspects, and the existing PVR Niryaana selector. Unclosed items
are lineage differences, equal-strength selections without a source rule and
independent predictive verification. This is code publication, not a chart
interpretation, personal report export, or MEVG predictive validation.
+6
View File
@@ -484,3 +484,9 @@ Prevention: 打分路径新增或改动输入模块时,先查它在不在两
`TASK-report-chart-blank-columns-20261003` T2 写的是「`_map_to_houses_values` 增字段」,`scripts/ashtakavarga.py` 在 `sealed_holdout_rerun.PRODUCTION_FILES` 里,只加字段、分数不变也让 `test_rectification_validation_integrity_gate` 4 条与 `test_sealed_holdout_contract_freshness` 3 条失败(ERR-110 同型)。改为在 `pl9_reader_export.py` 用引擎已有字段拆分,冻结文件零改动,门禁恢复全绿,无需重新冻结。
Prevention: 写任务书时(不只是执行时)就对照 `PRODUCTION_FILES` 与 dataset `frozen_scoring.files`;只为展示的字段优先在消费层(reader / mapper)从已有数据推出,不进冻结文件。关联 ERR-110、BUG-1200。
## ERR-116 | Goel 首/七强度不是 PVR Niryaana 的二/八,完整法也不是简法 | observed 2026-10-22
Goel《Predicting through Jaimini Astrology》第 1 章完整强度的 `lagna_seventh_strength` 比的是命宫和第七宫的 Goel 总分。弃用别名 `niryaana_shoola_strength` 是同一组首/七数字,带 `deprecated`、`replacement`、`not_for`。我方 Niryaana Shoola(#84)的 `select_niryaana_shoola_start_sign` 在 `scripts/rashi_dashas_native.py`,比的是第二宫和第八宫的 PVR Ayur 口径。两套不能互相接入。`scripts/goel_short_strength.py` 是第 5 章简法,给 Sthira / Niryaana 等用,也不是这一套完整法。
Prevention: 不要把 `lagna_seventh_strength` 或 `niryaana_shoola_strength` 接到 Niryaana 选择或大运计算。不要用 `goel_jaimini_strength` 替换 `goel_short_strength`。报告里印这一章交给 #91。关联 issue #94、#84。
@@ -0,0 +1,38 @@
# 进度:星盘大运右栏加上 Yogini(2026-10-22)
分支 `codex/chart-dasha-yogini-20261021`。起点 `28dd8df333370dd7f6c2ed56656f9e83f978382f`(已含 #86、#87)。没有 push。
## 提交
| 步 | SHA | 说明 |
| --- | --- | --- |
| T1 | `6eeb98c7745f134d0609e0cacd1bb27bbc9c7502` | 小运按比例单列,大运函数输出不变 |
| T2 | `3490e89403f3fcfe99a1d91260e8b4320cb0193e` | 只在接口返回的副本上挂小运 |
| T3 | `85567071c74f6460ec917aebc1011f429b346269` | 三张公开名人盘对照 PyJHora,小运做内部核对 |
| T4 | `7a296c7348abb73295b186ac0ed80ee376f15a01` | 按需取 Yogini,缓存按体系分开 |
| T5 | `5ebbd57b041b65c8a6e28ba8be168d57c57b8497` | 按轨道合并,刷新保留已到的轨 |
| T6 | `7b1070f86d1911f7b693724ce580c944dd751e61` | 右栏 Chara / Yogini 切换 |
| T7 | 本文件所在提交 | 切换条样式、DESIGN、VOICE、CHANGELOG、真人清单 |
## 对照
PyJHora `4.8.7`。Presley、Spears、Einstein 三张公开盘走 `compute_chart` 再 `_compute_dasha_system`。大运主星顺序一致,起止日误差都在 1 天以内。没有改算法,没有放宽误差,没有换样本。
小运不跟 PyJHora 比。时长 = 大运 `full_years` × 子运年数 ÷ 36,从该大运自己的 Yogini 起轮转 8 位。页面写「小运未经外部软件核对。」
完整解读仍直接调用 `calculate_yogini_dasha`。接口行去掉 `antardasha` 之后与完整解读的大运行逐字段相同;完整解读的行没有 `antardasha`。Ashtottari 与 `scripts/jyotish_api_server.py` 没有改。
## 测试
- `tests/test_yogini_seed_profile.py` + `tests/test_dasha_api_engine_parity.py`:15 passed,0 failed,0 skipped(`-rs` 没有 skip)。其中种子 5,接口对照 10。
- `frontend/tests/chart-dasha-yogini.test.ts`:4 passed,0 failed。
- `frontend/tests/chart-page-hook.test.ts`:28 passed,0 failed。
- `frontend/tests/chart-page-view.test.tsx`:28 passed,0 failed。
- `frontend/tests/chart-view-route.test.ts`:12 passed,0 failed。
- `frontend/tests/chart-view-zero-year.test.ts`:4 passed,0 failed。
- `frontend/tests/chart-planet-glyphs.test.tsx`:13 passed,0 failed。
- `frontend/tests/chart-dasha-switch-layout.test.ts`:1 passed,0 failed。
- `tsc --noEmit`:0 错。
- `npm run lint`:0 error,122 条既有 warning。
没有跑 Python 快速门、全量 `npm test`、`next build`。这三件留给验收。没有新增 BUG。真人清单只写步骤。
@@ -0,0 +1,105 @@
# 进度:Goel Jaimini 强度(issue #94,2026-10-22)
执行分支 `codex/goel-jaimini-strength-20261022`。工作树 `.worktrees/goel-jaimini-strength-20261022`。未 push。Python 用 `G:\Ferti\Jyotisha\.worktrees\agent-loop\.venv\Scripts\python.exe`(本工作树没有 `.venv`)。`core.autocrlf=false`。上游只读仓 `G:\Ferti\yinduzhanxing-ref`,提交 `5fb8379c`。
## 做了什么
- T1:四个上游模块放到 `scripts/` 根目录。`ROOT_PY_BUDGET` 448 → 452,常量旁写了三栏。`scripts/*.py` 计数 452。
- T2:测试原样搬入,只把 Niryaana 选择器的 import 改到 `scripts.rashi_dashas_native`。`test_bphs_validation_runtime.py` 新增 `test_full_reading_exposes_goel_jaimini_strength`,用文件里已有的虚构 `BASE_BIRTH_ARGS`。
- T3:`_goel_jaimini_evidence` 接到 `cmd_jaimini`(`mode` 为 `all` 或 `special`)和 full-reading 写入 `modules.jaimini` 之前。
- T4:接线后的口径测试(两种交点政策、七星同度 blocked 且不出 AK / 排序、full-reading 喂给 Goel 的经度)。
- T5:三张固定虚构盘与 200 张固定种子虚构盘。没有让步缩盘:三张盘 full-reading 均值 5.212 秒,200 张 × 交点两种口径约 34.74 分钟,低于 40 分钟,mean 与 true 都跑了。
- T6:研究笔记、ERR-116、CHANGELOG。Skill 版本不 bump。
## 四个 blob
| 文件 | 上游 `5fb8379c` | 落地后 `git hash-object` |
| --- | --- | --- |
| `scripts/goel_jaimini_strength.py` | `2170f781740affbad7b8ff4e048b88d87f997bcc` | `d13b3f785a86a17970e450f111d60fc8d52108ac` |
| `scripts/trikona_raman.py` | `1fc9283396acba98b9113bde7af0e27a80841a30` | 相同 |
| `scripts/sthira_brahma_goel_short_method.py` | `6e010b54f5ba480db3e6d8d79e711a1cc2d59fbf` | 相同 |
| `scripts/trikona_dasha.py` | `e6c8a27cf5e23e5c686154406ba5183226d12d79` | 相同 |
`goel_jaimini_strength.py` 相对上游的 diff 只有 `SOURCE` 一行,LF。旧值是上游本地书稿路径,没有入库。新值是 `SOURCE = 'V. P. Goel, Predicting through Jaimini Astrology'`。
测试文件上游 blob `e29c47182c03c2277cff46e271a7f664c3349601`。相对上游先只改一行:
```
-from scripts.niryaana_shoola_dasha import select_niryaana_shoola_start_sign
+from scripts.rashi_dashas_native import select_niryaana_shoola_start_sign
```
T4 在这个文件末尾另加了三条接线测试,不再是单行 diff。
## 接线与上游的两处差异
1. 捕获 `(ImportError, KeyError, TypeError, ValueError)` 时 `logger.warning` 记下异常类和信息,`reason` 写成 `f'{exc.__class__.__name__}: {exc}'`。这几类失败在 helper 内返回 blocked,不会抛进 full-reading 外层的 `except Exception`,因此不会把整个 `modules.jaimini` 带掉。
2. `cmd_jaimini` 传给 Goel 的经度用 `pd.get('degree_raw', pd['degree'])`。模拟盘只有 `degree` 时回退,上游那条特殊点测试仍过。full-reading 本来的 `planet_lons` 已是 `degree_raw`,原样传给 Goel。上升点仍用原来的 `asc_deg`(`lon`)。
没有把 `lagna_seventh_strength` / `niryaana_shoola_strength` 接到 Niryaana 选择或大运。没有改冻结文件、报告渲染、API 主文件、数据库。
## T5 数据(全是虚构盘)
三张盘是 `tests/test_report_english_edition.py` 的 day / night / south。`PYTHONHASHSEED=0`。
单独计时的 full-reading:day 6.343 秒、night 4.692 秒、south 4.600 秒,均值 5.212 秒。三张都是 `executed`,Goel AK 与 `chara_karaka_7` 的 AK 都是同一颗星(Venus / Mercury / Jupiter)。四个新键都在。
改前引擎是接线提交的父本 `eb67962d7`。改前改后:
| 检查 | 结果 |
| --- | --- |
| 中文完整数据版 Markdown | 三张 SHA-256 相同(day `1de47056e69f…`,night `0415e1a20dfe…`,south `51eb80c838cf…`) |
| 英文完整数据版 Markdown | 三张 SHA-256 相同(day `3e6eaadae15e…`,night `a36abde746d5…`,south `adef6214ebbb…`) |
| full-reading 与 `cmd_jaimini` 的 jaimini,去掉四个新键 | SHA-256 相同 |
| 改后四个新键 | full-reading 与 `cmd_jaimini`(mode=all)都有,状态 `executed` |
| `build_domain_facts` 选出的对话卡 | 12 个域 × 3 张盘,规范化 JSON 相同 |
`read_full_data_domain` 的原始副本不是逐字节相同。它整份拷贝 `worksheets`,其中 `advanced_systems.jaimini` 多了四个新键;这是任务书已经写明的资料包 JSON 变大,正文不印。另外两边还有运行时噪声:审计耗时、缓存时间、PyJHora 年盘快照、一张盘的 Yogini `reference_date`。去掉四个新键和这些噪声字段后,day / night 还剩 PyJHora 年盘快照差异,south 只剩 `reference_date`。没有为了抹平这些差异去改渲染或对话卡。
200 张固定种子(`Random(20261022)`,年 1940–2015、日 1–28、纬度 −45~60、经度 −120~150、时区按经度取半小时、岁差在 lahiri / raman / kp 间)。mean 与 true 各 200 次,4 个进程,墙钟 556.6 秒。
| 项 | 数 |
| --- | --- |
| 次数 | 400 |
| `goel_full_strength.status == executed` | 400 |
| blocked | 0 |
| AK 与 `chara_karaka_7` 不一致 | 0 |
| 单次 full-reading | 均值 5.537 秒,最小 4.839,最大 7.848 |
| mean / true 均值 | 5.530 / 5.544 秒 |
三张盘改前改后的 full-reading 耗时互相重叠(改前均值 5.672 秒,同一次改后 6.069 秒,另一次改后计时 5.212 秒),没有拆出稳定的增量。
冻结身份交集(`PRODUCTION_FILES` + `RESEARCH_FILES` + `frozen_scoring.files` 对上 `origin/staging...HEAD`)输出是 `[]`。
## 测试
工作树内 `pytest -q`。Windows 默认 GBK 标准输出打不出 full-reading 里已有的 emoji(`U+1F4D0`、`U+1F534`),`test_bphs_validation_runtime.py` 两条因此在子进程退出码 1。下面的数字是 `PYTHONUTF8=1` 再跑的结果。屏蔽 PyJHora 用临时目录的 `sitecustomize.py` 放在 `PYTHONPATH` 最前(`import jhora` 变成 `ModuleNotFoundError`),没有卸载包。
两次都是 238 条收集、237 通过、1 跳过、0 失败。跳过的是 `test_consultation_contract_golden.py` 里未设置 `JYOTISH_LIVE_CONTRACT_GOLDEN=1` 的线上重抓。
| 文件 | 结果 |
| --- | --- |
| `tests/test_goel_jaimini_strength.py` | 22 通过 |
| `tests/test_bphs_validation_runtime.py` | 3 通过 |
| `tests/test_python_hygiene_budget.py` | 2 通过 |
| `tests/test_rashi_dashas_native.py` | 18 通过 |
| `tests/test_niryaana_shoola_dasha.py` | 3 通过 |
| `tests/test_jaimini.py` | 42 通过 |
| `tests/test_runtime_jhora_import_scan.py` | 4 通过 |
| `tests/test_api_server_growth_contract.py` | 9 通过 |
| `tests/test_consultation_contract_golden.py` | 2 通过,1 跳过 |
| `tests/test_sealed_holdout_contract_freshness.py` | 9 通过 |
| `tests/test_rectification_validation_integrity_gate.py` | 22 通过 |
| `tests/test_reported_offset_research.py` | 14 通过 |
| `tests/test_rectification_engine_memoization.py` | 25 通过 |
| `tests/test_repo_privacy_markers.py` | 62 通过(文档提交前再复跑一次) |
没有弱化既有断言。没有重冻,没有改冻结记录或 golden。
## 移交 #91
本单不印报告。交给 #91:
- 报告印「Goel Jaimini 强度与特殊点」章,中英标签齐全。`blocked` 的中文写「无法判定」、英文写「Not determinable」,并注明原因(七星度数相同 / 强度相同无唯一选择)。
- `jyotish_engine.py` 受限资料 `jaimini_special_points.reason` 里「Brahma/Maheshwara/Rudra still lack a same-profile structured producer」随印章一并改。
- 交点两种口径并列印出,标明默认遵循正文(`include_nodes_text`)。
@@ -1,4 +1,4 @@
# 进度:婚恋合盘 staging 修复(T3–T6 与红线 3)
# 进度:婚恋合盘 staging 修复(T3–T6 已部署;T8 滚动已做)
- 任务书:`docs/tasks/TASK-synastry-staging-fix-20261021.md`
- 基线:`origin/staging` `998d07baf`(T1、T2 已在这条上,BUG-1399)
@@ -45,3 +45,68 @@
3. 切到 English。各节和时间线都有收起的 Analysis,点开能看到 Chart / So。
4. 从报告末尾选一节进对话,发出问题,能按这一节问下去。
5. 另:后台删掉某个非默认的已发布模型后,钉着它的旧咨询对话还能继续,并且改用当前默认模型。没有默认模型时才是「模型暂不可用」。
## T8 报告滚动(BUG-1404)
- 合盘报告外层改为整宽的 `.synastry-report-scroll`(`width: 100%`、`height: 100%`、`overflow-y: auto`)。`.synastry-report` 只居中排版,不再自带 `height: 100%` 和 `overflow`。打印时外层 `height: auto`、`overflow: visible`。
- 真机(执行方未做,不得写成已通过):桌面打开一份合盘报告,把指针放在正文栏两侧的空白上滚动,整份报告应跟着动。窄屏和打印另看一眼,长报告不要被裁成一页。
## T7 独立地址(BUG-1405)
- 新页面 `/synastry/[reportId]` 复用 `PersonalReportPage`,`surface="synastry"`,文档标题「婚恋合盘 · Jyotisha」,`lang` 仍走 `readReportLanguage`。
- 选人页「开始合盘」和「之前的合盘」、报告中心的合盘卡片改到 `/synastry/报告`。个人报告卡片仍是 `/reports/报告`。
- 旧地址打开合盘时 `location.replace` 到新地址,英文保留 `?lang=en`,不另留历史。新地址打开个人报告时换回 `/reports/报告`。
- 合盘揭幕后的打印样式加上 `media="print"`,平时侧栏还在。
- 失败态带上 `reportType`。个人报告失败断言的原值是没有这个字段,新值带上 `personal_full`,因为合盘地址要能认出个人报告。
- 真机(执行方未做,不得写成已通过):点「开始合盘」后,侧栏当前项仍是「婚恋合盘」。
- 左上角回到选人页仍是「‹ 婚恋合盘」。新路由让页面链接规则不接受普通 `<a href="/synastry">`,所以改成 `Link`,目的地不变。
## T9 重复标题(BUG-1406)
- 正文以该节标题开头时,质检返回 `repeated_heading`,只重写这一节。通过后保存前再剥掉开头的标题。中文和英文同一条规则。「沟通与理解力」这种紧挨着的字不剥。
- 真机(执行方未做,不得写成已通过):打开一份新写的合盘,各节标题下面的第一句不要再重复标题。
## T10 两人顺序(BUG-1407)
- 根因:去重把两个人按编号从小到大存放,生成又把较小的编号当成甲。等待页用的是选人页当场记下的顺序,所以只有等待页没反。
- 创建时把选人顺序另存一节。生成按这个顺序加载两个人,标题、卡片和追问标题跟着走。去重用的编号排序不动。同一对正在生成时,仍打开那份,顺序是当时保存的。
- 真机(执行方未做,不得写成已通过):先选甲、再选乙。等待页、揭幕后的标题、报告中心卡片、从报告进的对话标题都是甲 × 乙。
## 这一轮检查
| 检查 | 结果 |
| --- | --- |
| `tsc --noEmit` | 0 错 |
| 定向:滚动、重复标题、地址、顺序、报告渲染 | 通过,0 cancelled。失败态断言原值没有 `reportType`,新值带上 `personal_full` |
| 质检 `tests/test_synastry_full_reader_gate.py` | 通过。正文以节标题开头判失败 |
| 合盘创建真库(单独) | 通过。请求先是本人、后是另一人;顺序节是本人在前,去重编号是另一人在前 |
| `npm run build` | `/` 与 `/synastry` 为 Static。`/synastry/[reportId]` 为 Dynamic。首屏引用的 js/css gzip -9:JS 577,319,CSS 70,518,合计 647,837。对照 643,725,差 +0.64%,在 ±2% 内 |
| 全量 `eslint` | 0 error,122 warning,与基线相同。中途有过 1 个 error:新路由不接受 `<a href="/synastry">`。返回链接改成 `Link` 后消失 |
全量 Python 快速门没有跑:这个工作树没有项目虚拟环境。质检定向测试用系统 Python 跑过。
未推 staging,未改 `.gitea/`。真机未做,上面的真机步骤都不得写成已通过。
## T11 允许重新生成(BUG-1408)
- 已有 `ready` 报告时,「开始合盘」新建一份并再扣 `synastry.full`。旧报告留在「之前的合盘」。已有 `generating` 时仍打开那份等待页,不扣点。
- 去掉 `personal_reports_synastry_pair_ready_uidx`,同一对可以有多份写好的报告。`synastry_reports` 的一对一行没动,引擎结果继续复用,正文按新报告重写。
- 选人页在点数说明下,两人已有写好的合盘且没有正在生成时,显示「这两人已经合过 N 次,再生成会另扣 X 点」。N、X 来自这对人的 ready 份数和当前点数。
- 真机(执行方未做,不得写成已通过):同一对人再点「开始合盘」,应进入一份新的等待页,点数再减一次。上一份仍在「之前的合盘」里。按钮下能看到已经合过几次。
## 断言变更(T11)
| 测试 | 原值 | 新值 | 原因 |
| --- | --- | --- | --- |
| `synastry-full-create-route.test.ts` 同一对复用 | 已有 ready 时 status 200、`reused`、不扣点 | 只有 generating 复用,status 202、不扣点 | K6,BUG-1408。ready 不再复用 |
| `database-synastry-full-report.test.ts` 第二份 ready | 插入被 `personal_reports_synastry_pair_ready_uidx` 拒绝,count 为 1 | 第二份 ready 可以留下,count 为 2 | 旧报告要保留,不能再靠这个唯一索引挡住 |
## 这一轮检查(T11)
| 检查 | 结果 |
| --- | --- |
| `tsc --noEmit` | 0 错 |
| `npm run lint` | 0 error,122 warning,与基线相同 |
| 选人页渲染、创建路由 | 通过,0 cancelled。复用断言从 ready 的 200 改为 generating 的 202 |
| 合盘创建真库 | 通过。generating 时第二次仍是原 id,点数停在 81;写成 ready 后再建得到新 id,点数到 62。ready 份数是 1,生成中为真 |
| 同一对两份 ready | 通过。第二份 ready 留下,count 为 2。随后取消排队任务,指纹变化的另一份仍能写入 |
@@ -0,0 +1,42 @@
# 进度:婚恋合盘 T7~T11 第 1 次打回(issue #85)
- 修复单:`docs/tasks/TASK-synastry-staging-fix-fix-20261022.md`
- 被验提交:`57ee79cc5`
- 分支:`codex/synastry-staging-fix-20261021`
- 工作树:`.worktrees/synastry-staging-fix-20261021`
- 开工:`git fetch origin --prune` 后 `git merge origin/staging`(不 rebase)。无冲突。合入提交 `2579fa14e`,只带进任务书和验收清单。
- 没有新 BUG 号。没有改数据库、`.gitea`、引擎。没有 push。
## 做了什么
- G1:`tests/test_api_server_security.py` 的路由表在 `synastry` 和 `terms` 之间加入 `synastry/[reportId]`,旁边写了三栏。
- G2:`CHANGELOG.md` 的 BUG-1407 和 `PROGRESS-synastry-staging-fix-20261021.md` 的 T10,把「同一对已经有报告时,仍打开原来那份」改成「同一对正在生成时,仍打开那份」。其余句子没动。
- G3:删掉 `frontend/tests/synastry-report-surface.test.ts` 里永远成立的 `assert.equal("/synastry/abc".startsWith("/synastry/"), true)`。改为按现有侧栏渲染写法(`SidebarProvider` + `AppSidebar`)渲染侧栏,`pathname` 为 `/synastry/abc`,当前项 `data-active="true"` 是「婚恋合盘」,「我的报告」不是。合盘开关按外壳传入打开,否则这一项不会画出来。
## 断言三栏
| 位置 | 原值 | 新值 | 原因 |
| --- | --- | --- | --- |
| `tests/test_api_server_security.py` 路由表 | `synastry` 后面直接是 `terms` | 加入 `synastry/[reportId]` | issue #85 T7 合盘报告独立地址 |
| `frontend/tests/synastry-report-surface.test.ts` 侧栏当前项 | `assert.equal("/synastry/abc".startsWith("/synastry/"), true)` | `pathname` 为 `/synastry/abc` 时渲染侧栏,`data-active="true"` 的是「婚恋合盘」,「我的报告」不是 | 原断言永远成立,没有渲染侧栏 |
## 命令与数字
| 检查 | 结果 |
| --- | --- |
| 快速门 | 退出码 0。pytest 1099 条:通过 1097,失败 0,错误 0,跳过 2。G1 `test_capability_audit_scans_registry_and_local_sources` 通过。失败名单空。跳过的两条不是失败:`test_dig_bala_jupiter_synthetic_north_china_case_needs_better_than_house_only_linear_model`、`test_slice_glyphs_cover_their_table_characters` |
| `tsc --noEmit -p .` | 退出码 0,0 错 |
| `npm run lint` | 退出码 0。0 error,122 warning,与上一轮进度记录的基线相同 |
| `synastry-report-surface.test.ts` | 退出码 0。2 通过,0 失败,0 cancelled |
工作树没有 `.venv`,解释器用 `.worktrees/agent-loop/.venv/Scripts/python.exe`。
`tools/agent-loop/windows-known-failures.txt` 列的是前端 `test:db` 的 13 条,不是这次 pytest。这次 pytest 没有失败,没有多出来的名字。
## 偏离
- 快速门加了 `--skip-frontend-runtime`。`quick` 默认还会跑前端全量 `npm test`、lint 和 `next build`。修复单写明全量测试和 build 由验收方复跑,本轮不跑。Python 编译、审计和 pytest 目标与 `--profile quick` 相同。
- 第一次快速门退出码 1,发生在 pytest 之前:控制台编码是 GBK,`scripts/validate_bphs_invariants.py` 打印符号时 `UnicodeEncodeError`。没有改这个脚本。重跑设置 `PYTHONUTF8=1` 后,上面的退出码 0 才是结果。
- 为了在门禁只印一行时仍能数 pytest,设置了 `PYTEST_ADDOPTS` 把 junit 写到 `gate-logs/`(已被忽略,未提交)。
- `docs/tasks/README.md` 里这份修复单的进度改指 `PROGRESS-synastry-staging-fix-fix-20261022.md`,状态从待领取改为待验收。修复单「不用改的」那一节没有动。
- 快速门把 5 个 `references/oracle/artifacts/pending_packets/*.json` 改成了 CRLF,内容无差。已还原,没有提交。
+4 -4
View File
@@ -510,16 +510,16 @@
| `TASK-niryaana-shoola-pvr-20261018.md` | `PROGRESS-niryaana-shoola-pvr-20261018.md` | #84 Niryaana Shoola 改 PVR 口径(我们的表与 Shoola 逐行相同;推翻 BUG-1283 所选 profile;占星师 7a773d13) | 待验收 | `codex/niryaana-shoola-pvr-20261018` |
| `TASK-synastry-full-report-20261018.md` | #82 | 婚恋合盘:选人页 + 完整合盘报告(关系画像九节:结论+折叠的分析逻辑+关系时间线+技术依据摘要;英文按需;计费键 synastry.full) | 排队(等 #78、#79、#81) | `codex/synastry-full-report-20261018`;动表 |
| `TASK-synastry-report-chat-20261018.md` | `PROGRESS-synastry-report-chat-20261018.md` | 从合盘报告某一节进入对话问依据(绑定报告与节、对话里可用术语、只依据已存计算结果并逐条核对、计费照普通对话) | 已验收 | `549e37b99`;动表 |
| `TASK-synastry-staging-fix-20261021.md` | `PROGRESS-synastry-staging-fix-20261021.md` | #85 婚恋合盘 staging:P0 `.gte` 已在 staging(BUG-1399)。本分支补时间线起止、英文分析逻辑、删模型后旧对话改用默认模型、选人页开关文案,以及合盘创建真库测试(BUG-1400~1403) | 待验收 | `codex/synastry-staging-fix-20261021` |
| `TASK-synastry-staging-fix-20261021.md` | `PROGRESS-synastry-staging-fix-20261021.md` | #85 婚恋合盘 staging:T3~T6 已在 staging `ff6b228dd`(BUG-1400~1403)。本分支继续报告滚动、独立地址、重复标题、两人顺序(BUG-1404~1407) | 已合入 staging | `codex/synastry-staging-fix-20261021` |
| `TASK-synastry-report-chat-fix-20261020.md` | `PROGRESS-synastry-report-chat-20261018.md` | 大运核对要认报告里的「小运」和英文 mahadasha / antardasha;预填文案只留一句 | 已验收 | `549e37b99` |
| `TASK-other-subject-birth-time-edit-20261021.md` | — | 其他人的出生时间可以修改(去掉 `chart_profiles_guard_birth` 的填报时间不可改;推翻 people-archive P1 §验收 2 该条;active 锁不变) | 排队(等 #86 合入) | `codex/other-subject-birth-time-edit-20261021`;动表;不进循环 |
| `TASK-report-export-dialog-polish-20261021.md` | `PROGRESS-report-export-dialog-polish-20261021.md` | #90 导出弹窗:英文不可用说明改顶部浮层(每次打开一次);选中态描边 / 圆点 / 勾选框用主题色、底色中性(推翻 DESIGN「Selected states use canvas-muted + ink」,BUG-1078 主语保留) | 已合入 staging | `codex/report-export-dialog-polish-20261021` |
| `TASK-chart-ascendant-slash-20261021.md` | `PROGRESS-chart-ascendant-slash-20261021.md` | #87 上升状态格「不适用」改「/」+ 悬停 / 点按说明;报告上升行同改并在表下加说明(推翻 10-15 口径) | 已合入 staging | `codex/chart-ascendant-slash-20261021` |
| `TASK-report-english-han-leak-20261021.md` | `PROGRESS-report-english-han-leak-20261021.md` | #89 个人报告英文版约 4 成整份丢弃:漏译汉字源头补英文孪生字段、修吃空格;200 张固定种子回归 + 快速门 smoke(复发自 BUG-1272);中文逐字节不变 | 待验收 | `codex/report-english-han-leak-20261021` |
| `TASK-chart-dasha-yogini-20261021.md` | — | #88 星盘页大运右栏切换 Chara / Yogini,Yogini 补小运(按比例,内部核对,页面注明未经外部软件核对);Ashtottari 另立单(起运表与 PyJHora 8/12 宿不一致) | 待领取(等 #86、#87 合入) | `codex/chart-dasha-yogini-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 个月星历、解释补长);不设大小上限 | 待领取(等 #89 合入;T3 与 #90 串行) | `codex/full-data-parity-1-20261021` |
| `TASK-goel-jaimini-strength-20261022.md` | — | #94 搬上游公开的 Goel Jaimini 强度与 Brahma / Maheshwara / Rudra(4 个上游原样文件,按 #81 决策 A 先例根目录预算 448→452;来源串改书目引用);只做计算、不改报告;冻结身份不变 | 待领取(可与 #89 并行;须在 #91 印章前合入) | `codex/goel-jaimini-strength-20261022` |
| `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-20261021.md` | **#85 第 1 次打回**(T7~T11 主体通过):新地址没登记进路由清单致快速门红;CHANGELOG 与 T11 矛盾;侧栏点亮测试是空断言 | 待领取 | `codex/synastry-staging-fix-20261021` |
| `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-20261021.md` | **#89 第 1 次打回**:改了冻结的校正打分文件 `jaimini.py`;测试的 PyJHora 屏蔽没传到子进程(测的不是生产那份报告,也是慢的原因);缺英文时留空藏住漏洞 | 待领取 | `codex/report-english-han-leak-20261021` |
@@ -0,0 +1,9 @@
# 星盘大运切换(真人)
桌面和手机各做一遍。不要在这份清单上写「已通过」。
1. 打开星盘页,点「大运」。左栏是 Vimshottari。右栏默认是 Chara,能看到「现在」卡。
2. 右栏切到 Yogini。等这一栏出来后,点开当前大运,能看到小运。列表下面有一句「小运未经外部软件核对。」
3. 再切回 Chara。Chara 仍在,左栏 Vimshottari 没有被换掉。Chara 下面没有那句小运核对说明。
4. 看「现在」卡:大运、小运、小运剩余都在。
5. 把窗口收到手机宽度(约 375px)。两栏改成上下排。右栏的 Chara / Yogini 切换不把页面撑出横向滚动,两个选项都能点到。