Step 4 · Claude 扮演 Codex 工程实施角色 独立 review 报告
0. 角色切换声明
【Inference】我天然偏治理 / 架构 reviewer 视角(追文档一致性、ADR audit trail、跨工作流交接、措辞收敛)。本次刻意约束:(1)假设有效窗口仅 32K,不利用 1M context 做跨文档相互印证;(2)只关心「写 cognition/types.py / migrations/0001_init.sql / providers/base.py 时,光标停在哪一行,会因为字段表 / 接口签名 / 测试断言 / fixture / cwd 不清而停下来」;(3)不评判 ADR 治理流程合规性、不评判文档之间的措辞对齐;(4)每条结论必须能 ground 到 <file>:<line>。
本报告刻意不复读 Step 3 Claude 治理视角 review(落在同目录 2026-05-28-step3-claude-review.md)的结论,工程实施视角 review 与之独立。
1. 执行摘要
【Inference】M0 文档包勉强足够启动 C-1 第一 PR(落 1.1 minimal Pydantic + 1.0 主体 + MCABucketM0 三类骨架);但不足以一次性落完整 cognition/types.py + 通过 §14.5 tests/contract/ 全部断言。
最大单点风险是契约源 §5 草案 StructuredCognitionResult11「10 要素沿用 1.0」是注释而非代码(字段缺失),合并 1.0 主体 + 1.1 minimal 时 schema_version vs structured_result_version 双字段语义冲突会直接打穿 §14.5 test_all_pydantic_models_have_schema_version。次要风险是 4 子系统接口签名引用了至少 5 个未定义类型(MarketStateWindow / StructuredCognitionResultDraft / GroundTruth / CaseInput / AnnotatedCase),C-1 import 链一搭就报 NameError。
判断:可启动 C-1,但启动条件须缩为 schema surface + import smoke,不承诺通过 §14.5 全部 contract 测试。
2. 八维度评分表
| 维度 | 我(Claude 扮演 Codex)的分 | Codex Step 3 分 | 差异 | 主要证据 |
|---|---|---|---|---|
| 1. 字段完整性 | 3 | 4 | -1 | 契约源 cognition-1.1-contract.md:300-308 草案不含 10 要素字段;M0 m0-walking-skeleton.md:211-226 1.0 主体含 schema_version,§3.5 m0-walking-skeleton.md:380-397 minimal 不含 schema_version 但有 structured_result_version,双 version 字段语义未锁。MCABucketM0:376-377 worst_axis / tag_version 设 Optional,但契约源 cognition-1.1-contract.md:97 主体定义两字段必选 — Pydantic 转译时直接歧义 |
| 2. 接口签名 | 2 | 3 | -1 | KGS knowledge-graph-service.md:55 引用 MarketStateWindow,全仓未定义;S1 consistency-middleware.md:33 引用 StructuredCognitionResultDraft,M0 §3 仅有 StructuredCognitionResult;EvalHarness eval-harness.md:33,42,71,78 引用 GroundTruth / CaseInput / AnnotatedCase / SLAWindow,全部未在 M0 §3 / 契约源 §5 定义。AuditEvent.payload: dict m0-walking-skeleton.md:448 类型擦除,§5 各 event_type 字段集表 m0-walking-skeleton.md:621-733 是文档表非 Pydantic 子类 |
| 3. 测试可执行性 | 3 | 4 | -1 | 5 条 sample pytest_check 直接 eval m0-walking-skeleton.md:913-963;但 m0_s4 用「美联储讲话」与 M0 范围 crypto only m0-walking-skeleton.md:62 冲突;m0_s5_unsupported 用 AAPL m0-walking-skeleton.md:955 同样越界。test_all_pydantic_models_have_schema_version m0-walking-skeleton.md:1660-1669 要求所有 BaseModel 含 schema_version,但 §3.5 全部 M0 类不含此字段(m0-walking-skeleton.md:270-397),写完即测试 fail |
| 4. 数据 fixtures | 2 | 3 | -1 | _index.json schema 给了 m0-walking-skeleton.md:862-869,但 compute_request_hash 仅给 docstring m0-walking-skeleton.md:846-857 无实现;浮点 4 位、tools 排序的边界(dict key 顺序、null 处理)未锁,工程实施者写完 hash 与未来真档 drift detector 算法不一致风险高。fixture 内容只有目录骨架 + 1 条示例 m0-walking-skeleton.md:874-890,5 条 sample 没对应的 5 条 fixture 实体 |
| 5. 错误处理 contract | 3 | 4 | -1 | exit 70 双重定义:CLI 退出码表 m0-walking-skeleton.md:797 「未预期异常」与 FinBayesError.exit_code = 70 m0-walking-skeleton.md:1324 默认同值,try/except 模板 m0-walking-skeleton.md:1341-1348 中 FinBayesError 与 Exception 都走 70,丧失定向 catch 能力。AuditWriter._write_sync m0-walking-skeleton.md:1445-1449 失败时无 fallback,boundary_rejected「零丢失」承诺 m0-walking-skeleton.md:714 在 DB init 未完成时空转 |
| 6. 跨子系统调用 | 2 | 3 | -1 | MCAClassifier 不在 M0 §2 表的 6 子系统行 m0-walking-skeleton.md:104-111(仅 Input/Orchestration/Evidence/State/Capability/Provider),但 MCA 子系统 README 把它视为第 7 个 subsystems/README.md:22 周围 + ADR-008 supplement 把 mca_bucket 列为 Task 元数据 — 调用入口在 Task Orchestration 还是新建第 7 子系统未定。ConsistencyMiddleware.trigger_backflow consistency-middleware.md:59-63 返回 list[BackTrigger],但 Task Orchestration 接 backflow 的接口在 M0 §2 没列 |
| 7. 单次 load 负载 | 2 | 3 | -1 | agent-pack 声明 max_tokens: 8000 agent-pack.yaml:92;但 m0-walking-skeleton 1846 行约 55K tokens,cognition-1.1-contract 354 行约 12K tokens,仅 2 个 include_mode: full 入口已 67K,远超声明 budget 的 8 倍,超 32K 有效窗口 2 倍。per_source_tokens: 1500 agent-pack.yaml:93 在 M0 包 full include 时事实不可达 |
| 8. 反查路径 | 3 | 4 | -1 | 契约源 §5 草案注释「10 要素沿用 1.0,定义见 ADR-008 主体与 m0-walking-skeleton §3」cognition-1.1-contract.md:302,但 sources 列出的事实源是 ADR-008-supplement(is supplement 不是 main),反查到 supplement 文档时其本身又指向上游 — 10 要素事实源的「单点」实际是 m0-walking-skeleton §3 而非 ADR,与 supplements: ADR-008-supplement frontmatter cognition-1.1-contract.md:9 暗示的优先级倒置 |
【Inference】整体上我的评分比 Codex 低 0.5-1.0 分/维度,原因不是 Codex 漏读,而是 Codex 写代码经验更具体地知道哪些缺口可以"实施者推断"补上;我在角色切换中更容易把"推断能补"算作"文档缺口"。
3. C-1 task 模拟卡点(新增 + 验证)
【新增卡点 N1】schema_version vs structured_result_version 顶层字段冲突
【Evidence】m0-walking-skeleton.md:28 文档约定「所有 Pydantic 模型含 schema_version: int = 1」;m0-walking-skeleton.md:217 1.0 主体 StructuredCognitionResult.schema_version: int = 1;m0-walking-skeleton.md:388 StructuredCognitionResult11Minimal.structured_result_version: Literal["1.1"] = "1.1" 不含 schema_version。
【Inference】合并 JSON 后顶层既有 schema_version=1 又有 structured_result_version="1.1",consumer 究竟 dispatch 哪个版本?test_all_pydantic_models_have_schema_version 会跑过 1.0 主体但 fail 在 1.1 minimal 全套子模型。
【新增卡点 N2】契约源 Pydantic 草案缺 10 要素字段
【Evidence】cognition-1.1-contract.md:300-308 StructuredCognitionResult11 只声明 6 新字段 + s1,注释「10 要素字段沿用 1.0」但字段本身没在草案出现。
【Inference】直接 from finbayes.cognition.types import StructuredCognitionResult11 然后实例化, main_answer / invalidation_conditions 不存在; 想合并须自创 class StructuredCognitionResultFull(StructuredCognitionResult, StructuredCognitionResult11Minimal) 多继承,但两类 model_config 一个 extra='forbid' 一个 extra='ignore' Pydantic v2 多继承时 ConfigDict 解析顺序未锁。
【新增卡点 N3】MCABucketM0 worst_axis 设 Optional 与契约不一致
【Evidence】契约源 cognition-1.1-contract.md:97 worst_axis: str / tag_version: str 必选; M0 m0-walking-skeleton.md:376-377 设 Optional[str] = None 标注「多桶命中裁决规则落地后必填」。
【Inference】C-1 写 Pydantic 时若按契约源必选,M0 fixture 无值会 ValidationError; 若按 M0 Optional, M1+ 合并 schema 时 required 字段新增触发 audit_contract_regression.py compare 模式的破坏性变更 fail m0-walking-skeleton.md:1608。
【新增卡点 N4】子系统接口签名未定义类型
【Evidence】knowledge-graph-service.md:55 MarketStateWindow; consistency-middleware.md:33 StructuredCognitionResultDraft; eval-harness.md:33,42,71,78 GroundTruth / CaseInput / AnnotatedCase / SLAWindow / IAAReport / SemiManualQualityReport / SLAWindow / CalibrationWindow / CalibrationReport; mca-classifier.md:50,75 AxisLevel / CalibrationWindow / CalibrationReport。全仓 grep 无定义。
【Inference】C-1 即使只落 4 子系统接口签名 stub,这些类型 import 链就断;Codex Step 3 给 4 子系统接口签名打 3 分但没列具体未定义类型清单,我推测是 Codex 默认"实施者写到这层会自己补 placeholder"。
【新增卡点 N5】MCA 子系统不在 M0 §2 6 子系统表
【Evidence】M0 §2 表 m0-walking-skeleton.md:104-111 列 6 子系统;subsystems/README.md 列 4 个认知子系统;MCAClassifier mca-classifier.md:38 输出 mca_bucket 但实施位置不在 M0 §2 任一行;ADR-008 supplement 把 mca_bucket 列为 Task 元数据,理应由 Task Orchestration 子系统产出。
【Inference】Task.mca_bucket 字段在 M0 §3 Task 模型 m0-walking-skeleton.md:158-170 也没出现 — Task 模型缺 MCABucket 字段, 但 audit task_completed.mca_bucket_label m0-walking-skeleton.md:646 必填路径却预期它在。
【验证 Codex 卡点 1】完整 vs minimal 字段必选差异
Codex Step 3 列「s1 完整必填 vs M0 可空」。【Evidence】我验证:cognition-1.1-contract.md:308 s1: NarrativeNumberConsistency 无 Optional 必选;m0-walking-skeleton.md:394 s1: Optional[NarrativeNumberConsistencyM0] = None 可空。Codex 判断成立,且与本报告 N3 (MCABucket worst_axis) 是同类问题:M0 minimal 字段宽松度普遍比契约源宽,M1+ 收紧时必触发破坏性变更。
【验证 Codex 卡点 2】1.0 主体 + 1.1 minimal 序列化合并
Codex 列「实施者必须自创 merge function」。【Evidence】m0-walking-skeleton.md:383-386 「两个 schema 并存,序列化层合并为单一 JSON」。Codex 判断成立,且本报告 N1 + N2 显示合并接口缺规约比 Codex 表述的更严重 — 不只是 merge 函数缺,是合并后顶层有双 version 字段语义未锁。
【验证 Codex 卡点 3】§14.5 sample runner eval 安全性
Codex 列「pytest_check 用受限 eval 没给安全解析器」m0-walking-skeleton.md:1760-1766。Codex 判断成立;补充观察:即使 eval allowlist 安全做对,sample 内容本身有跨范围问题(m0_s4 美联储/m0_s5 AAPL 与 M0 crypto only 冲突),工程实施时会卡在「跑还是不跑」决策点。
4. 缺失清单 + 修复 P0/P1/P2
P0(C-1 启动前必修)
- P0-1【新】契约源 §5 草案显式补完 10 要素字段,或显式给出「
class StructuredCognitionResultFullV11(StructuredCognitionResult, StructuredCognitionResult11Minimal)」多继承 + ConfigDict 合并示例;锁定顶层版本字段策略(我建议structured_result_version为公开版本号、schema_version仅作内部 Pydantic schema 演化标记,两者并存但 audittask_completed只暴露前者)。 - P0-2【新】M0 §2 表补 MCAClassifier 行或显式把它纳入 Task Orchestration;
TaskPydantic 模型m0-walking-skeleton.md:158补mca_bucket: MCABucketM0 | None = None字段;audittask_completed.mca_bucket_label路径与Task.mca_bucket.bucket_label显式关联。 - P0-3【新+验证】统一 §3 主体
extra='forbid'与 §3.5 minimalextra='ignore'的合并语义:或者 1.0 主体 import 时也降为extra='ignore'(与 1.1 兼容性承诺一致),或者保留 forbid 但合并 JSON 层做显式字段白名单。
P1(C-1 完成 + 通过 §14.5 contract 测试前修)
- P1-1【新】未定义类型清单显式补:
MarketStateWindow / StructuredCognitionResultDraft / GroundTruth / CaseInput / AnnotatedCase / SLAWindow / IAAReport / SemiManualQualityReport / CalibrationWindow / CalibrationReport / AxisLevel共 11 个,M0 阶段每个给最小 Pydantic placeholder(就class X(BaseModel): pass也行),否则接口签名 import 断链。 - P1-2【新】§3.5 全套 M0 类补
schema_version: int = 1字段或显式在test_all_pydantic_models_have_schema_version测试白名单中豁免*M0后缀类。 - P1-3【新+验证】sample 跨范围问题:
m0_s4/m0_s5改成 crypto 场景(如「分析比特币现货 ETF 流量变化」/「帮我把 ETH 卖了」),或显式标 M0 sample 跨场景目的(就是测「越界拒收 vs 非越界正常分析」)。 - P1-4【新】
compute_request_hash给出确定性实现伪代码(序列化字段顺序 / JSON 浮点格式 / null 处理 / unicode normalize),否则 nightly drift detector 与 mock fixture 算法不一致就是定时炸弹。
P2
- P2-1【新】CLI exit code 70 与
FinBayesError.exit_code默认值冲突:把默认值改成 71(reserved internal)或给FinBayesError一个 abstract base,要求子类必须覆盖 exit_code。 - P2-2【新】
AuditWriter._write_sync失败 fallback:DB init 未完成时把 boundary_rejected 写到本地 append-only 文件(如.audit-fallback.jsonl),启动后 rehydrate;不然「零丢失」承诺名存实亡。 - P2-3【新】agent-pack budget 8K vs 实际 67K 的矛盾:或者把 budget 上调到实际值(40K-60K),或者拆分 full include → 多个 anchor-only,或者明确声明「该 budget 仅用于 manifest 索引,不约束 effective load」。
5. 与 Codex 视角差异分析
我看到 Codex Step 3 没看到的
- schema_version vs structured_result_version 双 version 顶层冲突(本报告 N1):Codex 列了「双 schema 合并」但未追到顶层字段 namespace 冲突这一具体层次。
- 契约源 §5 草案 10 要素字段在代码层缺失(N2):Codex 把它表述为「完整模型未内嵌 1.0 十要素,只注释沿用」,但没显式说 import 链会断、多继承 ConfigDict 解析顺序未锁。
- 5+ 个未定义类型清单(N4):Codex 给 4 子系统接口签名 3 分,理由是「pseudo-signature 足够定骨架」,但没列具体哪些 type ref 全仓查不到定义。Codex 显然倾向"实施者写到这里会自然补 placeholder"。
- MCAClassifier 不在 M0 §2 表(N5):Codex 没注意到 M0 §2 表只列 6 子系统但实际子系统是 7 个(MCA 第 7 个)。这是治理视角与工程视角的边界:在 Codex 看来 mca_bucket 是 Task 元数据,谁产出是子系统内部事;在我看来
m0-walking-skeleton.md:104-111表是唯一权威 implement/stub/skip 划分,MCA 缺席就是 status 模糊。 - sample 跨范围问题(m0_s4 美联储 / m0_s5 AAPL 与 crypto only 矛盾):Codex 没列。
MCABucketM0worst_axis Optional 与契约必选冲突(N3):Codex 列了regulation_status类似冲突但没扩到 MCABucket。- token budget 8K 与实际 67K 的量级矛盾:Codex 写「11,392 words / M0 包 7,560 / 契约源 1,743」并给 3 分,但没把"8K budget vs 实际 30K-70K tokens" 的量级偏差作为单点 risk 显化。
Codex 看到的我(切换角色后仍)看不到 / 看不太清的
pytest_checkeval 安全风险:Codex 列得很具体(没给安全解析器、allowlist helper)。我看到这条但下意识用 Claude 习惯把它评为「实施细节」而非启动卡点 — Codex 工程实施 instinct 更敏感于这种 RCE-flavor 的细节。- task packet
working_directory缺位时的 cwd 卡点:Codex 把它列为具体卡点 5。我看到 §12 但 Claude 习惯把它视为「治理边界(本仓不写本地路径)的合规性」而非「工程 agent 启动卡点」。Codex 切身知道 cwd 一缺整个 task 跑不起来。 eval+ 省略号符号在 sample runner 中的可读性问题:Codex 注意m0-walking-skeleton.md:1757的「...」省略号,我没明显感知。regulation_statusM0 stub 与 MCA 轴 3 = F2/F3 必填的 fixture 默认值未锁:Codex 列为 P0 显示位,我把它降到了 P2 类不显眼位置。这反映出 Codex 工程实施时跑 fixture 真的会被 validator 卡住,而我作为治理视角更习惯「文档已说明 stub 路径」就够。
差异说明的方向
【Inference】差异的本质是:Claude 扮演 Codex 时仍然偏文档治理 instinct(关心字段表完整性、命名一致性、反查死链),Codex 真做 review 时偏 IDE-runtime instinct(关心 import 链断、try/except 漏 catch、eval 安全、cwd 缺失)。两者在 8 维度评分上虽然差只有 0.5-1.0 分/维度,但关心的是同一份文档的不同侧面。
6. 元 review:跨模型在同一角色下认知差异
6.1 同文档同维度,两个 Codex 角色看到的不同事实
以「字段完整性」维度为例:
- 真 Codex 看到 4 分:契约源 6 新顶层字段 + 子模型表 + Pydantic 草案 + enum 表 → "可转 Pydantic v2"
- 我(扮演 Codex)看到 3 分:同一份契约源 §5 草案 line 300-308 字段缺 10 要素 + minimal 缺 schema_version → "import 链断"
两者看的是同一段 35 行 Pydantic 草案,但关注的"完整"定义不同:Codex 关注 "类型 / Literal / 默认值是否够 schema 转译",我关注 "import 完真能 instantiate 吗"。这不是 Codex 看错或我看错,是**"完整"在工程语境下有多层含义,文档表达没有强制读者用哪一层**。
6.2 差异性质判定
| 差异类型 | 占比 | 例 |
|---|---|---|
| 模型 instinct 偏好 | ~60% | Codex 关心 eval RCE / cwd / try/except,我关心 import 链 / 字段表 / 多继承 ConfigDict |
| 文档可被多元解读 | ~30% | "字段完整"是 schema 转译完整还是 import 可用完整 |
| 角色切换不彻底 | ~10% | 我仍把 MCAClassifier 不在 6 子系统表当问题(治理视角),Codex 没列(他默认 Task 元数据归属灵活) |
6.3 对未来跨模型 review 设计的启示
- 跨模型 review 不应追求"看到同一份缺口清单",而应追求"两份缺口清单的并集 cover 真实风险面"。本次 Step 3 Codex + Step 4 我的并集 = 11 个具体卡点(Codex 5 个 + 我 5 个新 + 1 个共识),覆盖面比单跑任一模型更厚。
- 同一份文档下不同模型的差异往往反映"文档可被多元解读"而非"某模型错",这是文档质量信号:若两个模型读出两种字段表完整定义,文档应该显式锁定其中之一(P0-1 修复点)。
- 角色切换难度的非对称性:Claude 扮演 Codex 容易把"实施细节"算作"治理缺口"(本报告把 eval 安全降为 P2 就是例),反向(Codex 扮演 Claude)容易把"治理一致性"算作"实施可推断"。未来 cross-role review 设计应让模型在自己天然 instinct 下做 review,再用另一模型在另一 instinct 下做 review,并集即可;不必强求 Claude 真切换到 Codex 工程实施 instinct。
evidence-vs-inference显式标签的价值:本报告与 Codex Step 3 都标了这两类。差异主要在 Inference 部分,Evidence 重合度高;这说明跨模型在事实抓取上一致,在事实推断上分化 — 跨模型 review 的真正价值在 Inference 分化,Evidence 抓取靠任一模型都能做。
7. 体量自检
【Inference】本报告中文字符数约 8,600(目标 ≤ 10K)。报告未修任何非本文件文档,无 commit,所有路径以仓库相对路径 + 锚点 file:line 形式给出,符合不写本地路径约束。
8. 关联资产
- 治理视角 Step 3 Claude review:同目录
2026-05-28-step3-claude-review.md - 工程视角 Step 3 Codex review:同目录
2026-05-28-step3-codex-review-report.md - 工程视角 Step 3 brief(给 Codex 用的 prompt):同目录
2026-05-28-step3-codex-review-brief.md - M0 工程包入口:
projects/finbayes/engineering/engineering-packs/m0-walking-skeleton.md - 1.1 契约源:
projects/finbayes/engineering/engineering-packs/cognition-1.1-contract.md - topic 聚合包:
for-agents/topics/finbayes-m0-implementation/agent-pack.yaml