diff --git a/AGENTS.md b/AGENTS.md index 7649359..8e7f61d 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -66,15 +66,15 @@ data → universe → factors(特征) → alpha(合成/预测) → portfolio(+ri | 项 | 值 | |---|---| -| `main` | 下表全部 gate 实测于 `c9cc12e`(PR #109);此后只落过 docs-only 的 #110(文档瘦身,pytest 复跑同为 2537) | -| `pytest -p no:warnings` | **2537 passed**(⚠️ 不要再传 `-q`:`pyproject.toml` 已含 `addopts="-q"`,叠成 `-qq` 会吞掉摘要行) | +| `main` | 下表全部 gate 实测于 `a5bbbba`(PR #113,D5 C5 收口) | +| `pytest -p no:warnings` | **2606 passed**(⚠️ 不要再传 `-q`:`pyproject.toml` 已含 `addopts="-q"`,叠成 `-qq` 会吞掉摘要行) | | `ruff check .` | clean | | phase0 锚(`run-phase0 --config config/example.yaml`) | **ic 0.9600 / annual 0.8408**(自 P0 起从未变过,任何改动都不许动它) | | `qt.exec_baseline_freeze --verify` | **77/77 @ `45c14aa`** | | `validate-config` | 32/32 | | 唯一 OPEN 的 PR | #38(历史遗留,保持 OPEN) | -**当前主线 = 因子层深度重构(设计 v3.2,D0–D7),走到 D5 C5(四腿全量对账)。** 全量跑已完成并暴露五类失败 F1–F5,全部已根因定位并裁定,**修复代码尚未开始**。 +**当前主线 = 因子层深度重构(设计 v3.2,D0–D7)。D5 C5 已收口(PR #113):11 因子 × 3 模式 33 格全绿,C5 通过 ⇒ 满足 C6 前置条件之一。** F1 残桶前视缺陷另立 correctness PR #112 修复(panels `unclassified` 729,029 → 0)。**下一步 = Step 4 / C6:删 11 个旧 runner**(owner 2026-07-28 已裁定退役重生成能力;前置条件另有 R16 覆盖数非降的逐条核销,且改造 PR 与删除 PR 必须分开)。 > **接手必读(唯一入口)**:[`tmp/design/HANDOFF_2026-07-30_claude_code.md`](tmp/design/HANDOFF_2026-07-30_claude_code.md) > ——含当前截面、F1–F5 裁定速查表、六步路线、派发/评审/限额的具体操作法、陷阱清单。 @@ -146,6 +146,6 @@ data → universe → factors(特征) → alpha(合成/预测) → portfolio(+ri ## 路线图 -1. **因子层重构收尾(当前主线)**:F1 残桶 correctness PR → C5 audit PR(F2/F3/F4 扩类 + F5 修复 + 真实重跑 + 填审计报告)→ C5 进度文档 → C6 删 11 个旧 runner → D6a–d 存量收口 → D7 收官全量重评估(**exec-only**)。 +1. **因子层重构收尾(当前主线)**:~~F1 残桶 correctness PR (#112)~~ → ~~C5 audit PR (#113)~~ → ~~C5 进度文档~~ → **C6 删 11 个旧 runner(下一步)** → D6a–d 存量收口 → D7 收官全量重评估(**exec-only**)。 2. **因子研究**:十一因子无一到 Adopt ⇒ 下一步优先做**换手/成本敏感的组合层验证**与更长 holdout,而不是继续堆新因子;补 PR #79 的 review;修订 HTML compendium。 3. **可选、须单独显式 goal**:I5g(强制 partial-fill / volume-cap);数据层 D6(`PanelStore` append/partition,仅当因子研究需要可复用派生面板时才启动);schema 守卫接 live `data-update`。 diff --git a/CLAUDE.md b/CLAUDE.md index 7649359..8e7f61d 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -66,15 +66,15 @@ data → universe → factors(特征) → alpha(合成/预测) → portfolio(+ri | 项 | 值 | |---|---| -| `main` | 下表全部 gate 实测于 `c9cc12e`(PR #109);此后只落过 docs-only 的 #110(文档瘦身,pytest 复跑同为 2537) | -| `pytest -p no:warnings` | **2537 passed**(⚠️ 不要再传 `-q`:`pyproject.toml` 已含 `addopts="-q"`,叠成 `-qq` 会吞掉摘要行) | +| `main` | 下表全部 gate 实测于 `a5bbbba`(PR #113,D5 C5 收口) | +| `pytest -p no:warnings` | **2606 passed**(⚠️ 不要再传 `-q`:`pyproject.toml` 已含 `addopts="-q"`,叠成 `-qq` 会吞掉摘要行) | | `ruff check .` | clean | | phase0 锚(`run-phase0 --config config/example.yaml`) | **ic 0.9600 / annual 0.8408**(自 P0 起从未变过,任何改动都不许动它) | | `qt.exec_baseline_freeze --verify` | **77/77 @ `45c14aa`** | | `validate-config` | 32/32 | | 唯一 OPEN 的 PR | #38(历史遗留,保持 OPEN) | -**当前主线 = 因子层深度重构(设计 v3.2,D0–D7),走到 D5 C5(四腿全量对账)。** 全量跑已完成并暴露五类失败 F1–F5,全部已根因定位并裁定,**修复代码尚未开始**。 +**当前主线 = 因子层深度重构(设计 v3.2,D0–D7)。D5 C5 已收口(PR #113):11 因子 × 3 模式 33 格全绿,C5 通过 ⇒ 满足 C6 前置条件之一。** F1 残桶前视缺陷另立 correctness PR #112 修复(panels `unclassified` 729,029 → 0)。**下一步 = Step 4 / C6:删 11 个旧 runner**(owner 2026-07-28 已裁定退役重生成能力;前置条件另有 R16 覆盖数非降的逐条核销,且改造 PR 与删除 PR 必须分开)。 > **接手必读(唯一入口)**:[`tmp/design/HANDOFF_2026-07-30_claude_code.md`](tmp/design/HANDOFF_2026-07-30_claude_code.md) > ——含当前截面、F1–F5 裁定速查表、六步路线、派发/评审/限额的具体操作法、陷阱清单。 @@ -146,6 +146,6 @@ data → universe → factors(特征) → alpha(合成/预测) → portfolio(+ri ## 路线图 -1. **因子层重构收尾(当前主线)**:F1 残桶 correctness PR → C5 audit PR(F2/F3/F4 扩类 + F5 修复 + 真实重跑 + 填审计报告)→ C5 进度文档 → C6 删 11 个旧 runner → D6a–d 存量收口 → D7 收官全量重评估(**exec-only**)。 +1. **因子层重构收尾(当前主线)**:~~F1 残桶 correctness PR (#112)~~ → ~~C5 audit PR (#113)~~ → ~~C5 进度文档~~ → **C6 删 11 个旧 runner(下一步)** → D6a–d 存量收口 → D7 收官全量重评估(**exec-only**)。 2. **因子研究**:十一因子无一到 Adopt ⇒ 下一步优先做**换手/成本敏感的组合层验证**与更长 holdout,而不是继续堆新因子;补 PR #79 的 review;修订 HTML compendium。 3. **可选、须单独显式 goal**:I5g(强制 partial-fill / volume-cap);数据层 D6(`PanelStore` append/partition,仅当因子研究需要可复用派生面板时才启动);schema 守卫接 live `data-update`。 diff --git a/docs/progress/07_factor_layer_refactor.md b/docs/progress/07_factor_layer_refactor.md index 9928263..4c115ff 100644 --- a/docs/progress/07_factor_layer_refactor.md +++ b/docs/progress/07_factor_layer_refactor.md @@ -37,3 +37,13 @@ - 评审两轮:APPROVE-WITH-NITS(LOW-1 位置性豁免可绕过 + NIT-1 静默钳位)→ 修复 → **delta 复核双双 CLOSED 可合并**(评审回退修复自证测试有牙)。 - gates(lead 独立重跑):pytest 2533 passed(node-ID 0 挤掉)、ruff clean、phase0 锚 0.9600/0.8408、32/32 configs、secret 0、exec_baseline --verify 77/77 @ 45c14aa。 - **D5a(PR #95,D5 的前三块——冻结/编目/探测;探测结论迫使插入新迁移步 D4b)**:**C1 冻结 exec 对账基线**(`qt/exec_baseline_freeze.py`)——22 份 exec artifact 是后续一切对账的参照,却 **gitignored 只存在于本机**,且设计假定的耐久副本 `scratchpad/baseline_reports/` **早已不存在**;新 runner 沿用同名输出路径,**跑一次就毁掉唯一基线**,随后的「对账」会比对刚被自己覆盖的文件(= 本仓在案的 `compare_postmerge.py` 空对账形态)。实冻 **77 个文件**(不是交办的 44——同族还有 11 份 `_exec_basis_sanity.md` + 22 张 dashboard,同样单份不可再生),**sha256 manifest 入 git**(字节留 gitignored,哈希只能经评审 diff 变动),每次读都验哈希,读取器结构性拒绝 live 路径(直连/symlink 别名/`..` 三种绕过全拒)。**provenance 按证据强度分级**:观察到的是 77 文件共享毫秒级 mtime(批量拷贝签名),对照 44 份 close 基准的 11 个递进 mtime 与 #74 重跑窗口吻合;「字节出自 #79 run」标注为**推断非观察**,字段名故意叫 `frozen_at_git_head` 而非 `producing_sha`。**C2 编目 11 runner 差异**(§六.5「未编目的差异算失败」)——用 **AST 级比对**而非抽读证明完整性(`_build_book_factors`/`_write_report`/`_section_payload` 11 份逐字符相同;其余 helper 剥掉字符串常量后坍缩成 1 组),另记 **7 个既有 bug**(只标不修)与 `FactorSpec` 16→20 键漂移(来自 #86/#91,须预登记否则对账时会被当 D5 回归去追)。**探测(`qt/saturation_probe.py`,可复跑工具非一次性脚本):D4 的 materializer 在真实评估面上跑不了**——995 票中 **84 票**首根 1min bar ≥ emit_start ⇒ pooled 饱和**永远无法提前终止、必打到 floor**(D4 已披露的代价在全规模是**构造性**兑现);磁盘 8.18/16.43 GB,名义内存 52.7/122.2 GB,而 **frame:峰值RSS 实测 2.2–2.45×**(`minute_bars` 逐票读完 `pd.concat`,parts 与结果同时在内存)⇒ 评估窗真实峰值 **≈115 GB vs 可用 56 GB**;**不止 pooled**——bounded 路径同样整 universe 单帧(`materialize.py:262`),光评估窗就超可用内存约一倍。**三条更便宜的出路全部证否**:按票分批会因 `service._ensure_coverage` 的缺口判定**只按日期不按 (date,symbol)** 而**静默丢名**(I5a 红线);按时间分块只救 3 个 bounded 因子;缩短窗口不动 pooled 加载左端(锚在 floor)。**关门的是 `intraday_amp_cut`**(**同时 pooled × 截面**)——按票分批毁其截面、按时间分块管不住其深度,两轴都绕不开。切口位置已实测:纯因子逐票 ≡ 整 universe **逐位相同**(728/1524 个可比 cell `max|diff|=0.0`),`intraday_amp_cut` 逐票 **1860 finite → 0** ⇒ **切口必须落在截面 combine 之前**。**暴露的设计层缺口(照实记)**:§八只给**决策热路径**(20 日尾窗)定过规模预算,**从未给评估路径定规模**,所以「整 universe 单帧」在设计评审里没人拦;而旧 runner docstring 白纸黑字写着 "the multi-year all-symbol minute panel is NEVER materialized"——**D4 的加载几何相对被替换对象是回归**,只是 D4 验收跑在 40 票 smoke 上看不见。lead 提的「复用 `panel_freeze.py` 的加载形态代替 D4b」**已证否**:它没有自己的加载形态,是 import 11 个 runner 调其私有 `_load_*_panel`——「复用」等于保留决策③要杀的第二条取数路径;可复用的是**形状**不是调用路径。⇒ **插入迁移步 D4b(per-symbol 流式物化)**,设计文档记为实施期修订 A1;C3–C6 刻意未开始(修 materializer 是改取值路径,须自带四腿验收,混进 D5 当「让 run 跑起来」正是本项目反复抓到的形态)。**评审两轮**:首轮 BLOCK 1 HIGH——被文档称作「幂等」的再冻结命令**静默销毁 provenance**(未改动树上跑,输出 `copied: 0 / already ok: 77` 报纯成功,git 里却清空 `source_note` 并把 `frozen_at_git_head` 改指向重跑者 = **主动的假声明**,而 **16 个测试全程绿灯**)→ 改为 provenance 继承 + 内容不变则一个字节不写 + **恒跑断言**(`source_note` 非空 / head ^[0-9a-f]{40}$ / sha256 合法 hex(原只验长度)/ `size_bytes`>0),评审逐条 mutation 四条全红;另修 2 MEDIUM(**本 PR 自己 suite 里的空 mutation**——那条 git-tracking 测试全程不碰 git,注释掉 `.gitignore` 仍通过 → 改查 **git 索引** `git ls-files -- `;**C6 爆炸半径漏编目 3 个 runner importer**,含**生产 D1 冻结基线的 `panel_freeze.py` 本身**,其重跑流程是「旧 SHA + 当前分支文件」的混合式、两种 C6 处置下都会失效)。**方法论(三个空 mutation,全部照实记)**:实现方两次(tamper 测试替换了文件里**不存在**的字节串;git 索引 mutation 用 `git add -f` 被 symlink 拒绝执行 → 什么也没改、测试**为错误的理由通过**),评审一次(它建议的 `git ls-files --error-unmatch` 对「未跟踪」与「路径不存在」**返回相同 rc=1**,据此的断言会在**最需要它的机器上空过**)——**三次都不是被测试抓住的,而是被「与预期矛盾的观察」抓住的;评审建议本身也需要 mutation 证据**。**顺带更正一条长期误诊**:「本机 pytest 摘要行被环境吞掉」是假的——`pyproject.toml:53` 已有 `addopts="-q"`,我们再传 `-q` 就是 `-qq`;去掉即出现 `N passed` 摘要行(点计数仍是有用的交叉校验,本轮就抓到 2113 vs 2114 之差,但它从来不是因为摘要不可得才必须存在)。gates:**2117 collected**(2116 passed + 1 skipped——跳的是字节绑定测试,其字节 gitignored;manifest 自洽测试**无 skipif 恒跑**)/ ruff / 31 configs / phase0 锚不变 / secret 0 / `--verify` 77/77 且 head 仍 `45c14aa` / 冻结面板 mtime 未变。 +- ✅ **`amp_marginal_anomaly_vol` 残桶 correctness fix(PR #112,单独成 PR、非重构一部分,照 #103 jump 先例)**:`amp_marginal_anomaly_vol_20` 是 11 个分钟因子里**唯一派生 5min bar 的**。新引擎路径先把 1min 预截到 `available_time ≤ 14:50`、compute 再 resample ⇒ `resample_intraday_bars` **emit 残桶**,每天多出一根**只有 4 个成分**的"5min bar"(振幅/收益类统计对 bar 长度敏感 ⇒ **系统性偏小、有方向**);旧 runner 先取整日 bar 再派生,14:50 那桶成分齐全但 `avail=14:51 > cutoff` 被整桶丢弃、当天最后一根是 14:45 完整桶。**因子定义是"5min bars 截断于 14:50"⇒ 14:45–14:50 那个完整桶在 14:50 根本不可得,旧路径才是定义忠实的那个**。修法 `_complete_grid_bars(coarse, freq)`、判据 `bar_end == bar_end.dt.ceil(freq)`,在 **compute 内**(不在 materializer 打补丁——那正是本缺陷的形状;`resample_intraday_bars` 未改,它是通用 data-layer 原语)。**结果**:panels `unclassified` **729,029 → 0**,`float_tail/threshold_flip/flip_contamination` 全 0(未靠任何容差类兜底);anchors 此前 FAIL 的 3 行现为 **rel = 0.00e+00 精确**;reports **首次真正跑起对比**。**verdict Reject/Reject 未变**(真跑出来的,不由相关系数推定),微小位移全部来自已登记的 `warmup_left_extension` 聚合效应(评估日 1199→1209),`_bookclose` 增量 ICIR **逐位复现冻结的 −0.311985**。**不 bump `spec.version`、不加 `FactorCorrection`**:#103 的 jump 是**已发布 artifact 本身脏**,而 F1 的缺陷由重构中的新引擎引入、**从未发布**,修复是让引擎**回到**已发布值——声明一次没发生的 supersession 等于往每份 artifact 写一句假话。"已发布值不移动"**直接测得**(评审用 `git show main:` 把修复前后两模块载入同一进程喂逐字节相同输入,5 只真实 symbol **整日几何 5/5 BITWISE-EQ**)。**缺陷足迹不小**:`600000.SH` 完整评估窗口(1,213 日)修复前 **567/1,213 日不同、max rel `1.456776e-01`**,修复后 0/1,213——聚合看着动得小是**稀释不是无害**。**评审三处文档缺陷**:①普查射程被夸大(初版写"评估窗内 591 只",实为在 **5,782 个缓存目录**上随机抽 600、与 995 只评估 universe 交集**仅 102 只 = 10.3%**,而它是论证链的**承重前提**)→ 补成全量普查(995/995、1,159,263 对 = `rows_frozen`、残桶 0,实现方与评审两个独立脚本逐项一致),初版错误**如实记录在案**;②判据放行 **09:30 集合竞价 bar**(`ceil(09:30,5min)=09:30` ⇒ 自成一桶、恰 1 个成分、算"完整"),与 docstring 给的理由不符 → 点名它、**行为不改**(两种几何与冻结基线都保留它,丢掉会移动已发布值 ⇒ 另开 PR),编目明写「已知且刻意不改,后人别顺手修」;③守卫射程写进自己的 docstring(`{1,5,15,30}min` 对齐、**`60min` 不对齐** ⇒ 11:01–11:30 每天被静默丢弃,实测 coarse 100 → dropped 20 全是 `bar_end=11:30`)。**mutation 四组各有红/绿见证,实现方与评审各自独立写了一套**(其中把 ceil 网格硬编码成 15min 使两条 whole-day 测试**变红** ⇒ 它们确实有牙,此前"它们不区分修复"的怀疑被证否)。gates:pytest **2546 passed**(node-ID 差分 0 挤掉)/ ruff / 锚 0.9600·0.8408 / 32 configs / `--verify` 77/77 / secret 0。 +- ✅ **D5 C5(PR #113,四腿全量对账收口——11 因子 × 3 模式 33 格全绿,C5 通过 ⇒ 满足 C6 前置条件之一)**:F2/F3/F4 扩类 + F5 修复 + NIT-1,配以「A 阶段做完停下等裁定、再花三小时重跑」的分段——**边界参数一旦烤进一次三小时的全量跑,改起来就是重跑一次**。 + - **F2**(bars-only 臂):600623.SH 那根整数成交量 bar 压在 same-slot μ+σ 阈值上、pandas rolling 浮点累加**路径依赖加载起点**(thr 差 ~4e-13)⇒ `vol > thr` 翻转,**输入侧零变化**。窗口/symbol 未动,按因子设**相对**界(kurtosis ≤5e-3 / relative_vwap ≤1e-5,实测 2.904e-3 / 1.530e-6;沿用截面臂的 2e-4 绝对界会全数越界),cap 25。**F3**:`frozen_finite_new_nan` 进 warmup 方向集(限 pooled + 早区)+ 新类 `warmup_sparse_valid_day_tail`。**F4**:float-dust 谓词(abs ≤1e-12)**前移到 `_in_warmup` 分支之前**(按**机制**识别不按位置)⇒ 月计数 `{07:8198,08:11,09:3,10:9}` → `{07:8198}` 天然单调;实测对已绿因子无副作用,**被否决的方案②(月计数 ≤30 豁免单调链)未被启用**。**F5**:后缀传进写出层直接写 `_bookclose`、删掉事后 `os.replace`——此前 close 模式先用共享 stem 写再移动,**decision→close 顺序跑完会销毁 decision 的 with_book 三件套**。**NIT-1**:panels summary 加**逐类 max_rel**(headline 在任何分桶之前更新,与 `unclassified=0` 并排会诱导"容差没牙"的误读;本例那个 `9.03e-01` 经两方独立复算完全落在已登记 warmup 内)。 + - **三个证据基窟窿(比修复本身更重要——它们说明"跑绿"曾经只覆盖"我们看过的那部分")**:①交接文档的结果总表把 `peak_ridge_amount_ratio_20` 的 panels 记成通过,而**日志是 `unclassified=30 / ok=False`**,它是 F3 同族的**第三个**因子 ⇒ F2/F3/F4 的边界参数原本推自一个**残缺证据基**;据此做了 **11 因子 × 3 模式的「表所记 vs 日志实测」全量对照**(33 格只此 1 格记错,panels 一列**不依赖日志**、另用 dump 的 served 面板独立重算互证)。②**整轮 C5 全量跑用的是 PR #109 之前的判据**——`warmup_ceiling` 由 `35de346`(07-28 02:08)引入,而幸存的 8 条 07-28 日志行**没有一条带这个字段** ⇒ bounded warmup 的 cell ceiling **一次都没上过场**,而审计骨架把它写成生效中的闸门。措辞已改准:ceiling = `(w−1)×|symbols|` 是**结构上限**,只要日期边界判据没坏就**数学上不可能被超过** ⇒ 它是「日期边界判据自身有没有坏」的 **backstop,不是量级/密度闸门,只有在另一个守卫已失效时才会响**;91.5% 结构上本就该接近 1,**既非警报也非余量**;**C4a LOW-1 的量级缺口仍然敞着**。③**reports 腿的 11 个 `1` 全部是 F5 的 `FileNotFoundError`、不是判定结果** ⇒ 该腿此前只被真正观测过一个因子;本 PR 是它对其余 10 个因子的**首次**观测,两类此前无人见过的漂移因此第一次露面(诊断 sink 的**纯新增 section**;D2 迁移导致的 `spec.description` **provenance 改写**),均非数值差异、均已登记(前者补做了 PR #105 当初做过而这三个因子没做过的验证:12 个 grid 逐格 `old=None` / mandatory+verdict 逐位不变 / **自造索引位移实测会被检出**;后者**逐对精确枚举 old→new 字符串,不用谓词**——宽泛的"description 改写可接受"会把某天真正改了因子定义陈述的那次一起放行)。另:`_make_logger` 是 truncate 的(重跑会静默销毁同名日志唯一副本),**B 之前先把 pre-fix 数字誊进被提交的审计报告**——`tmp/` 快照被 gitignore、只在本机,而本项目已因 `/tmp` 被清理丢过一次全量跑总日志。 + - **评审证否的两处 overclaim**:**HIGH-1「白名单是该密度谓词的枚举」是假的**——谓词在窗口内允许 **1,250** 对而类实际覆盖 **18** 对,**69 倍差**。处置是**改措辞、不改谓词**(改谓词会把闸放宽约 69 倍):该类如实标为**「枚举类 + 必要条件守卫」而非机制类**(这个区别是操作性的——读"机制类"的人会以为**可以照机制推导着扩**),证伪门槛从"低于中位"(按定义约一半的票满足、近乎恒真)收紧到**低于 p25**(仍 18/18,最差百分位秩 21.7%),`600906.SH` 的不对称证据射程写准(**只有否定方向"稠密 ⇒ 不进簇"成立**,且它在对照因子上只高于中位 **1 天**、是**单点证据**),**反棘轮约束不放宽反而更要紧**(既然没有规则决定成员集,"再有新成员就停下上报"是这一类**唯一**的守卫,反向测试从配角升为主力)。**HIGH-2「若引擎回归藏在别的指标里,C−B 会在那些行非零」是恒真**——评审 mutation 直接证否:把 `ic_mean` 在 **A/B/C 三本书里同时 ×1.5**,**C−B 仍精确 0.0**(那四个指标对书**构造性免疫** 44/44,引擎回归会让三者一起动、在差里对消);已换成有信息量的版本(artifact 层 C−B 非零共 **174 叶,全部落在 `sections[3]` + `book_view` + verdict reasons ⇒ 书视图爆炸半径被限制住,174/174 通过**),并**明写真正检出引擎回归的是 `no_book`/`bookclose` 两格 strict 对冻结基线的逐叶子闸**;**这条被证否的推理连同其 mutation 证据留在报告里,没有悄悄换掉**(与 `compare_postmerge.py` 那次空对账处理一致)。 + - **贴边的边界(新增 §三之四)**:`jump` float_tail **101/101(0 格)**、sparse-tail 窗口右端 **2021-11-15(0 天)**、cap **19/20(1 格)**、p25 密度守卫 **35 天 vs 门槛 36(1 天)**。反棘轮使这种紧是**有意的牙**,但读者得知道有多紧;其中 p25 那道门**红了就是 STOP-AND-REPORT、不许把门槛放回中位**——**而它红的时候恰恰最诱人**(中位门会放行,于是"改一个数就绿了")。 + - **方法论:本轮出现 5 次「证据/清单打不中它要支持的那个主张」,无一是被测试抓住的**:①白名单参数化测试**读被测常量本身** ⇒ 删一只票只是少一个 case、两次都绿(本仓第 **10** 例"不可能失败的测试");②**`.pyc` 按 (mtime, size) 校验** ⇒ **等长**改写在同一秒内会让"还原"后的源码被**变异后的字节码顶替**,据此把先前 **13 条 mutation 全部重跑**(**只修 harness 不重跑等于把已污染的证据留在案上**;推荐解法是每次变异用 `PYTHONPYCACHEPREFIX` 指向独立目录);③位移测试**为错误的理由通过**(尾部多出的下标就足以满足断言);④MD 前缀漏了 `to_section` 加的两个计算属性,且其覆盖测试**两侧同源**故对该元组无牙(现钉到四个 coverage 类 `@property` 名字的并集);⑤「p25 严格更紧」在案的两条 mutation **打不中它**(那两只票在中位门下也会红),已换成真正的证人(`000031.SZ` 低于中位、高于 p25 ⇒ p25 下红、中位下放行;带内共 **151** 只票)。另有**两次**"同一主张写四遍、改准三遍漏一遍"(其中一处测试 banner 断言 median 而其**下方 15 行**的代码 docstring 写 p25,**同屏自相矛盾**);已把权威处收敛到参数所在的 docstring、其余改为指针,**两份 Markdown 与 Python docstring 无共享 prose 机制这个限制如实写明**,收敛后剩 4 处纯重复、**0 矛盾、0 悬空**。 + - **重跑射程是实测不是论证**:扰动 `qt/factor_eval_reconcile.py` 后重算 5 个因子 `code_hash` → **5/5 逐字不变**;**负对照**扰动 `factors/compute/minute/primitives.py`(在 shared set 内)→ **5/5 全变** ⇒ 探针非空、harness 在 code_hash 射程之外、store 不失效。 + - **已登记、本 PR 不改**:`_make_logger` truncate;jump 的 reports 腿对**值改动**实际不设闸(593 个 diff 里 **518** 个走既有更正承载登记 #11、`with_book(decision)` 是 report-only #13 ⇒ 值级依据应看 `no_book`/`bookclose` 两个 strict 格与 panels 腿,**结构性增删仍设闸**)。 + - gates(lead 独立重跑):pytest **2606 passed** / ruff clean / phase0 锚 **0.9600·0.8408** / **32/32** configs / `--verify` **77/77 @ 45c14aa** / secret **0** / 陈旧措辞 grep **0** / 审计报告 `TBD` **0** / 编目对 main **纯追加(0 删除行)** / 冻结基线**今日 0 个文件被写**。 diff --git a/docs/progress/pr_ledger.md b/docs/progress/pr_ledger.md index af70258..00b9688 100644 --- a/docs/progress/pr_ledger.md +++ b/docs/progress/pr_ledger.md @@ -17,3 +17,7 @@ | #108 | 进度文档(D5 C4b) | | #109 | D5 C5 prep:性质测试迁移映射表 + 审计报告骨架 | | #110 | 文档瘦身:进度日志从 `CLAUDE.md` 逐字搬进 `docs/progress/`(398 → 151 行) | +| #111 | 台账补记 #108–#110 + 状态表标明 gate 实测于哪个 commit | +| #112 | `amp_marginal_anomaly_vol` 残桶 correctness fix(单独成 PR,非重构一部分) | +| #113 | D5 C5 四腿全量对账收口(F2/F3/F4 扩类 + F5 修复 + NIT-1 + 审计报告) | +| #114 | 进度文档(F1 + D5 C5) |