evorule-reactor
EvoRule 三层架构的 Tier 1 反应式执行器 —— 事实驱动的状态转换引擎。
- 版本:v0.2.1
- 依赖:evorule-tcb = "0.2.1"
- 协议:AGPL-3.0-or-later
- 测试:
cargo test全部 PASS(含complex_rule_test/reactor_test/ffi_test等) - build.rs 编译时门禁:F11 禁止
unwrap/expect/panic!/debug_assert!(非测试代码),G8 控制流白盒化,PASSED - G8 门控遵守:反应器主循环(
reactor.rs)的控制流分支是策略数据(Fact 变体的 match)而非硬编码业务逻辑;任何业务分支均由core_eval.json数据驱动,编译期通过build.rs递归扫描确认。 unsafe:#],FFI 边界,已文档化)- P0 修复(2026-07-25):
Box::leak内存泄漏已修复(IoType::parse返回Option);锁中毒改为e.into_inner()恢复(非 panic) - v0.2.0 重构(2026-08-04):
IoType内部从&'static str改为Arc<str>,支持IoType::new()注册任意 io_type(失去Copy,5 个const改工厂函数);IoHandler/IoDispatcher从 governance 下沉至本 crate(trait 改#[async_trait]object-safe);IoType::parse标记#[deprecated]。详见 MIGRATION_v0.2.0.md
设计原则
- 事实驱动:所有交互通过 Fact 通道进行
- 单一串行通道:保证调度确定性
- 稳定检测:队列空 + 无待处理 I/O = 稳定
- 无状态泄漏:所有状态由反应器维护
- Append-Only 审计链:所有 Fact 追加到 FactsLog,支持审计重放
- 哈希链完整性:每个 Fact 写入 WAL 时自动计算 BLAKE3 哈希链(
content_hash/prev_hash/chain_hash),篡改可检测
架构
用户/治理层 → FactSender → [command mpsc] → 反应器
↓
调用 TCB 核心
↓
产生新 Fact → event broadcast → 用户/I/O 订阅者/审计器
↓
所有 Fact → FactsLog(审计链 + 哈希链)
模块结构
src/
├── channel.rs # 通道封装(command/event)
├── error.rs # 错误类型(ReactorError / FactsLogError 等)
├── fact.rs # Fact 枚举(7 种变体)+ FactId + IoType
├── facts_log.rs # Append-Only FactsLog(内存 + WAL 持久化 + 哈希链)
├── ffi.rs # C FFI 接口(feature = "ffi")
├── hash.rs # BLAKE3 哈希链算法(单一真相源,tier2/CLI re-export)
├── invariants.rs # 结构不变量检查
├── io_dispatcher.rs # I/O 分发器(v0.2.0 从 governance 下沉;builder + register(IoType, handler))
├── io_handler.rs # IoHandler trait + IoResult(v0.2.0 从 governance 下沉;#[async_trait] object-safe)
├── lib.rs # 模块声明 + 公共 API 导出
├── phase.rs # 反应器阶段(Executing/Idle/Stable 等)
├── pure.rs # 纯函数执行器(TCB 调用封装)
├── reactor.rs # 反应器主循环 + ReactorBuilder + ReactorHandle
├── stable_detector.rs # 稳定状态检测器
├── state.rs # 反应器状态快照
└── wal.rs # WAL 读写(JSONL 格式,含哈希字段)
快速入门
use ;
use JsonValue;
let core_eval = vec!;
let reactor = builder.max_rounds.build;
let = reactor.spawn;
tx.send.unwrap;
while let Ok = rx.recv.await
API 列表
Reactor
| 方法 | 说明 |
|---|---|
Reactor::builder(core_eval) |
创建反应器构建器 |
builder.max_rounds(n) |
设置最大执行轮数 |
builder.build() |
构建反应器实例 |
reactor.spawn() |
启动反应器,返回通道和句柄 |
ReactorHandle
| 方法 | 说明 |
|---|---|
handle.join() |
等待反应器完成 |
handle.abort() |
中止反应器 |
handle.is_finished() |
查询反应器是否已结束 |
handle.current_phase() |
获取当前阶段 |
handle.causal_depth() |
获取因果深度 |
handle.structural_invariant_violations() |
获取结构不变量违规计数 |
handle.pending_io_count() |
获取待处理 I/O 数量 |
handle.current_step() |
获取当前执行步数 |
handle.snapshot() |
获取反应器状态快照 |
handle.interrupt() |
中断执行 |
Fact 类型
| 类型 | 说明 |
|---|---|
Fact::Command |
用户命令(触发执行) |
Fact::StateTransition |
状态转换(反应器自动产生,携带 cause 因果链) |
Fact::Stable |
稳定状态(队列空 + 无 pending I/O) |
Fact::Error |
错误(超时 / TCB 错误 / 队列溢出) |
Fact::IoRequest |
I/O 请求(TCB 产生,治理层消费) |
Fact::IoResponse |
I/O 响应(治理层产生,反应器消费) |
Fact::PayloadUpdate |
负载更新(治理层注入) |
审计链与哈希链
WAL 格式(含哈希链)
每条 WAL 记录包含以下字段:
哈希链算法
- 单一真相源:
evorule_reactor::hash模块 - 算法:BLAKE3
- content_hash =
blake3(fact_to_stable_json(fact)) - chain_hash =
blake3(prev_hash + content_hash) - 初始 prev_hash =
"genesis" - evorule-governance 和 evorule-cli 通过 re-export 使用同一算法,三方哈希值字节级一致
FactsLog
| 方法 | 说明 |
|---|---|
FactsLog::new() |
创建纯内存 FactsLog |
FactsLog::with_wal(path) |
创建带 WAL 持久化的 FactsLog |
FactsLog::recover(path) |
从 WAL 恢复 FactsLog(重放 + 挂载) |
facts_log.append(fact) |
追加 Fact(自动计算哈希链 + 写 WAL) |
facts_log.last_hash() |
获取审计链末尾哈希 |
facts_log.history() |
获取全部 Fact 历史 |
facts_log.version() |
获取当前版本号 |
C FFI 接口
启用 ffi feature 编译动态链接库:
C API 示例
evorule_reactor* reactor = ;
;
;
Feature Flags
| Feature | 说明 |
|---|---|
persistence |
WAL 持久化(FactsLog + 哈希链写入磁盘) |
ffi |
C FFI 接口(生成 cdylib) |
kani |
Kani 形式化验证(保留标记) |
版本策略
本项目遵循 Semantic Versioning:
- MAJOR:API 不兼容变更
- MINOR:向后兼容的功能新增
- PATCH:向后兼容的 bug 修复
设计文档参考
- 项目级文档总索引:
DOCS_INDEX.md(所有 L1 公开文档的唯一入口) - 项目级架构总览:
README.md(三层架构 + 快速开始) - 本模块规格:
REACTOR_SPEC.md
许可证
代码:AGPL-3.0-or-later(见 LICENSE 文件)。