refactor(middleware): 移除数据脱敏中间件及相关代码
Some checks failed
CI / Lint & TypeCheck (push) Has been cancelled
CI / Unit Tests (push) Has been cancelled
CI / Build Frontend (push) Has been cancelled
CI / Rust Check (push) Has been cancelled
CI / Security Scan (push) Has been cancelled
CI / E2E Tests (push) Has been cancelled

移除不再使用的数据脱敏功能,包括:
1. 删除data_masking模块
2. 清理loop_runner中的unmask逻辑
3. 移除前端saas-relay-client.ts中的mask/unmask实现
4. 更新中间件层数从15层降为14层
5. 同步更新相关文档(CLAUDE.md、TRUTH.md、wiki等)

此次变更简化了系统架构,移除了不再需要的敏感数据处理逻辑。所有相关测试证据和截图已归档。
This commit is contained in:
iven
2026-04-22 19:19:07 +08:00
parent 14f2f497b6
commit fa5ab4e161
68 changed files with 8049 additions and 3684 deletions

View File

@@ -0,0 +1,246 @@
# ZCLAW 发布前审计设计文档
> 日期: 2026-04-18
> 目标: 全维度审计系统问题,为首次用户发布做准备
> 方法: 4 专家组并行分析 + 交叉评审
## 背景
ZCLAW 已完成稳定化基线,进入发布准备阶段。在发布前组织了一次多维度深度审计,通过 4 个专家代理(后端稳定性、前端质量、安全与数据、工程卫生)并行分析,发现并验证了 24 个问题点。经交叉评审后纠正了 4 项原始审计误判。
## 审计纠正(原始误判)
| 原始声称 | 实际情况 |
|----------|----------|
| Cargo.lock 缺失 | 已提交并跟踪,`git ls-files Cargo.lock` 确认 |
| 无 CI/CD | `.github/workflows/ci.yml` + `release.yml` 完整存在 |
| src-tauri LOC 偏差 3x | 实际 61,257 行,与 TRUTH.md ~61,400 基本一致 |
| Token INTEGER 溢出 | 每行存单次请求 token 不溢出SUM() 已返回 BIGINT |
---
## 第一层:发布阻塞项(必须修复)
### 1. Director 死锁风险 — P0 CRITICAL
**文件**: `crates/zclaw-kernel/src/director.rs:506-536`
**问题**: `send_to_agent()` 顺序获取 `pending_requests.lock()`L506`inbox.lock()`L519后者在 `tokio::time::timeout` 内跨 `rx.recv().await` 持有L521-536。两个并发调用可互相阻塞。另有一条死信通道 `_response_tx/_response_rx`L490从未连接——sender 存入 pending_requests 但 receiver 无人读取。
**验证**: 修复后需添加并发 `send_to_agent()` 测试验证死锁消除。
**修复方案**: 用 `oneshot` channel 重构响应接收模式:
- 每次 `send_to_agent()` 创建 `oneshot::channel`
- sender 存入 `pending_requests`receiver 配合 `tokio::time::timeout` 等待
- 新增独立的 inbox 消费任务分发响应到对应 oneshot sender
- 变更 `pending_requests` 类型为 `HashMap<String, oneshot::Sender<A2aEnvelope>>`
**工时**: 2-4h重构 + 测试更新)
### 2. Pipeline Executor 内存泄漏 — P0 HIGH
**文件**: `crates/zclaw-pipeline/src/executor.rs`
**问题**: `runs: RwLock<HashMap<String, PipelineRun>>``cancellations: RwLock<HashMap<String, bool>>` 无限增长,无清理路径。
**修复方案**:
- 添加 `cleanup(max_age: Duration)` 方法,清除已完成/失败/取消的旧记录
-`execute_with_id()` 完成后自动调用清理
- 设置 `max_completed_runs` 上限(如 100超限淘汰最旧记录
**工时**: <1h
### 3. Pipeline 步骤超时缺失 + Delay 无上限 — P0 HIGH
**文件**: `crates/zclaw-pipeline/src/executor.rs`
**问题**: `ExecuteError::Timeout` 已定义但从未触发每步执行无超时包装`Action::Delay { ms }` 接受原始 u64恶意 YAML 可设 `ms: u64::MAX`
**修复方案**:
- `tokio::time::timeout` 包装每步 `execute_action` 调用
- 使用 `PipelineSpec.timeout_secs`已存在但未使用cap 5 分钟
- Delay ms 上限 60000超出时 warn 并截断
- `parser.rs`/`parser_v2.rs` 添加 YAML 解析时验证
**工时**: 1-2h
### 4. TRUTH.md Hands 数量偏差 — P0 (文档完整性)
**文件**: `docs/TRUTH.md`, `CLAUDE.md`
**问题**: 声称 9 Hand 启用实际 kernel 注册 7
- 6 个通过 `hands/*.HAND.toml` 扫描注册Browser/Clip/Collector/Quiz/Researcher/Twitter
- 1 个通过 `kernel/mod.rs:96` 编程注册ReminderHand`_` 前缀豁免 HAND.toml 扫描 `trigger_manager.rs:139`
- Whiteboard/Slideshow/Speech HAND.toml 仅存在于 `.claude/worktrees/` 开发分支 `impl Hand for`未合并到主分支
**修复方案**:
- TRUTH.md: 更新为 "6 HAND.toml + Reminder 系统内部 = 7 注册"
- CLAUDE.md §6: 明确标注 Whiteboard/Slideshow/Speech "开发中未合并"
- 确认桌面 UI 是否展示 9 Hand如有则同步更新
**工时**: <1h
### 5. rate_limit_events 清理 Worker 是空壳 — P0 (数据膨胀)
**文件**: `crates/zclaw-saas/src/workers/cleanup_rate_limit.rs`
**问题**: Worker body no-op注释说"rate limit entries are in-memory" main.rs batch flush 确实将限流条目写入数据库注意内存中的 DashMap 清理每 300 秒运行一次`state.rs:118`**数据库持久化条目**无限增长无任何删除机制
**修复方案**: 实现 Worker body执行 `DELETE FROM rate_limit_events WHERE created_at < NOW() - INTERVAL '1 hour'`确认调度器已注册此 Workermain.rs:47 已注册)。
**工时**: <1h
---
## 第二层:强烈建议修复
### 6. TypeScript 编译排除安全关键文件
**文件**: `desktop/tsconfig.json`
**问题**: 排除了 `ErrorAlert.tsx`文件已不存在残留排除项 `ErrorBoundary.tsx`527 行安全关键组件)。
**修复**: 删除排除项运行 `tsc --noEmit` 验证 ErrorBoundary 无类型错误
**工时**: <1h
### 7. LlmConfig api_key Debug 泄露
**文件**: `crates/zclaw-kernel/src/config.rs`
**问题**: `#[derive(Debug)]` 会在 `format!("{:?}", config)` 中打印 api_key 明文虽然当前无代码 Debug-print 此结构但日志调试时容易触发
**修复**: 移除 `Debug` derive实现自定义 `Debug` impl `"***REDACTED***"` 遮蔽 api_key
**工时**: <30min
### 8. 关键 .unwrap() 调用
**文件**:
- `crates/zclaw-saas/src/billing/handlers.rs:598` Response builder unwrap
- `desktop/src-tauri/src/classroom_commands/mod.rs:58` db_path.parent().unwrap()
**修复**: 替换为 `map_err` + `?` 传播
**工时**: <1h
### 9. 静默吞错关键集群
**文件与修复**:
- `crates/zclaw-kernel/src/kernel/approvals.rs:88,93,124` 已有 `tracing::warn!` 日志但级别应为 `error`审批状态丢失是严重事件
- `crates/zclaw-protocols/src/mcp_transport.rs:429` 记录僵尸进程风险
- `crates/zclaw-kernel/src/events.rs:21` `tracing::debug!("Event dropped: {:?}", e)`
- `crates/zclaw-runtime/src/tool/builtin/task.rs` 日志记录 subtask 事件丢失
- `crates/zclaw-growth/src/storage/sqlite.rs` 迁移 匹配 `sqlx::Error::Database` 检查 SQLite 错误码 1 子错误 "duplicate column name"区分幂等迁移与真实错误
**工时**: 2-4h
### 10. 缺失数据库索引
**新文件**: `crates/zclaw-saas/migrations/20260418000001_add_missing_indexes.sql`
```sql
CREATE INDEX IF NOT EXISTS idx_rle_created_at ON rate_limit_events(created_at);
CREATE INDEX IF NOT EXISTS idx_billing_sub_plan ON billing_subscriptions(plan_id);
CREATE INDEX IF NOT EXISTS idx_ki_created_by ON knowledge_items(created_by);
```
**工时**: <1h
### 11. 配置验证缺失
**文件**: `crates/zclaw-saas/src/config.rs`
**修复**: `SaaSConfig::load()` 添加
- `jwt_expiration_hours >= 1`
- `max_connections > 0`
- 改善默认 DB URL 连接失败的错误信息
**工时**: <1h
### 12. MCP Transport 响应错配
**文件**: `crates/zclaw-protocols/src/mcp_transport.rs`
**问题**: stdin/stdout 分离的 Mutex 可导致并发请求收到错误响应
**修复**: 合并 stdin + stdout 为单一 Mutex write-then-read 周期内持有锁
**工时**: 3-4h
---
## 第三层:可延后至首个补丁
| # | 问题 | 工时 |
|---|------|------|
| 13 | console.log 清理105处createLogger | 2-3h |
| 14 | ChatStore 双源真相重构 | 2-4h |
| 15 | 33处内联样式Tailwind | <1h |
| 16 | SaaS mixin `prototype: any` 类型约束 | <1h |
| 17 | serde_yaml 统一到 serde_yaml_bw | 1-2h |
| 18 | 32处 dead_code 审查清理 | 2-4h |
| 19 | webhook 废弃表删除迁移 | <30min |
| 20 | A2A feature gate 或移除 feature 定义 | <30min |
| 21 | dependency 内联声明workspace 引用 | 1-2h |
| 22 | KernelGrowth 隐式依赖显式化 | <30min |
| 23 | noUncheckedIndexedAccess 添加 | 2-4h |
| 24 | handStore/configStore duck-typingdiscriminator | <1h |
---
## TRUTH.md 数值校准清单
| 指标 | 当前值 | 应更正为 | 验证命令 |
|------|--------|----------|----------|
| #[test] (crates) | 433 | 425 | `grep -rn '^\s*#\[test\]\s*$' crates/ --include="*.rs" \| wc -l` |
| #[tokio::test] (crates) | 368 | 309 | `grep -rn '^\s*#\[tokio::test\]' crates/ --include="*.rs" \| wc -l` |
| Zustand Store | 21 | 26 (含子目录) | `find desktop/src/store/ -name "*.ts" \| wc -l` |
| Admin V2 页面 | 15 | 17 | `ls admin-v2/src/pages/*.tsx \| wc -l` |
| Pipeline YAML | 17 | 18 | `find pipelines/ -name "*.yaml" \| wc -l` |
| Hands 启用 | 9 | 7 (6 HAND.toml + Reminder) | `ls hands/*.HAND.toml \| wc -l` + kernel registry |
---
## 实施计划
### Batch 1: 发布阻塞修复 (Day 1, 上午 + 下午)
按依赖顺序执行总工时 ~6-9h建议分上下午
1. Pipeline 超时 + 内存泄漏 + Delay 上限#2, #3)— 上午
2. Director 死锁修复#1)— 上午可并行
3. rate_limit_events Worker 实现#5)— 下午
4. TRUTH.md + CLAUDE.md 数值校准#4)— 下午
**验证**: `cargo test --workspace --exclude zclaw-saas` + `tsc --noEmit`
### Batch 2: 强烈建议修复 (Day 2)
5. tsconfig 修复#6
6. LlmConfig Debug 遮蔽#7
7. 关键 unwrap 修复#8
8. 静默吞错修复 关键集群#9
9. 缺失索引迁移#10
10. Config 验证#11
11. MCP Transport 锁合并#12
**验证**: `cargo test --workspace --exclude zclaw-saas` + `pnpm tsc --noEmit` + `pnpm vitest run`
### Batch 3: 补丁迭代 (Day 3+)
按优先级从高到低处理第三层 12
---
## 关键文件列表
- `crates/zclaw-kernel/src/director.rs` P0 Director 死锁
- `crates/zclaw-pipeline/src/executor.rs` P0 Pipeline 内存泄漏 + 超时
- `crates/zclaw-saas/src/workers/cleanup_rate_limit.rs` P0 Worker 空壳
- `docs/TRUTH.md` P0 文档校准
- `desktop/tsconfig.json` P1 类型排除
- `crates/zclaw-kernel/src/config.rs` P1 Debug 泄露
- `crates/zclaw-saas/src/billing/handlers.rs` P1 unwrap
- `desktop/src-tauri/src/classroom_commands/mod.rs` P1 unwrap
- `crates/zclaw-protocols/src/mcp_transport.rs` P1 响应错配
- `crates/zclaw-saas/src/config.rs` P1 配置验证