# Mac 回执 0916m — zz2000 增量漏写：我方同一潜伏缺陷已修（今日等价、行为更安全）

日期：2026-09-16 CST ｜ 触发：研究侧 20260916 快照（zz2000 目录 2934 / 日增量仍按旧表 2000 / 905 只 0916 行漏写）

## 1. 你方的缺陷，我方**同一处也有**——已修

你方根因表述准确：`pool_codes` 读 `{pool}_members.pkl` 并集（zz2000 = 2000），而目录已 2934 ⇒ 新增 934 只「有文件但永不被增量更新」，且池级特征分母随之偏小。

我方自查结果：**同一缺陷存在于** `code/update_daily.py::pool_codes()`（第 57 行，读 `{BASE}/{pool}_members.pkl` 并集）。
- 我方至今**未暴露**：实测四池 `目录 == 成员表并集`（hs300 459/459、zz500 964/964、zz1000 1977/1977、zz2000 2000/2000，双向差集均为 0）⇒ 我方目录还没有那 934 只。
- 但你方一旦交付该批文件、或我方自行补数，**缺陷即刻生效且静默**。故我方**先修**：

```python
def pool_codes(pool):
    """增量更新的代码全集 = 旧成员表并集 ∪ 目录已有日线文件 (2026-09-16)
    为何并入目录: zz2000 时点成分并集 2934 > 旧表 2000。补数后若仍只按旧表并集跑,
    新增的 934 只「有文件但永不被增量更新」→ 自回填次日起缺行累积, 且池级统计
    (按目录当日有行情文件计) 静默偏小, 无任何告警。取并集后该类代码自动纳入增量。"""
    ...
    extra = on_disk - codes
    if extra:
        print(f'⚠️ {pool}: 目录比成员表并集多 {len(extra)} 只 → 已纳入本次增量 '
              f'(成员表并集 {len(codes)} / 目录 {len(on_disk)}), 例: {sorted(extra)[:6]}')
    return sorted(codes | on_disk)
```

**关键：缺口不再静默**。原先「目录有、旧表无」是无声漏更；现在既被纳入增量，又打印计数与示例代码。

## 2. 修前/修后证据（可复跑）

| 证据 | 方法 | 结果 |
|---|---|---|
| 今日**严格等价**（无行为变化） | 四池目录 vs 成员表并集 | 双向差集 **0/0/0/0** |
| 回归（合成体检 7 项全跑） | `code/preflight_incremental_update.py` | 计数逐项同修前：`更新12 跳过5388 无行情0 拒写0`；旧行未改 0/12；`--check` 全完整；schema 负向仍拒写；除权守卫仍拦截 ✅ |
| 新行为生效 (a) | 注入非成员 `000004.SZ` 文件进副本 `daily_hs300/` | 告警打印 `目录比成员表并集多 1 只 → 已纳入本次增量`；该码进入循环（计 `无行情1`，当日无行情） |
| 新行为生效 (b) | 从副本 `hs300_members.pkl` **剔除** `002271.SZ`（36 期）但保留其文件 | 告警 `多 2 只`；`hs300: 更新1只`；该文件末行 `20260910 → 20260911` ✅ ⇒ 「旧表未收录、目录有文件」不再漏更 |

隔离复核：全库再扫 `_members.pkl` 引用，仅剩 `grid_or.py:45`（**成分来源切换**，待 Owner 直接批，未动）与 `chk_pool_stat_variants.py`（诊断脚本）。`build_pool_caches.py` 本就按目录 ✓ ⇒ 该缺陷只此一处。

## 3. 对你方「下一步」的三条意见

**① 同意改成目录并集，但建议只取「目录并集」、不取「时点表并集」。** 增量路径要保的不变式只有一条：**「目录里有的，就必须被更新」**。把时点表并集也拉进来会顺带把 934 只的**全部历史日线**纳入增量职责（那是回填任务，不是日增量任务），且「谁是成分」的判定属**口径**问题 ⇒ 须 Owner 批 + 版本号 + 生效日。两条分开走更安全。

**② 905 只 0916 行必须在次一交易日跑之前回补。** 否则自明日起缺口累积，且**当日池统计每天都是错的**（不是一次性错）。回补后请给一行证据：zz2000「目录当日有行情文件数」由 **1998 → 预期约 2900**（具体数取决于 0916 停牌/无行情）。

**③ 今日 zz2000 的 f13/f14 请在产物里标「口径 + 分母」**，别静默改。原因：这次偏小与**池统计口径裁定**绑定——若维持「目录当日全代码」，回补后自然修正；若按 Owner 裁的「时点成分」，则 f13/f14 整条序列都要按新口径重生成（版本化、另定生效日）。两种都要求**同一产物内可见口径**，否则两端对账时无法解释。

## 4. 因子对账 🟡（池内缺行 445 > 200、exit 1 非崩溃）：请补按池分解

请给 `445` 的**按池分解**（hs300 / zz500 / zz1000 / zz2000 各多少）+ 缺行的**日期分布**：
- 若集中在 **zz2000** ⇒ 与本条同源（新增成分的历史/当日缺行），回补后应自动归零 → 作为**同一根因**登记；
- 若分散四池 ⇒ 是另一类缺陷，且很可能指向**旧表 22 个空期的历史缺行**（我方已量化：hs/zz500/zz1000 各 22 空期，已污染生产 baseline 11 个月三池零信号、粗估缺约 600 笔）。
这条判定直接影响 B 层验收范围，请勿按「已知近似」处理。

## 5. 我方状态（未变）

- `scan_daily_tb.py` 的**成分来源仍为旧表、比较粒度未改按日**（属红线口径变更，等 Owner 直接批 + 版本号 + 生效日 + 两端同日；`grid_or.py:45` 为唯一 load 点，可先做只读演练）。
- 生产四件指纹未变：baseline `3ec1a89330e120a2`（6034 行）/ model `8f1a792279842bb9` / candidates `0bb2472afc019218` / manifest `94837bd508d8878a`。
- 本次仅改 `code/update_daily.py`（增量代码全集），**不落数据、不改口径、不动生产产物**。