Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0193vBv6w5MV2cifdTUu9H5P
11 KiB
任务书 · 仓库整备修复单: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/releaseprofile 会拦。
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 |
决策记录
- 岁差默认 Raman + 用户可选的产品决定不变(见原任务书)。
- 校正引擎按请求岁差不在本单(归上游同步任务书任务 7);本单只修提示语。
- Gulika 的修法必须是"用当前激活的模式算",不是"把 Lahiri 换成 Raman"。
硬红线
- 不改
DEFAULT_AYANAMSA_NAME;不改参考集脚本里的显式lahiri;不改任何期望值。 scripts/jyotish_api_server.py行数不增长;page.tsx不增长。- 不改校正打分/阈值/golden;不动数据库。
tsc0 错、npm run lint0 error、class-name-definition-contract绿;Python 定向测试绿;无 Docker 的失败清单与01a45363基线逐条一致。
任务分解
任务 1(P1)· Gulika 用当前模式算,且不污染全局
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已有)。- 回执
"ayanamsa"写实际使用的名字。 - 回归测试(新文件
tests/test_gulika_ayanamsa_mode.py):apply_ayanamsa('raman')→ 记录 Moon 恒星黄经 →calculate_gulika(...)→ Moon 黄经不变;calculate_gulika回执ayanamsa == 'raman';再对lahiri重复一次。 - 合同测试:
grep -rn "set_sid_mode" scripts --include=*.py除ayanamsa_utils.py外为空(写进tests/test_ayanamsa_mode_ownership.py,锁定"只有ayanamsa_utils允许直接设模式")。 docs/BUG_HISTORY.md新增 BUG(现象=Raman 请求回执 gulika 标 lahiri、进程全局模式被改;根因=gulika.py:42;复发自=无;关联=BUG-511)。- 验收:本单开头那张表复现后两行黄经相等;
/api/consultation_workflow传raman的回执里grep不到"lahiri"。
任务 2(P2)· 设置组件样式与提示语
globals.css加.ayanamsa-preference规则(哪怕只是间距)或去掉该类名;class-name-definition-contract绿。AYANAMSA_SWITCH_HINT改为如实:切换影响之后的咨询、报告、星盘库与每日星语;生时校正目前固定按 Raman 计算,待后续版本跟随设置。frontend/DESIGN.md对应条目同步;文案对frontend/docs/VOICE.md。- 验收:
tests/ayanamsa.test.ts与settings-mvp-contract绿;tsc/ lint 0 error。
任务 3(P2)· 字面量清扫
按上表处置;验收命令:
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)待部署后做。