From a07c4750f8566b8a939f10522b5c215ea846cc74 Mon Sep 17 00:00:00 2001 From: shaofl <2899218482@qq.com> Date: Tue, 28 Jul 2026 01:33:50 -0700 Subject: [PATCH] docs: record refactor step D5 C4b (PR #107) --- AGENTS.md | 11 ++++++++++- CLAUDE.md | 11 ++++++++++- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index b762551..705c4dc 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -57,7 +57,7 @@ data → universe → factors(特征) → alpha(合成/预测) → portfolio(+ri ## 开发约定 - **交流中文**;代码/注释/commit message 用**英文**。 -- **Git**:feature 分支 + PR。**PR #1(P0+P1)、#2(P2-1)、#3(P2-2)、#4(进度文档)、#5(P2-3)、#6(进度文档)、#7(P2-4)、#8(进度文档)、#9(P3-1)、#10(进度文档)、#11(P3-2)、#12(P3-3)、#13(进度文档)、#14(P3-4)、#15(进度文档)、#16(P3-5)、#17(进度文档)、#18(P3-6)、#19(P3-7)、#20(进度文档)、#21(P3-8)、#22(进度文档)、#23(P4-1)、#24(进度文档)、#25(P4-2)、#28(tushare 权限/限频探测 + capability registry)、#29(I1–I4 分钟级 intraday pipeline,4 commit 一 PR)、#30(进度文档)、#31(P4-3 因子支撑端点缓存 + 21:00 data updater,2 commit 一 PR)、#33(P-I5a 事件驱动回测架构重构 + opt-in 分钟尾盘 event model,4 commit 一 PR)、#35(P-I5b 分钟尾盘执行期 raw stk_limit 涨跌停可行性,4 commit 一 PR)、#37(P-I5c MMP 分钟因子端到端 opt-in alpha)、#39(P-I5d MMP 五分位分组回测 standalone,含 I5c plumbing)、#41(数据层 D1 契约文档 + token 解析去重)、#43(数据层 D2 TushareCache specs/parsers 拆分)、#45(数据层 D3 report-only 数据质量层)、#47(数据层 D3b default-off `data-update` 质量报告钩子)、#49(数据层 D4 coverage ledger 批量写 + 进程内查找缓存)、#51(数据层 D5 opt-in 有界并发 + 全局限频器)、#53(P-I5e MMP 五分位 CSI300 独立泛化检验,负结果)、#55(P-I5f 分钟尾盘执行流动性/容量诊断,report-only)、#57(数据层 schema 注册表 + default-off drift 守卫)、#59(数据层 全A 增量 auto-warm + systemd 定时,default-off)、#61(数据层 全A 历史回填 `data-backfill`,分块/续跑/失败隔离)、#62(进度文档)、#63(因子评估契约层 `analytics/eval/` + StandardFactorEvaluator + dashboard + PR-C 因子,4 commit 一 PR)、#64–#73(PR-D…PR-M 十个分钟因子复现,**一因子一分支一 PR**)、#74(因子评估契约 v0.8 + v0.9 判定门修复)、#75(尾盘执行价 VWAP + 分钟持有期收益复权)、#76(报告披露修正 + I5f 名义按真实规模重测)、#77(`adj_factor` 下降质量检查)、#78(#76 的 follow-up:扫描式正则守卫被七种改写实测证否 → 闸门描述改单一来源)、#79(十一因子改 14:51 VWAP exec-to-exec 基准,**评审未返回、靠自查合并**)、#82(闸门/成交价描述全仓清扫,12 处;#78 守卫射程不足的修正)、#80(进度文档)、#84(因子层重构 D0 纸面契约:availability policy 常量 + 预指派表 + 性质编目)、#85(进度文档)、#86(因子层重构 D1:registry + PanelField requires + FactorSpec 契约 v1.0)、#87(因子层重构 D1 面板冻结:14 因子 raw 基线 + manifest)、#88(进度文档)、#89(因子层重构 D2:minute primitives + ops + 11 因子迁移,与冻结基线逐位一致)、#90(进度文档)、#91(因子层重构 D3:store 层——稀疏值存储 + key/指纹 + tail-recompute + R5 fina 视界统一)、#92(进度文档)、#93(因子层重构 D4:FactorService + decision-view materializer + pooled 饱和填充)、#94(进度文档)、#95(因子层重构 D5a:exec 基线冻结 + 11 runner 差异编目 + 可行性探测)、#96(进度文档)、#97(因子层重构 D4b:per-symbol 流式物化)、#98(进度文档)、#99(因子层重构 D5b:评估契约 v1.0 + 诊断通道 + 14:50 可见性守卫;**C4 中止上报**)、#101(因子层重构 D4c:store 去 universe 依赖——(date,symbol) 缺口判定 + store 只存 per-symbol 中间量、截面 combine 移到读出装配 + 调用方 symbol 列表单点归一化)、#103(jump_amount_corr_20 补 14:50 截断 correctness fix——唯一未做截断的分钟因子,exec_to_exec 下信息集越过自己入场锚的真实前视;含 dashboard 布局 5/4 分支修复 + census 守卫前缀匹配修复;单独成 PR 非重构一部分)、#105(因子层重构 D5 C4:统一 exec-only FactorEvalRunner——因子取数全走 factors.service、异构披露唯一家、C5 对账 harness 三模式 + 77/77 硬闸门、warmup 左延具名类登记)均已 merge 到 `main`**;**OPEN 未合并:#38**(见 P-I5d 处置,未获授权关闭)。commit 用 conventional 格式,**无 attribution**(不加 Co-Authored-By)。 +- **Git**:feature 分支 + PR。**PR #1(P0+P1)、#2(P2-1)、#3(P2-2)、#4(进度文档)、#5(P2-3)、#6(进度文档)、#7(P2-4)、#8(进度文档)、#9(P3-1)、#10(进度文档)、#11(P3-2)、#12(P3-3)、#13(进度文档)、#14(P3-4)、#15(进度文档)、#16(P3-5)、#17(进度文档)、#18(P3-6)、#19(P3-7)、#20(进度文档)、#21(P3-8)、#22(进度文档)、#23(P4-1)、#24(进度文档)、#25(P4-2)、#28(tushare 权限/限频探测 + capability registry)、#29(I1–I4 分钟级 intraday pipeline,4 commit 一 PR)、#30(进度文档)、#31(P4-3 因子支撑端点缓存 + 21:00 data updater,2 commit 一 PR)、#33(P-I5a 事件驱动回测架构重构 + opt-in 分钟尾盘 event model,4 commit 一 PR)、#35(P-I5b 分钟尾盘执行期 raw stk_limit 涨跌停可行性,4 commit 一 PR)、#37(P-I5c MMP 分钟因子端到端 opt-in alpha)、#39(P-I5d MMP 五分位分组回测 standalone,含 I5c plumbing)、#41(数据层 D1 契约文档 + token 解析去重)、#43(数据层 D2 TushareCache specs/parsers 拆分)、#45(数据层 D3 report-only 数据质量层)、#47(数据层 D3b default-off `data-update` 质量报告钩子)、#49(数据层 D4 coverage ledger 批量写 + 进程内查找缓存)、#51(数据层 D5 opt-in 有界并发 + 全局限频器)、#53(P-I5e MMP 五分位 CSI300 独立泛化检验,负结果)、#55(P-I5f 分钟尾盘执行流动性/容量诊断,report-only)、#57(数据层 schema 注册表 + default-off drift 守卫)、#59(数据层 全A 增量 auto-warm + systemd 定时,default-off)、#61(数据层 全A 历史回填 `data-backfill`,分块/续跑/失败隔离)、#62(进度文档)、#63(因子评估契约层 `analytics/eval/` + StandardFactorEvaluator + dashboard + PR-C 因子,4 commit 一 PR)、#64–#73(PR-D…PR-M 十个分钟因子复现,**一因子一分支一 PR**)、#74(因子评估契约 v0.8 + v0.9 判定门修复)、#75(尾盘执行价 VWAP + 分钟持有期收益复权)、#76(报告披露修正 + I5f 名义按真实规模重测)、#77(`adj_factor` 下降质量检查)、#78(#76 的 follow-up:扫描式正则守卫被七种改写实测证否 → 闸门描述改单一来源)、#79(十一因子改 14:51 VWAP exec-to-exec 基准,**评审未返回、靠自查合并**)、#82(闸门/成交价描述全仓清扫,12 处;#78 守卫射程不足的修正)、#80(进度文档)、#84(因子层重构 D0 纸面契约:availability policy 常量 + 预指派表 + 性质编目)、#85(进度文档)、#86(因子层重构 D1:registry + PanelField requires + FactorSpec 契约 v1.0)、#87(因子层重构 D1 面板冻结:14 因子 raw 基线 + manifest)、#88(进度文档)、#89(因子层重构 D2:minute primitives + ops + 11 因子迁移,与冻结基线逐位一致)、#90(进度文档)、#91(因子层重构 D3:store 层——稀疏值存储 + key/指纹 + tail-recompute + R5 fina 视界统一)、#92(进度文档)、#93(因子层重构 D4:FactorService + decision-view materializer + pooled 饱和填充)、#94(进度文档)、#95(因子层重构 D5a:exec 基线冻结 + 11 runner 差异编目 + 可行性探测)、#96(进度文档)、#97(因子层重构 D4b:per-symbol 流式物化)、#98(进度文档)、#99(因子层重构 D5b:评估契约 v1.0 + 诊断通道 + 14:50 可见性守卫;**C4 中止上报**)、#101(因子层重构 D4c:store 去 universe 依赖——(date,symbol) 缺口判定 + store 只存 per-symbol 中间量、截面 combine 移到读出装配 + 调用方 symbol 列表单点归一化)、#103(jump_amount_corr_20 补 14:50 截断 correctness fix——唯一未做截断的分钟因子,exec_to_exec 下信息集越过自己入场锚的真实前视;含 dashboard 布局 5/4 分支修复 + census 守卫前缀匹配修复;单独成 PR 非重构一部分)、#105(因子层重构 D5 C4:统一 exec-only FactorEvalRunner——因子取数全走 factors.service、异构披露唯一家、C5 对账 harness 三模式 + 77/77 硬闸门、warmup 左延具名类登记)、#107(因子层重构 D5 C4b:valley_price_quantile 绑定——combine_daily 声明式引擎扩展 + 平移面板第三条路逐比特等价双侧钉 + binding.py 折进 code_hash + 截面因子 panels 类边界三裁定)均已 merge 到 `main`**;**OPEN 未合并:#38**(见 P-I5d 处置,未获授权关闭)。commit 用 conventional 格式,**无 attribution**(不加 Co-Authored-By)。 - **不过度设计**:按路线图 MVP 先打通一条端到端链路,再加层(architecture.html §11,Phase 0→3)。 - **secrets** 一律走外部 `.config.json`;repo `.gitignore` 已排除数据产物(`*.parquet`等)、缓存、`tmp/`(仅留架构文档)。 - 文件小而专(<800 行),immutable 优先。 @@ -382,6 +382,15 @@ data → universe → factors(特征) → alpha(合成/预测) → portfolio(+ri - 评审 APPROVE-WITH-NITS(0 CRIT/HIGH/MEDIUM;64 个自造 mutation probe 全过、verbatim 8/8 复核、panels 模式独立重跑逐格一致);登记 LOW-1(bounded warmup 类无量级/cell 数上限,~1.6% 网格,**C5 加 cell 数 ceiling**)与 LOW-2(reports 腿 digit OR 规则散文理由可变义,verdict 标签仍严格);NIT-1/2 装饰性。 - gates(lead 独立重跑):pytest 2492 passed(node-ID 差分 0 挤掉)、ruff clean、phase0 锚 0.9600/0.8408、32/32 configs、secret scan 2 处 benign(新 config 的 external_secret_file 路径 + key 名,与 main 上 11 份 eval config 同形,无 token 值)、exec_baseline --verify 77/77 @ 45c14aa。 - 刻意不做:删旧 runner(C6)、11 因子全量四腿(C5)、vpq 绑定 + binding 折 code_hash(PR-C4b,lead 已裁定批准)、mmp_ew(D6c)、run registry(D7)。 + - **D5 C4b(PR #107,vpq 绑定 + code_hash 折叠——11 分钟因子全部绑定完成)**: + - **vpq 绑定**:`valley_price_quantile` 的 residualize 是逐日截面 OLS(值依赖 universe)⇒ 按 D4c 架构存 per-symbol `raw_qbar` 中间量、截面 combine 移到读出装配;combine 需日频 close ⇒ 唯一引擎扩展 `DailyCombineInput`/`combine_daily` **声明式**槽位(红线 #5 禁 isinstance 守住;顺带删掉了旧的 `isinstance(factor, ValleyPriceQuantileFactor)` 分发);`combine_daily_panel` 用 decision-lagged close + 左端 22 个 lagged 交易日 warmup(欠暖钳位有一行披露)。 + - **平移面板第三条路**:因子内部 T-1 会被 decision 视图二次滞后成 close_{d−2} ⇒ 传平移面板 + 关内部 T-1,**逐比特等价双侧钉**(binding 侧 `Series.equals` + 破坏对照 ~8.5e-2;runner 侧 fixture 240/240 max|diff|=0.0 + 左端 22 日硬断言;评审用不同 fixture + 新扰动独立复验)。 + - **binding.py 折进 code_hash**(lead 裁定 Q2):承重语义文件此前在 key 射程外;mutation 实证改 binding → 18/18 factor key 全变、改无关模块 → 0 变;dev-only `artifacts/factor_store/` 一次性失效已披露。 + - runner 启用 vpq + NeutralizationCoverage 机制 B(经新 `service.stored_payload` 回读 raw 中间量,同一 key/fingerprint/coverage 引擎、非第二取数路径)+ **anchors 模式修截面因子全 universe 服务**(5 锚 symbol < min_cross_section=10 必全 NaN——C5 对 intraday_amp_cut 本也会踩)。 + - **panels 类边界三裁定**(首个 FAIL 100% 分解后 lead 裁定):① pooled 月单调豁免锚到**结构性部分月**(冻结面板首个 finite 值所在月;初版位置性实现被评审 probe 绕过 → 修复 + 回退 mutation 证据);② 新具名类 `threshold_flip_contamination`(窗口 [2023-06-01,2023-07-14]、600623.SH ≤2e-04、其余 ≤1e-06、≤20,000 cell——PRV 临界 bar 翻转×逐日 OLS 污染族,输入侧变化已排除:ledger 零写入 + qbar 双几何逐位一致 1.1e-16,评审独立复算 1,241/1,241 格);③ float 尾加 abs 下限 1e-12 + cap 分档(bars-only 101 / 截面 1,000)。 + - **真实对账(cache-only `stk_mins_live_calls=0`,评审独立重跑逐数一致)**:panels rc=0(warmup=24,568 按月 902→19,980→3,667→19 豁免后单调 / float_tail=883 / flip_contamination=19,177 / unclassified=0)、reports 4/4 OK、anchors 5/5;vpq verdict Watch/Watch 与冻结基线同(数值微移全在登记 warmup 聚合效应内)。 + - 评审两轮: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 未变。 - ✅ 质量门(**当前 `main` @ `f432dc5` 实测**:`python -m pytest -p no:warnings` **1776 passed**、`ruff` clean、`validate-config` **31/31 配置逐个 OK**、`run-phase0`(demo)**ic 0.9600 / annual 0.8408 不变**)。构成对得上:`aa19968` 实测 **1740** → #78 加 2(含钉住破折号闭合的那条)= **1742** → #79 加 34(两个新测试文件,0 个既有测试被挤掉)= **1776**。新增测试分组(`--collect-only` 实数,`aa19968` 口径):**因子评估契约层 contract=337 + standard=113 + figures=7 / 十一因子(factor + eval runner,21 文件)=421 / PR#75 exec-vwap-basis=46 / D3 market quality 15→21(含 #77 `decreasing_adj_factor` 及其相对-vs-绝对尺度 mutation 测试)**。历史分组(旧 793 基线):`pytest` **793 passed**(P0=97 / P1=78 / P2-1=22 / P2-2=22 / P2-3=14 / P2-4=8 / P3-1=10 / P3-2=18 / P3-3=16 / P3-4=15 / P3-5=22 / P3-6=27 / P3-7=25+1 throttle / P3-8=8 / P4-1=28 / P4-2=17 / **intraday I1 schema=14 + feed=9 / I2 cache=10 / I3 aggregate=13 / I4 execution=10 / P4-3 cache=10 + updater=7 / P-I5a event-backtest=19 / P-I5b exec-feasibility=16 / P-I5c mmp-minute=18 / P-I5d mmp-quintile=19 / P-I5e 仅 config(无新测试,`test_cache_config` 的 config glob 自动 +1)/ P-I5f intraday-liquidity=17(+ `test_cache_config` config glob 自动 +1)/ D1 token-dedup index-feed +2 / D2 cache-modularization +5 / D3 data-quality market=15 + intraday=12 + report=14 / D3b data-update-quality=18 / D4 coverage-ledger-scaling=13 / D5 scheduler=9 + concurrency=12 / schema-registry-guard=62 / all-A-incremental=12 / all-A-backfill=22**);当时 `ruff` clean、`validate-config` 20 配置(data_update + phase_i5a…phase_i5f)+ `run-phase0`(demo)均 OK(**ic 0.9600 / annual 0.8408 自 P0 起从未变过**)。 - ⚠️ 剩余(已显式披露):日线 only、demo 路径非真数据、旧三因子无信号(P3-3/P3-4 实证;但其组合在 2024-2026 holdout 上 SSE50/CSI300/CSI500 全正、CSI500 高达 +17.8%——小样本/regime 翻转的持续例证);value/低波信号获得**独立样本符号级确认**(P3-7 SSE50/CSI300 量级衰减;P3-8 CSI500 泛化成立且更强),组合级盈利能力仍未确立(排名跨 cell 翻转);subset 报告文件名已可配置(P3-8 起不再互覆盖)。**分钟因子侧新增披露**:十一个复现因子全部 EXPLORATORY、**封顶 Watch,无一到 Adopt**,1× 费率下净多空为正的只有 2 个(PR-F/PR-L,且 PR-L 扛不住 2×)——**IC 强 ≠ 可交易**;MMP 的唯一正面证据(I5d)在修正引擎上退化、I5e 负结果加强;I5f 的容量结论已按**真实 100 万名义**重写(1000 万口径的"约半数不足"作废);**日频除权审计已完成**(GENUINE、无 vintage 接缝、评估池暴露 1/603,258,不重述任何因子结果),**分钟路径的复权缺陷已在 PR #75 修**;exec-to-exec 改基准已随 **PR #79 合并**,close-to-close 与 exec 两套 artifact 并存;⚠️ **#79 的 code review 未返回、靠自查合并**,其"未独立核"清单(五条 mutation 声称 / 十一个 runner 改动是否机械等同 / `execution_capacity` 透传)仍待后续检查——若查出问题,重述 exec 基准数字而非 close-to-close;schema 守卫**仍未接** live `data-update` 暖跑路径;HTML compendium(`artifacts/reports/factor_compendium.html`)**还读 v0.8 结果,待按最终结果修订**。 diff --git a/CLAUDE.md b/CLAUDE.md index b762551..705c4dc 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -57,7 +57,7 @@ data → universe → factors(特征) → alpha(合成/预测) → portfolio(+ri ## 开发约定 - **交流中文**;代码/注释/commit message 用**英文**。 -- **Git**:feature 分支 + PR。**PR #1(P0+P1)、#2(P2-1)、#3(P2-2)、#4(进度文档)、#5(P2-3)、#6(进度文档)、#7(P2-4)、#8(进度文档)、#9(P3-1)、#10(进度文档)、#11(P3-2)、#12(P3-3)、#13(进度文档)、#14(P3-4)、#15(进度文档)、#16(P3-5)、#17(进度文档)、#18(P3-6)、#19(P3-7)、#20(进度文档)、#21(P3-8)、#22(进度文档)、#23(P4-1)、#24(进度文档)、#25(P4-2)、#28(tushare 权限/限频探测 + capability registry)、#29(I1–I4 分钟级 intraday pipeline,4 commit 一 PR)、#30(进度文档)、#31(P4-3 因子支撑端点缓存 + 21:00 data updater,2 commit 一 PR)、#33(P-I5a 事件驱动回测架构重构 + opt-in 分钟尾盘 event model,4 commit 一 PR)、#35(P-I5b 分钟尾盘执行期 raw stk_limit 涨跌停可行性,4 commit 一 PR)、#37(P-I5c MMP 分钟因子端到端 opt-in alpha)、#39(P-I5d MMP 五分位分组回测 standalone,含 I5c plumbing)、#41(数据层 D1 契约文档 + token 解析去重)、#43(数据层 D2 TushareCache specs/parsers 拆分)、#45(数据层 D3 report-only 数据质量层)、#47(数据层 D3b default-off `data-update` 质量报告钩子)、#49(数据层 D4 coverage ledger 批量写 + 进程内查找缓存)、#51(数据层 D5 opt-in 有界并发 + 全局限频器)、#53(P-I5e MMP 五分位 CSI300 独立泛化检验,负结果)、#55(P-I5f 分钟尾盘执行流动性/容量诊断,report-only)、#57(数据层 schema 注册表 + default-off drift 守卫)、#59(数据层 全A 增量 auto-warm + systemd 定时,default-off)、#61(数据层 全A 历史回填 `data-backfill`,分块/续跑/失败隔离)、#62(进度文档)、#63(因子评估契约层 `analytics/eval/` + StandardFactorEvaluator + dashboard + PR-C 因子,4 commit 一 PR)、#64–#73(PR-D…PR-M 十个分钟因子复现,**一因子一分支一 PR**)、#74(因子评估契约 v0.8 + v0.9 判定门修复)、#75(尾盘执行价 VWAP + 分钟持有期收益复权)、#76(报告披露修正 + I5f 名义按真实规模重测)、#77(`adj_factor` 下降质量检查)、#78(#76 的 follow-up:扫描式正则守卫被七种改写实测证否 → 闸门描述改单一来源)、#79(十一因子改 14:51 VWAP exec-to-exec 基准,**评审未返回、靠自查合并**)、#82(闸门/成交价描述全仓清扫,12 处;#78 守卫射程不足的修正)、#80(进度文档)、#84(因子层重构 D0 纸面契约:availability policy 常量 + 预指派表 + 性质编目)、#85(进度文档)、#86(因子层重构 D1:registry + PanelField requires + FactorSpec 契约 v1.0)、#87(因子层重构 D1 面板冻结:14 因子 raw 基线 + manifest)、#88(进度文档)、#89(因子层重构 D2:minute primitives + ops + 11 因子迁移,与冻结基线逐位一致)、#90(进度文档)、#91(因子层重构 D3:store 层——稀疏值存储 + key/指纹 + tail-recompute + R5 fina 视界统一)、#92(进度文档)、#93(因子层重构 D4:FactorService + decision-view materializer + pooled 饱和填充)、#94(进度文档)、#95(因子层重构 D5a:exec 基线冻结 + 11 runner 差异编目 + 可行性探测)、#96(进度文档)、#97(因子层重构 D4b:per-symbol 流式物化)、#98(进度文档)、#99(因子层重构 D5b:评估契约 v1.0 + 诊断通道 + 14:50 可见性守卫;**C4 中止上报**)、#101(因子层重构 D4c:store 去 universe 依赖——(date,symbol) 缺口判定 + store 只存 per-symbol 中间量、截面 combine 移到读出装配 + 调用方 symbol 列表单点归一化)、#103(jump_amount_corr_20 补 14:50 截断 correctness fix——唯一未做截断的分钟因子,exec_to_exec 下信息集越过自己入场锚的真实前视;含 dashboard 布局 5/4 分支修复 + census 守卫前缀匹配修复;单独成 PR 非重构一部分)、#105(因子层重构 D5 C4:统一 exec-only FactorEvalRunner——因子取数全走 factors.service、异构披露唯一家、C5 对账 harness 三模式 + 77/77 硬闸门、warmup 左延具名类登记)均已 merge 到 `main`**;**OPEN 未合并:#38**(见 P-I5d 处置,未获授权关闭)。commit 用 conventional 格式,**无 attribution**(不加 Co-Authored-By)。 +- **Git**:feature 分支 + PR。**PR #1(P0+P1)、#2(P2-1)、#3(P2-2)、#4(进度文档)、#5(P2-3)、#6(进度文档)、#7(P2-4)、#8(进度文档)、#9(P3-1)、#10(进度文档)、#11(P3-2)、#12(P3-3)、#13(进度文档)、#14(P3-4)、#15(进度文档)、#16(P3-5)、#17(进度文档)、#18(P3-6)、#19(P3-7)、#20(进度文档)、#21(P3-8)、#22(进度文档)、#23(P4-1)、#24(进度文档)、#25(P4-2)、#28(tushare 权限/限频探测 + capability registry)、#29(I1–I4 分钟级 intraday pipeline,4 commit 一 PR)、#30(进度文档)、#31(P4-3 因子支撑端点缓存 + 21:00 data updater,2 commit 一 PR)、#33(P-I5a 事件驱动回测架构重构 + opt-in 分钟尾盘 event model,4 commit 一 PR)、#35(P-I5b 分钟尾盘执行期 raw stk_limit 涨跌停可行性,4 commit 一 PR)、#37(P-I5c MMP 分钟因子端到端 opt-in alpha)、#39(P-I5d MMP 五分位分组回测 standalone,含 I5c plumbing)、#41(数据层 D1 契约文档 + token 解析去重)、#43(数据层 D2 TushareCache specs/parsers 拆分)、#45(数据层 D3 report-only 数据质量层)、#47(数据层 D3b default-off `data-update` 质量报告钩子)、#49(数据层 D4 coverage ledger 批量写 + 进程内查找缓存)、#51(数据层 D5 opt-in 有界并发 + 全局限频器)、#53(P-I5e MMP 五分位 CSI300 独立泛化检验,负结果)、#55(P-I5f 分钟尾盘执行流动性/容量诊断,report-only)、#57(数据层 schema 注册表 + default-off drift 守卫)、#59(数据层 全A 增量 auto-warm + systemd 定时,default-off)、#61(数据层 全A 历史回填 `data-backfill`,分块/续跑/失败隔离)、#62(进度文档)、#63(因子评估契约层 `analytics/eval/` + StandardFactorEvaluator + dashboard + PR-C 因子,4 commit 一 PR)、#64–#73(PR-D…PR-M 十个分钟因子复现,**一因子一分支一 PR**)、#74(因子评估契约 v0.8 + v0.9 判定门修复)、#75(尾盘执行价 VWAP + 分钟持有期收益复权)、#76(报告披露修正 + I5f 名义按真实规模重测)、#77(`adj_factor` 下降质量检查)、#78(#76 的 follow-up:扫描式正则守卫被七种改写实测证否 → 闸门描述改单一来源)、#79(十一因子改 14:51 VWAP exec-to-exec 基准,**评审未返回、靠自查合并**)、#82(闸门/成交价描述全仓清扫,12 处;#78 守卫射程不足的修正)、#80(进度文档)、#84(因子层重构 D0 纸面契约:availability policy 常量 + 预指派表 + 性质编目)、#85(进度文档)、#86(因子层重构 D1:registry + PanelField requires + FactorSpec 契约 v1.0)、#87(因子层重构 D1 面板冻结:14 因子 raw 基线 + manifest)、#88(进度文档)、#89(因子层重构 D2:minute primitives + ops + 11 因子迁移,与冻结基线逐位一致)、#90(进度文档)、#91(因子层重构 D3:store 层——稀疏值存储 + key/指纹 + tail-recompute + R5 fina 视界统一)、#92(进度文档)、#93(因子层重构 D4:FactorService + decision-view materializer + pooled 饱和填充)、#94(进度文档)、#95(因子层重构 D5a:exec 基线冻结 + 11 runner 差异编目 + 可行性探测)、#96(进度文档)、#97(因子层重构 D4b:per-symbol 流式物化)、#98(进度文档)、#99(因子层重构 D5b:评估契约 v1.0 + 诊断通道 + 14:50 可见性守卫;**C4 中止上报**)、#101(因子层重构 D4c:store 去 universe 依赖——(date,symbol) 缺口判定 + store 只存 per-symbol 中间量、截面 combine 移到读出装配 + 调用方 symbol 列表单点归一化)、#103(jump_amount_corr_20 补 14:50 截断 correctness fix——唯一未做截断的分钟因子,exec_to_exec 下信息集越过自己入场锚的真实前视;含 dashboard 布局 5/4 分支修复 + census 守卫前缀匹配修复;单独成 PR 非重构一部分)、#105(因子层重构 D5 C4:统一 exec-only FactorEvalRunner——因子取数全走 factors.service、异构披露唯一家、C5 对账 harness 三模式 + 77/77 硬闸门、warmup 左延具名类登记)、#107(因子层重构 D5 C4b:valley_price_quantile 绑定——combine_daily 声明式引擎扩展 + 平移面板第三条路逐比特等价双侧钉 + binding.py 折进 code_hash + 截面因子 panels 类边界三裁定)均已 merge 到 `main`**;**OPEN 未合并:#38**(见 P-I5d 处置,未获授权关闭)。commit 用 conventional 格式,**无 attribution**(不加 Co-Authored-By)。 - **不过度设计**:按路线图 MVP 先打通一条端到端链路,再加层(architecture.html §11,Phase 0→3)。 - **secrets** 一律走外部 `.config.json`;repo `.gitignore` 已排除数据产物(`*.parquet`等)、缓存、`tmp/`(仅留架构文档)。 - 文件小而专(<800 行),immutable 优先。 @@ -382,6 +382,15 @@ data → universe → factors(特征) → alpha(合成/预测) → portfolio(+ri - 评审 APPROVE-WITH-NITS(0 CRIT/HIGH/MEDIUM;64 个自造 mutation probe 全过、verbatim 8/8 复核、panels 模式独立重跑逐格一致);登记 LOW-1(bounded warmup 类无量级/cell 数上限,~1.6% 网格,**C5 加 cell 数 ceiling**)与 LOW-2(reports 腿 digit OR 规则散文理由可变义,verdict 标签仍严格);NIT-1/2 装饰性。 - gates(lead 独立重跑):pytest 2492 passed(node-ID 差分 0 挤掉)、ruff clean、phase0 锚 0.9600/0.8408、32/32 configs、secret scan 2 处 benign(新 config 的 external_secret_file 路径 + key 名,与 main 上 11 份 eval config 同形,无 token 值)、exec_baseline --verify 77/77 @ 45c14aa。 - 刻意不做:删旧 runner(C6)、11 因子全量四腿(C5)、vpq 绑定 + binding 折 code_hash(PR-C4b,lead 已裁定批准)、mmp_ew(D6c)、run registry(D7)。 + - **D5 C4b(PR #107,vpq 绑定 + code_hash 折叠——11 分钟因子全部绑定完成)**: + - **vpq 绑定**:`valley_price_quantile` 的 residualize 是逐日截面 OLS(值依赖 universe)⇒ 按 D4c 架构存 per-symbol `raw_qbar` 中间量、截面 combine 移到读出装配;combine 需日频 close ⇒ 唯一引擎扩展 `DailyCombineInput`/`combine_daily` **声明式**槽位(红线 #5 禁 isinstance 守住;顺带删掉了旧的 `isinstance(factor, ValleyPriceQuantileFactor)` 分发);`combine_daily_panel` 用 decision-lagged close + 左端 22 个 lagged 交易日 warmup(欠暖钳位有一行披露)。 + - **平移面板第三条路**:因子内部 T-1 会被 decision 视图二次滞后成 close_{d−2} ⇒ 传平移面板 + 关内部 T-1,**逐比特等价双侧钉**(binding 侧 `Series.equals` + 破坏对照 ~8.5e-2;runner 侧 fixture 240/240 max|diff|=0.0 + 左端 22 日硬断言;评审用不同 fixture + 新扰动独立复验)。 + - **binding.py 折进 code_hash**(lead 裁定 Q2):承重语义文件此前在 key 射程外;mutation 实证改 binding → 18/18 factor key 全变、改无关模块 → 0 变;dev-only `artifacts/factor_store/` 一次性失效已披露。 + - runner 启用 vpq + NeutralizationCoverage 机制 B(经新 `service.stored_payload` 回读 raw 中间量,同一 key/fingerprint/coverage 引擎、非第二取数路径)+ **anchors 模式修截面因子全 universe 服务**(5 锚 symbol < min_cross_section=10 必全 NaN——C5 对 intraday_amp_cut 本也会踩)。 + - **panels 类边界三裁定**(首个 FAIL 100% 分解后 lead 裁定):① pooled 月单调豁免锚到**结构性部分月**(冻结面板首个 finite 值所在月;初版位置性实现被评审 probe 绕过 → 修复 + 回退 mutation 证据);② 新具名类 `threshold_flip_contamination`(窗口 [2023-06-01,2023-07-14]、600623.SH ≤2e-04、其余 ≤1e-06、≤20,000 cell——PRV 临界 bar 翻转×逐日 OLS 污染族,输入侧变化已排除:ledger 零写入 + qbar 双几何逐位一致 1.1e-16,评审独立复算 1,241/1,241 格);③ float 尾加 abs 下限 1e-12 + cap 分档(bars-only 101 / 截面 1,000)。 + - **真实对账(cache-only `stk_mins_live_calls=0`,评审独立重跑逐数一致)**:panels rc=0(warmup=24,568 按月 902→19,980→3,667→19 豁免后单调 / float_tail=883 / flip_contamination=19,177 / unclassified=0)、reports 4/4 OK、anchors 5/5;vpq verdict Watch/Watch 与冻结基线同(数值微移全在登记 warmup 聚合效应内)。 + - 评审两轮: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 未变。 - ✅ 质量门(**当前 `main` @ `f432dc5` 实测**:`python -m pytest -p no:warnings` **1776 passed**、`ruff` clean、`validate-config` **31/31 配置逐个 OK**、`run-phase0`(demo)**ic 0.9600 / annual 0.8408 不变**)。构成对得上:`aa19968` 实测 **1740** → #78 加 2(含钉住破折号闭合的那条)= **1742** → #79 加 34(两个新测试文件,0 个既有测试被挤掉)= **1776**。新增测试分组(`--collect-only` 实数,`aa19968` 口径):**因子评估契约层 contract=337 + standard=113 + figures=7 / 十一因子(factor + eval runner,21 文件)=421 / PR#75 exec-vwap-basis=46 / D3 market quality 15→21(含 #77 `decreasing_adj_factor` 及其相对-vs-绝对尺度 mutation 测试)**。历史分组(旧 793 基线):`pytest` **793 passed**(P0=97 / P1=78 / P2-1=22 / P2-2=22 / P2-3=14 / P2-4=8 / P3-1=10 / P3-2=18 / P3-3=16 / P3-4=15 / P3-5=22 / P3-6=27 / P3-7=25+1 throttle / P3-8=8 / P4-1=28 / P4-2=17 / **intraday I1 schema=14 + feed=9 / I2 cache=10 / I3 aggregate=13 / I4 execution=10 / P4-3 cache=10 + updater=7 / P-I5a event-backtest=19 / P-I5b exec-feasibility=16 / P-I5c mmp-minute=18 / P-I5d mmp-quintile=19 / P-I5e 仅 config(无新测试,`test_cache_config` 的 config glob 自动 +1)/ P-I5f intraday-liquidity=17(+ `test_cache_config` config glob 自动 +1)/ D1 token-dedup index-feed +2 / D2 cache-modularization +5 / D3 data-quality market=15 + intraday=12 + report=14 / D3b data-update-quality=18 / D4 coverage-ledger-scaling=13 / D5 scheduler=9 + concurrency=12 / schema-registry-guard=62 / all-A-incremental=12 / all-A-backfill=22**);当时 `ruff` clean、`validate-config` 20 配置(data_update + phase_i5a…phase_i5f)+ `run-phase0`(demo)均 OK(**ic 0.9600 / annual 0.8408 自 P0 起从未变过**)。 - ⚠️ 剩余(已显式披露):日线 only、demo 路径非真数据、旧三因子无信号(P3-3/P3-4 实证;但其组合在 2024-2026 holdout 上 SSE50/CSI300/CSI500 全正、CSI500 高达 +17.8%——小样本/regime 翻转的持续例证);value/低波信号获得**独立样本符号级确认**(P3-7 SSE50/CSI300 量级衰减;P3-8 CSI500 泛化成立且更强),组合级盈利能力仍未确立(排名跨 cell 翻转);subset 报告文件名已可配置(P3-8 起不再互覆盖)。**分钟因子侧新增披露**:十一个复现因子全部 EXPLORATORY、**封顶 Watch,无一到 Adopt**,1× 费率下净多空为正的只有 2 个(PR-F/PR-L,且 PR-L 扛不住 2×)——**IC 强 ≠ 可交易**;MMP 的唯一正面证据(I5d)在修正引擎上退化、I5e 负结果加强;I5f 的容量结论已按**真实 100 万名义**重写(1000 万口径的"约半数不足"作废);**日频除权审计已完成**(GENUINE、无 vintage 接缝、评估池暴露 1/603,258,不重述任何因子结果),**分钟路径的复权缺陷已在 PR #75 修**;exec-to-exec 改基准已随 **PR #79 合并**,close-to-close 与 exec 两套 artifact 并存;⚠️ **#79 的 code review 未返回、靠自查合并**,其"未独立核"清单(五条 mutation 声称 / 十一个 runner 改动是否机械等同 / `execution_capacity` 透传)仍待后续检查——若查出问题,重述 exec 基准数字而非 close-to-close;schema 守卫**仍未接** live `data-update` 暖跑路径;HTML compendium(`artifacts/reports/factor_compendium.html`)**还读 v0.8 结果,待按最终结果修订**。