diff --git a/docs/tasks/README.md b/docs/tasks/README.md index 8282180c..ae9cec5d 100644 --- a/docs/tasks/README.md +++ b/docs/tasks/README.md @@ -91,7 +91,8 @@ | 任务书 | 进度 | 主题 | 状态 | 落点 | | --- | --- | --- | --- | --- | -| `TASK-repo-hygiene-20260903.md` | `PROGRESS-repo-hygiene-20260903.md` | 岁差默认 Raman + 用户设置可选、参考集锁口径(P0,单独先推)、发布门本地可复现、注册表白名单、仓库地址、早期日志搬家、远端分支清理 | 待验收 | 分支 `codex/repo-hygiene-20260903` `2415e751` | +| `TASK-repo-hygiene-20260903.md` | `PROGRESS-repo-hygiene-20260903.md` | 岁差默认 Raman + 用户设置可选、参考集锁口径、发布门本地可复现、注册表白名单、仓库地址、早期日志搬家、远端分支清理 | 已验收(带修复单) | `b6a70aa7`、`2415e751`、`01a45363`(BUG-511);验收结论见修复单附录 | +| `TASK-repo-hygiene-fix-20260903.md` | — | Gulika 全局岁差泄漏(P1)、设置类名无样式、提示语对齐校正现状、剩余 lahiri 字面量、测试不写仓库 | 待领取 | 分支 `codex/repo-hygiene-fix-20260903` | ### 上游同步与能力接入 diff --git a/docs/tasks/TASK-repo-hygiene-fix-20260903.md b/docs/tasks/TASK-repo-hygiene-fix-20260903.md new file mode 100644 index 00000000..0e1b06cb --- /dev/null +++ b/docs/tasks/TASK-repo-hygiene-fix-20260903.md @@ -0,0 +1,126 @@ +# 任务书 · 仓库整备修复单: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)待部署后做。