research(rectification): scoring-method scaffold — LR weights, absence, precision follow-up pipelines on v4, verdicts pending v5 (BUG-1091)

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017eEAG8HD3mm8gsKXgk8uU8
This commit is contained in:
Jesse_Chen
2026-09-29 19:06:45 +08:00
co-authored by Claude Fable 5.1
parent 5f84637ea9
commit abf2ad6aea
12 changed files with 8092 additions and 1 deletions
@@ -0,0 +1,66 @@
# PROGRESS · 生时校正打分方法研究:似然比权重 / 缺席证据 / 精度追问(脚手架阶段,2026-09-29)
- 任务书:`docs/tasks/TASK-rectification-scoring-research-20260929.md`
- 执行:Claude(直接执行模式,fork 子代理),分支 `codex/rectification-scoring-research-20260929`,基线 `origin/staging` @ `6e393780`(任务书写作时 `5febb111`,其间只有文档提交)。**未推送。**
- 研究报告:`docs/research/rectification_scoring_research_2026_09_29.md` + `scoring_research_{lr,absence,precision_followup}_2026_09_29.json`
- 本轮范围(按调度方指令):在 v4 上完成 R-0 脚手架并把 R-A / R-B / R-C 流水线跑通;**所有判定字段写 `pending_v5`**,v4 数字只作调试参考。v5 交付后在 v5 上跑判定(复跑命令见研究报告末尾)。
## 开工
- `git fetch origin --prune` → worktree `.worktrees/rectification-scoring-research-20260929` 基于 `origin/staging`;任何 git 操作前 `git status -sb` 核对分支。
- 先读:定论页(含 §7 勘误)、`rectification_offline_research_2026_09_26.md`、`rectification_typed_event_scoring_2026_09_29.md`、ERR-110 / ERR-111。
- 环境:本机没有 `.venv`(所有 worktree 的 `.venv` 软链都指向不存在的 `/workspace/Jyotisha/.venv`),全部用系统 `python3` 3.13.5(swisseph 9.1.1、pytest、timezonefinder 齐)。快速门的前端步需要 Node 22:`frontend/node_modules` 软链到主检出,`npm` 用 `/exec-daemon/node` + `/exec-daemon/lib/node_modules/npm` 的 shim(系统 `node` 是 20.19,`/usr/bin/npm` 跑的 `tsx` 不在 PATH)。`PYTHONHASHSEED=0`(ERR-111)。
- 另一子代理并行做 v5 扩集(`.worktrees/rectification-holdout-expansion-20260929`),未触碰。
## 交付物
| 文件 | 内容 |
| --- | --- |
| `scripts/research/scoring_research_lib.py` | R-0:特征记录 provider(线上同源 evidence + 额外观察)、逐分对账、特征矩阵、似然比估计(α = 1)、案例级 bootstrap、加权 provider、leave-one-case-out、缩放答案、Platt 温度、缺席年 / 精度升降 / 月份平移辅助 |
| `scripts/research/scoring_research.py` | R-A / R-B / R-C 流水线;`--limit / --radii / --parts / --fast / --cache-dir / --holdout / --dataset-label / --out-suffix` |
| `tests/test_scoring_research.py` | 10 条:纯函数 9 条 + v4 公开案例 ±10 对账 0 差 1 条 |
| `docs/research/rectification_scoring_research_2026_09_29.md` | 报告(结构按任务书 R-D;结论栏全部 `pending_v5`;复跑命令) |
| `docs/research/scoring_research_*_2026_09_29.json` | 三份结果(`dataset: v4, verdict: pending_v5`) |
| `docs/BUG_HISTORY.md` | BUG-1091 `investigating`(开工核对最大号 1089;1090 由扩集单占用,未冲突) |
| `docs/research/ACTIVE_FRONTS.md`、定论页 §9、`docs/tasks/README.md` | 索引与状态板 |
生产代码、`sealed_holdout_rerun.py::PRODUCTION_FILES` 的 10 个冻结文件、任何常数:**零改动**(`git status` 只有上表文件)。
## R-0 · 对账(任务书硬红线 4)
- 研究计分器 vs 线上 `score_candidates`(经 `build_event_contribution_matrix` 同一条矩阵链):**20 例 × 3 档 = 60 个 case-radius,分数差 0、规则 id 差 0**(`reconciliation.unreconciled = 0`,三份 JSON 均记录)。
- 做法:provider 用 `precision_gate_lib.score_event_with_policy`(V0)+ 线上 `_controlled_transit_rules`(带缓存)/ `_ashtakavarga_auxiliary` / `_shadbala_verified_components_auxiliary`(取 context 里线上算好的结果),返回与 `_candidate_row` 相同的 evidence;额外观察只进 `FeatureStore`,不进 rule_ids / points,所以矩阵、`event_kind` 系数、`technique_layers`、出题都与线上一致。
- 特征 42 个:线上规则 25 + 额外观察 17(KP 宫头子主 / 星主 × MD/AD/PD、KP 上升子主、D60 × MD/AD/PD、Pranapada / Hora / Ghati / Bhava lagna 落领域宫)。特征值 = 该规则在该事件采样日期上命中的比例。真值标签 = 候选属于真值所在签名簇。
- 留一法按**案例**留(`loo_folds`),`scale` 与 `temperature` 也只从训练折估。
## R-A / R-B / R-C · 流水线状态
| 项 | 状态 | v4 调试参考(`raw` 口径,留一法) | 判定 |
| --- | --- | --- | --- |
| R-A A1 / A2 / A3 | 跑通(留一法 + 全集、六题回放、引擎头名、校准曲线、稳健性四项、LR 表 + 案例级 bootstrap 区间) | 头名 ±10 0.70 / 0.75 / 0.80(基线 0.80);±30 0.55 / 0.60 / 0.65(0.55);±60 0.45 / 0.55 / 0.50(0.40)。真值在区间除 ±60 A3 0.95 外全 1.00。`percent` 口径 softmax 后验过自信,挤出 3–5 例 | `pending_v5` |
| R-B 缺席 @0.5 / 1.0 / 2.0 分 | 跑通(含漏说 1–2 件 × 5 次) | 2.0 分(=卡片)把覆盖压到 0.85 / 0.70 / 0.40;0.5 / 1.0 分覆盖 1.00 但头名一律降 | `pending_v5`(v4 信号为负) |
| R-C C1 / C2 × prior / probe / both | 跑通 | 可追问件数每例均值 0.20 / 0.45 / 0.70;±30 上 C1_prior 7 例头名 0.71 | `pending_v5`(样本太少) |
各特征在 v4 上的 LR 与「LR≈1」名单在报告 R-A 第 3 条与 JSON `radii.*.lr_table` / `noise_features`:**42 个特征里 31 / 36 / 38 个(±10 / ±30 / ±60)的 5–95% 区间跨 0**。
## 复跑与确定性(任务书硬红线 5)
- `PYTHONHASHSEED=0 python3 scripts/research/scoring_research.py --cache-dir <scratch>` 连跑两次(758 s / 748 s,静态 context 走磁盘缓存),三份 JSON `cmp` **逐字节一致**;`--out-suffix rerun` 的副本比对后删除,不入库。
- JSON 不写耗时字段,`sort_keys=True`;随机(漏说抽样、月份平移、答错抽样、bootstrap)全部按 `f"{SEED}:{case_id}:{radius}:…"` 种子。
## 快速门
- 开工基线(`origin/staging` @ `6e393780`,未改任何文件)与改后各跑一次 `python3 scripts/run_quality_gate.py --profile quick`(PATH 带 Node 22 shim):
- Python:**1001 passed, 1 skipped** 两次相同(改后含新增的 10 条 `test_scoring_research.py`——门禁的 pytest 集合按清单收集,新文件不在清单里,计数没变;定向 `python3 -m pytest tests/test_scoring_research.py -q` 10 passed)。
- 前端 `npm test`:基线 4357 / pass 4301 / fail 25;改后 4357 / pass **4302** / fail **24**、cancelled 0。失败清单逐条比对:改后 24 条是基线 25 条的子集(少的一条 `D3 · the first stage line shows on send…` 是基线那次偶发红、改后绿,前端零改动);24 条全是需要 Docker / PostgreSQL / 部署环境的套件(Better Auth / billing / migration / staging sync 等),与 09-29 上一单验收记录的 24 条环境失败一致。
- 门禁整体 exit 1 = 该 24 条环境失败所致,基线同样 exit 1;**无新增失败**。
- 隐私:`tests/test_repo_privacy_markers.py` 在快速门 Python 步内通过(1001 passed 含之)。
## 缺口与说明
- **判定未做**:按任务书,R-A / R-B / R-C 的有无收益只能在 v5 上判;本轮 JSON 的 `debug_verdict_v4` 只是 `gate_verdict` 的机械输出,不作结论。
- R-A 的 `percent` 口径需要先解决后验标定(单温度 Platt 不够,校准曲线高桶过自信);v5 上若仍过自信,考虑按训练折做等分位标定或直接用 `raw` 口径(缩放到线上极差)。
- 六道题由线上矩阵出一次、各方案共用(隔离先验的影响);若某方案在 v5 上过门,实现前还应按方案矩阵重新出题再测一次。
- 大运边界邻近项(`merge_transition_proximity`)按线上原样附加、未重加权。
- R-B 的缺席年在 v4 上不可靠(传记摘录不是完整时间线);这条限制在真人口述上同样存在,报告已写明。
- 未做:R-C 的产品层实现、任何实现单;`CHANGELOG.md` 无用户可见变化,未改。
+1 -1
View File
@@ -256,7 +256,7 @@
| `TASK-mobile-chart-and-confirmed-edit-20260929.md` | `PROGRESS-mobile-chart-confirmed-edit-20260929.md` | **手机星盘 + 确认时间可改 + 天空定格**:iPhone 星盘被宽表撑出屏幕(BUG-1083);confirmed 状态改声明字段也重置排盘时间(推翻 BUG-264 约定);「那一刻的天空」改为重放汇聚→定格→右上角分享;去掉报告星图封面 | 已验收(Claude 2026-09-29),已推 staging | BUG-1083 |
| `TASK-rectification-futile-collect-stop-20260929.md` | `PROGRESS-rectification-futile-collect-stop-20260929.md` | **生时校正停掉无效补经历循环(止血)**:打字经历不收窄(BUG-560 后果),流程却一路索要,真机 22 件整窗不动;采集只为开闸、门开后只问点选卡问完即出卡;交付正文去吻合率;多段时旁白误报「范围没变」;交付轮带采集题 | 已验收(Claude 2026-09-29 合并验收:全量前端 4302/24 与基线同 24 条环境失败、tsc 0、lint 0 error、`/` Static、gzip +0.16%、快速门 pytest 1001 passed、两份回放复跑一致),待部署核对 | BUG-1084~1087 |
| `TASK-rectification-holdout-expansion-20260929.md` | — | **开放评价集扩到 ≥60 例(v5)**:所有打分判定都在 20 例上做,1 例 = 5pp,KP / 精度闸 / V1n 的 no_benefit 都只差 1–3 例。只用 Rodden AA 公开名人,事件人工核对出处,分层(年代 / 纬度 / 南半球 / 跨午夜 / UTC+8),v4 不动;基线成绩单 v4 子集须与已发布数字逐格一致。研究单的判定以 v5 为准 | 待领取 | — |
| `TASK-rectification-scoring-research-20260929.md` | — | **打分方法研究(离线)**:R-A 似然比校准权重(leave-one-case-out,KP / Pranapada / D60 作为特征由数据定权重、允许负权重)、R-B 缺席证据(口述时间线覆盖时段内的空白年扣分,必测漏说稳健性)、R-C 精度追问可行性(对已说事件追问月份,算在定向追问 2 条额度内)。判定必须在 v5 上做;有收益才立实现单并按 ERR-110 重冻结 | 待领取(脚手架可先在 v4 上开发) | — |
| `TASK-rectification-scoring-research-20260929.md` | `PROGRESS-rectification-scoring-research-20260929.md` | **打分方法研究(离线)**:R-A 似然比校准权重(leave-one-case-out,KP / Pranapada / D60 作为特征由数据定权重、允许负权重)、R-B 缺席证据(口述时间线覆盖时段内的空白年扣分,必测漏说稳健性)、R-C 精度追问可行性(对已说事件追问月份,算在定向追问 2 条额度内)。判定必须在 v5 上做;有收益才立实现单并按 ERR-110 重冻结 | 已实现待验收(Claude fork 2026-09-29:R-0 脚手架 + R-A / R-B / R-C 流水线在 v4 上跑通,对账 0 差,判定全部 `pending_v5`;生产代码零改动) | 分支 `codex/rectification-scoring-research-20260929`(BUG-1091 investigating) |
| `TASK-rectification-typed-event-scoring-research-20260929.md` | `PROGRESS-rectification-typed-event-research-20260929.md` | **打字经历按选择题规则计分(离线研究,不上线)**:计分通道不对称 + 已入账年份挡题;R0 学业质量题措辞 / 年精度显示成 1 月(冻结文件,需重新冻结) | 已验收(Claude 2026-09-29 合并验收:全量前端 4302/24 与基线同 24 条环境失败、tsc 0、lint 0 error、`/` Static、gzip +0.16%、快速门 pytest 1001 passed、两份回放复跑一致),待部署核对 | BUG-1088、1089 |
| `TASK-report-reader-polish-20260929.md` | `PROGRESS-report-reader-polish-20260929.md` | **报告页打磨**:生成入口挪进页面主体(删标题栏按钮)、详情页到底部按钮(懒渲染一次到底)、导出按钮带文字、目录一级/二级分层、去掉「字段」与 RL/NL 缩写表头、状态列同义重复去重、报告表格淡底色、分块导出显示真实文件大小 | Claude 直接执行并自验(tsc 0、lint 0 error、全量 fail 与基线同 24 条、`/` Static、gzip +7 B、快速门 Python 1000 passed),已推 staging,真机欠 | BUG-1092~1094 |
| `TASK-report-english-edition-20260929.md` | — | **报告中英两版**:同一次引擎计算渲染 zh/en 两遍(不用模型翻译),瑜伽库 406 条补英文、模板与前端表头英文化;中文逐字节不变、英文零汉字、两版数字序列一致;阅读页 `?lang=en` 切换,导出当前语言 + 「问 AI 建议导出英文版」提示;旧报告不补英文 | 待领取(依赖 reader-polish 合入) | — |