99 lines
11 KiB
Markdown
99 lines
11 KiB
Markdown
# 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 随后另树执行,不宣称生产端到端完成。
|
||
|
||
### 本次合入结果:认证阻塞,未交付
|
||
|
||
本地整合提交 `b27d4de963f9ba7c4072233cabe06c6875eb0582`;前置 bridge 复测 9 passed。`git push origin HEAD:staging` 返回 `Failed to authenticate user`,随后 `ls-remote` 证实远端仍 `a3577ce2fa0bfa6047d397e50ed2e676c58a4420`。前述“本次交付”是目标而非成功结果;当前未交付、未部署。BUG-985 测试缺陷仍可据第三环境验证标 resolved,BUG-984 按任务规定等前置合入后再实施。恢复本人 Git 写入认证后继续,不借凭据、不绕过串行约束。
|
||
|
||
## 基线、范围与交付
|
||
|
||
- 执行单:`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`;原 `python3` launcher 不可用。
|
||
- 同主机隔离 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 条目。
|