跳到主要内容

战略不变量 codify · L0.5 层(16 条契约型)

本文件是 SVA-9 九层防御的 L0.5 层产出:把战略白皮书 / 产品定义 / 架构文档中"用文字承诺"的正向价值与边界,变成"机器可断言的契约与不变量"。每条配 Build-Y 必含产出 + test 规格,M0 第一个 PR 必须把它们映射到工程仓 tests/invariants/*.py

codify 哲学按 ADR-013 换轨:从禁令型(Prevent-X 优先)→ 契约型(Build-Y 优先 + Require-X-when-Y 条件式 + 最小化 identity 级 Prevent-X)。每条先讲清要做成什么 / 产出什么正向价值,负向边界写成"在边界内主动做 Y",且负向篇幅不得压过正向。

三级硬度(继承 ADR-009 + ADR-013 §2):

  • identity 级:永不变 / 改即非 FinBayes(只能 fork 重起)
  • 当前版本立场:v3 版本约定,未来 ADR 可重审(走 change-protocol L3)
  • 工程约束:按 PR / ADR 可灵活调整(普通 PR + 三阶段 SOP)

M0 阶段 14 条核心,后续滚动补。任何战略 / 产品 / 架构迭代后,30 分钟扫一遍是否需要新增。

§0 总览

ID名称硬度主范式
I-01'ExecutionBoundary(执行边界)identityBuild-Y + 边界
I-02'ConditionalJudgmentContract(条件化方向判断契约)identityBuild-Y
I-03'UserSovereignty(用户主权三维)identityBuild-Y
I-04'RuntimeReasoningCompleteness(runtime reasoning 完整性)identityBuild-Y
I-05'UserFacingFieldRedaction(用户面字段名收敛)工程约束Require-X-when-Y
I-06'KellyCapTaskConditional(kelly_cap 任务条件化)— 已退役 2026-06-04(ADR-021)工程约束Require-X-when-Y
I-07'TaskMinimumFieldSet(任务字段动态组合)当前版本立场Require-X-when-Y
I-08'TaskTypeRequired(schema 顶层 task_type 显式)工程约束Build-Y
I-09'MCA-7Axes-Naming(MCA 7 轴名稳定)当前版本立场命名稳定
I-10'MechanismsSingleSource(8 机制单一事实源)工程约束Build-Y
I-11'CredentialFiltering(输出端凭证过滤双处)identityBuild-Y + 边界
I-12'ProfileDoesNotShrinkFactSpace(画像不裁剪事实空间)当前版本立场Build-Y
I-13'S1AlwaysActive(S1 每次综合输出必跑)identityBuild-Y
I-14'CognitionDataIndependence(认知数据独立性)identityBuild-Y
I-15'AgentAutonomousLoop(agent 自主循环本体)— 建造态,阶段 1/M2 起断言identityBuild-Y
I-16'JudgmentRecordIsLiveMemory(判断记录是活记忆非死档)— 建造态,阶段 2/3 起断言identityBuild-Y

与原 10 条禁令型的差分见 §1;原 I-05 ForbiddenLexicon 已按 ADR-013 §3.3 降级为 verify:kb hook(不进 L0.5),由 content-hygiene 校验承接。

I-15' / I-16' 是建造态 identity 不变量(2026-06-04 阶段 0 新增):编码 agent 产品本体目标态,当前代码(684d69d)尚未满足,其 test 在阶段 1–3 建成对应能力前预期为红、不作 M0 invariant gate 硬门;test 转绿即对应阶段完成的客观判据。这是把「有大脑、无身体」的差距如实登记成可断言契约,而非 codify 失误。


§I-01' · ExecutionBoundary(执行边界)

硬度:identity 级(永不变 / 改即非 FinBayes)

要做成什么(Build-Y 正向产出):FinBayes 是金融认知层,主动产出认知材料——结构化分析、条件化结论、判断检验材料。每次输出含三个核心字段:main_answer(结论 / 倾向 / 方向)、supporting_evidence(支撑证据)、sources(来源 + 时间戳,见 I-07')。当 task_type ∈ {交易准备 / 交易决策辅助 / 风险识别} 时,输出可以包含方向性结论,同时携带 I-02' 要求的条件化要素。"FinBayes → 下游执行端"链路中,用户拍板这一步由系统主动保留并呈现。

战略原文锚点

  • 战略白皮书 §9(identity 级不可变段:不直接下单、不持有账户凭证)
  • 战略白皮书 §6("不直接下单、不持有账户凭证")
  • ADR-009(唯一保留为 identity 级的是:认知与执行分工)

负向边界(在边界内主动做 Y):系统在认知层内主动做满分析与判断,把执行这一步留给用户——因此 code-base 不 import 交易执行 SDK(如 ccxt / interactive-brokers-api 等),StructuredCognitionResult 不收录 order_id / place_order / execute_trade / account_credential 等执行语义字段。

反例(违反时长这样):

# 错(直接调交易 API)
broker.place_order(symbol="NVDA", qty=100)
# 错(字段含执行语义)
result.order_id = "ord_xxx"

Test 规格

  • L1(grep)grep -rE "(ccxt|interactive_brokers|alpaca_trade_api)" src/ 必须空。
  • L2(Pydantic):StructuredCognitionResult 模型禁止注册 order_* / place_* / execute_trade 类字段。
  • L3(codebase audit):第三方依赖白名单校验,交易执行类 package 不在白名单。

Test 文件预期路径tests/invariants/test_i01_execution_boundary.py


§I-02' · ConditionalJudgmentContract(条件化方向判断契约)

硬度:identity 级

要做成什么(Build-Y 正向产出):FinBayes 主动给出带条件的方向判断——这是核心交付物,不是被禁止的能力。当 main_answer 含方向词("应该 / 建议 / 倾向 + 买入 / 卖出 / 持有 / 加仓 / 减仓")时,系统同时产出四类条件化要素,让判断可检验、可证伪

  • 成立条件 prerequisites ≥ 1 条
  • 失效条件 invalidation_conditions ≥ 1 条
  • 反方证据 counter_evidence ≥ 1 条(task_type ∈ {分析 / 复盘 / 风险识别 / 交易准备 / 交易决策辅助} 时)
  • 不确定性 / 缺口 uncertainty_and_gaps ≥ 1 条

reasoning 链路显式连接"证据 → 条件 → 结论方向"。允许说"应该买入 NVDA"——只要四个条件化字段齐备。战略要拦的是"封闭式答案"(无条件喊单),不是"方向词本身"。

战略原文锚点

  • 战略白皮书 §5("FinBayes 不给'BTC 现在该买'这种封闭答案,而是给'在以下条件下加仓的逻辑成立……'")
  • 战略白皮书 §5(典型场景:有条件的结论)
  • 产品定义 §4.4("交易准备 / 决策辅助类问题可以回答"三条规则)

负向边界(在边界内主动做 Y):系统主动拒绝产出"封闭式答案"——即 main_answer 含方向词但四个条件化字段全空 / 全占位符的情况,触发 schema 校验失败,引导补齐条件化要素。不采用"出现 应该买入 / 应该卖出 即判违规"的粗暴 grep(会一刀切误伤合规的条件化输出)。

反例

// 错(封闭答案:有方向无条件)
{
"main_answer": "应该买入 NVDA 100 股",
"prerequisites": [],
"invalidation_conditions": [],
"counter_evidence": []
}

// 对(条件化判断:方向 + 四要素齐备)
{
"main_answer": "在以下条件下加仓 NVDA 逻辑成立(建议方向:增持)",
"prerequisites": ["AI 资本支出指引未下修", "硬件供给约束未缓解"],
"invalidation_conditions": ["数据中心订单同比转负", "竞争性 ASIC 显著替代"],
"counter_evidence": ["估值已隐含高速增长,PE 分位 95%"],
"uncertainty_and_gaps": ["DGX Spark 早期占比未披露"],
"posterior": {"kelly_cap": 0.25, "reasoning": "……"}
}

Test 规格

  • L1(Pydantic inter_field_constraint):当 main_answer 正则匹配方向词时,断言四个条件字段 length ≥ 1。
  • L2(semantic check, M1+):方向词附近 N tokens 内必须存在条件标记("如果" / "在……前提下" / "假设" / "前提是")。
  • L3(V 维度 V1 judge):Claude judge 对 10 个 mock 输出打分 V1 ≥ 2.5(V1 = 条件化判断符合度)。
  • 明确删除原 codify 的 (应该|建议)(买入|卖出) 粗暴 grep。

Test 文件预期路径tests/invariants/test_i02_conditional_judgment.py


§I-03' · UserSovereignty(用户主权三维)

硬度:identity 级

要做成什么(Build-Y 正向产出):系统主动交付用户对自身数据与决策的三维主权:

  1. 数据主权:可查看 / 修改 / 清空 / 导出全部数据(含历史判断、偏好、个性化参数)。
  2. 执行自主权:判断到执行之间,系统主动保留并呈现用户拍板这一步。
  3. 候选→确认两步写入契约:任何写入用户档案 / 偏好 / 持仓配置的动作,先生成 candidate、再由用户 confirm 后才应用,系统不静默写入。

对应 API 主动提供:GET /api/v1/me/export(zip 含全部数据)、DELETE /api/v1/me(注销 + 软删除 30 天后硬删)、PATCH /api/v1/me/profile(先返回 candidate,confirm 后才应用)。用户面 UI 主动支持用户用自己的语言重述问题,不强制套 FinBayes 框架。

战略原文锚点

  • 战略白皮书 §9(identity 级不可变 + "两步写入契约(候选→用户确认)")
  • 产品定义 §3(用户产品形态)
  • ADR-009(保留 identity 级 = 认知与执行分工)

负向边界(在边界内主动做 Y):写入用户档案的代码路径主动走 candidate→confirm 两步——任何跳过两步的短路写入触发 raise。

反例

# 错(静默写入)
user.profile.risk_appetite = 0.8
db.commit()

# 对(两步写入)
candidate = build_candidate(user, change={"risk_appetite": 0.8})
return {"candidate_id": "...", "preview": ..., "confirm_required": True}
# 用户 confirm 后才:apply_candidate(candidate_id)

Test 规格

  • L1(unit test 数据主权):API export / delete 单元测试。
  • L2(unit test 候选→确认):写入路径必经 candidate→confirm,断言短路写入会 raise。
  • L3(prompt audit, M1+):用户面 prompt 模板 review 必含"不强制框架"检查。

Test 文件预期路径tests/invariants/test_i03_user_sovereignty.py


§I-04' · RuntimeReasoningCompleteness(runtime reasoning 完整性)

硬度:identity 级

要做成什么(Build-Y 正向产出)runtime 层任何含 confidence / score / posterior 等数值字段的输出,系统主动同级配齐对应 reasoning(推理链路文字),让判断在工程层可观测、可复盘、可优化。reasoning 内容非占位符,且至少引用 1 处证据(指向 supporting_evidencesources)。

这是内部研究 / 复盘需要的工程能力,不是"用户能看到完整推理链"的用户面 UI 要求——用户面字段名收敛见 I-05'。runtime 完整 ≠ 用户面暴露。

战略原文锚点

  • 战略白皮书 §2(制胜逻辑 — 结构化输出)
  • 战略白皮书 §4("判断的可学习性")
  • 战略白皮书 §5("用户产品不暴露体系本身"——明确分层)
  • 产品定义 §6.4("产品文案不暴露体系细节")

负向边界(在边界内主动做 Y):系统主动拒绝"裸 score"(只有数字无推理 / reasoning 为占位符 / reasoning 不引用证据),触发配对校验失败。

反例

# 错(裸 score)
{"confidence_score": 0.73}
# 错(reasoning 占位)
{"confidence_score": 0.73, "confidence_reasoning": "..."}
# 错(reasoning 不引用证据)
{"confidence_score": 0.73, "confidence_reasoning": "感觉挺有信心的"}

# 对
{
"confidence_score": 0.73,
"confidence_reasoning": "基于 supporting_evidence[0](Q3 财报订单同比 +25%)+ [1](DGX 出货节奏),当前供需仍偏紧(参见 phase_evidence.cycle_position)"
}

Test 规格

  • L1(Pydantic validator):含 *_score / *_confidence 字段时同级必有 *_reasoning 字段。
  • L2(contract test):10 mock query 跑后断言每个输出 reasoning 段长度达标——长度不再硬编 30 字,按产品定义 §7.1 表达密度策略分用户层级 L0/L1/L2/L3 各取最小长度。
  • L3(grep):reasoning 内容 grep \.\.\.|TODO|placeholder|感觉 必须空。
  • 明确删除原 codify 的"用户面必须暴露 reasoning"——那是 I-05' 的反向。

Test 文件预期路径tests/invariants/test_i04_runtime_reasoning.py


§I-05' · UserFacingFieldRedaction(用户面字段名收敛)

硬度:工程约束(可随 product / UI 迭代调整)

要做成什么(Build-Y 正向产出):用户面看到的是按产品意图组织的 widget 内容(用户语言)。每个字段在 contracts/structured-cognition-result.yaml 主动标注 surface: {user_widget | internal_audit | both} 元数据;用户面 renderer 主动只渲染 surface ∈ {user_widget, both} 的字段,体系字段名只在 internal_audit 暴露面出现。

战略原文锚点

  • 战略白皮书 §5("用户产品不暴露体系本身")
  • 产品定义 §6.4("M1-M8 / MCA 等术语不进入用户界面")
  • 产品定义 §7.3("用户可见层不直接展示上述字段名")

负向边界(在边界内主动做 Y):用户面字符串在边界内主动用用户语言重述同样信息——因此不出现 M[1-8]_ / phase_matrix / correlation_regime / mca_bucket / posterior 等内部 token。

反例

错(用户面文案):"根据 phase_matrix 分析,M5 传导图显示……"
对(用户面文案):"根据当前市场周期位置和资金传导路径……"(同样信息,用户语言)

Test 规格

  • L1(grep on UI bundle):产品 UI 编译输出 + 文案 i18n 文件 grep 体系字段名必须空。
  • L2(contract test renderer):mock 一个含 surface: internal_audit 字段的 result 喂给用户面 renderer,断言该字段不渲染。
  • L3(API response 校验):用户面 API 响应 schema 不允许 surface 为 internal_audit 的字段。

依赖MP-5 · 字段暴露面分层契约 落地。

Test 文件预期路径tests/invariants/test_i05_user_facing_redaction.py


§I-06' · KellyCapTaskConditional(kelly_cap 任务条件化)

⚠️ 本不变量已退役(2026-06-04,ADR-021 · kelly_cap 退役)。 kelly_cap 已从代码移除;以下内容仅作历史记录,本文档其余位置出现的 kelly_cap token 亦同步作废。

硬度:工程约束

要做成什么(Build-Y 正向产出):StructuredCognitionResult 按 task_type 主动拆出变体——task_type ∈ {交易决策辅助, 交易准备, 风险识别} 的变体含 posterior 块(内含 kelly_cap);其余 4 类(解释 / 分析 / 比较 / 复盘)的变体不含该块。值存在时值域 ∈ [0, 1),M0 推荐 0.25。产品层例:问"什么是 ETF 折溢价"返回不含 kelly_cap 的 schema。

战略原文锚点

负向边界(在边界内主动做 Y):解释类等 4 类任务的 schema 变体在边界内主动不暴露 posterior.kelly_cap;存在时主动约束 ∈ [0, 1)(M0 ≤ 0.25)。

反例

# 错(解释类任务输出 kelly_cap)
{"task_type": "explanation", "posterior": {"kelly_cap": 0.25}}
# 错(值越界)
{"task_type": "trade_decision_aid", "posterior": {"kelly_cap": 1.0}}

Test 规格

  • L1(schema-by-task):task_type → schema 变体映射;解释类 schema 不含 posterior 块。
  • L2(Pydantic Field validator)Field(ge=0.0, lt=1.0)
  • L3(contract test):跑 7 类任务各 1 个 mock,断言解释 / 分析 / 比较 / 复盘 4 类不含 posterior。

依赖MP-4 · 任务→必含字段动态组合契约 落地。

Test 文件预期路径tests/invariants/test_i06_kelly_cap_task_conditional.py


§I-07' · TaskMinimumFieldSet(任务字段动态组合)

硬度:当前版本立场(v3 当前,未来 ADR 可调)

要做成什么(Build-Y 正向产出):结构化认知输出按任务 / 意图动态组合字段——每个 task_type 有自己的最小必含字段集(基于产品定义 §7 表 2 锁定),系统按任务输出对应 schema 变体。这正面落实战略原文"这 10 个要素不是固化字段表,按任务动态组合"。

task_type最小必含字段集
解释类main_answer, supporting_evidence, sources, follow_up_questions
分析类+ multi_perspectives, counter_evidence, prerequisites, uncertainty_and_gaps, applicability_flags
比较类+ counter_evidence, uncertainty_and_gaps, applicability_flags
复盘类+ historical_judgment_links, prerequisites, invalidation_conditions, counter_evidence, uncertainty_and_gaps
风险识别+ multi_perspectives, prerequisites, invalidation_conditions, uncertainty_and_gaps, applicability_flags, regulation_status
交易准备+ counter_evidence, prerequisites, invalidation_conditions, uncertainty_and_gaps, applicability_flags, regulation_status, causal_graph
交易决策辅助+ counter_evidence, prerequisites, invalidation_conditions, uncertainty_and_gaps, applicability_flags, regulation_status, posterior

全任务硬约束:每个任务都含 s1(叙事-数字一致性,见 I-13')+ mca_bucket(任务元数据,不入 result body)。

战略原文锚点

  • 战略白皮书 §5("10 要素不是固化字段表,动态组合")
  • 产品定义 §7(任务→必含要素映射表)
  • ADR-008-supplement §3("动态可选,不强制全量出现")

负向边界(在边界内主动做 Y):系统主动按任务变体收紧字段,而非"扁平 schema 全部 Optional[X]=None 占位"——后者会破坏 schema 表达力,不采用"10 个字段缺一不可"的固化必填。

反例

# 错(10 字段全 stub:解释类也强制留无关字段 stub)
class StructuredCognitionResult(BaseModel):
main_answer: str
multi_perspectives: list[str] = Field(default_factory=list)
...

# 对(按 task 变体动态组合)
class ExplanationResult(BaseModel):
main_answer: str
supporting_evidence: list[...]
sources: list[...]
follow_up_questions: list[...]
# 不含 multi_perspectives / kelly_cap 等

class TradeDecisionAidResult(BaseModel):
main_answer: str
... # 含 posterior, applicability_flags, regulation_status, ...

Test 规格

  • L1(schema-by-task):每个 task_type 单独 Pydantic model。
  • L2(contract test):跑 7 类任务各 N 个 mock,断言对应 schema 通过、错配 schema 失败。
  • L3(cross-section grep)contracts/structured-cognition-result.yamlcontracts/tasks-fields-mapping.yaml 字段覆盖一致。

依赖MP-4 · 任务→必含字段动态组合契约 落地。

Test 文件预期路径tests/invariants/test_i07_task_min_field_set.py


§I-08' · TaskTypeRequired(schema 顶层 task_type 显式)

硬度:工程约束

要做成什么(Build-Y 正向产出):StructuredCognitionResult schema 顶层主动含显式字段 task_type: Literal["explanation", "analysis", "comparison", "review", "risk_identification", "trade_preparation", "trade_decision_aid"],作为下游 consumer dispatch 的一等输入。task_type 在产品入口由任务识别策略(ADR-004 LLM Function Calling 主导)决定。

战略原文锚点

  • 产品定义 §4.2(7 类任务清单)
  • A3 诊断报告 §5.3(当前 schema 无 task_type 字段是设计漏洞)

负向边界(在边界内主动做 Y):下游凭显式 task_type dispatch,主动避免"靠机制激活 flag 间接推断"——因此 task_type 不允许缺失或 None。

反例

# 错(无 task_type,下游靠机制激活反推)
{"main_answer": "...", "applicability_flags": {...}, "posterior": {...}}

Test 规格

  • L1(Pydantic required):task_type 必填,缺失 raise。
  • L2(cross-validate):task_type 与字段组合一致性校验(如 task_type=explanation 不应携带 posterior)。

依赖MP-4 · 任务→必含字段动态组合契约 + I-07' 落地。

Test 文件预期路径tests/invariants/test_i08_task_type_required.py


§I-09' · MCA-7Axes-Naming(MCA 7 轴名稳定)

硬度:当前版本立场(v3)

要做成什么(Build-Y 正向产出):MCA(Market Capability Assessment)7 轴名称主动稳定为 7 个 snake_case 名,全栈(代码 / contract / engineering-pack / 测试 fixture)统一引用,保证跨层语义可对齐:

  1. investor_structure
  2. derivatives_maturity
  3. institutional_friction
  4. non_market_actor
  5. credit_environment
  6. information_availability
  7. currency_cross_border

战略原文锚点

  • ADR-007 supplement §M2
  • contracts/mca-buckets.yaml(已修复,commit 7707241)

负向边界(在边界内主动做 Y):全栈主动复用这 7 名,因此不漂移到 axis_1 / axis_investor / investor_struct 等变体。

反例

# 错
- id: axis_1
name: axis_1
# 错
- id: axis_investor
name: investor_struct

Test 规格

  • L1(YAML schema validate)contracts/mca-buckets.yaml 跑 schema 校验,断言 7 个 axes name 值在锁定 set 内。
  • L2(grep):代码 / fixture / engineering-pack 中 axis_N 只允许出现在 id 字段,name 字段必须是 7 个 snake_case 名。
  • L3(contract test):MCA 输出对象 axes 字段断言键名 = 锁定 7 个。

Test 文件预期路径tests/invariants/test_i09_mca_7axes_naming.py


§I-10' · MechanismsSingleSource(8 机制单一事实源)

硬度:工程约束

要做成什么(Build-Y 正向产出):FinBayes 8 大机制(M1-M8)的语义定义集中在单一事实源——当前为 contracts/structured-cognition-result.yaml + ADR-007 supplement §8 机制升级定义(M0 阶段;M1+ 视情况派生独立 mechanisms contract 文件)。代码 / engineering-pack / 测试主动 import / 引用此事实源派生读取,保证机制语义全栈一致。

战略原文锚点

  • ADR-007 supplement §8 机制升级定义
  • Step 11 整改包 I 单一事实源原则

负向边界(在边界内主动做 Y):代码主动从事实源读机制语义,因此不在本地 hardcode / 重定义机制名或语义。

反例

# 错(在代码里重定义机制语义)
MECHANISM_M1 = "narrative_drift"
MECHANISM_M2 = "..."

# 对(import contracts 事实源)
from finbayes.contracts import load_mechanisms
mechanisms = load_mechanisms() # 从 contracts + ADR-007 supplement 派生读

Test 规格

  • L1(grep)grep -rE "MECHANISM_M[1-8]\s*=\s*['\"]" src/ 必须空。
  • L2(contract test):构造一个与真 contract 有差异的 mock contract,断言代码读到的 mechanisms 与 mock 一致(证明确实从文件读)。
  • L3(cross-section grep):engineering-pack 中机制名 set 必须 = contract 中 set。

Test 文件预期路径tests/invariants/test_i10_mechanisms_single_source.py


§I-11' · CredentialFiltering(输出端凭证过滤双处)

硬度:identity 级(凭证泄漏是安全 identity 级问题)

要做成什么(Build-Y 正向产出):系统在两个位置主动保证输出端无凭证泄漏(API key / OAuth token / 数据库密码 / 内部 trace_id):

  1. 综合层语义级:构造 StructuredCognitionResult 时主动不收录凭证字段。
  2. Output Pipeline 格式级:出口处主动做 regex 过滤 + 字段黑名单。

两处同时存在(任一缺失即违反),形成纵深防御。

战略原文锚点

负向边界(在边界内主动做 Y):两道关卡各自主动拦截——任何漏过综合层的凭证在 Output Pipeline 出口仍被过滤掉。

反例

# 错(只在 Output Pipeline 过滤,综合层照收)
result.debug = {"api_key": "sk-xxx", ...}

# 错(只在综合层过滤,Output Pipeline 不二次校验)
# 任何漏过综合层的凭证直接走出口

Test 规格

  • L1(unit test 综合层):mock 一个含 API key 的 evidence dict 喂给综合层,断言 result 内不含该 key 字符串。
  • L2(unit test Output Pipeline):手工构造一个"已被综合层污染"的 result,喂给 Output Pipeline,断言出口处仍能过滤。
  • L3(regression test):每次新增字段类型(M1+),都补对应 redaction case。

Test 文件预期路径tests/invariants/test_i11_credential_filtering.py


§I-12' · ProfileDoesNotShrinkFactSpace(画像不裁剪事实空间)

硬度:当前版本立场(v2→v3 audit 降级,但仍是 v3 立场)

要做成什么(Build-Y 正向产出):用户画像(risk_appetite / sector_preference / time_horizon 等)仅用于呈现层组织 / 排序 / 表达密度。runtime 层证据收集 / reasoning 生成主动对所有画像一致——同一查询对不同画像用户,底层 evidence set + reasoning 完全相同,差异只发生在 widget 表达密度 / 顺序 / 术语深度。这保证 FinBayes 对每个用户都交付完整事实空间。

战略原文锚点

  • 战略白皮书 §9(v2 不可妥协边界 → v3 降级 audit)
  • ADR-009(立场降级 audit trail)

负向边界(在边界内主动做 Y):呈现层主动用 profile 调表达密度 / 字段顺序 / 术语深度;runtime 层 evidence 收集器主动不依赖 profile——因此不出现 if user_profile.risk_appetite < 0.3: skip_evidence(...) 这类裁剪分支。

反例

# 错(画像裁剪事实空间)
if user.risk_appetite < 0.3:
evidence = filter_out_aggressive_evidence(evidence)

# 对(画像仅影响呈现)
runtime_result = analyze(query) # 不依赖 profile
ui_view = render(runtime_result, density=profile.get_density()) # 呈现层用 profile

Test 规格

  • L1(unit test):3 个画像用户跑同 query,断言 runtime evidence set 完全一致。
  • L2(code path audit):evidence 收集模块不允许 import user_profile。

Test 文件预期路径tests/invariants/test_i12_profile_no_shrink.py


§I-13' · S1AlwaysActive(S1 每次综合输出必跑)

硬度:identity 级(唯一全任务硬约束 — ADR-008-supplement §2.6 明示)

要做成什么(Build-Y 正向产出):S1(叙事-数字一致性检查)字段在每次综合输出中主动 active,无 task_type 例外——7 个 task 变体 schema 全部含 s1 字段必填,且 S1 的 8 子字段按 ADR-008-supplement §2.6 规定全填。这是系统对每条输出的叙事与数字自洽性的主动自检。

战略原文锚点

  • ADR-008-supplement §2.6(S1 每次综合输出必跑)

负向边界(在边界内主动做 Y):所有 task 变体主动 require s1——任何 task 类型缺 s1 字段触发 schema validation fail。

反例

# 错(某 task 变体缺 s1)
{"task_type": "explanation", "main_answer": "...", "supporting_evidence": [...]}
# 缺 s1 → schema validation fail

Test 规格

  • L1(Pydantic required):所有 task 变体 schema 均 require s1。
  • L2(contract test):S1 的 8 子字段非空 / 非占位符。

Test 文件预期路径tests/invariants/test_i13_s1_always_active.py


§I-14' · CognitionDataIndependence(认知数据独立性)

硬度:identity 级(定位级核心,与 I-01' 执行边界同级)

要做成什么(Build-Y 正向产出):FinBayes 的高质量分析/推理/认知结论/结构化输出内生于推理体系 + 认知表达规范——在零外部金融数据/信息接入、仅有通用 LLM 支撑时仍正常工作且保持高质量,并产出诚实的信息缺口标注。外部数据/信息(无论用户本地上传 Ch1,还是第三方 API/搜索/Data Horizon Ch2——对 FinBayes 一律是外部)是辅助证据,作用是完善/矫正/佐证,不是认知前提

战略原文锚点

负向边界(在边界内主动做 Y):认知链不得 hard-require 任何外部证据通道有值才能产出;无证据时数据精修层(posterior/s1/mca_bucket 等)诚实标"未拟合(无证据)",禁假填冒充真实推理(注:其契约级表示改动受 MP-3/4/5 治理,须走 change-protocol,见架构补充草稿)。

反例

  • 错:无外部数据时塌成"需接入实时数据才能回答"。
  • 错:无真实证据却假填 posterior/s1 常量冒充真实推理。
  • 对:零数据下给出有条件认知核 + 诚实标"这块缺数据、它会怎样改变判断"。

Test 规格(数据消融 gate)

  • 核断言:抽掉全部外部数据 → 仍过规格 §9 + 数据精修层标"未拟合"不假填。
  • 能力子测:用户上传证据(Ch1)能吃进判断;离线时不偷连外部源。

Test 文件预期路径tests/invariants/test_i14_cognition_data_independence.py


§I-15' · AgentAutonomousLoop(agent 自主循环本体)

硬度:identity 级(产品本体级,与 I-01' 执行边界同级;改即非 FinBayes)

建造态不变量(诚实标注):本条是 2026-06-04 阶段 0 文档矫正新增的产品本体 frame 硬化,依据金融真智能体骨架蓝图(E) + owner 议定结果。它编码的是目标态——当前 FinBayes(684d69d)尚是「一次性问答函数」、还没有主回路与主动信号触发器,因此本条 L1/L2 test 在阶段 1 / M2 建成最小自主循环前预期为红。这不是 codify 失误,而是如实把「有大脑、无身体」的差距登记成可断言契约(test 转绿 = 阶段 1 / M2 完成的客观判据)。本条不作 M0 invariant gate 的硬门,自阶段 1 / M2 起纳入硬门。

要做成什么(Build-Y 正向产出):FinBayes 的产品本体是一个带自主循环的金融认知 agent——存在一条跨回合主回路(感知接地 → 规划 → 行动调工具 / 认知机制 → 观察回灌 → 收敛,带显式迭代上限与明确终止态),以及一个 State Management 主动信号触发器(在无人提问时被 heartbeat / 市场变化唤醒、判断成立 / 失效条件触及时自主发起新一轮认知)。synthesize_cognition(单次综合)是这条循环在单个回合内被调用的一个认知动作,不是 runtime 的顶层入口。

战略原文锚点

  • 战略白皮书 §1 愿景闭环图 + 短期形态「对话入口 ≠ 问答函数」+ §4「判断的连续性」产品形态支柱 + §7 第一阶段「agent 自主循环最小闭环」核心交付
  • 产品定义 §1 产品本体 frame + §8 持续认知循环
  • 架构 §2「FinBayes 产品本体是带自主循环的认知 agent」identity 级架构不变量 + §9.2「单回合编排 + 主动信号触发器 = agent 的两个半」

负向边界(在边界内主动做 Y):runtime 顶层入口不得是「synthesize_cognition 一次合成即返回」的单次问答函数形态;不得只建 Task Orchestration(单回合编排)而无 State Management 主动信号触发器;最小自主循环(哪怕只监控 1 类失效条件、只对 1 个 Fin Object)不得被里程碑无限后推(架构 §25 已把最小切片前移 M2)。

反例(违反时长这样):

# 错(synthesize 是顶层入口 = 单次问答函数)
def handle_question(q):
return synthesize_cognition(q) # 一次合成即返回,无回路 / 无主动触发

# 对(synthesize 是被主回路调用的一个认知动作)
async def agent_loop(ctx):
while not converged and i < MAX_ITERS:
action = plan(ctx)
obs = await dispatch(action) # 可能是 synthesize_cognition,也可能是数据工具
ctx = observe(ctx, obs)
# + 独立的主动信号触发器在无人提问时唤醒本回路

Test 规格

  • L1(结构存在性,阶段 1 / M2 起转绿)src/ 存在主回路模块(perceive-act-observe + max_iterations 硬封顶)且 synthesize_cognition 的调用方是回路内的认知动作分发、不是顶层 handler;存在 State Management 主动信号触发器组件。
  • L2(行为断言,M2 起):构造带失效条件的 Judgment Record + 一次触及的市场变化 → 无用户输入即自主发起复盘(对应架构 M2「agent 行为门」首要验收)。
  • L3(结构反断言):不存在「顶层 handler 直接 return synthesize_cognition(...)」的单次问答路径。

Test 文件预期路径tests/invariants/test_i15_agent_autonomous_loop.py


§I-16' · JudgmentRecordIsLiveMemory(判断记录是 agent 活记忆,非死档)

硬度:identity 级(与 I-15' 自主循环同源;改即退回问答函数)

建造态不变量:同 I-15',编码目标态。当前 JudgmentRecord 带 validity / invalidation_conditions / created_at(可证伪要素的容器),但全 src 无 settle / reconcile / 对账路径——判断写进去即死档。本条 test 自阶段 2 / 3(到期对账闭环)建成起转绿,M0 不作硬门。

要做成什么(Build-Y 正向产出):Judgment Record 是 agent 的工作记忆 + 自主触发条件源,不是「用户的历史日志」。每条带成立 / 失效条件 + 时间窗 + 可证伪断言,且必须能被 agent 在到期 / 条件触及时自动拉真实数据对账,做判断跟进结算(旧称「三态结算」;按 ADR-022 formal 化为「验证状态+验证结论」两层枚举,见 glossary),原判断与复盘结论同时保留形成时间线(不覆盖)。

战略原文锚点

  • 产品定义 §3 状态资产正名「agent 工作记忆 + 自主触发条件源」+ §3.4 Judgment Record + §12「判断进入可对账闭环」agent 行为门
  • 战略白皮书 §1 短期形态「连续认知资产 = agent 状态层」
  • 架构 §2 agent 本体不变量 + §6 场景 S11 到期对账 + §11 Judgment Record 生命周期

负向边界(在边界内主动做 Y):Judgment Record 不得是 write-once 死档;失效条件字段不得只存不查(必须接入 I-15' 的主动信号触发器作为条件源);对账锚点是「成立 / 失效条件是否被市场触发、条件化倾向方向是否被事后演化支持」,不得是「按判断交易的真实盈亏」(FinBayes 不下单、不接触持仓,承接 I-01' 执行边界);结算不得二值化(三态,承认对错本身模糊)。

反例

  • 错:JudgmentRecord 写入后无任何 settle / reconcile 路径,posterior 给了分布却从不结算(当前 684d69d 状态)。
  • 错:复盘用新结论覆盖原判断(丢失时间线)。
  • 错:用真实盈亏做对账锚点(越过执行边界)。
  • 对:到期触发拉真实价格 → 判断跟进结算 → 原判断 + 复盘结论并存 + 校准信号留痕。

Test 规格

  • L1(grep,阶段 2 / 3 起转绿)src/ 存在 settle / reconcile 判断对账路径(当前预期红——正是蓝图记录的核心 P0 缺口)。
  • L2(行为断言):构造一条到期 Judgment Record → 触发对账 → 产出判断跟进结算之一 + 原判断未被覆盖(时间线保留)。
  • L3(边界反断言):对账锚点字段不含真实盈亏 / 持仓凭证(承接 I-01' / I-11')。

Test 文件预期路径tests/invariants/test_i16_judgment_record_live_memory.py


§1 与原版 10 条禁令型的差分

原 ID(禁令型)处理说明
I-01 NoOrderPlacement→ I-01' ExecutionBoundary(重写)从"禁字段" → "正向认知产出 + 禁依赖 / 禁路径边界"
I-02 NotDeciding→ I-02' ConditionalJudgmentContract(重写从禁"应该买入" → 允许带条件方向判断;删除粗暴 grep
I-03 UserSovereignty→ I-03' UserSovereignty(扩展)加候选→确认两步写入契约
I-04 CognitiveTransparency→ I-04' RuntimeReasoningCompleteness + I-05' UserFacingFieldRedaction(拆分runtime 完整(内部复盘需要)vs 用户面字段名收敛 分层
I-05 ForbiddenLexicon降级禁用词扫描属 product 层 lint,移交 verify:kb content-hygiene hook,不进 L0.5
I-06 KellyCapBound→ I-06' KellyCapTaskConditional(重写从单一值域约束 → "任务条件化存在性 + 值域"
I-07 SCR-1.1-Required→ I-07' TaskMinimumFieldSet(重写从"10 字段缺一不可" → "按任务动态组合最小必含子集"
I-08 MCA-7Axes-Naming→ I-09'(重编号 + 契约化)保留 7 轴稳定,正向表述
I-09 8-Mechanisms-Source→ I-10'(重编号 + 契约化)保留单一事实源,正向表述
I-10 CredentialFiltering→ I-11'(重编号 + 契约化)保留双处过滤,正向表述
——+ I-08' TaskTypeRequired(新增)schema 顶层 task_type 显式必填
——+ I-12' ProfileDoesNotShrinkFactSpace(新增)A1 漏发现的正向不变量
——+ I-13' S1AlwaysActive(新增)A1 漏发现 + ADR-008-sup §2.6 唯一全任务硬约束

净变化:原 10 条禁令型 → 新 13 条契约型。重写 4 条(I-01/02/06/07)、拆分 1→2 条(I-04 → I-04'+I-05')、降级 1 条(I-05 → verify:kb hook)、保留重编号 3 条(I-08/09/10 → I-09'/10'/11')、扩展 1 条(I-03)、新增 3 条(I-08'/12'/13')。

2026-05-30 增补:+ I-14' CognitionDataIndependence(identity 级)——由「认知数据独立性 + 护城河」对齐传导(owner 拍板),13 → 14 条。配套架构补充见 认知核/数据精修层分离草稿

2026-06-04 增补(阶段 0 文档矫正):+ I-15' AgentAutonomousLoop + I-16' JudgmentRecordIsLiveMemory(均 identity 级、建造态),把 agent 产品本体从隐性 frame 升为可断言契约,14 → 16 条。依据金融真智能体骨架蓝图(E) + owner 议定结果;与架构 §2 identity 级架构不变量对齐。两条为建造态:当前代码(684d69d)尚未满足,test 在阶段 1–3 建成对应能力前预期红、不作 M0 硬门,转绿即对应阶段完成判据。治理连带:本增补建议补一条轻量 ADR 增补走 §2 SOP 正式收录(与战略白皮书 frame 矫正回溯 ADR 一并列入 FB-RESUME 治理连带项待 owner 定)。

§2 不变量增删流程

何时新增不变量

触发新增动作
战略白皮书新版本发布30 分钟扫一遍,识别新承诺;确认需 codify 走 ADR 增补
产品定义文档迭代同上
架构 ADR 新增 / 修订看是否带新隐式承诺(如 ADR-010 类边界)
Review / 用户反馈发现"白皮书说了 X 但代码做了 -X"紧急补不变量 + 补 test

增删 SOP(按 ADR-013 五步翻译)

  1. Step 1 锚定战略原文:引用 ≥ 1 处白皮书 / 产品定义 / ADR 原文(含 §X line N)。
  2. Step 2 评估硬度级:identity / 当前版本立场 / 工程约束 三选一,必须明示。
  3. Step 3 Build-Y 优先:先写"系统主动做成 / 产出什么",此步未过不进 Step 4。
  4. Step 4 加 Require-X-when-Y 条件式:分任务类型 / 分暴露面,不一刀切。
  5. Step 5 仅 identity 级补 Prevent-X 边界:限于执行边界 / 凭证安全 / 事实空间裁剪,配可 fail 反例。

新增提案在本文件加新 §I-NN' 段,同步在工程仓加 tests/invariants/test_iNN_*.py,走 ADR-003-supplement 三阶段 SOP,配可 fail 反例 test 才算正式收录。

反模式(按 ADR-013 §6)

  • ❌ Prevent-X 优先翻译:把战略价值都先翻成"禁止 X" → 系统性漂移。
  • ❌ identity 级泛滥:工程约束级错放 identity 级 → 柔性丧失。
  • ❌ 凭印象 codify:不引用战略原文 line N,靠 AI 演绎。
  • ❌ 缺暴露面 codify:字段不分 user_widget / internal_audit。
  • ❌ 全任务一刀切:扁平 schema 全 Optional[X]=None 占位。
  • ❌ 不变量无反例 test → 等于没 codify。

§3 与 SVA-9 其他层的关系

与本文件的关系
L1(契约源)不变量是契约的底线:契约可收紧,但不能违反不变量
L2(contract test)本文件 test 规格落地在 tests/invariants/tests/contract_*.py 并存
L3(3-phase SOP)PR plan 段必扫是否触及不变量 + 必含正向产出对称段;verify checklist 双向(Build-Y 验证 + identity 级 Prevent-X 验证)
L4(Archon gate)milestone gate 节点必跑 pytest tests/invariants/ 全绿
L7(V 维度评测)I-02' 由 V1 judge 承担;test 规格中的 "Claude judge" 即指 L7
L8(L1 用户 vibe)用户能否凭直觉确认"是 FinBayes 该有的样子"——不变量的人类感官层验证

§4 关联资产