StructuredCognitionResult 1.1 契约源
§0 范围与定位
本文件是 ADR-008 supplement 锁定的 StructuredCognitionResult 1.1 工程契约的单点 Pydantic schema 派生源。事实源是 ADR-008 supplement 机制层输出契约扩展;本文件做工程化派生(字段表 + enum 清单 + 字段间约束 + Pydantic v2 草案),方便 EvalHarness M0 schema 实施任务一次 load。字段语义、触发条件、机制间反向耦合、回路收敛上限以 ADR-008 supplement 为准;本文件不复述机制定义,仅以「来源 §N.M」回引。
正向语义读法(ADR-013 Build-Y over Prevent-X):本契约不是「一堆字段表 + 一堆禁令」。每个子模型 / 字段先回答「这字段产出什么用户价值(产出意图)」,约束挂在意图之下——约束是为了保住那份价值,不是凭空列禁令。§2 每个子模型段开头标注 「产出意图」;阅读时先读意图,再读字段表与 §4 约束。
§1 顶层契约(StructuredCognitionResult)
| 字段 | 类型 | 默认 | 必选 | 来源 |
|---|---|---|---|---|
structured_result_version | Literal["1.1"] | "1.1" | 必选 | §2 开篇 |
| 10 要素字段(1.0 主体 inline) | main_answer / supporting_evidence / multi_perspectives / counter_evidence / prerequisites / invalidation_conditions / uncertainty_and_gaps / sources / follow_up_questions / historical_judgment_links | 见 §5 StructuredCognitionResultV10Body | 必选 | ADR-008 主体 + product-definition §7 |
phase_evidence | PhaseEvidence | None | None | M3 启用必选 | §2.1 |
causal_graph | TransmissionGraph | None | None | M5 启用必选 | §2.2 |
regulation_status | RegulationStatus | None | None | MCA 轴 3 = F2/F3 必选 | §2.3 |
applicability_flags | ApplicabilityFlags | None | None | M6 启用必选 | §2.4 |
posterior | BimodalPosterior | None | None | M7.uq 启用必选 | §2.5 |
s1 | NarrativeNumberConsistency | — | 必选(横切) | §2.6 |
Task schema 元数据 mca_bucket: MCABucket 必选;不进入 StructuredCognitionResult 本体(§2.7)。
10 要素的产出意图(1.0 主体,product-definition §7):每个要素先回答它给用户什么价值——
main_answer= 让用户第一屏就看到「结论 / 倾向」(非指令式,是认知材料)。supporting_evidence= 让用户看到「凭什么这么判断」的依据,可自行核验。multi_perspectives= 让用户看到「同一件事还有哪些看法」,不被单一视角锚定。counter_evidence= 让用户主动看到「反方证据」,对冲确认偏误(空也要明示理由)。prerequisites= 让用户看清「这判断在什么前提下才成立」。invalidation_conditions= 让用户拿到「什么情况下该推翻这判断」的可证伪触发器(强约束非空:没有失效条件的判断不可发布)。uncertainty_and_gaps= 让用户看到「哪里还不确定 / 信息有缺口」,而非伪装全知。sources= 让用户看到来源与时间戳,判断时效与可信度。follow_up_questions= 给用户「可以继续追问什么」的入口,把单次问答变成可深入的探究。historical_judgment_links= 让用户回看「过去相关判断」,形成可追溯的判断链。
§2 子模型字段表
§2.1 PhaseEvidence + ClockPhase + ClockPhaseMatrix(来源 §2.1)
产出意图:让用户看到「现在处在市场周期的哪一段、各时钟是否相互矛盾」,而不是只给一个孤立的涨跌判断。下面的字段与约束都服务于「周期位置可被复盘、矛盾被显式标注」这份价值。
PhaseEvidence:clocks: list[ClockPhase](M3 不激活为 [])/ phase_matrix: ClockPhaseMatrix | None(综合层产;M3 不激活为 None)。
ClockPhase:clock_id: str(取值 M3.t1–M3.t9)/ phase_label: str(机制自定枚举 late-debt / growth / speculative / hedge / ponzi 等)/ confidence: float ∈ [0,1] / evidence_ref: str。
ClockPhaseMatrix:axes: list[str](N ≤ 9)/ cells: list[list[CellLabel]](CellLabel 见 §3)/ contradictions: list[ContradictionEntry]。
ContradictionEntry:axes: list[str] / type: str / severity: Literal["low","medium","high"]。
§2.2 TransmissionGraph + 子结构(来源 §2.2)
产出意图:让用户看到「钱 / 风险从哪传导到哪、哪条路径有反向力量、相关性是否进入尾部联动」,而不是只给一个静态的相关系数。correlation_regime 服务于「让用户在尾部联动 / 制度切换时被提前提醒」这份价值。
TransmissionGraph:nodes: list[Node] / edges: list[Edge] / reverse_forces: list[ReverseForce] / endogeneity: dict[str, Literal["endogenous","exogenous"]](按 edge_id 键)/ correlation_regime: CorrelationRegime(M5 启用必选;regime_label 至少 normal)/ unbalanced_loop_warnings: list[UnbalancedLoopWarning]。
Node:id: str / object_ref: str / node_type: Literal["entity","relation","attribute"]。
Edge:id: str / from_node: str / to_node: str / edge_type: Literal["causal","reflexivity","shared-book","institutional-friction","cross-market-mapping"] / form: str | None(shared-book 四形态 acute-liquidity / structural-holder-rotation / policy-credit / a-share-retail-acute)/ path_confidence: float ∈ [0,1] / translation_loss: float ∈ [0,1]。
ReverseForce:edge_id: str / force_type: Literal["arbitrageur","policy-hedge","liquidity-supplier","fundamental-reverter","structural-flow"] / evidence_ref: str。
CorrelationRegime:regime_label: Literal["normal","tail-coupled","regime-switched"] / pair_correlations: list[PairCorrelation] / regime_shift_trigger: str | None。
PairCorrelation:node_id_a: str / node_id_b: str / correlation: float ∈ [-1,1] / regime_label_local: Literal["normal","tail-coupled","regime-switched"]。
UnbalancedLoopWarning:edge_id: str / reason: str。
§2.3 RegulationStatus(来源 §2.3)
产出意图:让用户看到「制度摩擦(涨跌停 / T+N / 熔断 / 限售等)会不会让一个理论上成立的判断在实操中失效」,把监管不确定性显式呈现而非默认忽略。
RegulationStatus:friction_layer: list[FrictionItem] / failure_modes: list[FailureModeFlag] / regulatory_uncertainty: float ∈ [0,1]。
FrictionItem:friction_type: Literal["t-plus-n","price-limit","trading-halt","intraday-regulatory-change","short-sell-restriction","circuit-breaker","foreign-investor-quota"] / severity: Literal["low","medium","high"] / affected_node_ids: list[str] / evidence_ref: str。
FailureModeFlag:mode: Literal["a-acute-liquidity","b-structural-holder-rotation","c-policy-credit","d-a-share-retail-acute"] / confidence: float ∈ [0,1] / triggered_by_friction: bool / evidence_ref: str。
§2.4 ApplicabilityFlags + PillarApplicability(来源 §2.4)
产出意图:让用户看到「这套判断的适用边界——估值 / 因子 / 衍生品三支柱各自是否适用、为什么不适用」,避免把一个只在某支柱成立的结论误当全局结论。reason 服务于「不适用要给得出理由,用户能据此自己判断」这份价值。
ApplicabilityFlags:valuation: PillarApplicability / factor: PillarApplicability / derivatives: PillarApplicability。
PillarApplicability:level: Literal["applicable","partial","not-applicable"] / reason: str | None(level=applicable 时可为 None)/ evidence_ref: str | None。
§2.5 BimodalPosterior + PosteriorMode(来源 §2.5)
产出意图:让用户看到「双峰 / 重尾的风险结构,而不是一个虚假精确的单点预测」——两个模态各自的概率与尾宽把「可能大涨也可能大跌」显式摊开。
kelly_cap 已退役(ADR-021,2026-06-04):
BimodalPosterior原含kelly_cap(认知层凯利上界估计),owner 定调其无用且误导,已从代码(FinBayes684d69d)与本契约移除;不确定性仍由双峰重尾分布(mode_a/mode_b/tail_width)承载。
BimodalPosterior:fit_method: Literal["prompt-direct","multi-scenario-fit","bayesian-module"] / mode_a: PosteriorMode / mode_b: PosteriorMode / slow_thinking_triggered: bool / prior_family: Literal["bimodal-fat-tail-default","single-mode-normal","single-mode-fat-tail","custom"]。(kelly_cap 已退役,见 ADR-021。)
PosteriorMode:value: float / weight: float ∈ [0,1] / tail_width: float ≥ 0。
§2.6 NarrativeNumberConsistency + 子结构(来源 §2.6)
产出意图:让用户看清「故事(叙事)和数字是否相互印证、印证强度多大、是谁在带动谁」——当叙事远超数字(远期外推 / 数据脱节 / 口径不可比)时给出方向性提醒;正向耦合时也明确告知「这次叙事和数字是对得上的」。backtrigger / convergence_flag 服务于「让这份一致性判断在内部可被复算、收敛可控」。
NarrativeNumberConsistency:s1_mode: list[S1Mode](可多选)/ coupling_direction: Literal["narrative-leads-numbers","numbers-lead-narrative","decoupled","positive-coupled"] / coupling_strength: float ∈ [0,1] / evidence: S1Evidence / falsification_ref: str | None / backtrigger: list[BackTrigger] / confidence: float ∈ [0,1] / second_order_branch: AttentionMarketBranch | None(由 §4 联动条件决定)/ convergence_flag: ConvergenceFlag。
S1Evidence:narratives: list[str] / numbers_ref: list[str](引用 id,不复制)。
BackTrigger:target: Literal["M5","M6","M7","M7b-meta"] / reason: str / priority: Literal["high","medium","low"]。
AttentionMarketBranch:attention_signals: list[AttentionSignal] / narrative_self_consistency: float ∈ [0,1]。
AttentionSignal:signal_type: Literal["funding-rate","on-chain-first-sign","concentration","kol","micro-cycle-phase"] / value: float / evidence_ref: str。
ConvergenceFlag:loop_count: int ∈ [0,3] / converged: bool / convergence_method: Literal["hash-stable","confidence-soft","max-loops","multimodal-archive"]。
§2.7 MCABucket(Task schema 元数据,来源 §2.7)
产出意图:给整条判断打上「当前市场上下文特征」标签(投资者结构 / 衍生品成熟度 / 制度摩擦等七轴),让同一套机制在不同市场环境下被正确加权、复盘时可按环境分层。属 Task 元数据,不入 result body;用户面如需呈现由 widget 翻译为「市场上下文」。
MCABucket:axis_1_investor_structure: Literal["L1","L2","L3"] / axis_2_derivatives_maturity: Literal["D1","D2","D3"] / axis_3_institutional_friction: Literal["F1","F2","F3"] / axis_4_non_market_actor: Literal["N1","N2","N3"] / axis_5_credit_environment: Literal["C1","C2","C3"] / axis_6_information_availability: Literal["I1","I2","I3"] / axis_7_currency_cross_border: Literal["K1","K2","K3"] / bucket_label: Literal["B1","B2","B3","B4","B5a","B5b","B6","B7"] / worst_axis: str(如 axis_4_N3)/ tag_version: str(如 mca-v1.0)。
七轴语义(投资者结构 / 衍生品成熟度 / 制度摩擦 / 非市场参与者注入 / 信用环境 / 信息可得性 / 货币与跨境约束)来源 ADR-007 supplement §2.2。
§3 enum 取值清单
| Literal | 取值 |
|---|---|
structured_result_version | 1.1 |
node_type | entity / relation / attribute |
edge_type | causal / reflexivity / shared-book / institutional-friction / cross-market-mapping |
edge.form 建议值 | acute-liquidity / structural-holder-rotation / policy-credit / a-share-retail-acute |
force_type | arbitrageur / policy-hedge / liquidity-supplier / fundamental-reverter / structural-flow |
endogeneity 值域 | endogenous / exogenous |
regime_label | normal / tail-coupled / regime-switched |
phase_matrix.cells 单元 (CellLabel) | aligned / lead-1 / lead-2 / lag-1 / lag-2 / opposed / not-applicable |
severity | low / medium / high |
friction_type | t-plus-n / price-limit / trading-halt / intraday-regulatory-change / short-sell-restriction / circuit-breaker / foreign-investor-quota |
failure_mode | a-acute-liquidity / b-structural-holder-rotation / c-policy-credit / d-a-share-retail-acute |
pillar.level | applicable / partial / not-applicable |
fit_method | prompt-direct / multi-scenario-fit / bayesian-module |
prior_family | bimodal-fat-tail-default / single-mode-normal / single-mode-fat-tail / custom |
s1_mode(多选) | a-far-extrapolation / b-source-missing / c-narrative-data-detachment / d-unit-accounting-incompatible / positive-coupling |
coupling_direction | narrative-leads-numbers / numbers-lead-narrative / decoupled / positive-coupled |
backtrigger.target | M5 / M6 / M7 / M7b-meta |
backtrigger.priority | high / medium / low |
attention.signal_type | funding-rate / on-chain-first-sign / concentration / kol / micro-cycle-phase |
convergence_method | hash-stable / confidence-soft / max-loops / multimodal-archive |
bucket_label | B1 / B2 / B3 / B4 / B5a / B5b / B6 / B7 |
| 七轴档位 | L1/L2/L3 · D1/D2/D3 · F1/F2/F3 · N1/N2/N3 · C1/C2/C3 · I1/I2/I3 · K1/K2/K3 |
§4 字段间依赖约束(来自 ADR-008 supplement 显式条款)
mode_a.weight + mode_b.weight = 1.0(±1e-6 容差,§2.5)。applicability_flags.valuation.level == "not-applicable"⇒s1.second_order_branch必须非None(§2.4 / §2.6)。applicability_flags.valuation.level == "applicable"⇒s1.second_order_branch == None(§2.6)。applicability_flags.valuation.level == "partial"⇒ 主流程 + 二阶并行,second_order_branch非None(子系统文档锁定)。applicability_flags.derivatives.level == "not-applicable"⇒posterior.fit_method不得选依赖衍生品 IV 的bayesian-module实现路径(§2.4 末段)。causal_graph.correlation_regime.regime_label == "regime-switched"⇒posterior强制必选(§2.5)。- M5 启用 ⇒
causal_graph.correlation_regime.regime_label至少normal,不可缺省(§2.2)。 - MCA
axis_3_institutional_friction ∈ {F2, F3}⇒regulation_status必选;F1时可缺省为空对象(§2.3)。 pillar.level == "applicable"时reason可为None;partial/not-applicable时reason应非空(§2.4)。convergence_flag.loop_count ∈ [0, 3],N=3 上限(§2.6 / ADR-007 supplement §2.3 v1 锁定)。- 概率类字段(
path_confidence/translation_loss/confidence/coupling_strength/regulatory_uncertainty/weight/narrative_self_consistency/ClockPhase.confidence/FailureModeFlag.confidence)值域[0, 1];tail_width ≥ 0;correlation ∈ [-1, 1]。(kelly_cap已退役,见 ADR-021。) s1.evidence.numbers_ref与s1.falsification_ref仅存引用 id,不复制 10 要素内容(§2.6)。
§5 Pydantic v2 草案
字段在跨 milestone(M0 → M1 → M2)从 Optional → required 的收紧时点与 audit 触发条件见 里程碑字段宽紧度演化矩阵。
# src/finbayes/cognition/types.py
from __future__ import annotations
from typing import Literal, Optional
from pydantic import BaseModel, ConfigDict, Field
S1Mode = Literal["a-far-extrapolation","b-source-missing","c-narrative-data-detachment","d-unit-accounting-incompatible","positive-coupling"]
RegimeLabel = Literal["normal","tail-coupled","regime-switched"]
PillarLevel = Literal["applicable","partial","not-applicable"]
Severity = Literal["low","medium","high"]
CellLabel = Literal["aligned","lead-1","lead-2","lag-1","lag-2","opposed","not-applicable"]
NodeType = Literal["entity","relation","attribute"]
EdgeType = Literal["causal","reflexivity","shared-book","institutional-friction","cross-market-mapping"]
ForceType = Literal["arbitrageur","policy-hedge","liquidity-supplier","fundamental-reverter","structural-flow"]
FrictionType = Literal["t-plus-n","price-limit","trading-halt","intraday-regulatory-change","short-sell-restriction","circuit-breaker","foreign-investor-quota"]
FailureMode = Literal["a-acute-liquidity","b-structural-holder-rotation","c-policy-credit","d-a-share-retail-acute"]
FitMethod = Literal["prompt-direct","multi-scenario-fit","bayesian-module"]
PriorFamily = Literal["bimodal-fat-tail-default","single-mode-normal","single-mode-fat-tail","custom"]
CouplingDirection = Literal["narrative-leads-numbers","numbers-lead-narrative","decoupled","positive-coupled"]
BackTriggerTarget = Literal["M5","M6","M7","M7b-meta"]
Priority = Literal["high","medium","low"]
AttentionSignalType = Literal["funding-rate","on-chain-first-sign","concentration","kol","micro-cycle-phase"]
ConvergenceMethod = Literal["hash-stable","confidence-soft","max-loops","multimodal-archive"]
BucketLabel = Literal["B1","B2","B3","B4","B5a","B5b","B6","B7"]
class _Base(BaseModel):
model_config = ConfigDict(extra="ignore")
class ContradictionEntry(_Base):
axes: list[str]; type: str; severity: Severity
class ClockPhase(_Base):
clock_id: str; phase_label: str
confidence: float = Field(ge=0.0, le=1.0)
evidence_ref: str
class ClockPhaseMatrix(_Base):
axes: list[str]; cells: list[list[CellLabel]]
contradictions: list[ContradictionEntry] = []
class PhaseEvidence(_Base):
clocks: list[ClockPhase] = []
phase_matrix: Optional[ClockPhaseMatrix] = None
class Node(_Base):
id: str; object_ref: str; node_type: NodeType
class Edge(_Base):
id: str; from_node: str; to_node: str; edge_type: EdgeType
form: Optional[str] = None
path_confidence: float = Field(ge=0.0, le=1.0)
translation_loss: float = Field(ge=0.0, le=1.0)
class ReverseForce(_Base):
edge_id: str; force_type: ForceType; evidence_ref: str
class PairCorrelation(_Base):
node_id_a: str; node_id_b: str
correlation: float = Field(ge=-1.0, le=1.0)
regime_label_local: RegimeLabel
class CorrelationRegime(_Base):
regime_label: RegimeLabel
pair_correlations: list[PairCorrelation] = []
regime_shift_trigger: Optional[str] = None
class UnbalancedLoopWarning(_Base):
edge_id: str; reason: str
class TransmissionGraph(_Base):
nodes: list[Node] = []
edges: list[Edge] = []
reverse_forces: list[ReverseForce] = []
endogeneity: dict[str, Literal["endogenous","exogenous"]] = {}
correlation_regime: CorrelationRegime
unbalanced_loop_warnings: list[UnbalancedLoopWarning] = []
class FrictionItem(_Base):
friction_type: FrictionType; severity: Severity
affected_node_ids: list[str]; evidence_ref: str
class FailureModeFlag(_Base):
mode: FailureMode
confidence: float = Field(ge=0.0, le=1.0)
triggered_by_friction: bool; evidence_ref: str
class RegulationStatus(_Base):
friction_layer: list[FrictionItem] = []
failure_modes: list[FailureModeFlag] = []
regulatory_uncertainty: float = Field(ge=0.0, le=1.0)
class PillarApplicability(_Base):
level: PillarLevel
reason: Optional[str] = None
evidence_ref: Optional[str] = None
class ApplicabilityFlags(_Base):
valuation: PillarApplicability
factor: PillarApplicability
derivatives: PillarApplicability
class PosteriorMode(_Base):
value: float
weight: float = Field(ge=0.0, le=1.0)
tail_width: float = Field(ge=0.0)
class BimodalPosterior(_Base):
fit_method: FitMethod
mode_a: PosteriorMode; mode_b: PosteriorMode
slow_thinking_triggered: bool
prior_family: PriorFamily
class S1Evidence(_Base):
narratives: list[str] = []
numbers_ref: list[str] = []
class BackTrigger(_Base):
target: BackTriggerTarget; reason: str; priority: Priority
class AttentionSignal(_Base):
signal_type: AttentionSignalType; value: float; evidence_ref: str
class AttentionMarketBranch(_Base):
attention_signals: list[AttentionSignal] = []
narrative_self_consistency: float = Field(ge=0.0, le=1.0)
class ConvergenceFlag(_Base):
loop_count: int = Field(ge=0, le=3)
converged: bool
convergence_method: ConvergenceMethod
class NarrativeNumberConsistency(_Base):
s1_mode: list[S1Mode] = []
coupling_direction: CouplingDirection
coupling_strength: float = Field(ge=0.0, le=1.0)
evidence: S1Evidence
falsification_ref: Optional[str] = None
backtrigger: list[BackTrigger] = []
confidence: float = Field(ge=0.0, le=1.0)
second_order_branch: Optional[AttentionMarketBranch] = None
convergence_flag: ConvergenceFlag
class MCABucket(_Base):
axis_1_investor_structure: Literal["L1","L2","L3"]
axis_2_derivatives_maturity: Literal["D1","D2","D3"]
axis_3_institutional_friction: Literal["F1","F2","F3"]
axis_4_non_market_actor: Literal["N1","N2","N3"]
axis_5_credit_environment: Literal["C1","C2","C3"]
axis_6_information_availability: Literal["I1","I2","I3"]
axis_7_currency_cross_border: Literal["K1","K2","K3"]
bucket_label: BucketLabel
worst_axis: str
tag_version: str
class StructuredCognitionResultV10Body(_Base):
"""1.0 主体(10 认知要素 inline 完整模型)。
字段提取自 product-definition.md §7 十要素表与 m0-walking-skeleton §3 的
`StructuredCognitionResult` 1.0 schema 草案。M0 已实现前 7 个内容字段;
剩余 3 个(multi_perspectives / prerequisites / follow_up_questions /
historical_judgment_links)由 1.0 主体在 1.1 完整模型合并时一次补齐。
内部 `model_config` 单独使用 `extra="forbid"`,语义是「锁 identity / 版本 / 安全
相关字段完整性」(防止 1.0 直出漏 structured_result_version 等核心键),不是
「禁止认知要素层按任务动态增减」——动态组合由 tasks-fields-mapping 决定,不靠
全局 forbid 固化(ADR-013 去全局固化);合并到 `StructuredCognitionResultFullV11`
后由后者的 `extra="ignore"` 覆盖(见下方 ConfigDict 合并语义锁)。
"""
model_config = ConfigDict(extra="forbid")
# 10 认知要素(product-definition §7)
main_answer: str = Field(..., min_length=30) # 1. 结论 / 倾向(第一屏题眼回应,≥30 字硬约束)
supporting_evidence: list[str] = Field(default_factory=list) # 2. 依据
multi_perspectives: list[str] = Field(default_factory=list) # 3. 多视角
counter_evidence: list[str] = Field(default_factory=list) # 4. 反方证据(M0 允许空但必须明示理由)
prerequisites: list[str] = Field(default_factory=list) # 5. 成立条件
invalidation_conditions: list[str] = Field(..., min_length=1) # 6. 失效条件(M0 必填非空)
uncertainty_and_gaps: list[str] = Field(default_factory=list) # 7. 不确定性 / 信息缺口
sources: list[dict] = Field(default_factory=list) # 8. 来源与时间戳
follow_up_questions: list[str] = Field(default_factory=list) # 9. 可继续追问项
historical_judgment_links: list[str] = Field(default_factory=list) # 10. 历史判断链接
# 1.0 主体内部 audit 字段(不暴露到 1.1 顶层 audit)
non_instruction_notice: str = "本回答是认知材料,不是执行指令。"
schema_validation_passed: bool = True
class StructuredCognitionResult11MinimalAdditions(_Base):
"""1.1 新增 6 顶层字段(与 m0-walking-skeleton §3.5 `StructuredCognitionResult11Minimal`
对应;本类提供 1.1 完整版字段类型,M0 子集见 m0-pack)。"""
structured_result_version: Literal["1.1"] = "1.1"
phase_evidence: Optional[PhaseEvidence] = None
causal_graph: Optional[TransmissionGraph] = None
regulation_status: Optional[RegulationStatus] = None
applicability_flags: Optional[ApplicabilityFlags] = None
posterior: Optional[BimodalPosterior] = None
s1: NarrativeNumberConsistency
class StructuredCognitionResultFullV11(
StructuredCognitionResultV10Body,
StructuredCognitionResult11MinimalAdditions,
):
"""1.1 完整模型:1.0 十要素 + 1.1 新增 6 顶层字段,共 16 顶层字段
(Task 元数据 `mca_bucket: MCABucket` 不入本模型本体,由 Task 携带,见 §2.7)。
ConfigDict 合并语义见下方「ConfigDict 合并语义锁」段。
"""
# extra="ignore" 是设计意图(不是疏忽):承接 ADR-008 supplement §3.1 兼容策略,
# 旧 1.0 consumer 读到 1.1 输出时必须能忽略新字段不报错;1.0 主体内部用 forbid
# 防误用、合并后由本层 ignore 覆盖,详见 §6 与 m0-pack §3.5 注释。
model_config = ConfigDict(extra="ignore")
ConfigDict 合并语义锁(C-E + C-J):
-
多继承顺序:
StructuredCognitionResultFullV11(StructuredCognitionResultV10Body, StructuredCognitionResult11MinimalAdditions)。Pydantic v2 多继承model_config取最末次显式声明者(本类自身的extra="ignore"覆盖父类)。即 1.0 主体的extra="forbid"在合并到 1.1 完整模型后被extra="ignore"覆盖,理由:1.0 → 1.1 兼容契约(ADR-008 supplement §3.1:旧 consumer 必须能忽略 1.1 新字段不报错)。 -
extra="ignore"是设计意图,不是疏忽:1.1 输出契约用extra="ignore"承接 ADR-008 supplement §3.1 兼容策略(旧 1.0 consumer 必须能忽略 1.1 新字段不报错);1.0 主体单独使用时(如 M0 阶段StructuredCognitionResult直出)保持extra="forbid",但其语义范围是**「锁 identity / 版本 / 安全相关字段完整性」**(防止 1.0 直出漏structured_result_version等核心键),不是「禁止认知要素层按任务动态增减字段」——「单次输出携带哪些认知要素」由task_type × 机制激活动态决定(事实源field_composition_policy/contracts/tasks-fields-mapping.yaml),不靠全局forbid钉死(ADR-013 Build-Y over Prevent-X,去全局固化)。Codex 实施时不得把StructuredCognitionResultFullV11.model_config改为extra="forbid",否则破坏兼容契约引入 schema drift。 -
顶层 audit 字段策略:1.1 顶层只暴露
structured_result_version: Literal["1.1"];1.0 主体内部的schema_validation_passed在合并模型中保留但不计入「audit-versioning 暴露面」(即 audit 层仅以structured_result_version作为版本筛选键)。 -
JSON 序列化口径:合并模型序列化时统一用
model_dump(by_alias=False, exclude_none=False),确保 10 要素 + 6 新字段在单一 JSON object 中输出(10 要素中 list 字段允许[],6 新字段在未启用机制时输出null)。 -
合并函数接口规约(供综合层在 1.0 + 1.1 两阶段产出时一次合并使用):
接口签名
merge_cognition_result_v1_1(base: dict, extension: dict) -> dict:base=StructuredCognitionResultV10Body.model_dump()(10 要素 + 内部 audit),extension=StructuredCognitionResult11MinimalAdditions.model_dump()(6 顶层字段 +structured_result_version);输出StructuredCognitionResultFullV11.model_validate(merged).model_dump(),顶层structured_result_version强制"1.1"(extension覆盖base残留),键冲突以extension为准(两类字段命名理论不重叠),历史遗留未知字段由extra="ignore"静默丢弃不 raise。
跨字段约束(§4 第 1 / 2 / 3 / 5 / 6 / 8 条)不在草案以 model_validator 强制实现,留 EvalHarness M0 实施任务在 cognition/types.py 落盘时按 Pydantic v2 @model_validator(mode="after") 加约束。
§6 与 1.0 兼容性
承接 ADR-008 supplement §3.1:
- 旧 consumer(声明
structured_result_version = "1.0")必须能忽略新字段不报错;合并模型StructuredCognitionResultFullV11顶层model_config = ConfigDict(extra="ignore")已就位(覆盖 1.0 主体的extra="forbid",合并语义见 §5 「ConfigDict 合并语义锁」),序列化层在反序列化 1.1 输出到 1.0 consumer 时 6 新字段以「未知字段宽容」模式跳过。 - 新 consumer 收到
structured_result_version = "1.0"(或缺省)时,6 新字段以None缺省;评测维度 D4 / D6 / D7 缺字段时降级为「文本层评测」并标注degraded-text-only,不阻断管线。 - 每条 Judgment Record 顶层写入
structured_result_version+mca_bucket;撤回 / 降级支持按版本筛选。 1.x系列承诺向后兼容;2.0走变更协议 L4 + 14 天异议期。
§7 半人工标注承接
承接 ADR-008 supplement §5.1 与 Phase 7 半人工标注 SLA 附录。
允许人工标注覆盖(v1):
causal_graph.edges[?].form ∈ {"policy-credit", "a-share-retail-acute"}(任务 A / B)。regulation_status.failure_modes[?].mode ∈ {"c-policy-credit", "d-a-share-retail-acute"}(与 form 联动)。mca_bucket.axis_4_non_market_actor = "N3"(任务 D,Audit Trail 标注「半人工」)。posterior.slow_thinking_triggered(任务 C,M7.meta-v1 推翻路径)。applicability_flags.{valuation|factor|derivatives}.level中applicable↔partial边缘判定(not-applicable门槛较硬,推翻须附reason+evidence_ref)。
必须模型自动产出:phase_evidence.clocks.* / phase_evidence.phase_matrix.cells / causal_graph.nodes / causal_graph.edges 主体结构 / causal_graph.correlation_regime.regime_label / posterior.mode_a / posterior.mode_b / s1.coupling_strength / s1.confidence / s1.convergence_flag.*。
§8 待对齐项
phase_evidence.clocks[?].phase_label未严格枚举化(机制自定枚举),下游按字符串处理;M3 v1 校准后再决议是否升级为Literal。causal_graph.edges[?].form在 ADR-008 supplement §2.2 列举 shared-book 四形态但未声明封闭枚举;草案保留Optional[str]。causal_graph.endogeneity键约束(必须覆盖所有edges[?].id,还是允许子集)未显式说明,草案按「子集允许」实现。regulation_status.friction_layer在 MCA 轴 3 = F1 时「整体None与字段为空对象」二选一未锁定。s1.evidence.numbers_ref/s1.falsification_ref引用失效时的处理路径(重评 / 降级 / 阻断)由 Phase 7+ 决议。mca_bucket.worst_axis多桶命中边界(N3 + F3 同时命中)的裁决规则在 MCAClassifier 子系统 §7 已 flag,本契约不锁定。→kelly_cap与战略不变量「FinBayes 不直接下单」的下游消费协议未在本契约层声明kelly_cap已退役(ADR-021),本条作废。- 子系统 placeholder 类型见 4 子系统文档「子模型类型 placeholder」段(知识图谱服务 / 一致性中间件 / 市场上下文分类器 / 评测台架),M0 阶段为接口签名 import 链闭合给的最小定义;M1+ 收紧路径见各子系统 §9 实现里程碑映射 + 后续
milestone-field-evolution-matrix.md。
§9 关联资产
- 工程契约事实源:ADR-008 supplement 机制层输出契约扩展。
- 行为契约事实源:ADR-007 supplement 金融认知体系第一版正式构成。
- 4 子系统索引:认知体系工程承接子系统目录。
- 子系统文档:知识图谱服务 · 一致性中间件 · 市场上下文分类器 · 评测台架。
- M0 最小子集 + 10 要素 Pydantic v0:M0 走通骨架工程包。
- 半人工标注 SLA:Phase 7 半人工标注 SLA 附录。
- 架构索引:FinBayes 工程架构文档 §29。
§10 变更记录
- 2026-05-29 Build-Y 换轨(ADR-013):补正向语义——§0 加「正向语义读法」;§1 加 10 要素「产出意图」;§2.1–§2.7 每子模型加「产出意图」(约束挂在意图之下,不凭空列禁令)。§5 ConfigDict 合并语义锁第 2 条 +
StructuredCognitionResultV10Body文档串明确extra="forbid"仅锁 identity / 版本完整性、不固化认知要素动态组合(与contracts/structured-cognition-result.yaml同步)。字段名 / 类型未变(无漂移)。