evorule-cli 0.4.1

EvoRule CLI - Local JSON rule executor for compliance-critical users (zero network, zero telemetry, musl static)
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
<!--
  Copyright 2026 EvoRule Project

  SPDX-License-Identifier: AGPL-3.0-or-later

  This file is part of EvoRule, licensed under GNU Affero General Public License v3 or later.
-->


# `evorule` CLI


[![版本 v0.3.2](https://img.shields.io/badge/version-v0.3.2-blue)](../Cargo.toml)
[![AGPL-3.0](https://img.shields.io/badge/license-AGPL--3.0--or--later-green)](../LICENSE)
[![文档索引 DOCS_INDEX](https://img.shields.io/badge/docs-DOCS_INDEX-8A2BE2)](../DOCS_INDEX.md)

> **架构层次**:EvoRule 三层架构之上的 **L1 命令行封装工具**(面向圈 2 合规用户,不引入新机制,只封装 evorule-tcb + evorule-reactor 已有的能力)。

> **业务规则模板位置说明(边界合规)**:
> 面向行业的开箱即用规则集(**医院 HIPAA / 律所利益冲突 / 金融 AML / 政务数据分级** 等)不在本仓——本仓仅保留机制层最小化演示用例(见本仓 `evorule-cli/examples/README.md``evorule-cli/tests/fixtures/`)。行业规则模板请参见对应独立仓。

**本地 JSON 规则执行工具,面向"圈 2 合规刚需"用户**(医疗/律所/金融/政务等隐私敏感行业)。

> **"evorule 没有智能,只有执行的最佳实践"**
> **"把你公司的合规规则写成一个 JSON 文件,放到本地,evorule 帮你跑 + 审计 + 重放 + 验真"**

**G8 门控遵守**:编译期 `build.rs` 递归扫描 `src/**/*.rs`(非测试代码)拦截「硬编码业务控制流」违规;所有业务语义均由规则目录的 JSON 数据驱动,CLI 本身只做命令分发 + 文件读写 + fact log 格式转换。

## 特性


- **零网络** —— 不调用任何外部服务
-**零遥测** —— 无任何隐式上报
-**零 AI 决策** —— 不调用 LLM
-**零系统依赖** —— musl 静态链接,1.8 MB 单文件
-**完整审计** —— 每步 fact 落盘(tier1 WAL JSONL 格式,与 evorule-governance 互通)
-**哈希链** —— blake3 哈希链 + 结构不变量校验(防篡改)
-**FIFO 队列** —— 修复原 LIFO bug,正确执行 push 语义
-**确定性加载** —— 规则文件按文件名排序,跨平台一致
-**可对比** —— 两个 fact log 按 FactId 对齐 diff(非 HashSet)
-**可重放** —— `replay` 子命令播放 fact log
-**可验真** —— `verify-chain` 子命令验证 fact log 完整性
-**可证来源(G-A1)** —— `anchor-keygen` 生成 ed25519 审计锚点密钥对,`verify-anchors` 离线校验锚点真实性(防抵赖,哈希链之上的密钥签名)
-**可重现构建** —— 同源码两次构建 SHA256 一致(圈 2 监管可独立复现)
-**G8 门控** —— 编译期拦截"硬编码控制流"违规(与 tier1/tier2 同套规则)
-**多架构** —— `x86_64-unknown-linux-musl` + `aarch64-unknown-linux-musl`(AWS Graviton / RPi 适用)

## 快速开始(圈 2 用户)


```bash
# 1) 下载(根据 CPU 架构选)

wget https://gitee.com/evorule/evorule/releases/download/v0.3.1/evorule-x86_64
wget https://gitee.com/evorule/evorule/releases/download/v0.3.1/evorule-aarch64

# 2) 验证(可选,确认下载完整)

sha256sum -c evorule-x86_64.sha256

# 3) 装上

chmod +x evorule
mv evorule /usr/local/bin/evorule

# 4) 校验你的合规规则

evorule validate /etc/company-rules/

# 5) 跑你的合规规则

evorule run /etc/company-rules/ -o /var/log/evorule-fact.log

# 6) 验真(确认 fact log 未被篡改)

evorule verify-chain /var/log/evorule-fact.log

# 7) 出事故?重放

evorule replay /var/log/evorule-fact.log

# 8) 监管检查?导出 fact log

cat /var/log/evorule-fact.log

# 9) 生成 G-A1 审计锚点签名密钥对(一次性运维;私钥种子请私密保存,公钥可分发给验证方)

evorule anchor-keygen --output /root/.evorule/audit-sk-seed.txt

# 10) 离线校验审计锚点真实性(防抵赖;公钥缺省用导出物内嵌 verifying_key)

evorule verify-anchors audit-export.json
```

## 编译(开发者)


### 前置


- **Linux 容器** / **WSL Ubuntu 22.04** / 真 Linux
- `rustup` 1.92+(推荐 rustup 自动管理)
- 对应架构的 musl 工具链:
  - x86_64: `apt install musl-tools && rustup target add x86_64-unknown-linux-musl`
  - aarch64: `apt install musl-tools gcc-aarch64-linux-gnu && rustup target add aarch64-unknown-linux-musl`

### 编译(默认 x86_64)


```bash
cd evorule-cli  # 在 evorule 仓根目录下执行;Linux 用户进入对应目录即可
bash build-musl.sh
# 产物: $TARGET_DIR/x86_64-unknown-linux-musl/release/evorule

#   1.8 MB,静态链接,stripped

```

### 编译 aarch64(AWS Graviton / RPi)


```bash
bash build-musl.sh --target aarch64-unknown-linux-musl
# 产物: $TARGET_DIR/aarch64-unknown-linux-musl/release/evorule

#   1.4 MB,静态链接,stripped

```

### 可重现构建(reproducible build)


```bash
bash build-musl.sh --target x86_64-unknown-linux-musl --repro
# 输出:

#   REPRODUCIBLE ✓ <SHA256>

#   Both builds produced identical SHA256

```

**原理**:

- `SOURCE_DATE_EPOCH=1700000000` 固定所有时间戳
- `CARGO_INCREMENTAL=0` 强制全量构建
- `RUSTFLAGS=-Wl,--build-id=none` 去掉 linker 随机 build-id
- `CARGO_PROFILE_RELEASE_STRIP=true` 自动去符号
- 两次 `cargo clean` + `cargo build` 产出**字节完全相同**的二进制

**圈 2 价值**:监管机构可以独立复现 release artifact,验证供应链可信。

### 验证二进制


```bash
$ file evorule
ELF 64-bit LSB pie executable, x86-64, ... static-pie linked, ...

$ ldd evorule
        statically linked
```

### Windows 开发构建


```cmd
cd D:\evorule
cargo build --release --bin evorule
REM 产物: .build\rust\release\evorule.exe
```

## 子命令


### 1. `evorule validate <rules-dir>`


校验 JSON 规则文件,验证 transform 类型是否在 core_eval 元指令白名单内。

```bash
evorule validate ./rules/
```

输出:

- `[OK]   transform[N]: type='branch'` —— 合法 type
- `[ERROR] transform[N]: unknown type 'X'` —— 未知 type(阻断)
- `[ERROR] transform[N]: missing 'type' field` —— 缺少 type 字段(阻断)

合法 type 白名单(core_eval 元指令):

| type         | 用途                                     |
| ------------ | ---------------------------------------- |
| `branch`     | 条件分支(domain 匹配 → on_true/on_false) |
| `set`        | 修改 payload 字段(set/add/sub)           |
| `push`       | 推指令到队列前端(插队语义)               |
| `io_request` | 产生 I/O 请求信号(不修改状态)            |
| `noop`       | 空操作                                   |
| `increment`  | 自增(业务指令,由 core_eval 映射)         |
| `decrement`  | 自减(业务指令,由 core_eval 映射)         |

退出码:

- 0 = 全部通过
- 1 = 有 error(未知 type 或缺 type 字段)
- 2 = 规则目录不存在或无 .json 文件

---

### 2. `evorule run <rules-dir> [--payload X | --payload-file X] [-o output] [--max-steps N]`


加载并执行 JSON 规则,输出 fact log(tier1 WAL JSONL 格式,每行一个 Fact)。

```bash
# 默认空 payload

evorule run ./rules/

# 提供初始 payload(JSON 字符串)

evorule run ./rules/ --payload '{"user_id": 42}'

# 从文件读 payload(Windows 友好,避免命令行转义问题)

evorule run ./rules/ --payload-file ./payload.json

# 输出到文件(而非 stdout)

evorule run ./rules/ -o ./fact.log

# 限制最大执行步数(防死循环,默认 10000)

evorule run ./rules/ --max-steps 100
```

输出示例(tier1 WAL JSONL 格式):

```json
{"id":1,"instruction":{"type":"noop"},"type":"Command"}
{"cause":1,"id":2,"new_payload":{"x":42},"new_queue":[],"type":"StateTransition"}
{"final_snapshot":{"x":42},"id":3,"type":"Stable"}
```

**Fact 类型**(7 种,与 evorule-reactor / evorule-governance 一致):

| type              | 字段                              | 说明                                                 |
| ----------------- | --------------------------------- | ---------------------------------------------------- |
| `Command`         | id, instruction                   | 用户提交新指令(触发执行)                             |
| `StateTransition` | id, cause, new_payload, new_queue | 状态转换(每步执行)                                   |
| `IoRequest`       | id, cause, io_type, params        | I/O 请求信号(0.2.0 无 handler → Error)               |
| `IoResponse`      | id, request_id, result, error     | I/O 响应(0.2.0 不产生)                               |
| `Stable`          | id, final_snapshot                | 稳定状态(最终快照,始终发射)                          |
| `Error`           | id, message                       | 执行错误(max_steps 超限 / TCB 错误 / 无 I/O handler) |
| `PayloadUpdate`   | id, path, value                   | 载荷更新(0.2.0 不产生)                               |

退出码:

- 0 = 执行完成(可能含 Error fact,但 CLI 本身不失败)
- 1 = 加载或执行错误(规则目录问题 / payload 解析失败)
- 2 = 规则目录不存在或无 .json 文件

---

### 3. `evorule replay <fact-log>`


播放 fact log(pretty-print,每个 Fact 一行摘要)。

```bash
evorule replay ./fact.log
```

输出示例:

```text
=== Replaying ./fact.log ===
[F1] Command type=noop
[F2] StateTransition cause=F1
[F3] Stable
=== End (3 facts) ===
```

---

### 4. `evorule diff <a.log> <b.log>`


对比两个 fact log(**按 FactId 数组下标对齐**,非 HashSet)。

```bash
evorule diff ./before.log ./after.log
```

输出示例(差异):

```text
=== Diff ./before.log <-> ./after.log ===
A: 3 facts
B: 3 facts

[~] [F2] StateTransition cause=F1
[~] [F2] StateTransition cause=F1
[~] [F3] Stable
[~] [F3] Stable

=== 2 difference(s) ===
```

diff 前缀:

- `[~]` —— 两边都有但内容不同
- `[-]` —— 只在 A
- `[+]` —— 只在 B
- `(identical)` —— 完全相同

---

### 5. `evorule verify-chain <fact-log>`


验证 fact log 完整性(**三层验证**):

1. **哈希链**:blake3 链式哈希(与 evorule-governance 字节级一致)
2. **FactId 单调递增**:每个 Fact 的 id 必须严格大于前一个
3. **cause 引用有效性**:`StateTransition.cause``IoRequest.cause` 必须指向已存在的 FactId

```bash
evorule verify-chain ./fact.log
```

输出示例(通过):

```text
=== Verifying hash chain: ./fact.log ===
Facts: 3
Algorithm: blake3 (compatible with evorule-governance auditor)

[OK] Hash chain computed
[OK] Structural invariants verified (FactId monotonic, cause references valid)
     genesis → F1 → F2 → ... → F3 (final)
```

输出示例(篡改检测):

```text
=== Verifying hash chain: ./tampered.log ===
Facts: 3
Algorithm: blake3 (compatible with evorule-governance auditor)

[OK] Hash chain computed
[ERROR] Structural invariant violations:
        fact[2]: id=3 not strictly greater than prev id=99 (monotonicity violated)
Error: Hash chain verification failed: structural violations: 1
```

退出码:

- 0 = 哈希链 + 结构不变量全部通过
- 1 = 任一检查失败(fact 被篡改或结构异常)

**与 evorule-governance 的关系**:`hash.rs` 复制自 `evorule-governance/src/hash.rs`,由 `include_str!` 交叉验证测试强制双边同步。CLI 与 tier2 Auditor 对同一份 fact.log 必产生相同的链哈希。

---

## G8 门控(编译期拦截)


evorule-cli 的 `build.rs` 强制执行 G8 + F11,**与 evorule-reactor / evorule-governance 同一套规则**:

| 规则    | 禁止                                                   | 目的                               |
| ------- | ------------------------------------------------------ | ---------------------------------- |
| **G8**  | `"conditional"` / `"while_loop"` / `"sequence"` 字面量 | 反应器/治理层/CLI 都不得展开控制流 |
| **F11** | `debug_assert!` / `.unwrap(` / `.expect(` / `panic!(`  | 主代码路径不 panic-prone           |

**扫描范围**:递归扫描 `src/**/*.rs`(含 `src/commands/*.rs` 等子模块),通过 `strip_test_mod` 剥离 `#[cfg(test)] mod tests { ... }` 测试模块体。

**零豁免原则**:G8/F11 对 `src/**/*.rs`(非测试)零容忍,无任何业务字面量豁免。

任何违规立即 `exit(1)`,违规行号 + 标签全打印。

**紧急跳过**(不推荐):

```bash
EVORULE_SKIP_GATE=1 cargo build
```

## 规则文件格式


JSON 规则文件遵循 `core_eval.json` 格式(transform 列表)。

**示例**:`rules/my-rule.json`:

```json
{
  "transform": [
    {
      "type": "branch",
      "params": {
        "domain": {
          "type": "instruction",
          "instruction_type": "increment"
        },
        "on_true": [
          {
            "type": "set",
            "params": {
              "attr": "x",
              "operation": "add",
              "value": "__exec__.instruction.params.delta"
            }
          }
        ]
      }
    }
  ]
}
```

**`set` 指令的 `attr` 字段**:

- 字面字符串(如 `"x"`):直接作为 payload 字段名
- 点分路径(如 `"a.b.c"`):自动创建嵌套对象,设置 `payload.a.b.c`
- **不要**`"__exec__.payload.x"` —— 这会被当作路径引用解析,而非字段名

**多文件**:`run` 会按**文件名字典序排序**后加载目录下所有 `*.json` 文件的 `transform` 数组,保证跨平台确定性。

**支持的文件格式**:

- `{"transform": [...]}` —— 标准格式
- `{"transforms": [...]}` —— 别名(同义)
- `[{...}, {...}]` —— 顶层数组,每项是一条 transform
- `{...}` —— 单条 transform 对象

**I/O 类型**(mechanism-policy separation):

自 v0.2.0 起,`io_type` 支持任意字符串(`IoType::new("your_service")`),不再限于固定白名单;`IoType::parse` 已 `#[deprecated]`,新代码用 `IoType::new`。内置 5 个工厂函数(字符串值不变,向后兼容):

| io_type         | 内置工厂函数              | 用途               |
| --------------- | ------------------------- | ------------------ |
| `call_external` | `IoType::call_external()` | 调用外部服务       |
| `query_db`      | `IoType::query_db()`      | 查询数据库         |
| `http_get`      | `IoType::http_get()`      | HTTP GET 请求      |
| `save_memory`   | `IoType::save_memory()`   | 保存到记忆         |
| `call_service`  | `IoType::call_service()`  | 调用外部服务(通用) |

**业务语义**既可通过 `call_service` + `service_name` 表达(如 `"io_type": "call_service", "service_name": "audit_log"`),也可直接用自定义 io_type(如 `"io_type": "audit_log"`,由应用层 subscriber 按字符串路由)。机制层只认字符串、不校验语义,校验由 `ReactorBuilder::known_io_types` 或 subscriber 决定。

---

## 圈 2 合规刚需演示(30 秒话术)


> "把你公司的合规规则写成一个 JSON 文件,放到本地文件夹。
> 运行 `evorule run ./rules/`,它会:
>
> 1. 执行你的规则
> 2. 记录每一步到本地 fact log(tier1 WAL JSONL 格式,与 tier2 审计链互通)
> 3. **不会联网,不会上报,不会 AI 决策**
> 4. 出事故?`evorule replay fact.log` 重放
> 5. 监管检查?fact.log 本身就是审计证据
> 6. 验真?`evorule verify-chain fact.log` 验证哈希链 + 结构完整性
> 7. 供应链可信?同源码两次构建 SHA256 一致,监管可独立复现"

**对比 Excel 宏 / VBA**:

| 维度       | Excel 宏      | evorule                        |
| ---------- | ------------- | ------------------------------ |
| 规则格式   | 散在各个 cell | 集中 JSON,版本控制友好         |
| 执行可重复 | 不一定        | 100% 确定性 + 可重现二进制     |
| 审计追踪   | 没有          | 完整 fact log + blake3 哈希链  |
| 防篡改     | 没有          | 哈希链 + 结构不变量校验        |
| 跨文件规则 || 简单(目录扫描,确定性排序)      |
| 时间回放   | 撤销 5 步     | 任意时刻回放                   |
| 监管汇报   | 手工截图      | 自动导出 fact.log              |
| 架构选择   | 仅 x86        | x86_64 + aarch64(Graviton/RPi) |

---

## 圈 2 分发清单(给合规用户)


| 物料                                 | 来源                  | 大小   |
| ------------------------------------ | --------------------- | ------ |
| `evorule-x86_64-unknown-linux-musl`  | CI artifact / release | 1.8 MB |
| `evorule-aarch64-unknown-linux-musl` | CI artifact / release | 1.4 MB |
| `*.sha256`                           | 校验文件              | < 1 KB |
| AGPL-3.0 许可证文本                  | 随源码提供            | -      |
| 用户规则文件                         | 用户自备              | -      |

**目标交付命令**:

```bash
# Linux x86_64 圈 2 用户

wget https://gitee.com/evorule/evorule/releases/download/v0.3.1/evorule-x86_64
chmod +x evorule-x86_64
./evorule-x86_64 validate /etc/company-rules/
./evorule-x86_64 run /etc/company-rules/ -o /var/log/evorule-fact.log
./evorule-x86_64 verify-chain /var/log/evorule-fact.log

# Linux aarch64 圈 2 用户 (AWS Graviton / RPi)

wget https://gitee.com/evorule/evorule/releases/download/v0.3.1/evorule-aarch64
chmod +x evorule-aarch64
./evorule-aarch64 run /etc/company-rules/ -o /var/log/evorule-fact.log
```

---

## 端到端测试


`tests/e2e.sh` 是一个 TAP 格式的 e2e 测试,覆盖 5 个子命令的 28 个用例:

```bash
# 自动检测二进制

bash tests/e2e.sh

# 显式指定

bash tests/e2e.sh .build/rust/x86_64-unknown-linux-musl/release/evorule
bash tests/e2e.sh .build/rust/aarch64-unknown-linux-musl/release/evorule
```

测试覆盖:

```
ok 1   - --version exits 0
ok 2   - --help shows subcommands
ok 3   - validate valid rule exits 0
ok 4   - validate invalid rule exits 1
ok 5   - validate unknown-type errors
ok 6   - validate empty dir exits 2
ok 7   - validate nonexistent dir exits 2
ok 8   - run valid rule exits 0 with Stable fact
ok 9   - run with --payload exits 0
ok 10  - run with --payload-file exits 0
ok 11  - run -o writes JSONL with Command first line
ok 12  - run --max-steps 0 produces Error fact
ok 13  - replay exits 0 with Replaying header
ok 14  - replay nonexistent exits 1
ok 15  - diff identical logs
ok 16  - diff different logs shows differences
ok 17  - verify-chain valid log exits 0
ok 18  - verify-chain tampered log exits 1
ok 19  - all fact log lines are valid JSON with type+id
ok 20  - FIFO queue: step1 then step2 (order=second confirms FIFO)
ok 21  - deterministic loading: 3 files loaded in order, all fields set
ok 22  - verify-chain on echo log exits 0
ok 23  - validate hospital example rules
ok 24  - validate law-firm example rules
ok 25  - hospital example runs with payload (Stable)
ok 26  - law-firm example runs with payload (Stable)
ok 27  - hospital example produces IoRequest + Error (no handler in 0.2.0)
ok 28  - verify-chain on hospital log (complex facts) exits 0
```

**aarch64 验证**:用 `qemu-user-static` 模拟跑(不需要真 ARM 机器):

```bash
sudo apt install qemu-user-static
bash tests/e2e.sh .build/rust/aarch64-unknown-linux-musl/release/evorule
```

---

## 安全与验真


### `verify-chain` 哈希链验证


`evorule verify-chain <fact.log>` 同时做 **三重校验**,任何一项不通过立即返回退出码 1:

| 校验层        | 算法/规则                                                  | 失败原因                        |
| ------------- | ---------------------------------------------------------- | ------------------------------- |
| 结构完整性    | FactId 单调递增 + `cause` 引用必须指向已出现的 FactId      | 篡改 FactId 顺序 / 插入虚假因果 |
| BLAKE3 哈希链 | `chain_hash = blake3(prev_hash + content_hash + id_bytes)` | 修改任何已落盘 Fact 的 content  |
| WAL 格式      | 每行必须是合法 JSON,且含 `type` + `id` 字段                | 文件损坏 / 手工编辑             |

哈希算法**单一真相源**在 `evorule-reactor/src/hash.rs`,cli 与 evorule-governance 均 re-use 同一实现,避免分叉。

### 供应链可信:可重现构建


同源码两次 `cargo build --release`(同一 Rust toolchain、同一 target)产物 SHA256 一致。圈 2 监管方可独立从 GitHub/Gitee 拉源码构建,与官方 artifact 做 SHA 对比,无需信任分发渠道。

---

## 已知限制(0.3.1)


- ❌ 无 I/O handler(`io_request` 会产生 IoRequest fact + Error fact,不实际执行 I/O)
- ❌ 无 HTTP API(本 crate 是本地 CLI,不提供 HTTP 服务;如需 HTTP/SSE 由应用层基于核心仓机制自行构建)
- ❌ 无配置文件(后续加 `.evorule.toml`)
- ❌ 无 hot-reload(后续加)
- ✅ 0 网络 ✓
- ✅ 0 遥测 ✓
- ✅ 0 系统依赖(musl 静态链接)x2 架构 ✓
- ✅ 1.8 MB 单文件 ✓
- ✅ G8 门控(递归扫描 src/\*_/_.rs + strip_test_mod)✓
- ✅ blake3 哈希链(与 evorule-governance 交叉验证)✓
- ✅ 结构不变量校验(FactId 单调 + cause 引用)✓
- ✅ FIFO 队列(pop_front,修复原 LIFO bug)✓
- ✅ 确定性加载(文件名排序,跨平台一致)✓
- ✅ e2e 测试 28/28 ✓
- ✅ 可重现构建 ✓

---

## 架构


```
evorule-cli
├── src/
│   ├── main.rs          # 入口:tracing 初始化 + 子命令分发
│   ├── cli.rs           # clap derive 参数定义(5 个子命令)
│   ├── error.rs         # CliError 枚举 + 退出码映射(0/1/2)
│   ├── executor.rs      # 同步反应器循环(FIFO + max_steps + I/O 两阶段)
│   ├── fact_log.rs      # JSONL 读写(tier1 WAL 格式,fact_to_json/fact_from_json)
│   ├── hash.rs          # blake3 哈希链(复制自 evorule-governance,交叉验证)
│   ├── io_util.rs       # 规则加载(确定性排序)+ payload 解析 + 文件读写
│   ├── output.rs        # human-readable 格式化 + diff 前缀
│   └── commands/
│       ├── mod.rs       # 子命令模块声明
│       ├── validate.rs  # validate:core_eval 元指令白名单校验
│       ├── run.rs       # run:加载→执行→输出 fact log
│       ├── replay.rs    # replay:读 fact log → pretty-print
│       ├── diff.rs      # diff:按 FactId 数组下标对齐比对
│       └── verify_chain.rs # verify-chain:哈希链 + 结构不变量
├── build.rs             # G8/F11 编译期门控(递归扫描 + strip_test_mod)
├── tests/
│   ├── e2e.sh           # 28 个 TAP 端到端测试
│   └── fixtures/        # 测试 fixtures(valid/invalid/unknown-type/empty/echo/fifo/multi)
└── examples/            # 圈 2 合规模板(hospital/law-firm)
```

**依赖范围**:

- `evorule-tcb`(纯函数 `execute_transition`)—— 核心 TCB
- `evorule-reactor`(`Fact`/`FactId`/`IoType`/`wal`/`serde_to_tcb`)—— Fact 序列化
- `blake3` —— 哈希链(复制自 evorule-governance,避免拉入 axum/sqlx/reqwest 破坏 musl)
- 不依赖 `evorule-governance`(避免破坏 musl 静态链接)
- 不创建 tokio runtime(`execute_transition` 是同步纯函数)

---

## CI 集成


中文版 Gitee Go CI (`.gitee-ci/`) 自动构建并上传产物到 Gitee release:

| Workflow                        | 触发                            | 输出                                              |
| ------------------------------- | ------------------------------- | ------------------------------------------------- |
| `.gitee-ci/ci.yml`              | push / PR (main, master, release/\*\*) | Linux + Windows 全量测试 + e2e + TCB 确定性 |
| `.gitee-ci/release.yml`         | tag `v*`                        | Linux x86_64 (musl) + Linux aarch64 (musl) + Windows x86_64 二进制 + SHA256 → Gitee release |

每个 build stage 内置 G8 门禁校验(通过 evorule-tcb / evorule-cli build.rs 自动执行)。

**macOS 二进制**:Gitee Go 无 macOS runner,由未来英文版仓库(GitHub Actions)发布。
**GitHub 关系**:本仓库不向 GitHub 镜像(`不做镜像`),英文版将独立仓库发布。

---

## 配套工具


- **`core_eval.json`** —— 宪法文件(默认在 `evorule-tcb/core_eval.json`)
- **可视化时间旅行调试器** —— 后续做(可视化版 replay,由应用层实现)

---

## v0.3.2 更新


- **`verify_hash_chain` 已删除**: 原函数始终返回 `true` 是"假验证"陷阱,已彻底删除。替代方案:用 `verify-chain` 命令读取带哈希字段的 WAL 并逐一校验
- **`validate` 元指令白名单修正**: 仅 6 种真元指令(branch/set/push/io_request/collect/merge)。noop/increment/decrement 是指令层类型,不是元指令,不得混入白名单
- **build.rs 新增 L1b 变更治理门禁**: CHANGE_REQUEST.md 必须存在且审查状态为"已批准"/"紧急通过";新增策略层反模式检测
- **`EVORULE_SKIP_CR_GATE=1`** 环境变量可跳过 L1b 变更治理门禁(仅限本地开发)

## 参见(项目级治理文档)


- [**DOCS_INDEX.md**]../DOCS_INDEX.md —— **所有 L1 公开文档的唯一入口(必读)**
- [`README.md`]../README.md —— EvoRule 主入口,三层架构 + 快速开始
- [`CONTRIBUTING.md`]../CONTRIBUTING.md —— 贡献流程
- [`CODE_OF_CONDUCT.md`]../CODE_OF_CONDUCT.md —— 社区行为准则
- [`CLA-individual.md`]../CLA-individual.md —— 个人贡献者许可协议
- [`VERSION_STRATEGY.md`]../VERSION_STRATEGY.md —— 版本号标准
- `docs/constitution.md`(待发布)—— evorule 仓治理结构(治理模型/决策层级/贡献者阶梯)
- `docs/oss_strategy.md`(待发布)—— 开源治理策略(AGPL-3.0 解释 + 商业 license 路径)
- 安全审计基线(待发布,1.0 升门时提供)
- 威胁模型(待发布,1.0 升门时提供)