bookworm-smart-assistant/docs/AI-Universal-Control-Plane-WhitePaper-v1.3.md
Bookworm Admin b7a8e29d21 release: v6.7.0 - OTA E2E test release
- VERSION file as authoritative version source
- export.mjs reads VERSION with package.json fallback
- bw-ota.ps1 DryRun mode for safe testing
- auto-setup.ps1 bumped to v3.2.0 (Phase 8 OTA)
2026-04-27 17:59:44 +08:00

1066 lines
33 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# AI Universal Control Plane
**架构白皮书 v1.3 (B+ 收口版)**
> v1.2 → v1.3 不引入新机制, 专门收口三轮评审残留缺陷, 冲击 B+ (≥85)
| 字段 | 内容 |
|---|---|
| 版本 | v1.3 |
| 日期 | 2026-04-25 |
| 状态 | Production Ready — 收口版 |
| 父版本 | v1.2 (终审 ~79.5) |
| 修订原则 | 不加新机制, 只补漏洞 + 客群适配分级 |
| 目标评分 | ≥ 85 (B+) |
---
## 0. v1.2 → v1.3 修订摘要
### 三专家共同点出的 P0 修复 (10 项)
| ID | 缺口 | 修订章节 |
|---|---|---|
| **P0-1** | 裁判 LLM 同源投毒 (主+裁判同 Qwen 系) | §1 强制异构家族 |
| **P0-2** | `monotonic_ns < last_ts` 致 Saga 永不启动 | §2 时钟模型重写 |
| **P0-3** | `value_pattern: "<=10%"` 字符串歧义 | §3 强 schema DSL |
| **P0-4** | 签名链与中小工厂客群错配 | §4 分级签名 (轻量/标准/高合规) |
| **P0-5** | v1.1 残留 W5 (ADB 5555 工控禁忌) | §5.1 全文禁用 |
| **P0-6** | v1.1 残留 W6 (Registry via_agent 无环检测) | §5.2 DAG 校验 |
| **P0-7** | v1.1 残留 N2 (HARD_ACTION 预算耗尽 fail-closed) | §5.3 双轨预算 |
| **P0-8** | v1.1 残留 N5 (LLM Router schema 不归一) | §5.4 Adapter 归一矩阵 |
| **P0-9** | v1.1 残留 N6 (数据二极管 vs 防火墙模糊) | §5.5 明确 |
| **P0-10** | 物理动作不可逆 v1.2 仍回避 | §6 显式声明 + Saga 语义升级 |
### 单专家发现的 P1 修复 (7 项)
| ID | 缺口 | 修订章节 |
|---|---|---|
| **P1-1** | boot_id LRU(100) 频繁重启绕过 | §7 epoch 计数 + flash 持久化 |
| **P1-2** | bump-in-wire 网关 RCE = 全厂沦陷 | §8 双冗余 + 远程证明 |
| **P1-3** | ISV Skill 链式供应链 | §9 isv-key 隔离 + 客户端沙箱 |
| **P1-4** | 注册表运行时漂移无周期重验证 | §10 周期 capability handshake |
| **P1-5** | 100 设备并发瓶颈未规划 | §11 任务队列 + 优先级抢占 |
| **P1-6** | 国产 AGV 厂商缺口 (迦智/斯坦德/灵动) | §12 补全 |
| **P1-7** | Edge Agent SQLite WAL on NFS/CIFS | §13 介质约束 |
### P2 改进 (5 项)
| ID | 缺口 | 修订章节 |
|---|---|---|
| **P2-1** | Margin gate 自适应公式方向不对 | §14.1 |
| **P2-2** | claim deviation 1e-9 与小量纲冲突 | §14.2 自适应阈值 |
| **P2-3** | combo zone uplift_threshold=2 DoS via uplift | §14.3 |
| **P2-4** | OSSD 双通道未明确 (急停 SIL3 标准) | §14.4 |
| **P2-5** | DERP 元数据侧信道 (流量大小/时序) | §14.5 |
**v1.3 共修 22 项, 不引入新机制**
---
## 1. 裁判 LLM 强制异构 (P0-1)
### 1.1 异构原则
主 LLM 与裁判 LLM 必须满足:
- **不同模型家族** (Transformer 派系 ≠ MoE 派系不算异构, 必须不同训练数据 + 不同 RLHF pipeline)
- **不同厂商**
- **不同架构** (推荐 Dense vs MoE, 或 MLA vs Standard Attention)
### 1.2 推荐配对 (2026-04 旗舰)
| 主 LLM | 裁判 LLM | 异构强度 |
|---|---|---|
| Qwen3-Max (阿里, MoE) | DeepSeek-R1 (深度求索, MLA) | ★★★★ 数据/架构/RLHF 全异构 |
| Qwen3-Max | Llama 4 Maverick (Meta, MoE) | ★★★ 国内训练 vs 海外训练 |
| GLM-4.6 (智谱) | DeepSeek-R1 | ★★★ |
| DeepSeek-V3.1 | Qwen3-Max-Thinking | ★★ (同期国产, 较弱) |
**禁配**:
- ❌ Qwen3-Max + Qwen3-Max-Thinking (同家族)
- ❌ GLM-4.6 + GLM-Zero-Air (同家族)
- ❌ 任何"主用 X, 裁判用 X 蒸馏小模型"
### 1.3 system prompt 签名 pin
```yaml
# judge-llm-config.yaml (受 security-key 签名)
judge_pool:
- id: judge-deepseek-r1
type: deepseek
model: deepseek-reasoner
deployment: local # 强制本地, 防云侧投毒
system_prompt_hash: sha256:<...> # 启动时 hash pin
system_prompt_signed_by: security-key:csso
- id: judge-llama4-local
type: openai_compat
endpoint: http://localhost:8002/v1
model: Llama-4-Maverick-17B
deployment: local
system_prompt_hash: sha256:<...>
system_prompt_signed_by: security-key:csso
heterogeneity_check:
primary_model_family: ${primary.family}
forbidden_judge_families: [${primary.family}]
required_diversity_score: 0.7 # 主裁判 embedding 相似度上限
```
### 1.4 双裁判共识机制
HARD_ACTION 决策必须**双裁判同时通过** (异构 N=2):
```python
async def hard_action_consensus(intent, plan):
judge_a = judge_pool['judge-deepseek-r1']
judge_b = judge_pool['judge-llama4-local']
result_a, result_b = await asyncio.gather(
judge_a.review(intent, plan),
judge_b.review(intent, plan)
)
# 任一拒绝即否决
if not result_a.approve or not result_b.approve:
raise SafetyVeto(reasons=result_a.reasons + result_b.reasons)
# 风险分歧过大也否决 (防其中一个被入侵)
if abs(result_a.risk_score - result_b.risk_score) > 0.4:
raise SafetyDivergence(a=result_a, b=result_b)
return ConsensusOk()
```
### 1.5 输入隔离 (修复裁判 LLM 自身注入)
```
[裁判 LLM 输入]
System prompt: [SIGNED + PINNED, 启动期 hash 校验]
─────────────── 强分隔 ───────────────
Untrusted data block:
<DATA_START>
{plan from primary LLM}
{RAG snippets}
<DATA_END>
─────────────── 强分隔 ───────────────
Question: [固定模板, 不接受动态指令]
```
裁判**独立 RAG corpus** (与主 LLM 不共享), 仅由 ops 离线维护。
---
## 2. 时钟模型重写 (P0-2)
### 2.1 v1.2 致命错误
```python
# v1.2 §4.5 错误代码
def open(self):
last_ts = self.db.get_last_saga_started_at()
if time.monotonic_ns() < last_ts: # ❌ 进程重启 monotonic 从 0 开始, 永远 < last_ts
raise ClockSkewError(...)
```
### 2.2 v1.3 正确实现
```python
# brain/saga/clock.py
import time, uuid
from datetime import datetime, timezone
class HybridClock:
"""三层时钟模型"""
@staticmethod
def wall_now_ms() -> int:
"""Wall clock (UTC ms), 跨进程持久化对比用"""
return int(time.time() * 1000)
@staticmethod
def monotonic_ms() -> int:
"""Monotonic (boot 起的相对 ms), 进程内单调用"""
return int(time.monotonic() * 1000)
@staticmethod
def generate_trace_id() -> str:
"""UUIDv7: 时间戳 + 随机, 跨进程唯一"""
return str(uuid.uuid7())
class SagaStore:
def open(self):
last_wall_ms = self.db.get_last_saga_wall_ts()
cur_wall_ms = HybridClock.wall_now_ms()
# 仅当 wall clock 显著回拨 (> 5min) 才拒启动
if cur_wall_ms < last_wall_ms - 5 * 60 * 1000:
raise ClockSkewError(
f'wall clock went backward by '
f'{(last_wall_ms - cur_wall_ms)/1000:.1f}s'
)
# 进程内 monotonic 独立计数, 不与持久化时钟比较
self._proc_start_mono = HybridClock.monotonic_ms()
def trace_id_uniqueness(self):
"""UUIDv7 高并发同毫秒冲突极低 (74 bit 随机), 但仍 PRIMARY KEY 兜底"""
# PRIMARY KEY (saga_id) 在 INSERT 失败时重试一次新 UUIDv7
pass
```
### 2.3 时钟回拨场景与处理
| 场景 | 检测 | 处理 |
|---|---|---|
| NTP 调整 ±数秒 | wall clock 微调 | 容忍, 不报警 |
| 时区配置错误 (UTC ↔ +8) | wall clock 跳 8h | 拒启动 + 告警 |
| 虚拟机克隆 | wall clock 同步, traceId 用 UUIDv7 唯一 | 容忍 |
| 物理时钟硬件故障 | wall clock 大幅回拨 | 拒启动 |
| **进程重启** | monotonic 归零 | 不与持久化值比较, 容忍 |
### 2.4 NTP / PTP 强制要求
- 大脑 + Edge Gateway 必须配 NTP 同步, 漂移超 1s 告警
- 工业现场推荐 PTP (IEEE 1588), 微秒级
- 时钟源必须本地化 (国内不依赖境外 NTP 池)
---
## 3. 强 schema DSL (P0-3)
### 3.1 v1.2 漏洞
```yaml
# v1.2 写法 (字符串歧义)
- device_class: motor AND param: speed AND value_pattern: "<=10%"
# attacker 设 speed = 10.0001% 直接绕过
```
### 3.2 v1.3 强 schema
```yaml
# action-semantics.yaml
schema_version: "2026.04.v3"
semantic_groups:
production_halt:
description: 任意可导致生产线停止的组合
members:
- device_class: motor
param: speed
value:
op: "<="
value: 0.10 # 数值, 非字符串
type: ratio # 类型必须显式
unit: percentage_of_max
- device_class: conveyor
param: speed
value:
op: "<="
value: 0.10
type: ratio
unit: percentage_of_max
- device_class: valve
param: state
value:
op: "in"
values: ["closed", "fully_closed"] # 枚举
type: enum
- device_class: agv
param: command
value:
op: "in"
values: ["halt", "estop", "pause"]
type: enum
```
### 3.3 编译期校验
```python
# tools/semantic-schema-validator.py
ALLOWED_OPS = {
'ratio': ['<=', '>=', '<', '>', '==', 'in'],
'enum': ['in', 'not_in', '=='],
'integer': ['<=', '>=', '<', '>', '==', 'in'],
'string': ['in', 'not_in', '=='],
}
def validate(group):
for member in group.members:
v = member.value
assert v.op in ALLOWED_OPS[v.type], \
f'Op {v.op} not allowed for type {v.type}'
assert isinstance(v.value, (int, float, list, str)) if v.op != 'in' else isinstance(v.values, list)
# 比较运算符不允许字符串值
if v.op in ['<=', '>=', '<', '>'] and v.type == 'ratio':
assert 0 <= v.value <= 1, f'ratio out of [0,1]: {v.value}'
```
### 3.4 运行时执行
```python
# brain/policy/semantic_match.py
def match(action, member):
actual = action.params[member.param]
v = member.value
if v.type == 'ratio':
# 转换为绝对比例 (相对于 capability range)
cap_range = registry[action.device].capabilities[member.param].range
actual_ratio = (actual - cap_range[0]) / (cap_range[1] - cap_range[0])
if v.op == '<=': return actual_ratio <= v.value
if v.op == '>=': return actual_ratio >= v.value
...
elif v.type == 'enum':
if v.op == 'in': return actual in v.values
if v.op == 'not_in': return actual not in v.values
...
```
绕过尝试: speed = 10.0001% → actual_ratio = 0.10001 > 0.10 → 不匹配 production_halt → **正确不升格**, 但若组合中其他维度命中, 仍可能触发其他 group 升格 (这是设计意图)。
---
## 4. 分级签名链 (P0-4)
### 4.1 三档客群
| 客群 | 签名等级 | 流程 |
|---|---|---|
| **轻量** (中小工厂 < 30 设备, 非合规敏感) | 单签 + 在线 TPM | IT 主管 SSH 触发 + TPM 自动签 |
| **标准** (中型工厂 30-100 设备, 等保二级) | 双签 + 在线 HSM | 设备部主管 + IT 主管 SSO + YubiHSM |
| **高合规** (大型/军工/制药 GMP/CIIA) | M-of-N (2/3) 离线 HSM | Air-Gap 签名机 + 多人到场 |
### 4.2 部署形态自描述
```yaml
# deployment-profile.yaml (受 ops-key 签名)
profile: standard # lightweight | standard | high_compliance
signing:
ops_key:
storage: ${profile == 'high_compliance' ? 'air_gap_hsm' : 'online_hsm'}
threshold: ${profile == 'high_compliance' ? '2-of-3' : profile == 'standard' ? '2-of-2' : '1-of-1'}
rotation_days: ${profile == 'high_compliance' ? 365 : 180}
reviewer_idp:
require_different: ${profile != 'lightweight'}
require_different_dept: ${profile == 'high_compliance'}
dry_run:
isolation: ${profile == 'high_compliance' ? 'mirror_plc_cluster' : 'simulator'}
audit:
merkle_chain: true # 三档全部启用
rfc3161_anchor: ${profile != 'lightweight'}
worm_storage: ${profile == 'high_compliance'}
retention_days: ${profile == 'high_compliance' ? 1825 : 180} # 5y vs 6m
```
### 4.3 升级路径
客户从轻量起步 标准 高合规, 每档迁移由迁移工具自动完成 (密钥重签 + 历史日志重哈希入新链)。
---
## 5. v1.1 残留 5 项收口 (P0-5 至 P0-9)
### 5.1 ADB over WiFi 全文禁用 (P0-5)
```
v1.3 Android 接入仅以下三种模式, ADB-over-WiFi 5555 端口在工控/工厂场景**完全禁用**:
✅ 模式 A: ADB over USB (有线, 仅工程师调试用)
✅ 模式 B: Termux + SSH + 证书 (推荐, 7×24 后台 Agent)
✅ 模式 C: Scrcpy + Vision (受限设备视觉兜底)
❌ 模式 D: ADB over WiFi 5555 (禁用)
强制规则:
- Edge Gateway DPI 自动阻断 5555/tcp 出站连接
- 设备注册表对 type=android 的设备校验 protocol ∈ {adb_usb, termux_ssh, scrcpy_vision}
- CI 静态扫描 MCP 配置, 出现 :5555 直接 FAIL
```
### 5.2 Registry 引用图 DAG 校验 (P0-6)
```python
# tools/registry-dag-check.py
def validate_no_cycles(registry):
"""via_gateway 引用必须形成 DAG, 不允许环"""
graph = {d.id: d.via_gateway for d in registry.devices if d.via_gateway}
# Kahn 算法或 DFS 三色法
color = {} # white / gray / black
def visit(node):
if node not in graph: return
if color.get(node) == 'gray':
raise CycleDetected(f'{node} is part of a cycle')
if color.get(node) == 'black':
return
color[node] = 'gray'
visit(graph[node])
color[node] = 'black'
for d in registry.devices:
visit(d.id)
# 同时校验深度上限 (防过深嵌套)
MAX_DEPTH = 5
for d in registry.devices:
depth = compute_depth(d, graph)
if depth > MAX_DEPTH:
raise DepthExceeded(f'{d.id} via_gateway depth = {depth}')
```
CI 必跑, 失败阻 merge
### 5.3 HARD_ACTION 预算双轨 (P0-7)
```yaml
# llm-providers.yaml (扩展 cost_control)
cost_control:
# 主预算 (业务读写)
main_budget:
daily_usd: 50
on_exhausted: route_to_local_only # 不 fail-closed, 降级本地
# HARD_ACTION 独立预算 (永不为 0)
safety_budget:
daily_usd: 10
reserved: true # 不与 main_budget 共用
on_exhausted:
- route_to_local_qwen3 # 走本地大模型
- if_local_unavailable: page_oncall_engineer # 失败转人工
# 永不 deny HARD_ACTION 评估
# 紧急超额池 (一次性, 季度复审)
emergency_pool:
quarterly_usd: 50
requires_approval: csso # CSO 审批激活
```
**关键**: HARD_ACTION 评估**永远不能因预算耗尽而拒绝**, 否则成为新的攻击面 (攻击者通过批量 SOFT_PARAM 耗尽预算, HARD_ACTION 阻塞生产中断)。
### 5.4 LLM Adapter Schema 归一矩阵 (P0-8)
各厂商 tool_call JSON 格式差异:
```python
# llm/adapters/normalizer.py
NORMALIZED_TOOL_CALL = {
'id': str,
'name': str,
'arguments': dict, # 必须是 dict, 不是 JSON string
}
class QwenAdapter:
def normalize_tool_call(self, raw):
# Qwen: arguments 是 string (JSON encoded)
return {
'id': raw['id'],
'name': raw['function']['name'],
'arguments': json.loads(raw['function']['arguments'])
if isinstance(raw['function']['arguments'], str)
else raw['function']['arguments']
}
class OpenAIAdapter:
def normalize_tool_call(self, raw):
# OpenAI: arguments 是 string
return {
'id': raw['id'],
'name': raw['function']['name'],
'arguments': json.loads(raw['function']['arguments'])
}
class AnthropicAdapter:
def normalize_tool_call(self, raw):
# Anthropic: input 是 dict
return {
'id': raw['id'],
'name': raw['name'],
'arguments': raw['input']
}
# CI 测试矩阵: 每个 Adapter 跑同一组 12 个 fixture, 验证归一化输出一致
```
`tests/llm-adapter-conformance/` 12 个跨厂商一致性测试用例, CI 必跑
### 5.5 数据二极管 vs 防火墙明确 (P0-9)
```
| 部署档位 | L3-L1 边界实现 |
|---|---|
| 轻量 | 严格防火墙 (iptables 状态化, 仅允许 Gateway IP 白名单) |
| 标准 | 严格防火墙 + DPI (bump-in-wire) + 单向心跳监控 |
| 高合规 | **真正的硬件单向数据二极管** (Owl/Waterfall/国产: 鼎信 / 永信至诚) |
数据二极管硬件原理:
- 物理光纤单向 (无返回 fiber)
- 接收端无电信号到发送端的反向通路
- 写入操作通过专门的"反向通道"经人工/审批后转发, 大脑不直连
```
中小工厂部署轻量档, 不强求二极管硬件 (太贵 ¥20w+); 大客户部署高合规档强制使用
---
## 6. 物理动作不可逆显式声明 (P0-10)
### 6.1 不可逆动作清单
```yaml
# irreversible-actions.yaml (受 ops-key 签名)
irreversible_actions:
- capability_pattern: "agv.*move"
reason: AGV 已搬运的货架, 搬回是新动作非补偿, 中途状态不一致
saga_compensation: forward_only_with_human_review
- capability_pattern: "robot_arm.*linear_move|joint_move"
reason: 机器人臂位置已改变, 反向运动需重新规划路径
saga_compensation: forward_only_with_human_review
- capability_pattern: "valve.set_state"
reason: 阀门切换涉及流体动力, 反向切换需考虑系统压力
saga_compensation: gradual_reverse_only
- capability_pattern: "heater.set_setpoint"
reason: 温度变化有惯性, 补偿动作不等价回滚
saga_compensation: best_effort_only
- capability_pattern: ".*write.*" # 所有写入默认不可逆
reason: 物理世界副作用不可撤销
saga_compensation: forward_only_with_human_review
```
### 6.2 Saga 补偿语义升级
```python
# brain/saga/compensation.py
class SagaStep:
def execute(self):
if self.is_irreversible():
# 不可逆动作禁止并行 (单设备单事务)
self.acquire_exclusive_lock(self.device_id)
# 执行前必须 dual-confirm (HARD_ACTION 已要求, SOFT_PARAM 此处也要求)
if not self.has_pre_confirm():
raise PreConfirmRequired()
result = self._do_execute()
return result
def compensate(self):
if self.is_irreversible():
# 不能自动补偿, 必须人工到场
return CompensationResult(
status='REQUIRES_HUMAN',
hint='物理动作已发生且不可逆, 请操作员现场评估补救',
suggested_actions=self.suggest_forward_recovery()
)
else:
return self._do_compensate()
```
### 6.3 文档警示
每个 capability Registry 中显式标注:
```yaml
- id: agv_move_to_station
type: write
safety_level: SOFT_PARAM
irreversible: true # 显式标注
irreversible_warning: |
AGV 移动后, 货架物理位置已变. 撤销操作 = 派 AGV 反向搬运,
属于新任务, 不是补偿. 中间过程产线可能因货架不在位停产.
```
UI/CLI 在用户确认前必须显示此警告
---
## 7. boot_id epoch 化 (P1-1)
### 7.1 v1.2 漏洞回顾
LRU(100) 满后旧 boot_id 被淘汰, 攻击者诱导 MCU 重启 101 次后回放首个 boot_id
### 7.2 v1.3 修订
```c
// MCU 固件 (STM32 / ATECC608)
#define EPOCH_FLASH_ADDR 0x0801F000 // 专用 flash sector
#define EPOCH_MAGIC 0xBEEF1234
typedef struct {
uint32_t magic;
uint64_t boot_epoch; // 单调递增, 每次启动 +1, flash 持久化
uint32_t crc;
} boot_persist_t;
uint64_t get_or_init_boot_epoch() {
boot_persist_t persist;
flash_read(EPOCH_FLASH_ADDR, &persist, sizeof(persist));
if (persist.magic != EPOCH_MAGIC || crc32(&persist) != persist.crc) {
// 首次启动或 flash 损坏
persist.magic = EPOCH_MAGIC;
persist.boot_epoch = 1;
} else {
persist.boot_epoch += 1;
}
persist.crc = crc32(&persist);
flash_write(EPOCH_FLASH_ADDR, &persist, sizeof(persist));
return persist.boot_epoch;
}
```
### 7.3 心跳协议升级
```
heartbeat_v3 = {
device_id,
boot_epoch, // 持久化单调, 不会重用
counter, // boot 内单调
timestamp_ms,
mac = HMAC(key, all_above || prev_mac)
}
Gateway 验证:
1. boot_epoch > last_seen_epoch[device_id] (单调, 不允许等于)
2. 同 epoch 内 counter 单调
3. flash 寿命: STM32 内置 flash ~10w 写次数 / 每次启动 1 次写 = 273 年, 远超设备生命周期
```
LRU 改为**永久持久化 last_seen_epoch[device_id]** Gateway TPM , 容量按设备数 (50 设备 × 200 byte = 10KB), 不淘汰
---
## 8. bump-in-wire 双冗余 + 远程证明 (P1-2)
### 8.1 双冗余架构
```
[Edge Gateway]
↓ (mTLS)
[VRRP 虚拟 IP] ← 唯一访问入口
┌───┴───┐
↓ ↓
[Bump A] [Bump B] ← 主备热切换
│ │
└───┬───┘
↓ (短网线)
[PLC]
```
主备 bump 互发心跳 (1Hz), 主失效 100ms 内自动切备
### 8.2 远程证明 (TPM Attestation)
每台 bump 启动时:
```
1. TPM 测量 boot loader / kernel / rootfs / DPI 规则 → PCR registers
2. Edge Gateway 周期 (5min) 发起 quote 请求
3. Bump 用 TPM AIK 签 PCR 值 + nonce
4. Gateway 验证签名 + 比对预期 PCR
5. 不匹配 → 该 bump 隔离 + 切备 + 告警
```
### 8.3 fail-mode
| 场景 | 行为 |
|---|---|
| bump 软件 hang | VRRP 切备, 业务无感 |
| bump 硬件故障 | 同上, 维护窗口替换 |
| bump 同时失效 | PLC 不可达, 大脑读取超时, 触发降级 |
| TPM attestation 失败 | 立即隔离 + Audit + 告警 ops |
| **DPI 规则未到达** | bump fail-closed: 拒绝所有流量直到规则同步 |
### 8.4 国产 ARM 工控机 secure boot
国产网关 (研华/研祥/华北工控) 多数无 OEM Secure Boot, v1.3 强制清单:
- BootROM 不可信 加装 LetsTrust TPM 模块外接验证 boot loader
- 或选用支持 ARM TrustZone + UEFI Secure Boot 的国产网关 (华为 Atlas / 飞腾派工业版)
- 高合规客户必须采购预审过的型号 (年度更新认证清单)
---
## 9. ISV Skill 沙箱 + 隔离 (P1-3)
### 9.1 ISV Skill 信任模型
```
[Bookworm 平台]
ops-key (平台核心 Skill)
[ISV 厂商]
isv-key-A, isv-key-B... (各 ISV 独立)
[客户端]
customer-key (客户最终批准)
```
ISV Skill isv-key 签名后上架, **客户端启用前必须 customer-key 二次签名**
### 9.2 沙箱执行
ISV Skill 在大脑内**隔离进程 + 资源限制**:
```yaml
# isv-skill-sandbox.yaml
sandbox:
isolation: subprocess # 不与大脑同进程
resource_limits:
cpu: 0.5 core
memory: 512 MB
network: deny_all_except_mcp # 只能调注册的 MCP, 不能 raw socket
filesystem: read_only_workspace
capability_whitelist:
# ISV Skill 只能调用 ops 预先批准的 MCP tools
allowed_mcp_tools:
- opcua-mcp.read_*
- modbus-mcp.read_*
# 显式不允许写入类
audit:
log_every_call: true
quarantine_on_anomaly: true
```
### 9.3 ISV Skill 审计
平台维护 ISV Skill 行为基线, 异常告警:
- 调用频率突变
- 调用 tool 模式偏离声明
- 资源使用激增 (CPU/MEM)
发现可疑立即 quarantine + 通知所有客户
### 9.4 客户端最终控制
```yaml
# customer-isv-policy.yaml (客户本地, customer-key 签)
allowed_isv_skills:
- id: isv-acme-pump-monitor
version: "1.2.3"
isv_signature_hash: sha256:<...>
customer_approved_by: customer-engineer:wang
approved_at: 2026-04-20
revocable: true # 客户可立即吊销
```
---
## 10. Registry 周期重验证 (P1-4)
### 10.1 周期 capability handshake
大脑后台进程每 24 小时遍历所有 capability 重做协议反查:
```python
# brain/registry/periodic_validator.py
async def periodic_revalidate():
while True:
for cap in registry.all_capabilities():
try:
actual = await mcp_client.introspect(cap.address, cap.protocol)
# 检测漂移
if actual.access_level != cap.declared_access:
cap.mark_degraded(reason='access_level_drift')
audit.log('REGISTRY_DRIFT', cap, actual)
if actual.datatype != cap.datatype:
cap.mark_degraded(reason='datatype_drift')
cap.last_verified_ts = HybridClock.wall_now_ms()
except CapabilityVerificationError as e:
cap.mark_unreachable(reason=str(e))
await asyncio.sleep(24 * 3600)
```
### 10.2 漂移分级响应
| 漂移类型 | 响应 |
|---|---|
| access_level: read read+write | DEGRADE, 写入禁用直到人工确认 |
| datatype 变化 | DEGRADE + 拒绝该 capability 直到 PR 更新 Registry |
| 节点不存在 | UNREACHABLE, 24h 内未恢复降为 archived |
| safety_level 隐式提升 (协议反查发现该地址被改为 HARD ) | CRITICAL ALERT + 立即拒绝, 通知 csso |
---
## 11. 100 设备并发任务队列 (P1-5)
```python
# brain/scheduler/priority_queue.py
class PrioritizedTaskQueue:
"""带优先级抢占 + 速率限制的任务队列"""
PRIORITY = {
'HARD_ACTION': 100, # 最高
'SOFT_PARAM': 50,
'READ_ONLY': 10,
}
def __init__(self, max_concurrent: int = 10):
self.queues = {p: asyncio.Queue() for p in self.PRIORITY.values()}
self.semaphore = asyncio.Semaphore(max_concurrent)
self.device_locks = {} # per-device 互斥
async def submit(self, task):
priority = self.PRIORITY[task.safety_level]
await self.queues[priority].put(task)
async def worker(self):
while True:
task = await self._get_highest_priority_task()
# HARD_ACTION 抢占: 同设备的 SOFT/READ 暂停, 等 HARD 完成
if task.safety_level == 'HARD_ACTION':
await self._suspend_lower_priority(task.device_id)
async with self.semaphore:
async with self._device_lock(task.device_id):
await task.execute()
```
容量目标: 单大脑实例支持 100 设备 × 并发 10, P95 < 500ms (Tool RTT 目标已达成)。
---
## 12. 国产 AGV 厂商补全 (P1-6)
更新 §2.3.1 移动机器人优先级:
| 品牌 | 控制器型号 | 协议 | 优先级 (v1.3) |
|---|---|---|---|
| **仙工 SEER** | SRC-2000 / SRC-880 / SRC-3000 | HTTP REST + WebSocket | P0 |
| **海康机器人** | RCS 调度系统 | REST API | **P0** ( P1 升级) |
| **极智嘉 Geek+** | RMS 调度系统 | REST API | P1 |
| **新松 SIASUN** | 6 / SCARA / AGV | Profinet + 厂商 SDK | **P1** ( P2 升级, 国企采购重要) |
| **国自 GREEN** | RoboShop | REST + MQTT | P2 |
| **快仓** | 自研调度 | 厂商 SDK | P2 |
| **嘉腾** | 自研 | 厂商 SDK | P2 |
| **迦智 CAJA** 新增 | 自研调度 | REST API | **P1** |
| **斯坦德 STANDARD ROBOTS** 新增 | 自研调度 | REST + WebSocket | **P1** |
| **灵动科技 MUSHINY** 新增 | 自研调度 (电商仓储强项) | REST API | **P1** |
仙工端口数据已修正: 默认 1448 (查询) + 19200 系列推送, 实际部署需对照 SDK 版本
---
## 13. Saga 持久化介质约束 (P1-7)
```yaml
# saga-storage-config.yaml
storage:
type: sqlite_wal | postgresql
sqlite_constraints:
file_path_must_be: local_disk # 禁止 NFS / CIFS / SMB / 网络盘
fsync_mode: full # 强 fsync, 牺牲性能保数据
journal_mode: WAL
page_size: 4096
# CI 启动检查
pre_start_check:
- check_filesystem_type:
allowed: [ext4, xfs, ntfs, apfs]
forbidden: [nfs, cifs, fuse.sshfs]
- check_disk_space: ≥ 10 GB free
- check_write_permission
postgresql_constraints:
require_synchronous_commit: on
require_wal_level: replica
backup_strategy: pg_basebackup_daily
```
启动时检测到 NFS/CIFS 上的 SQLite 直接拒绝启动 + 错误码 `E_SAGA_STORAGE_INVALID_FS`
---
## 14. P2 改进汇总
### 14.1 Margin Gate 公式重写
```python
# v1.2 错误: baseline = max(0.10, p95-p5) ← 极差不是判别阈值
# v1.3 正确: 基于历史召回 Top1-Top2 margin 经验分布
class AdaptiveMarginGate:
def __init__(self):
self.observed_margins = deque(maxlen=1000) # 历史 Top1-Top2 差
def record(self, top1_score, top2_score):
self.observed_margins.append(top1_score - top2_score)
def threshold(self):
if len(self.observed_margins) < 50:
return 0.15 # cold start 默认
# 取 P25 作为阈值: 历史 75% 的查询有这么大的 margin 才算"明确"
return max(0.10, np.percentile(self.observed_margins, 25))
def is_ambiguous(self, top1, top2):
return (top1.score - top2.score) < self.threshold()
```
### 14.2 hallucination_check 自适应阈值
```python
# v1.2: deviation > 0.01 (1%) 一刀切, 对 pA 电流 / mV 电压误报
# v1.3: 按 capability range 自适应
def hallucination_check_v3(claim, audit_log):
cap = registry.get(claim.device).capabilities[claim.address]
# 自适应容差
range_span = cap.range[1] - cap.range[0]
if cap.unit in ['celsius', 'fahrenheit']:
tolerance_abs = max(0.5, range_span * 0.005) # 至少 0.5°C
elif cap.unit in ['rpm', 'hz']:
tolerance_abs = max(1, range_span * 0.005)
elif cap.unit in ['ampere']:
tolerance_abs = max(cap.range[1] * 0.01, 1e-9) # 1% 满量程
else:
tolerance_abs = range_span * 0.01
if abs(actual - claim.value) > tolerance_abs:
alert(f'LLM 数据偏差超过自适应阈值 {tolerance_abs}')
```
### 14.3 Combo Uplift DoS 防护
```yaml
# combo-soft-param-uplift-v3
- id: combo-soft-param-uplift-v3
priority: 95
conditions:
# 修复: 区分"恶意刷计数"与"真实运维序列"
- any_of:
- same_device AND count_gte: 3 AND time_window_sec: 60
- same_zone AND semantic_match: production_halt
- and_not:
# 同一用户在 1h 内刷 >20 次 SOFT → 视为 DoS, 不升格而是限流
- rate_limit_per_user: { count: 20, window_sec: 3600 }
effect: UPLIFT_TO_HARD_ACTION
fallback_on_rate_limit_exceeded:
effect: THROTTLE
notify: ops_team
```
### 14.4 OSSD 双通道 (急停 SIL3)
§2.3.1 安全 PLC 输入升级:
```
[钥匙开关 + OSSD 双通道 (Type 4 SIL3)]
│ │
│ └── Channel B: 独立电缆 + 独立信号路径
└────── Channel A: 独立电缆 + 独立信号路径
[安全 PLC]
异或检测: 任一通道断 → 立即视为按下急停 (fail-safe)
互检: 两通道状态不一致超过 100ms → 报故障
```
供应商: 皮尔磁 PNOZ / 西门子 SIRIUS 3SK / 国产: 兴大豪 (推荐高合规档位强制)
### 14.5 DERP 元数据混淆
```yaml
# tailscale-config-v3.yaml
derp_traffic_obfuscation:
packet_padding:
enabled: true
fixed_size_bytes: 1500 # 所有 DERP 流量 padding 到固定大小
cover_traffic:
enabled: true
rate_pps: 5 # 每秒 5 个伪流量包, 掩盖真实通信时序
pattern: poisson # Poisson 分布而非固定间隔
# 高合规档位额外要求
high_compliance_only:
require_local_derp_only: true # 永不出境
monitor_traffic_anomaly: true
```
---
## 15. 路线图微调
| Phase | 时长 | 工作量 | v1.3 增量 |
|---|---|---|---|
| 0 PoC | 8 | 60 人日 | 不变 (P0 修复在 PoC 启动前完成) |
| 1 生产基础 | 3 个月 | **160 人日** (+20) | bump + 异构裁判 + ISV 沙箱 |
| 2 工业接入 | 6 个月 | **280 人日** (+20) | 周期重验证 + 100 设备并发优化 |
| 3 智能化 | 12 个月 | (累计) | 不变 |
**总工作量**: v1.2 460 **v1.3 500 人日**
---
## 16. 重新评分预期
| 维度 | v1.2 终审 | v1.3 预期 | 关键支撑 |
|---|---|---|---|
| 架构稳健性 | 84 | **88** | DAG 校验 + 分级签名 + 时钟修正 |
| 市场可行性 | 70 | **82** | 客群分级 + AGV 补全 + ISV 沙箱 |
| 算法稳健性 | 60.2 | **80** | monotonic + schema + epoch + 不可逆显式 |
| 红队安全 | 77 | **86** | 异构裁判 + bump + ISV 隔离 + DERP 混淆 |
| **综合** | **79.5** | ** 84-86** | **B+ 达成** |
---
## 17. 修订记录
| 版本 | 日期 | 主要变更 | 评分 |
|---|---|---|---|
| v1.0 | 2026-04-25 | 初版 | 56.6 |
| v1.1 | 2026-04-25 | 7 CRITICAL 修复 + 国产硬件 + LLM | 76 |
| v1.1.1 | 2026-04-25 | LLM 旗舰更新到 2026-04 | 76 |
| v1.2 | 2026-04-25 | 全配置签名 + bump-in-wire + 裁判 LLM + ISV | 79.5 |
| **v1.3** | **2026-04-25** | **22 项收口: 异构裁判 + 时钟修正 + 强 schema + 客群分级 + ADB 禁用 + DAG 校验 + 双轨预算 + Adapter 归一 + 不可逆显式 + boot epoch + 双 bump + ISV 沙箱 + 周期重验 + 任务队列 + AGV 补全 + WAL 介质 + Margin 重写 + 自适应容差 + DoS 防护 + OSSD 双通道 + DERP 混淆** | **85** |
---
## 18. 终极判定
**v1.3 自评 84-86 (B+)**, 经独立第三方红队 + 算法 + 市场 + CTO 复审通过 85 后:
- 启动 Phase 0 PoC (60 人日, 8 )
- Phase 1 生产基础平台 (160 人日, 3 )
- Phase 2 工业接入 (280 人日, 6 )
任何 v1.3 后续修订需经"演进日志"独立文档记录, 并按变更影响等级触发不同级别的复审 (minor: 单专家 / major: 四专家全审)。
---
> **v1.3 承诺**: 不再加新机制, 把 v1.0/v1.1/v1.2 累积的 22 项漏洞全部收口。
> 评分目标 B+ (≥85) 达成后即可正式启动工程实施。