Files
Jyotisha/docs/tasks/TASK-repo-hygiene-fix-20260903.md
T

127 lines
11 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 任务书 · 仓库整备修复单:Gulika 全局岁差泄漏、设置类名无样式、剩余字面量、测试改写仓库文件(2026-09-03)
基线:`origin/staging` @ `01a45363`(`codex/repo-hygiene-20260903` 已快进合入:`b6a70aa7`、`2415e751`、`01a45363`)。分支 `codex/repo-hygiene-fix-20260903`。BUG 编号从 **512** 起(staging 当前最大 BUG-511;开工再核对)。
这是 `TASK-repo-hygiene-20260903.md` 的验收修复单。验收结论见文末;这里只列没过的项。
---
## 为什么要做(验收实证,2026-09-03,独立工作树 `01a45363`,CI 同款依赖)
### P1 · `scripts/gulika.py` 把进程级恒星黄道模式硬切成 Lahiri 且不恢复
- `scripts/gulika.py:42` `_sidereal_ascendant` 直接 `swe.set_sid_mode(swe.SIDM_LAHIRI)`;`:92` 回执写死 `"ayanamsa": "lahiri"`。`swe.set_sid_mode` 是**进程全局**状态,`jyotish_api_server.py` 是常驻进程。
- 复现(同一进程内,先 `apply_ayanamsa('raman')`):
| 步骤 | Moon 恒星黄经(2000-01-01 12:00 UT) |
| --- | --- |
| 调 `calculate_gulika` 之前 | 200.9169(Raman) |
| 调 `calculate_gulika` 之后 | **199.4706**(已变成 Lahiri) |
- 线上表现:对 `/api/consultation_workflow` 传 `ayanamsa: raman`,回执 `chart.modules.gulika.ayanamsa` 仍是 `lahiri`;同一请求里排在 Gulika 之后计算的任何模块,以及**下一个请求里直到再次 `apply_ayanamsa` 之前的任何计算**,都可能按 Lahiri 算。主盘 Moon 本次仍是 Vishakha 只是因为它排在 Gulika 前面。
- 这是 `80102459` 之前就有的旧代码,但产品默认改成 Raman 之后它从"无害的重复设置"变成"静默换口径"。仓内 `set_sid_mode` 直调只有这一处(`grep -rn set_sid_mode scripts | grep -v ayanamsa_utils`)。
### P2 · 新设置组件的容器类名没有样式规则,`browser` / `release` profile 会红
- `frontend/src/components/ayanamsa-preference-field.tsx` 渲染 `className="sheet-section ayanamsa-preference"`,`globals.css` 只有 `.ayanamsa-preference-option` 与 `.ayanamsa-preference-hint`,没有 `.ayanamsa-preference`。
- `frontend/tests/class-name-definition-contract.test.ts` 因此红:`+ 'ayanamsa-preference (src/components/ayanamsa-preference-field.tsx)'`。staging 门禁用 `--skip-frontend-runtime`,所以没拦住;提升 `main` 前的 `browser` / `release` profile 会拦。
### P2 · 设置提示语与校正引擎现状不符
- `AYANAMSA_SWITCH_HINT` 写"切换只影响之后的新计算",但 `scripts/active_rectification_event_engine.py:50` 用模块常量 `AYANAMSA = DEFAULT_AYANAMSA_NAME`,`scripts/candidate_time_sensitivity_scan.py:112` 兜底 `"lahiri"`;前端 `engine-client.ts:479` 传了 `ayanamsa`,Python 校正引擎不读。用户选 Lahiri 后,咨询按 Lahiri、校正按 Raman,同一个人两套口径。
- "校正岁差按请求"已列入 `TASK-upstream-sync-20260903.md` 的解冻三项,本单**不改校正引擎**,只把话说对。
### P2 · Python 侧仍有依赖"默认恰好是 Lahiri"的字面量
`grep -rn "'lahiri'\|\"lahiri\"" scripts/*.py`(排除 `ayanamsa_utils`、参考集/对照脚本):
| 位置 | 性质 | 处置 |
| --- | --- | --- |
| `scripts/prashna_context.py:64,95` | 请求兜底 | 改 `_request_ayanamsa` 同款:请求有则用,无则 `DEFAULT_AYANAMSA_NAME` |
| `scripts/candidate_time_sensitivity_scan.py:112` | 校正扫描兜底 | 改 `DEFAULT_AYANAMSA_NAME`(与校正引擎常量一致,等上游同步再按请求) |
| `scripts/cmd_muhurta.py:29,115`、`scripts/cmd_solar_return.py:44`、`scripts/muhurta.py:616,670,1316,1445,1517`、`scripts/ephemeris_adapter_contract.py:43` | CLI / 函数默认参数 | 改 `DEFAULT_AYANAMSA_NAME`;CLI `--help` 文案随之 |
| `scripts/collect_vedastro_official_parity_raw.py:147`、`scripts/shadbala_dig_source_of_truth_audit.py:73`、`scripts/oracle_boundary_audit.py:259`、`scripts/pyjhora_multi_case_panchanga_gulika_replay.py:56`、`scripts/local_accuracy_report.py:230` | 参考集/外部对照,显式 Lahiri 是口径 | **不动**,各加一行注释"参考口径,勿改为默认" |
### P2 · 全量 pytest 之后仓库仍被改写
任务书 1.4 要求"全量 pytest 后 `git status --short` 为空"。执行方修了 `character_level_inventory_manifest` / `numeric_oracle_gap_queue_v3` / `hard_gap_source_hunt`,但这三对仍直接写 `references/oracle/`:
| 测试 | 被改写文件 |
| --- | --- |
| `tests/test_full_technique_invocation_matrix.py` | `references/oracle/full_technique_invocation_matrix_2026_07_22.json` |
| `tests/test_muhurta_factor_only_scoring_packet.py` | `references/oracle/muhurta_factor_only_scoring_packet_2026_07_23.json` |
| `tests/test_prashna_sphuta_oss_case_probe.py` | `references/oracle/prashna_sphuta_oss_case_probe_2026_07_20.json` |
---
## 决策记录
1. 岁差默认 Raman + 用户可选的产品决定不变(见原任务书)。
2. 校正引擎按请求岁差**不在本单**(归上游同步任务书任务 7);本单只修提示语。
3. Gulika 的修法必须是"用当前激活的模式算",不是"把 Lahiri 换成 Raman"。
## 硬红线
1. 不改 `DEFAULT_AYANAMSA_NAME`;不改参考集脚本里的显式 `lahiri`;不改任何期望值。
2. `scripts/jyotish_api_server.py` 行数不增长;`page.tsx` 不增长。
3. 不改校正打分/阈值/golden;不动数据库。
4. `tsc` 0 错、`npm run lint` 0 error、`class-name-definition-contract` 绿;Python 定向测试绿;无 Docker 的失败清单与 `01a45363` 基线逐条一致。
## 任务分解
### 任务 1(P1)· Gulika 用当前模式算,且不污染全局
1. `scripts/gulika.py`:删除 `swe.set_sid_mode(swe.SIDM_LAHIRI)`。`_sidereal_ascendant` 在当前激活模式下调用 `swe.houses_ex(..., swe.FLG_SIDEREAL)`;若 `calculate_gulika` 需要显式口径,加可选参数 `ayanamsa_name`,由 `ayanamsa_utils.apply_ayanamsa` 设置后**在 `finally` 里恢复原模式**(`ayanamsa_utils` 需提供读取/恢复当前模式的辅助;`ACTIVE_AYANAMSA_NAME` 已有)。
2. 回执 `"ayanamsa"` 写实际使用的名字。
3. 回归测试(新文件 `tests/test_gulika_ayanamsa_mode.py`):`apply_ayanamsa('raman')` → 记录 Moon 恒星黄经 → `calculate_gulika(...)` → Moon 黄经不变;`calculate_gulika` 回执 `ayanamsa == 'raman'`;再对 `lahiri` 重复一次。
4. 合同测试:`grep -rn "set_sid_mode" scripts --include=*.py` 除 `ayanamsa_utils.py` 外为空(写进 `tests/test_ayanamsa_mode_ownership.py`,锁定"只有 `ayanamsa_utils` 允许直接设模式")。
5. `docs/BUG_HISTORY.md` 新增 BUG(现象=Raman 请求回执 gulika 标 lahiri、进程全局模式被改;根因=`gulika.py:42`;复发自=无;关联=BUG-511)。
6. 验收:本单开头那张表复现后两行黄经相等;`/api/consultation_workflow` 传 `raman` 的回执里 `grep` 不到 `"lahiri"`。
### 任务 2(P2)· 设置组件样式与提示语
1. `globals.css` 加 `.ayanamsa-preference` 规则(哪怕只是间距)或去掉该类名;`class-name-definition-contract` 绿。
2. `AYANAMSA_SWITCH_HINT` 改为如实:切换影响之后的咨询、报告、星盘库与每日星语;**生时校正目前固定按 Raman 计算**,待后续版本跟随设置。`frontend/DESIGN.md` 对应条目同步;文案对 `frontend/docs/VOICE.md`。
3. 验收:`tests/ayanamsa.test.ts` 与 `settings-mvp-contract` 绿;`tsc` / lint 0 error。
### 任务 3(P2)· 字面量清扫
按上表处置;验收命令:
```bash
grep -rn "'lahiri'\|\"lahiri\"" scripts/*.py | grep -v "ayanamsa_utils\|参考口径"
```
只允许剩参考集/对照脚本(每处带"参考口径"注释)。
### 任务 4(P2)· 测试不写仓库
三对脚本加 `--output-dir` / `--no-write`(沿用执行方在 `character_level_inventory_manifest.py` 的做法),测试改写 `tmp_path`。验收:`python -m pytest -q --continue-on-collection-errors tests` 之后 `git status --short` 为空。
### 任务 5(P3,可选)· 机器相关计数测试标记
`tests/test_character_level_inventory_manifest.py` 有 6 条断言本机碎片目录数量(`assert 3 >= 60`、`495 >= 500`、`0 >= 10`),只在原作者机器上绿。若产品同意,加 `@pytest.mark.external`(三栏说明),让 `pytest -m "not external"` 成为发布门的默认口径;不同意则留在 BLOCKED。
## 交付物
- `docs/tasks/PROGRESS-repo-hygiene-fix-20260903.md`;`docs/tasks/README.md` 状态板本单一行。
- 做不了的写 `BLOCKED.md`。
---
## 附 · 原任务书验收结论(2026-09-03,staging `01a45363`)
| 任务 | 结论 | 证据 |
| --- | --- | --- |
| 0.a 参考集锁口径 | 通过 | 公开案例复验 `valid=true`、`pass_rate=1.0`、gated 66/66、`reference_ayanamsa=lahiri`;夹具日期未改;acceptance check `partial` 且 `user_invocation_tests=true` |
| 0.b 标签一致 | **未通过(P1)** | `jyotish_api_server.py` 三处已改;但 `gulika.py` 仍硬切 Lahiri 并写死标签,Raman 请求回执含 `lahiri`,且泄漏进程全局模式 |
| 0.c 用户设置 | 通过(带 2 个 P2) | 迁移 `20260903010000_profile_ayanamsa.sql`(默认 raman、四值 check);`/api/account` 四值校验;单选 UI 在星盘资料表;`resolveAyanamsa` 贯通咨询/校正载荷/报告/星盘库/每日星语;端到端:传 lahiri → Moon Swati,传 raman / 不传 → Vishakha。P2:容器类名无样式(合同测试红);提示语与校正引擎现状不符 |
| 0.d 记录 | 通过 | CHANGELOG 2026-09-03 条目;BUG-511 |
| 1 发布门可复现 | 部分通过 | 依赖装对后收集 ERROR 13 → 0;全量红 89 → 73(其余为环境/参考值过期,见 BLOCKED 三条);**1.4 未通过**:跑完仍有 3 个 oracle JSON 被改写 |
| 2 注册表白名单 | 通过 | `test_capability_evidence_pool` 绿;`audit_capabilities --mode validate` 通过 |
| 3 仓库地址 | 通过 | 产品仓路径 grep 为空;Gitea remote 不再误报 |
| 4 早期日志搬家 | 通过 | 四份进 `docs/history/`;根目录 7 个 md(+ 被忽略的 COVERAGE 报告);gate 路径已改 |
| 5 分支清理 | 通过 | 远端 74 → 7,未合入 4 条保留 |
前端:`tsc` 0 错、lint 0 error / 73 warning、全量 2572 pass / 26 fail / 10 skipped,26 条失败里 25 条是 Docker / rsync / YAML 工具 / Playwright 环境项(与既往基线同类),**1 条是本轮新红**(class-name 合同)。`page.tsx` 未动(2041 行是 `d159f08e` 校正面合入后的数字,不属本轮)。`jyotish_api_server.py` 11120 行 ≤ 上限。staging 门禁在 `01a45363` 上仍在跑,health 仍是 `591ffd21`,产品实测(设置切 Lahiri / Raman 看 Moon)待部署后做。