背景
认知三件套(感知/思维/表达)的讨论暴露出一个隐含前提:三个 L0 内核(渲染、语音、视觉)+ 快慢双脑,如果各自维护“现在发生了什么“的时间顺序,打断、部分结果、结论修订、降级标注这四件事在跨内核时无法对齐。苏舰切片 1 已用文本态跑通最小语言交流(会话真源、pending 互斥、幂等重放、degraded 标注、failed_roles、模板兜底、按日指标),这些语义本质都是“同一轮内的有序事实“,但目前只是 C++ 后端的散落字段,没有任何中立契约描述顺序与修订关系。语音一旦接入,“念到一半被打断“要求表达层与思维层共享同一条时间线;视觉一旦接入,屏幕事件也必须落在同一条线上才能参与同一轮裁决。
选项
- A. 各子系统自造时间线。 风险:打断语义三处实现、跨内核顺序无法证明、复盘时无法重建一轮的因果链。
- B. 认知层独立契约 crate(选定)。 新增
zjchina-cognition:只定义事件索引、时间线与仲裁空位;不存载荷、不做模型路由、不做会话存储。 - C. 等语音与视觉“基本完善“再定。 风险:接口凭想象定型(
Synthesizer::speak返回()已证明打断要改 trait),返工成本转嫁给内核;且语言交流在文本态已在跑,等待没有业务收益。
证据
- 苏舰轮次语义天然是时间线事件:
turn_index(轮次序号)、pending(开始即落盘)、degraded+failed_roles(部分失败)、reply_fallback(模板兜底)、turns_total/采纳(终态与后续)。一套 Event 词汇即可描述,无需新状态机。 - ADR-0004 要求“时间上可验证不腐“:多写者(快脑/慢脑/操作员)必须能事后证明“哪条结论先出、被谁修订“,时间线是它的内存侧索引,与台账/CID 链同一诉求。
- ADR-0005 渲染路由:web 用 DOM+SSR、真机自绘。两套表达层共享同一条时间线,才可能同源不同渲染,否则降级文案与推荐卡片会对不上。
- 打断与首字预算是硬约束:快脑若能在慢脑到达前答复,必须限动作,否则用户会看到两套结论闪烁。
拍板
1. 时间线契约(五要素)
- 事件 ID:单调递增
seq(从 1 起),是游标拉取的唯一依据;不使用 UUID(排序不需要全局唯一)。 - 单调时钟:
at_ms取自进程单调钟(非墙钟),时钟回拨时钳制为上次时间;跨机对比不依赖at_ms,只依赖seq。 - 来源标记:
Source::{Sense, Fast, Slow, Act, Operator}——复盘时必须能回答“这条是看到的、想到的,还是说出来的“。 - 背压:有界保留(容量上限淘汰最旧)+ 消费者用
since(cursor)拉取,不做推送回调(避免订阅者持锁,也避免慢订阅者拖垮快脑)。 - revision 语义:修订只能新增
Kind::Revision并revises指回被修订 seq,历史不可改写;is_superseded(seq)判定。载荷纪律:note仅理由码/短句,聊天原文、画像、SKU 明细留在各自真源(对齐苏舰台账“不含会话 ID 与原文“)。
2. 仲裁规则(政策,不进实现)
- 快脑硬截止 300ms(
FAST_DEADLINE_MS);超时即让位慢脑。 - 快脑在慢脑裁决前只允许三类动作:澄清、确认、打断接管(
FastAction::{Clarify, Confirm, Interrupt});不得给出推荐/交易类结论。 - 同一轮由
turn标识定义(苏舰turn_id);跨轮事件不得互相修订。 - 慢脑失败分三档,不得合并:
- 部分角色失败 → 置
degraded=true,仍用有效观点出建议,并记failed_roles(Kind::Degraded,部分降级); - 全部角色失败/超时 → 不产生推荐,给可重试追问(
Arbitrator::fallback_after_slow_failure,总兜底); - 回复器失败 → 保留已产生的结构化推荐,改用确定性模板(
reply_fallback,不影响结构与排序)。
- 部分角色失败 → 置
- 首字出声目标 300ms(
SPEECH_FIRST_WORD_MS);慢脑单轮软目标 15000ms(SLOW_DEADLINE_MS)。与 C++ 侧 65s 整轮总兜底分层:65s 覆盖网络+三角色,15s 是慢脑单次决策期望。
3. API 形状(三件套,L3 空位)
Event:seq/at_ms/source/kind/turn/revises/note,构造用 builder,序号与时间由时间线赋值。Timeline:append/since(cursor)/latest/is_superseded/cursor/ 有界len。Arbitrator:只定契约不落实现(may_preempt/fallback_after_slow_failure)。默认政策写在本 ADR;实现等语音接入(第二战)后按真实需求抽取,避免现在凭想象定型。
4. 层级关系
| 层 | crate | 职责 | 与认知层的关系 |
|---|---|---|---|
| 线协议 | zjchina-core | 跨语言 DTO + schema 导出,中立、禁 web-sys/axum | 时间线事件的线协议以 core 的 DTO 形态出线,本 crate 不另造序列化 |
| 运行时 | zjchina-agent | Provider/三角色/Opinion -> Decision 的实际决策执行 | 产出 Decision/Revision 事件,是慢脑的实现方 |
| 认知契约 | zjchina-cognition(本 crate) | 事件索引 + 时间线 + 仲裁空位,零第三方依赖 | 不含决策逻辑:谁知道答案归 agent,谁先开口归仲裁 |
| 内核 | zjchina-render / zjchina-speech / 视觉 | 感知与表达 | 只做订阅者,不互相调用、不持业务状态 |
| 业务 | sujian / tidewatch / factorywatch | 领域语义(导购、盯盘、孪生) | 只通过契约与内核交互,内核不感知业务名词 |
5. 边界纪律
- speech / render 只做订阅者:语音不得直接问 agent,渲染不得直接读会话;跨层只经时间线事件或线协议。
- 内核不感知“军师/导购/孪生“等业务名词,否则三内核会分叉成三套。
- 分期纪律:A 阶段收口只做
rodiofeature gate + license 查证 + 行为测试;SpeakHandle/取消/逐句流式/打断语义属于 C 阶段,等真需要时再定,现在定容易定错。 - 跨语言边界:苏舰主体是 C++26 模块,不能直接依赖本 crate。时间线对 C++ 侧只以线协议暴露(字段与词表),语义一致性由本 crate 的苏舰轮次回放测试与 C++ 侧断言共同锁定;本 ADR 只落契约与回放,不做 C++ 接入。
不做:不实现仲裁、不做模型路由、不做会话存储、不做 ASR/视觉、不做领域词表、不解析业务载荷。
日期:2026-11-04。拍板者 zj。