Resolve BUG-985 using independent third-environment review recorded in 0ca3871d. Retain staging's complete BUG-984 task and approved read-only policy.
Co-Authored-By: Claude Code <noreply@anthropic.com>
11 KiB
PROGRESS · 跨午夜门禁浮点断言修复(2026-09-20)
2026-09-20 独立 review 后交付追加
产品已提供第三套独立 Linux/Python 3.13 环境复验并允许合入,证据在 staging 0ca3871d 的任务索引:定向 18 项通过,回退同日 3 绿/跨午夜相关 4 红,校正 glob 200 → 216 全绿。BUG-985 改 resolved,旧双机缺口解除;下文保留原执行时历史。同步 a3577ce2 时缓存补单按产品要求完整取 staging 版(已吸收原分支六行),不丢策略 b 授权。此次仅交付已 review 通过的原核心修复与测试修复,BUG-984 随后另树执行,不宣称生产端到端完成。
基线、范围与交付
- 执行单:
TASK-rectification-cross-midnight-gate-fix-20260920.md(F1–F4)。用户要求同步代码执行该单,不扩大到 BUG-984 缓存实施。 - fetch 后远端
origin/staging = 1b646659e7c0dc07051b00d7e5c48633dee8498c;按单从aa46da1016ffda65e4224af444a23710e084474a建独立工作树codex/rectification-cross-midnight-gate-fix-20260920,再合并最新 staging 得到验证基线777bd53d。仅四份文档有冲突,保留双方记录及最新 review 结论;没有覆盖主检出的未跟踪文件,没有 stash,也没有重写别的分支。 - BUG 编号核对:远端 staging 最大 980,原实现最大 984;本轮使用 985。
- 本轮仅改两个 Python 测试文件及任务/验收记录;相对
777bd53d,scripts/、前端、数据库、Skill、历史 golden、冻结报告与打分常数均不改。同步提交带入的其他前端改动来自已在 staging 的提交,不是本单改造。 - 尚未推送 staging、未部署;BUG-981 端到端仍受 BUG-984 阻塞。不能用本单测试结果宣布生产跨午夜问题全部解决。
F1 · 同进程新旧路径逐位对照
- 保留原测试名和三个 ordinal,每例仍覆盖 121 分钟。
- A 使用真实引擎正常 contexts;B 复用同一批 contexts,只在
scoring_service.merge_transition_proximity调用边界去掉candidate_at,交给生产 helper 既有 legacy 回退路径。主事件引擎本身需要该字段,不能在主矩阵入口直接删除。 - 检查候选完整时间序列与窗口一致、所有候选日期等于请求日期、legacy 边界被调用且收到 121 项。最终分数及贡献矩阵均做 canonical JSON 字节严格相等,不使用容差或硬编码浮点哈希。
- 既有防复发核查:BUG-733 的 memoization docstring、同进程四层缓存差分和分档 golden 比较仍在;BUG-712 的坐标量化及缺 golden 失败测试仍在。此次是 BUG-733 同形复发,原规则只约束既有测试,没有阻止新文件引入绝对哈希。
既有断言变更三栏
| 原值 / 方式 | 新值 / 方式 | 原因 |
|---|---|---|
| 三个 ordinal 各等于某台机器预先生成的分数 SHA-256 | 同一进程 A 新路径与 B 生产 legacy 路径,121 个分数 canonical 字节严格相同;另加整份贡献矩阵字节相同 | 要守的是“同日新旧不变性”,不是跨机器浮点字节一致;没有加容差、skip 或删除场景 |
| 窗口内只有一个日期 | 该日期集合恰等于请求 birth_date,且真实 contexts 时间序列等于窗口枚举 |
防止单日但锚点错误时 A/B 无意义 |
F2 · 快速门桥接
保留 re-export 并在文件顶部说明用途与重复计数:单独运行源文件或 test_rectification_*.py 中的 bridge,各为 9 项;两者同时选择为 18 项,但只有 9 个独立场景。未移除 quick glob 的覆盖,也不把重复项记成新增测试。
F3 · 时段扫描调用链与 BUG-984 定级
确认可达,因此 BUG-984 是 BUG-981 端到端验收阻塞项。 限定为证据未变且尚未触发三轮转分钟的历史跨午夜时段缓存命中;新建、无缓存或证据改变会进入已修路径。未修改缓存策略或 SQL。
| 层 | 符号及基线行号 | 证据 |
|---|---|---|
| 前端分支 | frontend/src/lib/rectification-agentic/v9/score-persist.ts:154,177–192,scoreAndPersistCurrentEvidence |
旧缓存只比较证据指纹即可返回;未命中调 runV9BlockScan;版本探测在分钟分支 266 行 |
| HTTP 客户端 | frontend/src/lib/rectification-agentic/v9/engine-client.ts:1021–1032,685–720 |
POST /api/rectification/v5/block_scan,携带日期、时间窗、事件和步长 |
| API 注册/入口 | scripts/jyotish_api_server.py:3562–3563,9100–9105 |
_compute_rectification_v5_block_scan 规范化后调用服务 |
| 时段扫描 | scripts/rectification/api_service.py:449–461,467–508 |
block_scan 调 score_candidates,段支持率消费其候选分数 |
| 评分 | scripts/rectification/api_service.py:211–214 |
调 build_event_contribution_matrix 和 score_from_matrix |
| 矩阵 | scripts/rectification/scoring_service.py:237–250,295–303 |
生成真实 contexts,并调 merge_transition_proximity |
| 日期来源/应用 | scripts/active_rectification_event_engine.py:90–103,593,608–614;scripts/rectification/dasha_transition_proximity.py:155–182 |
跨日枚举保留 candidate_at,已修 helper 从它取日期用于计算及缓存键 |
窗口核对:declared-birth-window.ts:19–35,131–145、search-window.ts:16,38–60,193–206、case-service.ts:133–172。
| 无申报钟点的路径 | 窗口 | exclusive span | 阶段 | 本身跨日期 |
|---|---|---|---|---|
| late_night | 23:00–03:59 | 299 分钟 | block_scan | 是 |
| unknown | 00:00–23:59 | 1439 分钟 | block_scan | 否 |
unknown 首轮的 late_night 分组只筛同日钟点,不把候选移到次日(api_service.py:416–431,476–480);后续选中跨午夜窗再重算才进入跨日触发范围。原修复单把两者均称作容易跨午夜的论据不够精确,本轮按源码明确此边界。
分钟防线仍在 engine-client.ts:425–454,既有回归 rectification-engine-convergence.test.ts:94–124、rectification-engine-version-cross-midnight.test.ts:68–109;它们不覆盖时段提前返回。回执 started/completed 的来源不同,聚合 SQL 仍取 max(engine_version),本轮仅源码核查,未作数据库实测声明。已把结论写入 BUG-984 与缓存补单 §0。
验证
环境与可复现边界
- Windows 主机:Python 3.11.7,pyswisseph
20230604,无项目.venv,使用系统python;原python3launcher 不可用。 - 同主机隔离 Linux Docker:Python 3.13.15、glibc 2.36,pyswisseph
20230604,镜像python:3.13-bookworm。从验证基线 Git archive 解包两份/work/base、/work/fix,只向后者覆盖两个测试文件。按仓库requirements.txt/requirements-dev.txt安装完整 Python 依赖;没有改仓库依赖、workflow,没有发布端口或挂载宿主 Docker socket。 - Linux 原测试 ordinal 2/3 失败,Windows 原测试全绿,已实证两个环境的浮点行为不同。但这是同一物理机器上的 Windows/Linux 两个运行环境,不冒充任务书要求的两台独立机器。另一台 Linux 机器/runner 的同 SHA 复验仍属环境缺口。
| 验证 | Windows 基线 | Windows 修复 | Linux 基线 | Linux 修复 |
|---|---|---|---|---|
| 原文件 + bridge | 18 通过 | 纳入下行 | 14 通过 / 4 失败(ordinal 2/3 × bridge) | 纳入下行 |
| 原文件 + bridge + memoization | — | 32 通过 | — | 32 通过 |
tests/test_rectification_*.py |
216 通过 | 216 通过 | 214 通过 / 2 失败 | 216 通过 |
| 内存回退日期修复 | — | 3 同日通过 / 1 跨午夜失败(预期红) | — | 3 同日通过 / 1 跨午夜失败(预期红) |
| quick(Linux 为其中 Python 步,未进入前端步骤) | 缺 mcp,退出 1 | 同一失败 | 881 通过 / 6 失败 / 5 跳过 | 883 通过 / 4 失败 / 5 跳过 |
| Linux 归档补 Git 索引后定向复验隐私/七政 | — | — | 65 通过 / 1 失败 | 65 通过 / 1 失败 |
- Windows quick 两侧均在
interpretation_source_inventory_gate.py导入处报ModuleNotFoundError: No module named 'mcp';缺失引用输出逐项相同,不标通过。 - Linux quick 两侧均退出 1,未进入前端步骤。基线独有两个失败正是 ordinal 2/3;修改版的四个失败均属于基线,新增失败 0。共同失败逐项为:
test_qizheng_api_productization.py::test_qizheng_endpoint_returns_eleven_bodies_and_twelve_palaces(400 != 200)、test_repo_privacy_markers.py::test_tracked_repository_has_no_privacy_markers、::test_local_python_venv_is_not_tracked、::test_gitignore_covers_venv_symlink_name(后三项为 archive 未带 Git 元数据)。 - 为核实归档缺口,在两份隔离目录初始化仅本地 Git 索引、按宿主真实
git ls-files -z清单追踪,不提交/推送,重跑隐私及七政文件:两侧均 65 通过/1 失败,三项 Git 缺口解除,七政 400 的失败仍逐条相同。没有修改测试或越界修七政;未重跑完整 quick,不能把这次定向补验合成为“快速门全绿”。 - 独立只读审查未发现阻塞代码问题;审查方另实跑原文件 9 passed、bridge 9 passed,确认 quick 的校正 glob 收集 216 项,本组仅 9 项;原文件与 bridge 同时选择才重复到 18,不将旧任务书所述“同 glob 重复”当成本轮实测事实。
- 开工预检:远端 verified;focused 的历史镜像路径断言失败,与错误台账已知缺口一致,不制造
.workbuddy目录消红。 - 回退验收通过独立进程内编译替换 helper 的日期表达式实现,仅内存中令
candidate_date = birth_date,没有编辑红线生产文件。两环境均三个同日 ordinal 绿、真实跨午夜矩阵断言红。 - 定向日志、Windows quick/glob 基线对照日志保留在本机会话临时目录;Linux
/tmp/{base,fix}-*.log已复制到宿主临时目录后停止本轮容器,容器保留供复核,不占用运行资源。只落统计、符号和环境信息,不复制请求体或出生资料。 - 最终将本轮文件加入 Git 索引后实跑
python -m pytest tests/test_repo_privacy_markers.py -ra:62 passed。git diff --check通过;生产红线、历史 golden 与 references 相对777bd53d零差异,测试文件硬编码 64 位分数哈希为零。
验收状态
| 项目 | 结论 |
|---|---|
| F1 断言实现、双浮点环境、回退对照 | 本地验证通过;两台独立机器要求仍为环境缺口 |
| F2 快速门覆盖与重复计数说明 | 通过 |
| F3 调用链查证与定级 | 通过;BUG-984 另单实施,未关闭 |
| F4 记录与独立复核 | 通过:BUG-981/984/985、补单 §0、状态板、BLOCKED 与补验清单已更新;独立审查无阻塞发现且两个文件分别 9 项通过 |
| staging 合入、门禁、部署 | 尚未执行,不声称已交付 |
补验清单:docs/testing/rectification-cross-midnight-gate-fix-20260920.md。不新增用户可感知行为,本轮不新增 CHANGELOG 条目。