跳到主要内容

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. 字段完整性34-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. 接口签名23-1KGS 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. 测试可执行性34-15 条 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. 数据 fixtures23-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. 错误处理 contract34-1exit 70 双重定义:CLI 退出码表 m0-walking-skeleton.md:797 「未预期异常」与 FinBayesError.exit_code = 70 m0-walking-skeleton.md:1324 默认同值,try/except 模板 m0-walking-skeleton.md:1341-1348FinBayesErrorException 都走 70,丧失定向 catch 能力。AuditWriter._write_sync m0-walking-skeleton.md:1445-1449 失败时无 fallback,boundary_rejected「零丢失」承诺 m0-walking-skeleton.md:714 在 DB init 未完成时空转
6. 跨子系统调用23-1MCAClassifier 不在 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 负载23-1agent-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. 反查路径34-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 = 1m0-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-377Optional[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-1766Codex 判断成立;补充观察:即使 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 演化标记,两者并存但 audit task_completed 只暴露前者)。
  • P0-2【新】M0 §2 表补 MCAClassifier 行或显式把它纳入 Task Orchestration;Task Pydantic 模型 m0-walking-skeleton.md:158mca_bucket: MCABucketM0 | None = None 字段;audit task_completed.mca_bucket_label 路径与 Task.mca_bucket.bucket_label 显式关联。
  • P0-3【新+验证】统一 §3 主体 extra='forbid' 与 §3.5 minimal extra='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 没看到的

  1. schema_version vs structured_result_version 双 version 顶层冲突(本报告 N1):Codex 列了「双 schema 合并」但未追到顶层字段 namespace 冲突这一具体层次。
  2. 契约源 §5 草案 10 要素字段在代码层缺失(N2):Codex 把它表述为「完整模型未内嵌 1.0 十要素,只注释沿用」,但没显式说 import 链会断、多继承 ConfigDict 解析顺序未锁。
  3. 5+ 个未定义类型清单(N4):Codex 给 4 子系统接口签名 3 分,理由是「pseudo-signature 足够定骨架」,但没列具体哪些 type ref 全仓查不到定义。Codex 显然倾向"实施者写到这里会自然补 placeholder"。
  4. 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 模糊。
  5. sample 跨范围问题(m0_s4 美联储 / m0_s5 AAPL 与 crypto only 矛盾):Codex 没列。
  6. MCABucketM0 worst_axis Optional 与契约必选冲突(N3):Codex 列了 regulation_status 类似冲突但没扩到 MCABucket。
  7. token budget 8K 与实际 67K 的量级矛盾:Codex 写「11,392 words / M0 包 7,560 / 契约源 1,743」并给 3 分,但没把"8K budget vs 实际 30K-70K tokens" 的量级偏差作为单点 risk 显化。

Codex 看到的我(切换角色后仍)看不到 / 看不太清的

  1. pytest_check eval 安全风险:Codex 列得很具体(没给安全解析器、allowlist helper)。我看到这条但下意识用 Claude 习惯把它评为「实施细节」而非启动卡点 — Codex 工程实施 instinct 更敏感于这种 RCE-flavor 的细节。
  2. task packet working_directory 缺位时的 cwd 卡点:Codex 把它列为具体卡点 5。我看到 §12 但 Claude 习惯把它视为「治理边界(本仓不写本地路径)的合规性」而非「工程 agent 启动卡点」。Codex 切身知道 cwd 一缺整个 task 跑不起来。
  3. eval + 省略号符号在 sample runner 中的可读性问题:Codex 注意 m0-walking-skeleton.md:1757 的「...」省略号,我没明显感知。
  4. regulation_status M0 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 设计的启示

  1. 跨模型 review 不应追求"看到同一份缺口清单",而应追求"两份缺口清单的并集 cover 真实风险面"。本次 Step 3 Codex + Step 4 我的并集 = 11 个具体卡点(Codex 5 个 + 我 5 个新 + 1 个共识),覆盖面比单跑任一模型更厚。
  2. 同一份文档下不同模型的差异往往反映"文档可被多元解读"而非"某模型错",这是文档质量信号:若两个模型读出两种字段表完整定义,文档应该显式锁定其中之一(P0-1 修复点)。
  3. 角色切换难度的非对称性:Claude 扮演 Codex 容易把"实施细节"算作"治理缺口"(本报告把 eval 安全降为 P2 就是例),反向(Codex 扮演 Claude)容易把"治理一致性"算作"实施可推断"。未来 cross-role review 设计应让模型在自己天然 instinct 下做 review,再用另一模型在另一 instinct 下做 review,并集即可;不必强求 Claude 真切换到 Codex 工程实施 instinct。
  4. 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