跳到主要内容

FinBayes Case 库 70/20/10 三集分集物理实施约定

§0 范围与定位

本文件定义 FinBayes case 库在工程仓的物理实施:目录布局、case_id 命名规约、三集公开范围 gate、防数据泄漏约束。事实源在 Phase 4 评测体系 + ADR-007 supplement + EvalHarness 子系统 + Phase 5 治理,本文件不重述分集语义。

§1 物理目录约定(工程仓相对路径)

工程仓 case 库根目录:fixtures/cases/。三集为顶层子目录,每集按 MCA 桶(B1 / B2 / B3 / B4 / B5a / B5b / B6 / B7)二级分子目录:

fixtures/cases/
├── dev/ # 70% · 可公开 · 进 git
│ ├── B1/ C1.json C7.json
│ ├── B2/ C2.json C3.json
│ └── B7/ L1.json L2.json L9.json
├── test/ # 20% · 仅 .fact.json 进 git
│ ├── B1/ C8.fact.json
│ └── B3/ C9.fact.json
├── holdout/ # 10% · 完全私密 · 不进 git(仅 .gitkeep)
├── _truth/ # 标答 / 期望激活 / 关键洞察 / 事后演化(全部 gitignore)
├── _schema/ # case.schema.json
└── _index.json # 全集 case_id ↔ split ↔ bucket ↔ sha256 映射

文件格式:JSON(与 M0 走通骨架 Mock Provider Fixture 规范 同体例),每文件含 schema_version: 1

§2 case_id 命名规约

保留原命名作为业务标签(C1-C10 / A-1-A-4 / L1 / L2 / L9 / L13 已在 18 case 报告中固化,迁移成本高);在 case JSON 顶层加 split + mca_bucket + public_scope 三字段补足元信息。

case 文件顶层字段:

{
"schema_version": 1,
"case_id": "C1",
"case_label": "Fed-2022",
"split": "dev",
"mca_bucket": "B1",
"public_scope": "full",
"as_of_date": "2022-09-21",
"source_anchor": "governance/workstreams/finbayes-cognition-system-research/drafts/2026-05-28-phase2-case-01-fed-2022.md",
"facts": { },
"ground_truth_ref": "_truth/C1.truth.json"
}

字段语义:split ∈ dev / test / holdout;mca_bucket ∈ B1..B7(含 B5a/B5b);public_scope ∈ full / fact-only / private;as_of_date 为该 case 事实层「认知时点」(ISO-8601 日期,详见 §5.5),即评测时模型被允许看到的信息截止时刻——事实层任何信息的时间戳不得晚于 as_of_date。与各子系统 as_of 参数(见 MCA 分类器 / 知识图谱服务)同语义。

文件命名<case_id>.json(如 C1.json / A-2.json),事实层导出加 .fact.json 后缀。

可选 composite 标签<split>-<bucket>-<case_id>(如 D-B1-C1 / T-B4-A2)由 _index.json 自动生成,不写入 case 文件本身,避免 split / bucket 漂移引发的级联改动。

§3 70/20/10 分集落到 18 case

比例case 数候选 case
dev70%13C1 / C2 / C3 / C4 / C5 / C6 / C7 / A-1 / A-2 / A-4 / L1 / L2 / L9
test20%4C8 / C9 / C10 / L13
holdout10%1-2A-3(首选)+ 季度补 case 中 ≥ 1

v1→v2 治理门槛phase5):dev 触发 ≥ 4 case + 跨 ≥ 2 MCA 桶 + ≥ 1 pending 桶证据。holdout 桶位均匀:每季度补 15-20 case 时按桶位均匀回填,避免长期偏 B1。

§4 公开范围 gate

public_scope进 git公开内容私密内容
devfull✅ 进治理库 + 工程仓完整 case 报告 + 标答 + 期望激活清单 + 关键洞察 + 模型输出
testfact-only.fact.json 进 git事实层(市场快照 + 信源 + 时间戳 + 关键数字 + MCA 桶位标签)标答 / 期望激活 / 关键洞察 / 事后演化(落 _truth/ 目录,gitignore)
holdoutprivate❌ 不进 git全部内容仅在评测系统本地存储

实施方式(v1 起步)

  1. .gitignore 规则:
    fixtures/cases/holdout/**
    !fixtures/cases/holdout/.gitkeep
    fixtures/cases/_truth/**
    !fixtures/cases/_truth/.gitkeep
    fixtures/cases/test/**/*.truth.json
    fixtures/cases/test/**/*.insights.json
  2. CI 校验:pre-commit 跑 scripts/check_case_split.py,遇 public_scope != "full" 字段进入 git 暂存区则阻断。
  3. v2 升级路径(待评估):holdout 改 git-crypt 或拆独立私有 repo。v1 阶段「不进 git + 本地单点存储 + 季度 rotate」足够。

§5 防数据泄漏约束

  1. 三集互斥:同一 case_id 不得同时出现在任意两集(_index.json + CI 校验)。
  2. holdout 不进任何公开评测报告 / Agent pack 派生 / Docusaurus 站点。
  3. 模型训练 / 提示词调试 / fixture 录制:仅用 dev 集。
  4. 常规评测:dev + test。
  5. 季度大评估 / 防退化基线对照才动用 holdout(每 4 季度 ≥ 20% 抽检,对齐 phase5 §防退化)。
  6. 跨集 hash 校验:按 facts + case_id 计 SHA256,test / holdout 与 dev 同 hash 即报警。
  7. 时间序防泄漏:除上述按 case_id 的集合互斥外,再叠加按时点(as_of_date)的时间序约束,禁止未来信息回灌到过去样本。规则见 §5.5。

§5.5 时间序切分约束(金融防泄漏核心)

金融评测的核心泄漏风险不是「同一 case 跨集」,而是时间泄漏:用「事后才知道的信息」去评判「当时只能看到过去」的判断,会系统性高估模型能力。MCA 桶随机分集解决「桶覆盖均衡」,但不约束时间——本节在其上叠加时点切分。

§5.5.1 as-of 时点是事实层的硬边界

每个 case 顶层带 as_of_date(§2)。语义:评测该 case 时,模型被允许看到的信息截止于 as_of_date 当日(含)。

约束内容
事实层不含未来信息facts 内任何信息的时间戳 ≤ as_of_date;事后才发生的价格 / 事件 / 财报不进 facts
标答与事实物理隔离「之后实际怎么演化 / 标答」只落 _truth/(gitignore),评测输入阶段绝不喂给模型;模型先在 as_of_date 视角下作答,再与 _truth/ 比对
信源时间戳校验每条信源带 published_atpublished_at > as_of_date 的信源视为泄漏,CI 校验报错
as_of 参数贯穿子系统调用(MCA 分类 / 知识图谱时钟相位)以 case 的 as_of_date 作为 as_of 入参,保证时点一致,不读时点之后的图谱状态

§5.5.2 训练 / 校准 / 评测按时点切分

在 70/20/10 桶切分之上,叠加时间序不重叠约束。原则:训练(dev)用较早时间窗,holdout 取最近时间窗,使「在最新、模型从未在训练中见过的时段」上评测,逼近真实「上线后面对未来」的场景。

时间窗角色时间序规则
dev(70%)较早 + 中段时间窗训练 / 提示词调试 / fixture 录制只用 dev;其 as_of_date 应 ≤ 切点 T_cal
test(20%)中段时间窗(校准期)常规评测 + 阈值校准;as_of_date 落 (T_cal, T_holdout]
holdout(10%)最近时间窗as_of_date > T_holdout(取数据集中最近的时间窗);仅季度大评估启用

切点 T_cal / T_holdout 由数据集时间分布拍板(v1 起步建议 T_holdout = 数据集最近 1 个季度起点),任何调整走 governance/change-protocol.md

§5.5.3 跨集时间不重叠的硬规则

规则内容违规判定
单调时点max(dev.as_of_date) ≤ min(test.as_of_date) ≤ min(holdout.as_of_date)(同一事件多 case 允许等于切点)任意集时点跨越切点反向 → CI 报错
holdout 取最近holdout 全部 case 的 as_of_date 不早于 test / dev 的最大时点holdout 出现早于 test 最大时点的 case → 报警(除非显式标 legacy 例外)
禁未来回灌 devdev 集 fixture 录制 / 训练绝不引入 as_of_date 晚于该 case 的任何外部信息录制 fixture 含晚于 case as_of_date 的响应 → 报错
时点与 hash 双校验§5 第 6 条 SHA256 碰撞校验 + 本节时点单调校验同时跑任一失败即阻断

与桶切分的关系:桶(B1..B7)保证「能力维度覆盖」,时点保证「无时间泄漏」。二者正交叠加——同一桶内的 case 仍须满足跨集时点单调;若某桶 case 时间分布过窄无法满足时点切分,优先保时点约束、按 phase5 季度补 case 时回填该桶的最近时间窗样本。

§5.5.4 时间序泄漏的检测落点

scripts/check_case_split.py(§7)扩展校验项:

  1. 每 case:facts 内信源 published_atas_of_date(事实层无未来信息)。
  2. 跨集:时点单调(dev ≤ test ≤ holdout)+ holdout 取最近窗。
  3. _index.json 增列 as_of_date,供 EvalHarness 按时点过滤。
  4. 违规默认阻断(pre-commit + CI);legacy 例外须在 _index.json 显式标注 time_split_exempt: true + 理由。

§6 case_id × split × bucket 建议映射表

v1 起步建议分配,待 Phase 5 治理首季评估拍板。任何调整走 governance/change-protocol.md

case_idbucketsplitscopecase_idbucketsplitscope
C1B1devfullC8B1testfact-only
C2B2devfullC9B3testfact-only
C3B2devfullC10B3testfact-only
C4B1devfullA-3B5bholdoutprivate
C5B1devfullL13B7testfact-only
C6B1devfullA-1B5adevfull
C7B1devfullA-2B4devfull
A-4B6devfullL1B7devfull
L2B7devfullL9B7devfull

桶位分布(v1 起步 18 case):B1 6 + B2 2 + B3 2 + B4 1 + B5a 1 + B5b 1 + B6 1 + B7 4 = 18。

§7 实施清单(Codex / 工程仓接手人)

  1. 创建目录:mkdir -p fixtures/cases/{dev,test,holdout,_truth,_schema}/{B1,B2,B3,B4,B5a,B5b,B6,B7} + 落 .gitkeep
  2. case 文件迁移:从治理库 18 case 报告抽事实层 + 标答层 → 工程仓 JSON(脚本 scripts/migrate_case_reports.py,待新建)。
  3. .gitignore 更新:按 §4 规则追加。
  4. case 文件顶层字段:按 §2 schema 落 split / mca_bucket / public_scope / as_of_date / source_anchor 五字段;为 18 case 回填 as_of_date(取事件认知时点)。
  5. 跨集校验脚本:scripts/check_case_split.py 输出 _index.json + 报 split 互斥违规 + 报 hash 碰撞 + 报时点单调违规(§5.5.3)+ 报事实层未来信息(§5.5.4),pre-commit 接入。
  6. _index.json:启动期 / CI 期自动生成,含 case_id / split / mca_bucket / public_scope / as_of_date / sha256 / composite_id 七字段(legacy 例外另带 time_split_exempt)。
  7. EvalHarness 接入:evaluate_batch(split=...) 读取 _index.json,按 split 加载 case,并以各 case as_of_date 作为子系统 as_of 入参(时点一致,不读时点之后状态);holdout 仅在「季度大评估」流程显式启用。
  8. 时间序切点:拍板 T_cal / T_holdout(§5.5.2),v1 起步 T_holdout = 数据集最近 1 季度起点;调整走 governance/change-protocol.md

§8 关联资产