-
Notifications
You must be signed in to change notification settings - Fork 0
Safety Gateway
EnerOS Bot edited this page Jul 5, 2026
·
1 revision
中文 | English
维护版本:v0.51.2 | 最后更新:2026-07-06
SafetyGateway 是 EnerOS 双执行域架构中通用域 → 实时域的唯一通道。所有来自 Agent / AI / 规划优化模块的指令必须经过 SafetyGateway 的 7 阶段决策管线、约束校验、优先级仲裁与执行器才能下放到实时域。本页概述类型层不可绕过机制;完整决策记录请参阅 ADR-0015。
| 目标 | 实现机制 | 验证手段 |
|---|---|---|
| 通用域无法直接调用实时域 API | 类型层封装 + 编译期检查 |
clippy::disallowed_types 在 CI 中拒绝违例 |
| 实时域禁止堆分配 / 锁竞争 / 动态分派 |
NoAlloc marker + AllocTracker + lockfree 默认 |
WCET 框架 + 单线程 --test-threads=1 测试 |
| 决策可审计、不可篡改 |
RepositoryAuditSink + HMAC-SHA256 链 |
HMAC 链断链检测 |
| 约束不可降级 | Constraint as Kernel Law | 编译期 trait seal + 运行时拒绝 |
[Agent/AI/规划] → [Auth] → [Validate] → [Constraint] → [Priority]
↓
[Decide] → [Execute] → [Audit]
| 阶段 | 职责 | 关键类型 |
|---|---|---|
| Auth | API Key / JWT / mTLS 认证 | AuthMiddleware |
| Validate | 类型层密封的命令验证 | Validated<Command> |
| Constraint | N-1 / 热稳 / 电压 / 频率 约束校验 | ConstraintEngine |
| Priority | 多 Agent 冲突优先级仲裁 | PriorityArbiter |
| Decide | 决策合成与签署 | DecisionPipeline |
| Execute | 下放至实时执行器 | RtExecutor |
| Audit | HMAC 链写入 WORM 审计日志 | RepositoryAuditSink |
#[derive(Debug, Clone)]
pub struct Validated<T>(T);
impl Validated<Command> {
/// 仅 SafetyGateway 可构造。新版本通过 sealed trait 收紧
pub fn new(cmd: Command) -> Self { Self(cmd) }
}
pub struct SafetyGateway { /* ... */ }
impl SafetyGateway {
pub fn submit(&self, cmd: Command) -> Result<Validated<Command>, GatewayError> {
// 7 阶段管线...
Ok(Validated::new(cmd))
}
}
// 实时域 API 仅接受 Validated<Command>,不接受裸 Command
pub fn rt_execute(cmd: Validated<Command>) { /* ... */ }外部代码无法直接构造 Validated<Command>,必须经过 SafetyGateway::submit。
clippy.toml 中禁用实时域路径上的 Mutex / RwLock / Box::new / Vec::new 等:
[[disallowed-types]]
path = "std::sync::Mutex"
reason = "RT domain: lock contention is non-deterministic"CI 中 cargo clippy --workspace --all-targets -- -D warnings 强制执行,违例即编译失败。
实时域代码标记 NoAlloc trait,运行时 AllocTracker 注入后检测任何堆分配并 panic:
pub trait NoAlloc {}
#[cfg(feature = "rt_check")]
pub struct AllocTracker { /* ... */ }
#[cfg(feature = "rt_check")]
impl AllocTracker {
pub fn install() -> Self { /* 注入全局分配器钩子 */ }
pub fn assert_no_alloc<F: FnOnce() -> R, R>(&self, f: F) -> R { /* ... */ }
}#[cfg(feature = "rt_check")]
pub fn wcet_bench<F: FnOnce() -> R, R>(label: &str, budget: Duration, f: F) -> R {
let start = Instant::now();
let r = f();
let elapsed = start.elapsed();
if elapsed > budget {
panic!("WCET violation: {} {:?} > {:?}", label, elapsed, budget);
}
r
}CI 中以 --test-threads=1 跑 WCET 测试避免噪声。
pub struct RepositoryAuditSink {
repo: AuditRepository,
hmac_secret: [u8; 32],
last_hash: Vec<u8>, // 前一条目的 SHA-256
}
impl AuditSink for RepositoryAuditSink {
fn write(&mut self, entry: &AuditEntry) -> Result<()> {
let chain_hash = hmac_sha256(&self.hmac_secret, &[&self.last_hash, &entry.encode()]);
self.repo.append(&entry, &chain_hash)?;
self.last_hash = chain_hash;
Ok(())
}
}任何篡改历史记录都会导致后续 HMAC 校验失败。
-
AllocTracker重入 bug 在 v0.49.1 通过直接调用绕过,待 v0.52.0 彻底修复 -
HardwareWatchdog当前不是 trait,仅CommandResult变体被断言 -
Validated::new当前用#[doc(hidden)] pub而非 sealed trait,待 v0.52.0 收紧 - 67 个
unwrap/expect残留于非测试代码(v0.51.0 已移除 88 个,TODO v0.52.0) - WCET 测试需
--test-threads=1
- ADR-0015 RT 类型层安全
- 双执行域 — 通用域 vs 实时域对比
- 主仓库 docs/developer-guide.md — 7 阶段决策管线实现细节
- 主仓库 crates/eneros-gateway/ — 源码
EnerOS Wiki | v0.51.2