# MoonAnsi Guard 集成指南

这份文档说明 MoonAnsi Guard 可以怎样接入真实工程。项目定位是库，不是独立平台，因此重点是给上层系统提供安全文本和结构化审计结果。

## CI 日志

适用场景：构建服务展示第三方脚本输出、开源项目测试日志或远程执行结果。

推荐流程：

1. 捕获 stdout 和 stderr。
2. 调用 `scan(output)`。
3. 保存 `result.text()` 作为可展示日志。
4. 保存 `result.findings()` 作为审计记录。
5. 如果 `result.risk_level()` 为 `high`，在页面上提示用户查看安全原因。

## AI Agent 工具调用

适用场景：AI Agent 调用 shell、构建工具、包管理器、测试工具后，把输出返回给用户。

推荐流程：

1. 工具调用完成后，不直接把原始输出拼进回复。
2. 先调用 `scan(output)`。
3. 模型只读取或展示 `result.text()`。
4. 将高危 findings 附加到工具调用元数据中，供前端或审计系统展示。

## Web 日志平台

适用场景：把终端输出展示在网页、仪表盘、工单系统或告警系统中。

推荐流程：

1. 后端统一清洗原始日志。
2. 前端只展示安全文本。
3. 风险列表用标签、侧栏或折叠面板展示。
4. 结合 `risk_score()` 做排序，让高风险日志优先进入人工复核。

## 示例代码

```moonbit
let result = @ansi_guard.scan(untrusted_output)

if result.risk_level() == "high" {
  println("blocked: terminal output needs review")
} else {
  println(result.text())
}
```

如果希望保留可信日志中的颜色：

```moonbit
let result = @ansi_guard.scan_with_policy(
  trusted_output,
  @ansi_guard.Policy::styled(),
)
```

## 流式进程输出

进程、WebSocket、SSH 代理和 AI Agent 工具通常按数据块产生输出。控制序列可能跨越数据块边界，不能逐块独立调用 `scan`。

```moonbit
let scanner = @ansi_guard.StreamScanner::new(
  policy=@ansi_guard.Policy::agent(),
)
let session = @ansi_guard.AuditSession::new()

for chunk in output_chunks {
  session.record(scanner.feed(chunk))
}
session.record(scanner.finish())

let result = session.result()
```

`StreamScanner` 只缓存尚未结束的尾部控制序列，普通文本和完整序列会立即处理。所有命中记录的偏移均相对于完整逻辑输入。

## 自动化安全门禁

```moonbit
let gate = @ansi_guard.GatePolicy::balanced()
let decision = result.decide_with(gate)

match decision {
  @ansi_guard.Allow => publish(result.text())
  @ansi_guard.Review => request_review(result.summary())
  @ansi_guard.Block => reject_output(result.summary())
}
```

`GatePolicy::strict()` 适合公开 CI，`balanced()` 适合常规 Agent，`permissive()` 适合可信内部终端。还可以通过 `GatePolicy::new` 配置分数、命中数量和指定类型阻断规则。

## JSON 与报告脱敏

完整报告可能包含剪贴板或文件传输载荷。生产环境建议默认使用脱敏模式：

```moonbit
let json = result.json_report_with(@ansi_guard.ReportPolicy::redacted())
```

- `full()`：完整诊断内容；
- `bounded()`：保留内容但限制长度；
- `redacted()`：保留安全文本，隐藏捕获的控制序列；
- `metadata_only()`：只保留分类、偏移、分数和决策元数据。

## 验收建议

评审或使用者可以用 `examples/attack-cases.md` 中的样例构造输入，并检查：

- 安全文本是否保留了可读内容；
- 高危序列是否被删除；
- 风险分类是否准确；
- `risk_level()` 是否符合预期；
- 跨数据块控制序列是否仍能被识别；
- 门禁策略是否给出可解释的阻断或复核原因；
- 脱敏报告是否不会重复记录敏感载荷；
- 项目测试是否全部通过。
