aps-agent/docs/round-8-audit-mirror-plan.md

92 lines
5.3 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.

# 第 8 轮工作计划(轻量合并版):审计事件独立介质镜像(AuditMirror)
更新日期:2026-08-01
## 1. 本轮目标
新增审计事件独立介质镜像:`APS_AUDIT_MIRROR=1` 启用时,`write_audit` 在写世界内 `auditEvents` 的同时,把每条审计事件同步追加到独立 append-only JSONL 镜像(按租户/项目隔离);`/api/gov/audit` 优先读取镜像(事件以镜像为准),业务进程修改 world 无法抹掉独立介质证据;矩阵 116 行「审计 append-only 且可检测篡改」剩余项(业务进程不可改写历史事件/独立介质)前进一步。
## 2. 背景和当前状态
- 当前已完成:第 6 轮 AuditLedger 锚定根(篡改可检测,但审计事件本体仍只存 world 内);`verify_audit_chain` 链式校验;`write_audit` 105 个调用点统一走同一函数。
- 当前缺口:审计事件只存世界内 `auditEvents`,业务进程改 world 可抹掉历史(虽会被锚定根揭穿,但证据本体缺失);无独立介质事件副本。
- 本轮为什么现在做:矩阵 116 行剩余「业务进程也无法修改历史事件;独立介质」;本地可验证(显式启用 + tmp 目录)。
- Workspace preflight:第 7 轮收口(451 passed);服务 8003/5173 正常;共享脏工作区、无提交。
- 方向分析:Q1 推荐选项 B(审计事件独立存储镜像),目标续跑轮授权执行。
## 3. 本轮工作方向
```text
write_audit 只写 world auditEvents(105 调用点)
-> audit_mirror.py:AuditMirror append-only JSONL(按租户/项目隔离,原子追加)
-> write_audit 条件镜像(APS_AUDIT_MIRROR=1;失败不影响业务写)
-> /api/gov/audit 优先读镜像(有镜像以镜像为准,无镜像回退 world)
-> 黄金测试:镜像追加、改 world 不影响镜像、隔离、启用/禁用
-> 矩阵 116 行注记;CHANGELOG
```
## 4. 已确认决策
任务重量:
- 档位:轻型(audit_mirror 新模块 + write_audit 条件分支 + 网关读取优先 + 黄金测试)。
- 规模依据:调用点签名不变(0 处调用点改动);改动集中在 audit.py(1 处定义)+ gateway(1 处读取)+ 新模块;风险 LOW。
- 选择原因:独立介质是矩阵 116 行明确剩余项;镜像方案避免 105 处签名重构。
P0/P1 决策(按 Q1 推荐采纳):
- 决策 1(P0):本轮切片 = 审计事件独立介质镜像(选项 B)。
- 决策 2(P1):不新建分支、不提交、不推送。
- 决策 3(P1):验证深度 = 聚焦 audit_mirror 测试 + 全量黄金回归。
默认假设:
- 假设 1:镜像默认关闭(`APS_AUDIT_MIRROR=1` 显式启用),避免侵入未配置环境与常规测试;生产启用由运维显式开启。
- 假设 2:镜像文件路径 `APS_AUDIT_MIRROR_DIR` 或 `server/data/audit-mirror/<tenant>/<world>.jsonl`;写入失败仅记日志不影响业务(镜像尽力而为,主证据仍在 world+锚定)。
- 假设 3:`/api/gov/audit` 有镜像时事件列表以镜像为准(且镜像计数≥world 时用镜像),否则回退 world(兼容旧数据)。
- 假设 4:镜像行 `{event, mirroredAt}` 保留完整事件 JSON,供链校验与锚定复用。
未决但不阻塞:镜像 WORM 介质/加密、自动清理策略、跨进程锁强化(后续轮)。
## 5. 范围
In scope:
- `server/agent_core/audit_mirror.py`(新):`AuditMirror.append_event(event)` / `read_events()` / `count()`,按租户/项目隔离。
- `server/agent_core/audit.py`:`write_audit` 在返回前,若 `APS_AUDIT_MIRROR=1` 则调用镜像追加(try/except 容错)。
- `server/gateway/app.py`:`gov_audit` 优先读镜像(镜像存在且非空时以镜像为事件源)。
- `tests/golden/test_audit_mirror.py`(新):镜像追加/读取、改 world 不影响镜像、租户隔离、启用/禁用开关、链校验仍可作用于镜像事件。
- 文档:`docs/architecture/harness.md`、`docs/product/plan-completion-matrix.md`(116 行注记)、`docs/CHANGELOG.md`。
Out of scope:
- 105 处调用点签名重构、WORM/加密、清理策略、跨进程锁强化。
- 提交/推送/合并/清理用户改动。
## 6. 成功标准
- 聚焦:`python -m pytest -q tests/golden/test_audit_mirror.py -p no:cacheprovider` 通过(≥4 项)。
- 全量:`python -m pytest tests/golden -q -p no:cacheprovider`(固定 .venv)≥ 451。
- ruff 干净;git diff --check 无空白错误。
## 7. 验证方式
- audit_mirror 单测(追加/读取/隔离/开关/篡改);gov_audit 镜像优先 API 测试;全量回归。
## 8. 关键风险
| 风险 | 影响 | 控制方式 |
|---|---|---|
| 镜像写入失败影响业务 | 审计丢失但业务中断 | try/except 容错,仅记日志 |
| 测试污染共享目录 | 断言漂移 | tmp 目录 + 环境变量隔离 |
| 镜像与 world 不一致 | 读取歧义 | gov_audit 有镜像以镜像为准 + 测试锁定 |
## 9. 停止条件
- 全量黄金测试非本轮相关回归无法快速定位时暂停。
- 任何提交/推送/合并/清理操作停下等待授权。
## 10. 本轮完成定义
- 实现、测试、文档完成;聚焦与全量通过;矩阵/CHANGELOG 回写;不提交。
- 收口:报告主要结论、关键洞察、需要特别留意的地方。
## 11. 下一步
轻量合并版:主 agent 实现 + 验证 + 收口报告。