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

24 KiB
Raw Blame History

任务书 · 仓库整备与 main 提升前置:岁差默认 Raman 且用户可选、发布门可跑、地址/日志/分支清理(2026-09-03

基线:origin/staging @ d159f08e(校正会话面重做 codex/rectification-ux-20260903 已合入)。分支 codex/repo-hygiene-20260903。BUG 编号从 510 起(staging 当前最大 BUG-509;开工再 grep -oE '^## BUG-[0-9]+' docs/BUG_HISTORY.md | sort -t- -k2 -n | tail -1 核对)。

本任务书是 2026-09-03 产品审查决定的"仓库小活",但调查时发现任务 0 不是小活:它决定 main 能不能提升。任务 0 单独先做、先推、先验收,任务 15 随后。


为什么要做(事故实证)

A. 默认岁差(ayanamsa)在 staging 上从 Lahiri 变成了 Raman,公开真实案例复验因此失效(P0)

  • 来源:801024592026-08-20feat(product): present consult and rectification in local skill formCursor 执行)把 scripts/ayanamsa_utils.pyACTIVE_AYANAMSA_NAME = 'lahiri' 改为 DEFAULT_AYANAMSA_NAME = 'raman',并把 scripts/jyotish_engine.py 全部 default='lahiri' 改成 DEFAULT_AYANAMSA_NAME;前端 birth-time-journey-assessment.ts:28,40global-birth-payloads.ts:49 同步硬编码 "raman"。提交信息只有一句 "Default ayanamsa to Raman with true_pushya support"CHANGELOG.mddocs/BUG_HISTORY.md 均无记录。
  • 影响量化(同一台机器、同一 .venv,只换 checkout):
检查 生产 7b620c7aLahiri staging 8e214e29Raman
tests/run_real_case_revalidation.py valid true false
pass_rate(门槛 0.98 1.0 0.9394
gated_passed / gated_total 66 / 66 62 / 66
虚构盘 2000-01-01 12:00 UTC (0,0) Moon nakshatra Swati Vishakha
同盘 Vimshottari 首段 Rahu 余运 → Jupiter 2000-09-202016-09-20 Jupiter 余运 1998-11-272014-11-27
tests/test_user_invocation_acceptance_contract.py::test_fixture_dasha_timeline_rejects_workbuddy_regression_claims 通过 失败

两套岁差相差约 1°26′,Moon 落在 nakshatra 边界附近的盘会整段大运换主;公开案例复验的参考值来自 Lahiri 口径的公开来源,而 tests/run_real_case_revalidation.py:64 调用 jyotish_engine.py没有显式传 --ayanamsa,跟着默认走,所以门槛从满分掉到 0.94。run_quality_gate.py --profile release 包含真实案例复验(skip_real_cases: False),也就是说现在的 staging 过不了发布门main 无法提升。根因不是 Raman 本身,而是:参考集对照没有锁定自己的口径;产品没有把岁差作为用户可见、可选的设置;三处标签与实际计算不一致。

  • 一致性问题(无论默认取哪个都要修):scripts/jyotish_api_server.py:2853:4017ayanamsa_policy 兜底成字面量 'lahiri' 交给 VedAstro 适配器,:7030 把返回体里的 'ayanamsa' 写死 'lahiri',而本地引擎按 DEFAULT_AYANAMSA_NAME 算——本地与 VedAstro 对照用的不是同一套岁差,且证据包标签可能与真实计算不一致。:7086ayanamsa_display 又兜底 'Raman'

B. 技法注册表新 entry_type 没进白名单

references/technique_registry.jsonrangacharya_jaimini_variant 用了 entry_type: "experimental_variant"evidence_role: "comparison_only"tests/test_capability_evidence_pool.py::test_registry_is_backend_evidence_pool_not_flat_user_skill_list 的白名单没有这两个值 → 常红。scripts/capability_evidence_pool.py 对未知 role 既不计入 audit_only_entries 也不报错。

C. 仓库地址还是旧研究仓

pyproject.toml:54-58.codex-plugin/plugin.json:7,9,10,39、根 SKILL.md:4 的 description、scripts/skill_release_package.py:27scripts/skill_release_manifest.py:15skills/jyotish-engine-modules/SKILL.md:67 都指向 https://github.com/732642856/yinduzhanxing。这是上游研究仓,不是本产品仓。tests/test_skill_release_package.py:59tests/test_skill_release_manifest.py:16 锁着旧地址。scripts/remote_repo_visibility_check.py:22 在 remote 不是 GitHub 时退回这个旧 slug 做可见性检查,而本仓 origin 是 Gitea。

D. 根目录还剩四份早期实现日志

progress.md209 KB)、findings.mdtask_plan.mdCHANGELOG_v6.2_to_v6.9.mdscripts/run_quality_gate.py:125,126,137RELEASE_CRITICAL_UNTRACKED_PATHS 锁着前三个路径,所以 09-03 的文档轮没能搬。

E. 远端 70 条分支,66 条已完全合入 staging

git branch -r --merged origin/staging 的结果见任务 5。未合入的只有 4 条。

F. 本地环境与 CI 依赖不一致,全量 pytest 在本地无法收集

本地 .venv 装的是 mcp 2.1.1requirements.txtmcp>=1.0,<2)且没装 hypothesis → 13 个测试模块收集失败(test_mcp_strict_workflow_*test_varga_bphstest_historical_event_backtest 等)。scripts/user_invocation_acceptance_check.py 因 PyJHora missing_dependency 输出 status: fail,对应测试红;requirements-reference-engines.txt 不在任何 workflow 的安装步骤里。这些不是代码 bug,但发布门要的是"一条命令本地可复现 CI 结论"。


决策记录(产品授权,2026-09-03)

  1. 产品已同意:每周提升一次 main;仓库小活交 coding agent;删除已合入的远端分支。
  2. 产品负责人 2026-09-03 拍板:默认岁差保持 Raman,并在用户设置里可选。 可选值 raman(默认)/ lahiri / kp / true_pushya,与 Python AYANAMSA_MODES 一致。PM 曾建议回 Lahiri(理由:公开来源与既有 benchmark 都按 Lahiri 校准;生产用户此前看到的是 Lahiri 盘),产品明确否决;因此本轮的原则改为:产品计算用用户设置(默认 Raman),参考集与外部对照各自显式锁定口径,任何地方不再依赖"默认值恰好是什么"。提升 main 后生产用户的 Moon nakshatra / 大运可能相对旧版变化,这是产品已知并接受的后果,CHANGELOG 必须写明并告诉用户可在设置里切回 Lahiri。
  3. 本任务书不改任何被哈希锁定的 skills/*/versions/**,也不改指向上游研究仓的 references/cross_project_contract/**references/upstream/**tests/test_import_yinduzhanxing.pytests/test_upstream_import_plan.py——那些地址是导入来源的真实记录。
  4. progress.md / findings.md / task_plan.md 的"发布关键文件必须已跟踪"检查保留,只改路径。

硬红线

  1. 任务 0 不得通过改期望值让测试变绿:test_fixture_dasha_timeline_rejects_workbuddy_regression_claims 的日期、tests/run_real_case_revalidation.py 的参考值、references/** 的 oracle 目标值一律不动;让它们变绿的唯一合法手段是显式传参口径--ayanamsa lahiri),并在三栏说明里写清"原来依赖默认值"。
  2. 不得在同一轮里改校正引擎的打分/阈值;DEFAULT_AYANAMSA_NAME 本轮不改(保持 raman)。
  3. scripts/jyotish_api_server.py 行数不得增长(tests/test_api_server_growth_contract.py);一致性修复是改字面量为常量,不是加逻辑。
  4. 分支删除只删任务 5 列出的已合入名单;4 条未合入分支不删;本地 worktree 正在使用的分支(codex/unified-loading-20260902codex/frontend-optimization-20260828codex/streaming-ux-20260901)远端可删、本地不动。
  5. 不改 .gitea/workflows/** 的触发条件;给发布门补依赖只允许改 requirements-dev.txt / requirements.txt 与 workflow 的 pip install 行。
  6. npm run lint 0 error、tsc --noEmit 通过、测试总数不低于开工基线;无 Docker 的失败清单与基线逐条比对。
  7. 不在脏工作树切分支;不自行提升 main

让步顺序:功能与测试不回归 > 发布门本地可复现 > 岁差一致性 > 地址/日志/分支整洁。


开工前置

git fetch origin --prune
git worktree add -b codex/repo-hygiene-20260903 ../.worktrees/repo-hygiene-20260903 origin/staging
# CI 同款依赖(本地复现发布门)
.venv/bin/python -m pip install -r requirements.txt -r requirements-dev.txt
.venv/bin/python -m pip show mcp | grep Version   # 必须 1.x

先读:AGENTS.md §2/§3/§5/§9、docs/research/pre_work_error_ledger.md(本轮碰引擎默认值与远端分支,§9 预检必跑)、scripts/ayanamsa_utils.py 全文、git show 80102459 --statscripts/run_quality_gate.py 的 profile 表。


任务分解

任务 0(P0,单独先推)· 岁差成为用户设置(默认 Raman),参考集显式锁口径,"算的"和"写的"一致

0.a 参考集与外部对照显式锁定口径(先做,这一步单独就能让发布门变绿)

  1. tests/run_real_case_revalidation.py:64jyotish_engine.py 调用显式加 --ayanamsa lahiri(参考值来自 Lahiri 口径的公开来源),报告 JSON 增加 reference_ayanamsa: "lahiri" 字段;scripts/local_accuracy_report.py 同理。
  2. tests/test_user_invocation_acceptance_contract.py::test_fixture_dasha_timeline_rejects_workbuddy_regression_claimsbase 命令显式加 --ayanamsa lahiri(三栏说明:原值=依赖默认、新值=显式 lahiri、原因=夹具日期是 Lahiri 口径);期望日期一字不改。
  3. VedAstro / oracle 对照:scripts/jyotish_api_server.py:2853:4017ayanamsa_policy 不再兜底字面量 'lahiri',改为该次请求实际使用的岁差名,让本地与 VedAstro 对照同口径;references/oracle/** 的目标值不动(它们各自的 ayanamsa 元数据字段就是口径)。
  4. 验收:tests/run_real_case_revalidation.pyvalid: truegated 66/66pass_rate ≥ 0.98;上述夹具测试通过;scripts/user_invocation_acceptance_check.pychecks.user_invocation_tests: true

0.b 标签与实际计算一致

  1. scripts/jyotish_api_server.py:7030'ayanamsa': 'lahiri' 改为实际值;:7086ayanamsa_display 从实际名派生(AYANAMSA_LABELS 或等价映射),不再兜底 'Raman'。所有回执(/api/consultation_workflow/api/chart、校正、报告证据包)必须带 ayanamsa 实际名,前端只显示回执,不得自己猜。
  2. 验收:grep -rn "'lahiri'\|\"lahiri\"\|'raman'\|\"raman\"" scripts/jyotish_api_server.py frontend/src --include=*.py --include=*.ts --include=*.tsx | grep -v test 只剩常量定义、标签映射与设置选项,没有散落的兜底字面量。

0.c 用户设置:账户与出生资料面板里可选岁差

  1. 数据:profilesayanamsa 列(Drizzle 迁移,frontend/db/migrations/text not null default 'raman',check 约束四个值)。这是本轮唯一的动表,npm run test:db 必须真跑(AGENTS §7.6)。
  2. 接口:/api/account 读写该字段;服务端校验只接受四个值;未登录/旧客户端不带字段时按 raman
  3. 界面:「账户与出生资料」面板加一个单选(Raman【默认】/ Lahiri / KP / True Pushya),每项一句话说明(文案先对 frontend/docs/VOICE.md),下方一行提示"切换只影响之后的新计算;已生成的报告和校正结果保持当时的口径"。frontend/DESIGN.md 同提交更新。
  4. 贯通:frontend/src/lib/global-birth-payloads.ts:49birth-time-journey-assessment.ts:28,4080102459 触及的其余前端文件(consult/route.tsbirth-time-journey-service.tspersonal-report-generation.tsconsultation-technique-audit.ts)不再硬编码,统一从一个导出 resolveAyanamsa(profile)(新建 frontend/src/lib/ayanamsa.ts,类型 "raman" | "lahiri" | "kp" | "true_pushya",默认常量 DEFAULT_AYANAMSA = "raman")取值;咨询、校正、报告、星盘库、每日星语全部把它传给 Python。
  5. 已有数据:校正案例与已生成报告记录创建时的岁差(若表里没有字段,本轮只在新写入的 JSON 载荷里带 ayanamsa,不追加第二个迁移);切换设置不重算历史。校正引擎(frontend/src/lib/rectification-agentic/v9/**scripts/active_rectification_*.py)里若有按 Raman 校准的阈值或 golden,本轮不动,只确认它们在 lahiri 下不会崩(跑一遍 tests/rectification-*.test.ts),异常写 BLOCKED。
  6. 验收:
  • 设置切到 Lahiri 后,用附录那张虚构盘(2000-01-01 12:00 UTC0/0)发一次咨询:回执 ayanamsa = lahiri、Moon nakshatra = Swati;切回 Ramanayanamsa = raman、Vishakha。技法审计表与星盘头显示的岁差与回执一致。
  • tsc 0 错、npm run lint 0 error、npm run test:db 通过、相关前端套件 fail=0page.tsx 行数不增长。
  • 产品负责人在 staging 部署后按上面两步实测一次。

0.d 记录

  1. CHANGELOG.md 新条目:默认岁差自 801024592026-08-20)起为 Raman,本轮补齐用户设置与四个可选值,说明升级后老用户可能看到 Moon nakshatra / 大运变化并可在设置切回 Lahiri。docs/BUG_HISTORY.md 新增 BUG(现象=公开案例复验 valid=false 与三处标签不一致、根因=参考集未锁口径 + 字面量兜底、修复=0.a/0.b、关联记录=无、复发自=无)。

任务 1(P0)· 发布门一条命令本地可复现

  1. 依赖:requirements-dev.txt 已有 hypothesis;确认 mcp>=1.0,<2requirements.txt 生效(本地 .venv 装错版本是环境问题,写进 PROGRESS 的"环境备忘"即可,不改 pin)。
  2. scripts/user_invocation_acceptance_check.pyPyJHora 缺失时 status 现为 fail。改法二选一并写明:(a) 在 workflow 安装 requirements-reference-engines.txt(注意 AGPL 隔离说明,只装在门禁 runner,不进镜像);(b) 让 missing_dependency 归入 partialtest_one_command_user_invocation_acceptance_check 的断言 report["status"] == "pass" 按三栏说明改为接受 partial,同时 external_adapter_status 仍必须在 {"pass","partial","complete"}。建议 (b):PyJHora 是外部参照引擎,缺席应降级不应失败。
  3. 用 CI 同款依赖跑 python -m pytest -q --maxfail=1(发布门原命令)与 .venv/bin/python scripts/run_quality_gate.py --profile release,把每一条红按"代码 bug / 环境 / 参考值过期"分类写进 PROGRESS,代码 bug 的修在本轮内,环境类给出复现命令,参考值过期的不改值、写 BLOCKED。起点数据见附录。
  4. 测试不得改写仓库文件:本地全量跑一遍后 git status 出现 12 个 docs/research/character_level_*_latest.* 与 2 个 references/oracle/*_2026_07_2x.json 被改写(scripts/character_level_inventory_manifest.py:27-30 等把"latest"报告直接写进仓库路径)。让这些脚本在测试里写 tmp_path,或测试用只读模式;验收标准是全量 pytest 后 git status --short 为空。
  5. 验收:release profile 本地退出 0PROGRESS 里有全量红名单处理表;docs/tasks/README.md 状态板"已合入 / 待核对"各行不受影响。

任务 2P1)· 注册表 experimental_variant

  1. tests/test_capability_evidence_pool.py 白名单加 experimental_variantentry_type)与 comparison_onlyevidence_role);scripts/capability_evidence_pool.pycomparison_only 计入 audit_only_entries 同等处理(不能影响结论),summary 增加 comparison_only_entries
  2. 加一条断言:所有 entry_type == "experimental_variant" 的条目 verification_level.prediction.rule 必须是 blockeduser_visibility 必须是 expert_audit
  3. 验收:该测试文件全绿;scripts/audit_capabilities.py --mode validatevalid=true, problem_count=0

任务 3P1)· 仓库地址

  1. 改:pyproject.toml 五个 URLHomepage/Repository/Changelog → https://git.copse.top/root/JyotishaBug Reports → https://git.copse.top/root/Jyotisha/issuesDocumentation → 仓内 README.md 的 Gitea 链接);.codex-plugin/plugin.json 四处;根 SKILL.md:4 description 里的 GitHub: 改为 Repo: https://git.copse.top/root/Jyotishascripts/skill_release_package.py:27scripts/skill_release_manifest.py:15skills/jyotish-engine-modules/SKILL.md:67
  2. tests/test_skill_release_package.py:59tests/test_skill_release_manifest.py:16 同步(三栏说明)。
  3. scripts/remote_repo_visibility_check.pyremote 不是 GitHub 时不再退回旧 slug,改为报告 provider: gitea 并用 git ls-remote 验证可达;tests/test_remote_repo_visibility_check.py 的 slug 解析用例不动,新增一条 Gitea remote 用例。
  4. 验收:grep -rn '732642856/yinduzhanxing' --include=*.py --include=*.toml --include=*.json --include=*.md . | grep -v 'references/\|skills/.*/versions/\|docs/\|progress.md\|findings.md\|tests/test_import_yinduzhanxing\|tests/test_upstream_import_plan\|tests/test_project_fragment_governance' 为空;python3 scripts/pre_work_check.py --remote-timeout 8 --command-timeout 45 不因 slug 误报 blocked。

任务 4P2)· 早期日志搬家

  1. git mv progress.md findings.md task_plan.md CHANGELOG_v6.2_to_v6.9.md docs/history/,新建 docs/history/README.md 一段说明("2026-06~08 的实现日志,不是运行说明")。
  2. scripts/run_quality_gate.py RELEASE_CRITICAL_UNTRACKED_PATHS 三个路径改为 docs/history/...;根 README.md 文档地图与 AGENTS.md §4 最后一行同步。
  3. 验收:run_quality_gate.py --profile release 的"关键文件已跟踪"检查通过;根目录 ls *.md 只剩 AGENTS.md BLOCKED.md CHANGELOG.md CLAUDE.md CONTEXT.md README.md SKILL.mdCOVERAGE_AUDIT_REPORT.md 在 .gitignore,不算)。

任务 5P2)· 远端分支清理

已完全合入 origin/staging 的 66 条,一次删除(先 git fetch origin --prune 再核对 git branch -r --merged origin/staging 与下表一致,多出或少了的写 PROGRESS):

codex/admin-account-reset codex/agent-voice-20260901 codex/agentic-consultation-runtime
codex/consultation-birth-accuracy-20260901 codex/fix-daily-starlanguage-guard-20260818
codex/fix-feature-flag-admin-runtime-policy-20260811 codex/fix-gitea-artifact-upload-20260805
codex/fix-gitea-manifest-auth-20260805 codex/fix-local-artifact-inputs-20260805
codex/fix-rectification-case-context-20260811 codex/fix-rectification-current-turn-binding-20260812
codex/fix-rectification-duplicate-collect-20260902 codex/fix-rectification-focus-baseline
codex/fix-rectification-free-settlement-20260811 codex/fix-rectification-history-hydration-20260812
codex/fix-rectification-home-new-session-20260812 codex/fix-rectification-session-model-20260811
codex/fix-rectification-turn-projection-20260812 codex/fix-report-scroll-product-admin-20260818
codex/fix-sidebar-contract-ci-20260820 codex/fix-staging-artifact-resolution-20260805
codex/fix-vendored-artifact-inputs-20260805 codex/frontend-optimization-20260828
codex/integrate-github-main-gitea-20260805 codex/internal-gitea-artifact-action-20260805
codex/pr1-skill-registry codex/pr2-final-response codex/pr3-rectification-v10
codex/pr4-rectification-event-contract-v2 codex/pr5-report-evidence-bundle-v2
codex/pr6-report-document-v2 codex/pr7-product-domain-registry codex/pr8-evals-observability
codex/pr8-local-gate-closure codex/production-selfhosted-migration
codex/rectification-activity-birth-context-20260812 codex/rectification-p0-p1-20260820
codex/rectification-provisional-adopt-20260901 codex/rectification-question-in-message-20260902
codex/rectification-same-turn-confirm-20260812 codex/rectification-tails-20260901
codex/remove-admin-step-up-20260816 codex/report-blocked-repairs-20260902
codex/report-writer-failure-20260902 codex/run-vendored-artifact-uploader-20260805
codex/staging-gate-repair-20260811 codex/staging-skill-style-present-20260820
codex/streaming-ux-20260901 codex/ui-optimize-staging-20260817 codex/unified-loading-20260902
codex/use-gitea-artifact-action-20260805 delivery/payment-package-epay
docs/close-staging-controller-incident docs/close-staging-release-acceptance
docs/correct-report-smoke docs/personal-report-staging-acceptance
docs/record-staging-env-owner-drift docs/record-staging-host-key-rotation
feat/one-way-skill-personal-report fix/staging-admin-verification-host
fix/staging-controller-fetch-timeout fix/staging-gate-attested-controller
fix/staging-gate-build-timeout fix/staging-gate-retry-and-admin-audit
fix/staging-public-verification-race fix/staging-ssh-secret-and-env-owner
revert/staging-from-main
git push origin --delete <上表>

未合入的 4 条不删,只登记:

分支 最后提交 领先 staging 处置
codex/rectification-ux-20260903 2026-09-03 5 进行中(已验收待合入),不动
codex/rectification-ux-20260902 2026-09-02 3 被 0903 版替代,等 0903 合入后由产品决定删除
codex/diagnose-rectification-request-20260827 2026-08-27 5 8 月诊断分支,产品决定
fix/staging-gate-checkout-retry 2026-08-06 1 已被后续门禁修复覆盖的可能性大,产品决定

验收:git ls-remote --heads origin | wc -l 从 71 降到 5mainstaging 加 3 条保留分支,若 0902 已删则 4)。


附录 · 2026-09-03 本地全量 pytest 起点数据

环境:同一台机器、同一 .venv(缺 hypothesismcp 为 2.1.1、无 PyJHora / Docker)。python -m pytest -q --continue-on-collection-errors tests

检出 FAILED 收集 ERROR
staging 8e214e29 89 13
生产 7b620c7a(只跑 staging 红的 54 个文件) 83

也就是说 89 条红里 83 条在生产提交上同样红,属于环境缺依赖或参考值/产物过期,不是这两周的回归;执行方分类时可直接从这 83 条的"环境 / 过期"两类起手,重点核对以下 6 条 staging 独有的红

测试 本地现象 初判
test_user_invocation_acceptance_contract.py::test_fixture_dasha_timeline_rejects_workbuddy_regression_claims Jupiter 段 2014-11-27 ≠ 期望 2016-09-20 夹具是 Lahiri 口径却跟着默认 Raman 跑(任务 0.a)
test_user_invocation_acceptance_contract.py::test_one_command_user_invocation_acceptance_check checks.user_invocation_tests: falsestatus: failexternal_adapter_status 已是 partial 同上,上一条的连带
test_skill_release_clean_trial.py::test_premium_skill_zip_runs_from_clean_directory 打包后的 acceptance check 同样 fail 同上,连带
test_local_accuracy_report.py2 条) scripts/local_accuracy_report.py 抛 SystemExit 大概率是公开案例复验 valid=false 传导,任务 0 完成后复跑;若仍红再单独查
test_dynamic_rectification_fact_priority.py::test_historical_event_priority_preserves_vimshottari_actor_difference assert 0.0 > 0(信息增益为 0 依赖 Vimshottari 边界,先在任务 0 之后复跑;仍红则归校正引擎,写 BLOCKED 交产品
test_minute_rectification_development.py::test_v3_development_result_stays_shadow_only assert 1 == 0 同上

13 个收集 ERROR 全部是 No module named 'hypothesis'mcp.server.fastmcpmcp 2.x),装对依赖即消失。

交付物

  • 任务 0 单独一次推送(含 CHANGELOG + BUG_HISTORY),推送后在 PROGRESS 写明 staging 部署 SHA。
  • docs/tasks/PROGRESS-repo-hygiene-20260903.md:每个任务的命令输出摘要、全量 pytest 红名单处理表、三栏说明、环境备忘。
  • docs/tasks/README.md 状态板:本任务书一行,并把"待开的任务书 · 仓库小活"那行改为指向本文件。
  • 做不了的写 BLOCKED.md,不写"通过"。