Files
Jyotisha/docs/tasks/PROGRESS-rectification-cross-midnight-20260920.md
T
jesse-uxandClaude Code aa46da1016 fix(rectification): use candidate dates for cross-midnight dasha scoring
Add date-isolated caches and regression coverage, align scoring identity, and freeze full research reruns while preserving historical artifacts. Record unresolved cache/receipt identity and end-to-end acceptance gaps for branch review only.

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-20 13:56:11 +08:00

138 lines
16 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.
# PROGRESS · 跨午夜候选 Dasha 日期修复(2026-09-20)
## 基线、授权与边界
- 用户要求执行远端 `dacd4044` 的任务;fetch 时远端已追加产品决策补充 `03cba4780a220b132cf4f06d22e14608aaf9ad3c`,本轮以该后代为基线。
- 任务:`TASK-rectification-cross-midnight-dasha-20260920.md`。产品决策 A/B/C 已放行:修复候选级日期、重新冻结重跑、通过 V9 `engine_version` 区分结果。
- 工作树 `.worktrees/rectification-cross-midnight-20260920`;分支 `codex/rectification-cross-midnight-20260920`。上一轮已提交的独立工作树只作基线读取与测试,不更改其源码。
- 开工核对 Bug 最大号为 980;本单使用 BUG-981。已与任务书会话确认其未修改相关生产文件、未占用编号。本会话各实现任务文件所有权分开。
- 不改打分权重、确认门、Skill 版本、V4 `INPUT_CONTRACT_VERSION`、数据库结构、workflow、依赖、DNS 或 main。
- 可选回执实现哈希增强不做;采用默认 `engine_version` 与既有后端 `ALGORITHM_VERSION` 同步 bump,保留原环境覆盖语义。线上环境是否覆盖另行验收,不借用凭据。
## 执行中纠正的任务书事实
任务书 §1.4 的 `BUG-3315` 实为历史文档行号,对应记录是 BUG-198;相关开窗记录另有 BUG-114 / BUG-353,不新增不存在的编号。候选枚举与时段映射回归仍在,未覆盖后来加入的日期辅助项。
T4 追踪发现:`v9EngineVersion()` 默认值主要用于 started/failed 回执;成功 compare / diagnostics 回执使用实际 `algorithmVersion`。`liveEngineScoringIdentityFromEnv()` 还会把非粗版本的环境覆盖视为算法身份,`cachedEngineScoreIsReusable()` 已有算法身份相等比较,`score-persist.ts` 在身份与输入相同时可直接复用旧分数。因而任务书“全仓只写不比”并不准确,只改默认串不足以落实产品 C,甚至可能继续使用错误的缓存分数。
最小实现选择:在本单允许的 `scoring_service.py` 将既有 `ALGORITHM_VERSION` 从 `rectification-v5-matrix-scoring-7` 提升为 `rectification-v5-matrix-scoring-8`,前端默认标记同步;复用既有失效逻辑,不新增按版本拒绝打开历史会话的门,不修改 Skill、V4 input contract、SQL 或旧回执。成功结果保留实际来源身份,不能把旧缓存强行重新标成新版。环境若覆盖旧算法身份,部署验收仍需核实;没有受控访问时列为缺口。
## 必读与预检
已读错误台账、分钟分辨率研究结论、前轮偏差报告、任务书和 BUG-098 / 427 / 428 / 621 / 978 / 979 / 980。旧 BUG-098 的跨午夜保护针对候选枚举,不足以覆盖后来加入的 transition-proximity 日期参数;BUG-427/428 的实现归属与曝光边界继续有效。
本机运行 `python scripts/pre_work_check.py --remote-timeout 8 --command-timeout 45`:实际 Python 3.11.7,有 pytest;无本工作树 `.venv`。远端 verified、碎片与适配器检查成功;focused tests 因既有 `test_preflight_fragment_scan_reports_authority_layers_and_risk_buckets` 的 `.workbuddy` 镜像路径断言失败。与前轮台账一致,不冒写预检全绿。
## 执行与验收结论
核心日期修复、重新冻结及完整重跑完成;T4 缓存/回执身份仍未闭环,因此整单未通过完整验收。产品随后要求“按分支推送,我远程 review”,本轮仅向独立分支 `codex/rectification-cross-midnight-20260920` 交付供评审,推送结果以远端 SHA 核对为准;不合入 staging,不部署,不以其他会话的 staging 部署证明本轮已发布。保留原测试基线 `03cba478`,不混入同期其他任务的提交。
| 项目 | 状态 | 证据/下一步 |
| --- | --- | --- |
| T1 修复前红测 | 通过 | 原实现 4 failed / 4 passed,包含跨年、闰日、一般午夜日期/缓存及真实引擎回归;同日 golden 原来即通过 |
| T2 最小生产修复 | 核心日期修复通过;部署未验收 | 19 个同日窗口共 2299 候选分数与矩阵字节相同;真实跨日全 121 候选等于日期正确独立计算;性能中位 -0.87%;独立生产选择性测试 4 项通过 |
| T3 冻结及重跑 | 完成,独立校验通过 | 900 组合与 20 例均完整重跑,旧新逐例变化均为 0;独立复算真实源码身份、历史字节、汇总与 Markdown 45 格全部一致 |
| T4 回执版本 | 部分实现,整体验收未通过 | 默认与后端身份同步;minute正常版本探测失效旧cache、新Case成功回执/历史打开定向通过;旧block_scan缓存仍绕过版本检查,BUG-984另立补单 |
| T5 记录、独立验收 | 本地记录与独立复核完成 | BUG-981~984、BLOCKED、CHANGELOG、测试清单与验收补单已记录;Python 广域 300 项/4 个基线失败,新增失败 0;T4/构建/部署缺口不写通过 |
所有报告保留已曝光数据边界,官方独立有效试次仍为 0;修复后数字是否变化以逐例复算为准,不能从实现改动推断数值必变。
## 红测与同窗对照证据
修复前输出(去掉所有案例参数,只保留测试标识):
```text
FFF....F [100%]
FAILED test_every_candidate_uses_own_date_and_caches_do_not_cross_dates[2000-01-01]
FAILED test_every_candidate_uses_own_date_and_caches_do_not_cross_dates[2000-02-29]
FAILED test_every_candidate_uses_own_date_and_caches_do_not_cross_dates[2000-12-31]
FAILED test_real_cross_midnight_all_candidates_match_independent_dated_calculation
4 failed, 4 passed in 7.32s
```
日期为纯合成测试日期,不是案例出生资料。同日真实引擎 golden 修复前即绿。
性能与分数比较口径:公开已曝光 v3,raman / mean,半径 ±60、步长 1;20 个窗口各 121 候选。历史 12 文件打分身份 `b15d9ea15227cd58` 不变;新扩展生产身份 `7fffd1db612af1f2`。性能从原生静态上下文到矩阵及得分,5 对交替执行,不能与任务书另一环境的 8.6 秒直接比。
| 项 | 基线 | 修复后 |
| --- | --- | --- |
| 5 次耗时(秒) | 27.479 / 21.570 / 20.713 / 21.362 / 21.438 | 21.151 / 21.252 / 20.739 / 21.429 / 21.526 |
| 耗时中位(秒) | 21.438497 | 21.252369(-0.8682%) |
| 非跨日分数字节比较 | 19 个窗口,2299 候选 | 全部相同,矩阵字节亦同 |
| 真实跨日窗口对日期正确独算 | 121 候选中 16 个跨日候选不同,同日 0 不同 | 全 rows / matrix 相同,差异 0 |
| 该跨日窗口最大绝对分差 | 0.0267 | 0 |
这里是该公开样本的实测,不把算术上界或这个幅度推广到所有真实会话。可提交脱敏证据见 `docs/testing/rectification-cross-midnight-scoring-evidence-20260920.json`。
## 独立验收:明确未通过与另行问题
1. **BUG-984 / T4 未完整通过**:独立 TS 探针在无环境覆盖的 `block_scan` 历史缓存上实测 `cached:true`、旧算法 -7、HTTP 调用 0;真实工具路径写 started -8 / completed -7。SQL `max(engine_version)` 的源码核验显示聚合可能取 -8,不能据此证明重新评分。未真跑 SQL,因此数据库部分只报源码证据。补单 `TASK-rectification-cross-midnight-dasha-fix-20260920.md` 待批准,不擅改缓存政策/迁移。
2. **BUG-982 / 既有聚类跨度**:纯虚构三分钟跨午夜簇沿 `build_candidate_decisions()` 输出 1440 分钟宽度;旧 BUG-624/639 的同日范围保护仍在,但不覆盖该跨日调用链。没有顺改候选淘汰或范围策略。
3. **BUG-983 / 既有凌晨锚点**:前端凌晨申报的跨日钟点窗仍配原申报日期,生产枚举将起点绑当天、中心移到次日。helper 本轮只修与 `candidate_at` 一致,不能声称上游候选日期也已正确。
因此本轮可以分别验收“候选级日期修复”与“指定条件下版本身份”,不能说所有跨午夜路径端到端已闭环。BUG-981 未有部署证据前仍 investigating;BUG-982~984均 investigating,不冒标 resolved。
## 重新冻结与完整重跑
两份正式 freeze 均先于各自评分开始;评分结束再次核对真实当前文件身份。旧 8 份产物归档逐字节保留并有 manifest,原路径的两份旧 JSON 与旧 freeze 也未改;准备阶段冻结/试跑另标 superseded,不充当最终证据。
| 项目 | 结果 |
| --- | --- |
| 历史 12 文件打分身份 | `b15d9ea15227cd58`(不变) |
| 新扩展生产 18 文件身份 | `7fffd1db612af1f2` |
| 最终研究 7 文件身份 | `2931d4661bf53dde` |
| 申报偏差重跑 | 900/900 组合完成、45 格、排除 0;旧新逐例所有保存字段 0 变化,耗时 399.902 秒 |
| 固定口径 shadow 重跑 | 20/20 例完成、排除 0;逐例 0 变化,耗时 3.158 秒 |
| T3 定向四文件 | 52/52 通过(包含 quick 桥接重复收集,不能算 52 个独立新增用例) |
数字未变不等于生产缺陷不存在:旧 T1 最终版已有离线按日期分组适配,新版矩阵走修复后的原生单调用;T2 的 shadow fact-ranker 本来按候选日期构事实,不走此次 helper。两者仍非完整生产问答/交付回放,也不是新的独立盲测。
独立只读审查已从真实文件复算 12/18/7 文件集及逐文件 SHA,核对历史 8 份归档与 Git 基线原字节、3 份 superseded 准备产物,以及两份正式冻结/报告/契约。900 组合完整、每格分母 20,summary 独立算术复算一致,Markdown 全部 45 格逐格吻合;20 例汇总与六项指标表亦同。独立审查另执行生产轻量 4 项、T3 选择性 5 项通过,未重复 900 评分;不把执行方的 52/52 冒称独立复跑。上表 399.902 秒为执行方外层耗时,JSON 内部 replay 区间为 399.819 秒,计时边界不同。
T2 数值口径:公开已曝光 v3、raman/mean、±10、步长 1、12文件打分身份 `b15d9ea15227cd58`,扩展生产上下文身份 `7fffd1db612af1f2`。竞争 top-1/top-3 0.45/0.50,哈希头名平均误差 6.45 分钟,三项仍未过原门槛;误确认 0、稀疏证据拒绝 1、确认覆盖 0;实际哈希头名命中 0.05。不得拿含并列 top-1 当唯一头名命中率,不因重新冻结增加官方盲测试次。
## 前端与确认门验收
基线测试工作树为已提交的 `932f2fff`;与开工 `03cba478` 之间只有两次任务文档提交,业务与测试代码相同。前端对照实际核对 1500 文件;没有安装/升级依赖或修改旧源码。以下最终轮覆盖报告路径更新,早期候选 77 失败只是阶段数据,不替代最终结果。
| 检查 | 基线 | 最终候选 |
| --- | --- | --- |
| TypeScript | 0 error | 0 error |
| lint | 0 error / 120 warning | 0 error / 120 warning |
| 全量前端 | 3486 总 / 3407 pass / 79 fail | 3493 总 / 3414 pass / 79 fail |
| 新增版本与确认门定向 | — | 14/14 通过 |
| BUG-621 + convergence + 新增版本 | 52 总 / 48 pass / 4 fail | 59 总 / 55 pass / 4 fail |
| build | 外部 node_modules junction 超出 Turbopack filesystem root | 同原因失败;Static/gzip 未验收 |
全量 79 个失败标题与基线集合完全一致,新增失败 0;BUG-621 组合的 4 个失败标题也完全一致,为 Windows symlink EPERM。真实历史绑定 Skill 打开用例通过,但不是线上登录/DB E2E。Docker可用,部分全量失败涉及网络地址池/环境,不能写成无Docker。详见 `docs/testing/rectification-cross-midnight-frontend-results-20260920.json`。
主会话独立运行新增日期回归、桥接与隐私守卫共 80 项通过;17 个受保护文件(12冻结评分文件及确认门、历史枚举/请求实现、主API)与基线逐字节相同。实际 `holdout_passed()` 仍 False,runtime 六键值及类型全部相同。最终文档阶段再跑真实冻结身份、确认门及三组隐私守卫,86 passed / 0 failed(13.17 秒);14 份本轮 JSON 解析成功,`git diff --check` 通过。
## Python 广域回归收尾
基线三个校正 glob 共 284 项,280 passed / 4 failed。当前首轮共 300 项,294 passed / 6 failed;原四项失败标识及实际断言值均未改变,新增两项为版本身份相关断言:`test_score_candidates_matches_baseline_golden` 的决策代表候选 ID 不同,以及 `test_holdout_gate_keeps_proportional_default` 仍要求旧算法 -7。已保留该轮失败证据,不把它算作通过。真实引擎同进程旧/新身份 A/B 已确认仅两项身份变化,精确迁移后主会话核对所有其他 golden 叶与基线相同;未整份重写 golden、未改变分数或比较器。原进程出现的三个静态特征 hash 差异在另外两个新进程复测消失,旧身份独立复测与旧 golden 全字段相等,未覆盖这些历史 hash。修正后三文件定向(memoization、relative-support、freshness)25 passed / 0 failed(2.12 秒);两个 final.freeze 所绑定的 12/18/7 文件集合均不含这三项测试/快照文件,真实字节身份验证仍绿。主会话独立复跑上述 25 项亦全部通过(2.04 秒)。广域全套另起日志重跑,不覆盖首轮失败证据,最终 4 failed / 296 passed / 300 total(609.52 秒、exit 1);四个失败标识与实际断言值均同基线,新增失败 0,收集数增加 16(含桥接),但不宣称全套全绿。
| Python 广域失败项 | 基线与最终对照 |
| --- | --- |
| `test_long_real_conversation_reaches_vedastro_after_local_range_is_narrow` | 既有 winning_segment 不符,实际/期望字段值未变 |
| `test_selector_changes_do_not_change_legacy_or_v5_score_bytes` | 既有 V5 分数 hash 不符,最终实际仍 `e20199f79f4283da`,未改断言 |
| `test_v3_development_result_stays_shadow_only` | 两侧均 `v3_improved_case_count` 实际 1 / 期望 0 |
| `test_frozen_implementation_hash_matches_manifest` | 既有历史 v2 hash 不符,最终实际仍 `f642651ef4dec9b5`,未刷新历史冻结 |
脱敏计数、失败标识与中间轮证据见 `docs/testing/rectification-cross-midnight-20260920-results.json`。本机 quick 仍因缺 mcp 阻断;前端 build / Static / gzip、受控登录态、数据库回执聚合与部署验收仍缺,按补验清单处理。
## 既有断言调整三栏
| 原值 / 原断言 | 新值 / 新断言 | 原因 |
| --- | --- | --- |
| 研究跨日测试要求原生生产 rows 不等于日期正确结果 | 要求原生 rows 等于独立日期正确结果,并锁定单矩阵调用 | 原断言描述旧缺陷;本单修复后新增正确性保障,不再锁住已知错误 |
| 当前研究/确认测试引用旧 JSON / freeze | 引用新 cross_midnight JSON / final.freeze;旧文件保留字节验证 | 原报告留作历史,新实现重新预冻结;门禁值与独立性断言不变 |
| 当前树身份只包含历史 12 文件 | 保留原断言,新增 18 文件生产与 7 文件研究身份及漂移拒绝 | 本次修复在 12 文件之外,不能靠旧hash没变宣称当前身份一致 |
| 前端 currentTreeRerun 来源为旧同名 JSON | 新 `sealed_holdout_rerun_cross_midnight_2026_09_20.json` | 只迁来源;所有确认行为断言保留 |
| relative-support 测试要求算法身份 `rectification-v5-matrix-scoring-7` | 要求 `rectification-v5-matrix-scoring-8` | 本单已授权同步算法身份;同一测试的 proportional 默认与 policy-v3 断言保留 |
| memoization golden 代表候选 UUID `85ca5490-07ab-54b7-acf0-59385f705015`、snapshot 算法 -7 | 真实引擎输出 UUID `e8c11277-022c-519c-95e9-6a0a04e8bf23`、snapshot 算法 -8 | 版本身份参与确定性 UUID;同进程旧/新身份 A/B 仅这两叶变化。精确更新两叶,不整份刷新;主会话独立逐叶核对所有其他值与 Git 基线相同,数值、历史特征 hash、比较器均保留 |
## 报告保存与权限边界
原两份 JSON 的 shell 覆盖被拒后,没有换执行者覆盖它们;改用独占新建的正式报告 `reported_offset_cross_midnight_2026_09_20.json` 与 `sealed_holdout_rerun_cross_midnight_2026_09_20.json`。旧 JSON / 旧 freeze 原字节保留;准备阶段产物与最终身份分开,修改 evaluator 路径后重新冻结再重跑,不拿之前的冻结追认新脚本。当前契约与测试读取新正式路径,原数字留作历史,不因新实现自动判旧数字算错。