MP-5 — 字段暴露面分层契约(field surface layering protocol)
⚠️ 2026-06-04 更新(ADR-021):
kelly_cap已退役并从代码移除。 本契约中kelly_cap的暴露面分类、block list 项、以及翻译成「仓位上界(非仓位建议)」的用户面映射全部作废;其余字段暴露面约定不变。
§0 决策简述
决议:StructuredCognitionResult 与 Task schema 的每个字段必须显式声明其 surface(暴露面)属性,三选一:
user_widget:仅出现在用户面 UI / 用户面 API 响应internal_audit:仅出现在内部审计 / 复盘 / 评测 / 监控 / 日志(不进用户面)both:两面都出现,但用户面渲染必须用产品语言(不暴露体系字段名)
触发:
- A2 + A4 诊断共同发现:12 份工程化文档没有任何一份显式声明字段 surface → 工程默认"全字段都用户面" → I-04 误读("用户面必须暴露 reasoning")的根因
- 战略白皮书 §5 line 570:"用户产品不暴露体系本身"
- product-definition.md §6.4 line 303:"M1-M8 / MCA 等术语不进入用户界面"
- product-definition.md §7.3 line 370:"phase_matrix / correlation_regime 不进入界面"
定位:ADR-013 §3.2 "Require-X-when-Y 条件式契约"的 surface 维度落地物;解决"runtime 完整 vs 用户面收敛"分层缺失问题;I-05' UserFacingFieldRedaction 的事实源。
§1 暴露面三态定义
§1.1 user_widget
语义:字段在用户面 widget / UI / API 响应中渲染,用户能直接看到。
渲染要求:
- 必须用产品语言(不暴露体系字段名 / 机制名 / 内部 ID)
- 渲染密度 / 顺序可由 user_profile.expression_density 调整(按 product-definition.md §7.1 表达密度策略)
- 默认可折叠 / 可展开(如 reasoning 默认折叠,用户点开看详情)
典型字段:
main_answer(核心结论,必渲染)supporting_evidence(用户可看到的证据,可折叠)sources(来源 + 时间戳,可折叠)follow_up_questions(继续追问入口)
§1.2 internal_audit
语义:字段仅出现在内部审计 / 评测 / 监控 / 复盘 / 日志。用户面 renderer 必须 filter out 此类字段。
消费者:
- EvalHarness D1-D11 / V1-V3 评测
- 综合层 self-review hook(复盘 / 复跑)
- 监控 / 告警 / SLO dashboard
- L1 vibe-check 中"展开技术细节"模式(默认折叠)
- 模型训练数据采集 / 标注 pipeline
典型字段:
s1.s1_mode/s1.s1_score等体系内部 tokenmca_bucket.bucket_label(任务元数据,产品文案不暴露)phase_evidence.phase_matrix(M3 时钟相位矩阵)causal_graph.correlation_regime(M5 相关性跃迁标签)posterior.kelly_cap(除决策辅助任务的内部审计层;用户面如需要由 widget 翻译成"仓位上界(非仓位建议)"产品语言)applicability_flags(三态适用性标志,产品文案不暴露 M6 术语)
§1.3 both
语义:字段同时承担两面用途。用户面渲染必须用产品语言翻译(不暴露体系字段名 / 机制名);内部审计使用原始字段值。
典型字段:
counter_evidence(用户能看到反方证据,但呈现时不写"counter_evidence:[...]"而是"反方观点:")prerequisites(用户能看到"成立条件"但不写"prerequisites: ...")invalidation_conditions(用户能看到"判断失效条件")uncertainty_and_gaps(用户能看到"不确定性")multi_perspectives(用户能看到"多视角"但不写 token "multi_perspectives")confidence_reasoning(reasoning 链路用户可展开,渲染时用产品语言)
§2 17 字段 × surface 映射
来源:综合 MP-4 §2 任务字段矩阵 + 战略白皮书 §5 line 570 / product-definition.md §6.4 / §7.3 不暴露策略 + A4 诊断发现。
| 字段 | surface | 渲染规则 / 备注 |
|---|---|---|
main_answer | user_widget | 核心结论,用户面必渲染(产品语言) |
supporting_evidence | both | 用户看产品语言呈现的证据;评测 / 审计层看原始 evidence object |
multi_perspectives | both | 渲染为"多视角"段;不暴露字段名 |
counter_evidence | both | 渲染为"反方观点 / 反方证据"段 |
prerequisites | both | 渲染为"成立条件"段 |
invalidation_conditions | both | 渲染为"判断失效条件"段 |
uncertainty_and_gaps | both | 渲染为"不确定性 / 缺口"段 |
sources | user_widget | 来源 + 时间戳,可折叠 |
follow_up_questions | user_widget | 继续追问入口 |
historical_judgment_links | both | 渲染为"历史判断链接"段(用户可点跳转) |
phase_evidence | internal_audit | M3 相位矩阵;用户面如需要由 widget 翻译为"市场周期位置"产品语言(不暴露 phase_matrix token) |
causal_graph | internal_audit | M5 传导图;用户面如需要由 widget 翻译为"资金传导路径"产品语言(不暴露 correlation_regime token) |
regulation_status | internal_audit | M5.4 制度摩擦;用户面如需要由 widget 翻译为"政策合规观察"产品语言 |
applicability_flags | internal_audit | M6 三态适用性;用户面如需要由 widget 翻译为"适用范围"产品语言(不暴露 M6 术语) |
posterior | internal_audit | 含 kelly_cap;用户面(仅决策辅助任务)由 widget 翻译为"仓位上界(非仓位建议)"产品语言(不暴露 kelly_cap token) |
s1 | internal_audit | 叙事-数字一致性内部 token;用户面如需要由 widget 翻译为"叙事-数字一致性观察"产品语言 |
mca_bucket | internal_audit | 任务元数据层;不入 result body;评测 / 复盘 / 监控用 |
统计:
user_widget独占:3 个字段(main_answer / sources / follow_up_questions)both双暴露:7 个字段(supporting_evidence / multi_perspectives / counter_evidence / prerequisites / invalidation_conditions / uncertainty_and_gaps / historical_judgment_links)internal_audit独占:7 个字段(6 机制层新字段 + mca_bucket)
§3 暴露面策略:白名单为主、禁词兜底(ADR-013 Build-Y over Prevent-X)
范式声明:本协议的暴露面策略是 「白名单为主、禁词兜底」,不是 「默认遮蔽、例外放行」。
- 白名单(正向、默认产出):每个
internal_audit字段必须产出对应的user_widget_translation(用户价值翻译)。这是 Output Pipeline 的默认行为——内部要素默认被翻译成用户能用的价值语言(仓位上界(非仓位建议) / 市场周期位置 / 政策合规观察 / 资金传导路径 / 适用范围 / 叙事-数字一致性观察 / 市场上下文)。contracts/field-surface-mapping.yaml的user_widget_translation_whitelist段是其事实源。 - 禁词(兜底、仅拦 token 字面):下面的 block list 只拦截「体系内部 token 字面」(机制名 / 字段内部 token / MCA 轴 token / 评测维度名),是兜底校验,不拦截被翻译后的用户价值语义。grep 的判定对象是 token 字面,自然语言价值翻译不在拦截范围。
用户面 UI / API 响应 / 产品文案 / i18n 文件禁止出现以下 token 字面(兜底校验对象):
§3.1 机制名 token
M1, M2, M3, M4, M5, M5.4, M6, M7, M7.uq, M8
m1, m2, m3, m4, m5, m5_4, m6, m7, m7_uq, m8
mechanism_M1, mechanism_M2, ..., mechanism_M8
§3.2 字段内部 token
phase_matrix
correlation_regime
applicability_flags
kelly_cap
posterior
regulation_status
mca_bucket
s1_mode, s1_score, s1.backtrigger
bucket_label
fit_method
§3.3 MCA 7 轴名 token(仅 internal_audit;用户面渲染需翻译)
investor_structure
derivatives_maturity
institutional_friction
non_market_actor
credit_environment
information_availability
currency_cross_border
§3.4 评测维度名(D1-D11)
D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11
注(关键):以上 block list 是 token 层 grep 兜底,只匹配 token 字面,不包括「自然语言翻译版本」。已定义的用户价值翻译永远放行——用户面应当默认产出"市场周期位置"(翻译自 phase_evidence)、"仓位上界(非仓位建议)"(翻译自 posterior / kelly_cap)、"政策合规观察"(翻译自 regulation_status)、"资金传导路径"(翻译自 causal_graph)、"适用范围"(翻译自 applicability_flags)、"叙事-数字一致性观察"(翻译自 s1)、"市场上下文"(翻译自 mca_bucket)等产品语言。block list 把这些价值语义误杀即为实现 bug(违反 §3 白名单为主原则)。
§4 落地物:contracts/field-surface-mapping.yaml
新单一事实源 yaml,机器可读,由 Output Pipeline / 用户面 renderer / V 维度 V2 judge / verify:kb hook 消费。
# contracts/field-surface-mapping.yaml
schema_version: 1.0
last_updated: 2026-05-29
upstream_anchor: governance/workstreams/finbayes-arch-rewrite/decisions/MP-5-field-surface-layering-protocol.md
# 17 字段 → surface 映射
field_surfaces:
# user_widget 独占(3 字段)
- field: main_answer
surface: user_widget
rendering: 直接渲染(产品语言)
- field: sources
surface: user_widget
rendering: 可折叠列表(产品语言)
- field: follow_up_questions
surface: user_widget
rendering: 继续追问入口(产品语言)
# both 双暴露(7 字段)
- field: supporting_evidence
surface: both
user_widget_rendering: 产品语言"证据/依据"段(不暴露字段名 token)
internal_audit_rendering: 原始 evidence object
- field: multi_perspectives
surface: both
user_widget_rendering: 产品语言"多视角"段
internal_audit_rendering: 原始 perspective list
- field: counter_evidence
surface: both
user_widget_rendering: 产品语言"反方观点 / 反方证据"段
internal_audit_rendering: 原始 counter_evidence list
- field: prerequisites
surface: both
user_widget_rendering: 产品语言"成立条件"段
internal_audit_rendering: 原始 prerequisites list
- field: invalidation_conditions
surface: both
user_widget_rendering: 产品语言"判断失效条件"段
internal_audit_rendering: 原始 invalidation_conditions list
- field: uncertainty_and_gaps
surface: both
user_widget_rendering: 产品语言"不确定性 / 缺口"段
internal_audit_rendering: 原始 gaps list
- field: historical_judgment_links
surface: both
user_widget_rendering: 产品语言"历史判断链接"段(点跳转)
internal_audit_rendering: 原始 judgment_link list
# internal_audit 独占(7 字段)
# user_widget_translation 是必产正向白名单; block_tokens 仅兜底拦截 token 字面
- field: phase_evidence
surface: internal_audit
user_widget_translation: 市场周期位置
block_tokens: [phase_matrix, M3]
- field: causal_graph
surface: internal_audit
user_widget_translation: 资金传导路径
block_tokens: [correlation_regime, M5]
- field: regulation_status
surface: internal_audit
user_widget_translation: 政策合规观察
block_tokens: [M5.4, regulation_status]
- field: applicability_flags
surface: internal_audit
user_widget_translation: 适用范围
block_tokens: [applicability_flags, M6, three_pillars]
- field: posterior
surface: internal_audit
user_widget_translation: 仓位上界(非仓位建议)(仅 trade_decision_aid 任务)
block_tokens: [posterior, kelly_cap, M7, M7.uq, fit_method]
- field: s1
surface: internal_audit
user_widget_translation: 叙事-数字一致性观察
block_tokens: [s1, s1_mode, s1_score, backtrigger, S1]
- field: mca_bucket
surface: internal_audit
user_widget_translation: 市场上下文(如适用)
block_tokens: [mca_bucket, bucket_label, investor_structure, derivatives_maturity, institutional_friction, non_market_actor, credit_environment, information_availability, currency_cross_border]
# 正向白名单(必须产出的用户价值翻译,默认产出)
user_widget_translation_whitelist:
- {source_field: phase_evidence, value: 市场周期位置}
- {source_field: causal_graph, value: 资金传导路径}
- {source_field: regulation_status, value: 政策合规观察}
- {source_field: applicability_flags, value: 适用范围}
- {source_field: posterior, value: 仓位上界(非仓位建议)}
- {source_field: s1, value: 叙事-数字一致性观察}
- {source_field: mca_bucket, value: 市场上下文}
# 兜底 block list(仅拦截体系内部 token 字面,不拦截价值翻译语义)
internal_token_block_list:
mechanism_tokens:
- M1
- M2
- M3
- M4
- M5
- M5.4
- M6
- M7
- M7.uq
- M8
field_internal_tokens:
- phase_matrix
- correlation_regime
- applicability_flags
- kelly_cap
- posterior
- regulation_status
- mca_bucket
- s1_mode
- s1_score
- bucket_label
- fit_method
mca_axes_tokens:
- investor_structure
- derivatives_maturity
- institutional_friction
- non_market_actor
- credit_environment
- information_availability
- currency_cross_border
eval_dimension_tokens:
- D1
- D2
- D3
- D4
- D5
- D6
- D7
- D8
- D9
- D10
- D11
# verify:kb hook 钩点
verify_hooks:
- hook: require_user_widget_translation
rule: 每个 surface=internal_audit 字段必须配 user_widget_translation(正向白名单),缺则 fail
- hook: grep_internal_token_block_list
targets:
- src/finbayes/web/ # 用户面 UI 源
- src/finbayes/api/v1/ # 用户面 API 响应
- docs/user-facing/ # 产品文案
- locales/ # i18n 翻译文件
rule: 兜底 grep internal_token_block_list 的 token 字面,命中即 fail;价值翻译白名单语义放行
- hook: enforce_renderer_filters_internal_audit
rule: 用户面 renderer 测试断言 surface=internal_audit 字段原始 token 不进入 user response(其价值翻译应进入)
# 表达密度策略联动(与 product-definition.md §7.1 衔接)
expression_density:
L0:
user_widget_render: 默认仅 main_answer + 1-2 行 summary
foldable:
- supporting_evidence
- sources
L1:
user_widget_render: + multi_perspectives + counter_evidence(折叠)
foldable:
- prerequisites
- invalidation_conditions
- uncertainty_and_gaps
L2:
user_widget_render: + 全部 both 字段(折叠)+ posterior widget 翻译版(决策辅助任务)
foldable: []
L3:
user_widget_render: + internal_audit 字段的 widget 翻译版全展开
foldable: []
§5 实施路径与 milestone 时间线
| Milestone | 动作 |
|---|---|
| M0(C-1 第一个 PR) | • 落地 contracts/field-surface-mapping.yaml(本 MP-5 同 commit)• Pydantic schema 每字段加 surface 元数据(Field(..., json_schema_extra={"surface": "..."})• Output Pipeline 默认产出 user_widget_translation(白名单),internal token 走兜底过滤 • verify:kb hook 增加 require_user_widget_translation + internal_token_block_list 兜底 grep |
| M1 | • L0-L3 表达密度策略落地(user_widget 默认折叠 / 展开规则) • widget 翻译层落地(phase_evidence → 市场周期位置;posterior → 仓位上界(非仓位建议)) |
| M2+ | • 按用户反馈调整 user_widget / internal_audit 边界(走 ADR-013 §2 工程约束级流程) |
§6 与既有协议的关系
| 既有 | MP-5 怎么承接 |
|---|---|
| strategic-whitepaper §5 line 570 "用户产品不暴露体系本身" | MP-5 是该原意的工程层 codify 落地(machine-readable surface 元数据) |
| product-definition.md §6.4 / §7.3 "M1-M8 / phase_matrix / correlation_regime 不进入界面" | MP-5 §3 兜底 block list 完整继承并扩展(仅拦 token 字面,价值翻译白名单放行) |
| product-definition.md §7.1 "表达密度可调 L0-L3" | MP-5 §4 yaml expression_density 段承接 |
| MP-4 任务→必含字段动态组合契约 | 与 MP-4 正交:MP-4 决定"哪些字段在哪个任务存在";MP-5 决定"已存在字段是否暴露用户面" |
| ADR-010 输出端凭证过滤 | MP-5 是 ADR-010 上层泛化(凭证过滤是 surface=internal_audit 的极端特例) |
| ADR-013 codify 哲学换轨 | MP-5 是 ADR-013 §3.2 "Require-X-when-Y 条件式契约"在 surface 维度的落地物 |
§7 反模式(禁止)
- ❌ 字段无 surface 声明 —— 任何新字段提交 PR 必带 surface 标注,否则 verify:kb fail
- ❌ 用户面直接渲染 internal_audit 字段原始 token —— Output Pipeline 必须翻译,不允许"用户面直接 JSON.dumps(result)"
- ❌ 用户面文案出现 block list token 字面 —— verify:kb 兜底 grep 命中即 fail
- ❌ block list 误杀价值翻译 —— 把"市场周期位置 / 仓位上界(非仓位建议) / 政策合规观察"等已定义用户价值语义当禁词拦掉,是违反 §3 白名单为主原则的实现 bug
- ❌ 新增 internal_audit 字段不配 user_widget_translation —— 每个 internal_audit 字段必须同步声明对应价值翻译(白名单),否则 verify:kb fail(require_user_widget_translation)
- ❌ block list 缺漏新机制名 —— M9+ 新机制必须同步更新兜底 block list;走 ADR L3 流程
§8 关联资产
- ADR-013 · codify 哲学换轨(本 MP 是 §3.2 surface 维度落地物)
- ADR-012 · SVA-9 战略愿景对齐九层防御方案(L1 契约源层)
- ADR-010 · 输出端凭证过滤位置(凭证过滤是 surface=internal_audit 极端特例)
- MP-4 · 任务→必含字段动态组合契约(与本 MP 正交)
- ADR-008 supplement · 机制层输出契约扩展(6 机制层字段定义源)
- 13 条契约型不变量 deep design spec(drafts/):13 条契约型不变量 deep design spec(I-05' UserFacingFieldRedaction 落地依赖)
- FinBayes 产品定义(§6.4 + §7.1 + §7.3 不暴露策略源)
- FinBayes 战略白皮书 v3(§5 line 570 "用户产品不暴露体系本身"原话)
- 变更协议 · 体系级变更流程