本篇正文写于命名裁决之前,仍在使用旧名:
本境 在此指长期存储(现为 学籍 Xueji,本境已还给环境层)、
ActionParity 与 OriginBus 在此当部件名用(二者是商标,
对应的技术名是 影核 Action Kernel 与 北桥 Northbridge),
观察器本象现已拆分为 取象 Quxiang。
裁决与理由见 命名裁决 · EN。
This document predates the naming decision and still uses the retired names. The decision is published rather than quietly applied, because renaming the prose is a separate editorial change that has not been made yet.
RFC-0002 — 带外观察面 Out-of-Band Observation Plane
Status: Draft · Request for Comments Version: 0.1 Date: 2026-08-08
一个人站在机箱前,能看见机器自己报不出来的东西:内存条没插紧、卡插错了槽、风扇积灰。 机器只会说"未检测到内存"——它没有"你的内存条歪了 3 毫米"这个传感器。
这台 AI 计算机现在没有那个站在机箱前的人。
1. 出血点:三次靠"机器外面"才破的案
三个案子,三个不同子系统,同一个形状——机器的自述是错的或不足的,靠一个它管不着的观察者才纠正过来。
| # | 机器自述(in-band) | 带外观察(out-of-band) | 结论 |
|---|---|---|---|
| 1 | codex:user cancelled MCP tool call |
南桥 audit.log:零记录 |
不是"用户取消了",是请求从未到达。责任在 harness 闸门,不在南桥 |
| 2 | uking crashlog:unclean_exit |
OS 进程表:该 pid 仍存活 | 不是崩溃,是退出检测误报(多实例/残留标记) |
| 3 | 影核 v0.1:status: done |
外部 rm 后回读磁盘:文件不存在 |
done 是自证的,世界已经变了而它一无所知 |
注意第 1 例的性质:两个观察者互相矛盾,真相在矛盾里。 如果只信 codex,结论是"用户取消"(假);只信南桥,只知道"没收到"(不完整)。 是分歧本身指出了故障位置。
推论式的教训(案子 4,代价更大):demo/task2 曾把这次故障归因为"Codex 沙箱只读拦截了写",
这条结论作为 verified fact 存活了整整一个任务周期。真因是两件事——harness 审批闸门 +
本机 Windows 沙箱 runner 本身损坏(CreateProcessAsUserW failed: 5,连只读命令都起不来)。
在带外观察缺席时,机器不但会报错,还会自信地报出一个错误的病因。
2. 为什么这不是"再加一个更聪明的 AI"
这是本 RFC 最容易被做错的地方。
更高的维度 ≠ 更强的模型。
可靠性工程里有个成熟概念叫 common-mode failure(共因失效): "failures in multiple parts of a system may be caused by a single fault" —— 冗余部件如果共享同一个设计缺陷或同一个环境,它们会同时失效,冗余等于零。
两个 LLM 共享失效模式:都会流畅、自信地输出错误;都只能看见被喂进上下文的东西; 都对"有什么没被喂进来"没有感知。拿一个 LLM 去审另一个 LLM,不是增加了一个维度, 是在同一个维度里多花了一倍 token。
所以带外观察者的判据不是聪明,是独立,而独立的定义只有一条:
R1 · 独立性 = 不共享失效模式。
| 观察者 | 对"模型自信地说谎"独立? | 对"这份代码逻辑错了"独立? | 对"本机环境坏了"独立? |
|---|---|---|---|
| 另一个 LLM | ✗ | 部分 | ✗ |
| 另一个 harness(换厂商) | 部分 | 部分 | ✗ |
stat() + sha256 |
✓ | ✓(它不参与推理) | ✗ |
| OS 进程表 / 退出码 / 事件日志 | ✓ | ✓ | ✓ |
| 时间(隔一段再看) | ✓ | ✗ | 部分 |
| 人 | ✓ | ✓ | ✓ |
一个 stat() 调用在"抗说谎"这一维上,比一个更强的模型可靠得多。 这不是贬低模型,
是分工:判断交给聪明的,见证交给笨的。
3. 终止条件:观察者必须笨到能被直接验证
「谁来观察观察者」的无限回归,不靠再加一层解决,靠简单性终止。
先例是 1972 年的:James Anderson 的 reference monitor 要求四条属性(NEAT), 其中 Evaluable 的原文是——
amenable to analysis and tests, the completeness of which can be assured
即:它必须小到能被完整地验证。
R2 · 观察者必须比被观察者笨。 如果验证器和被验证系统一样复杂,它就需要自己的验证器,回归不终止。
这条律回过头解释了参考实现里一个看起来朴素的选择:observe() 是 20 行 fs.stat + sha256,
不是"让 agent 评估一下写成功没有"。笨是特性,不是妥协。
同时它立刻照出一个现存风险:本仓库的验证器已经是 15KB / 43 条判据的 JS 程序,
且实测坏过两次(verify-state.mjs 的 artifact 路径解析错,对三个任务全部误报;
CHECK2 存在性检查冒充验证)。按 R2,验证器正在长成"需要自己的验证器"的尺寸。
这是已经发生的债,不是预警。
4. 真相来自分歧
R3 · 单一观察者只能提供证词,不能提供真相。真相出现在两个独立观察者的分歧处。
§1 的三个案子全是这个形状。所以带外观察面的最小可用形态不是"再加一个日志",而是 让两条互不依赖的记录能被对上。
参考实现里已经存在的雏形:审计日志的 actor 字段(southbridge_cli / southbridge_mcp)。
案子 1 的定责正是靠按 actor 分组计数完成的——2 条 CLI、0 条 MCP,通道责任当场落地。
5. 与本象的边界(不要混淆)
本象已经在做"观察",但观察的对象不同、服务的消费者也不同:
| 本象 Benxiang | 带外观察面 | |
|---|---|---|
| 观察什么 | 动作的目标(那个文件、那份表格) | 机器自己(进程、通道、判决、环境) |
| 服务谁 | 机器自己(用于 Verify 闭环) | 机器外面的人 / 另一台机器(用于诊断与定责) |
| 信任模型 | 在带内,与动作共享运行时 | 必须带外,不共享失效模式 |
| 失效时 | 动作误判成功或失败 | 没人知道机器坏了 |
一句话:本象让机器看见世界;带外观察面让世界看见机器。
RFC-0004 §6.5 那条未决问题(southbridge_verify 与写动作同进程,严格说不算独立观察者)
现在有归属了:它不是本象的欠债,是带外观察面缺席的一个症状。
6. AI 的盲区和人的盲区不是一回事
人的盲区是有边界的看见:太小的看不清,太远的看不见,但知道自己视野之外还有东西。
AI 的盲区是默认全黑,只有被喂进上下文的几块是亮的——而且它对"有哪些没被喂进来" 本身没有任何感知(见 bugscope A4 · 缺席不会自己发声)。
后果是不对称的:
一个只能看见别人递给它的东西的系统,永远不可能自己发现"没被递给它的那部分"。
所以带外观察面对这台机器不是增强件,是基础设施。人的机箱前那一眼是可选的; 这里不是。
7. 现状审计:我们已有什么、缺什么
已有(但全部是 ad-hoc,靠人临时想起来):
| 能力 | 现状 |
|---|---|
磁盘真相(stat/sha256) |
已制度化(evidence / footprint),是目前唯一牢靠的一条 |
审计的通道归属(actor) |
已有,但只在人手工去查时才起作用 |
| 另一个 harness 交叉验证 | 做过(Hermes / codex),但是一次性演示,不可复跑(见 RFC-0000 §11 D4) |
| OS 层观察(进程表 / 退出码) | 只在 uking 排障里手工用过一次 |
| 沙箱化重放(把核心复制到临时目录、注入故障条件再跑) | 手工做过(审计不可写、并发丢账本),未沉淀为设施 |
缺(按价值排序):
- 独立的再观察进程。 现在
verify与write同代码同进程,同一个observe()错了两边一起错。 - 分歧检测。 有两份可对的记录(自述 vs 磁盘 vs 审计),但没有任何东西自动去对。
- 环境层观察。 本机 codex 沙箱 runner 坏了整整一个任务周期没被发现,因为没有任何人观察 harness 本身是否健康。
- 验证器的瘦身或分层(R2 债务,见 §3)。
8. 最小实现建议(不做大设计,只做能立刻还债的)
按本架构规矩,只提能绑上已复现缺陷的:
M1 · 把再观察拉出进程。
verify由独立进程冷启执行,不复用写路径的任何内存状态。 (CLI 驱动已天然满足;MCP 驱动不满足。这是已存在的不对称,不是新工作。)M2 · 分歧断言。【已实现并验证,2026-08-08】 参考实现oob/crosscheck.mjs。 两组对账,各自取自互不依赖的记录:- X1 · 学历声称的产物 ↔ 影核审计台账。 首轮实跑即抓到一条真的:
demo/task2/actionable-notes.md在南桥辖区内、创建于 16:21(审计 07:59 就开始记了), 审计里 0 条记录——它绕过了协议,因而没有风险判级、没有备份、查不到是谁写的。 - X2 · boot 自报的装载量 ↔ 磁盘实数(黑盒跑 hook 解析文本,不碰内部)。 这是把已复现过的"谎报装载量"缺陷从验证器搬到运行时。
对账器自己首轮就误报了:把
demo/task1/task.origin.json判成"绕过南桥", 可学历本来就走本境benjing-put,不归影核管。拿 A 协议的账去查 B 协议的活, 必然全判违规——那是对账器自己的 bug,不是发现。 已加benjing_scope辖区并锁进反向用例 O7.4。 这件事本身是 bugscope §5「结论是怀疑,不是判决」的实证:一个爱喊狼来了的观察者, 比没有观察者更坏,因为它会训练人忽略它。与「回头看」的分工:
reobserve对的是声明 vs 世界(时间维度,过去说的话今天还成不成立);crosscheck对的是记录 A vs 记录 B(横向维度,两套独立台账此刻是否互相印证)。验证:
node oob/verify-oob.mjs— 29 条判据,其中 24 条是反向用例,连跑两轮一致。- X1 · 学历声称的产物 ↔ 影核审计台账。 首轮实跑即抓到一条真的:
M3 · 环境健康的带外快照。【已实现并验证,2026-08-08】 参考实现oob/env-probe.mjs(ShadowOS 仓库),三个探针: ① 这台机器还能不能起最小子进程(就是案子 4 那一行) ② 写路径端到端还通不通(走南桥 CLI,再独立回读磁盘,不采信南桥自报的 sha) ③ 现在是谁在跑(harness / node / platform;观察不到写unobserved,不编造) 跑完与上一条快照比对,只报分歧、不解释分歧(§4)。作为独立的 SessionStart hook 运行而非并进北桥的 boot 摘要——观察者不能长在被观察者体内(R1);北桥挂了这一行仍要能打出来。 成本 154ms。验证:node oob/verify-oob.mjs— 19 条判据,其中 15 条是反向用例 (起不了进程必须报 fail、南桥 fail-closed 必须被看见、探针消失必须发声、 快照自己落盘失败必须自曝、摘要不许谎报),连跑两轮一致。实现过程中撞到的一件事值得记:验证器第一版的判决行把条数硬编码成"14 条中 11 条", 加判据后立刻与现实脱节——写验证器的人自己犯了它要防的那个病。 已改为计数由代码算出。
9. 诚实边界与先例
- 本 RFC 的两条核心律都不是首创。 R1 是可靠性工程的 common-mode failure; R2 是 Anderson 1972 reference monitor 的 Evaluable 属性。带外管理本身在服务器领域 是成熟设施(BMC / IPMI 一类:独立供电、独立通道、主机死了它还活着)。 我们没有发明带外观察,我们是发现这台 AI 计算机压根没装。
- 新的仍然是前提:传统系统的部件不会自信地编造,带外管理主要用于"主机死了够不着"; 这里的部件活着的时候就会编,所以带外观察从"运维便利"变成正确性的前置条件。
- 不主张:本 RFC 不定义带外观察者应该多智能、用什么协议、是否要常驻。 这些都没有实测支撑,等撞到再说。
License: Apache-2.0