# ZCLAW 全面功能审计报告 V11 > **审计日期**: 2026-04-02 > **审计范围**: 10 Rust crate + desktop 前端 + admin-v2 管理后台 > **基线**: V10 审计追踪(20 项发现) --- ## 1. 执行摘要 ### 关键指标 | 指标 | 数值 | 文档值 | 状态 | |------|------|--------|------| | Tauri 命令(注册) | 175 | 58+ / 130+ | 文档不一致 | | Tauri 命令(有前端调用) | ~90 | - | 51% 利用率 | | SKILL.md | 76 | 66/75/77 | 文档不一致 | | Hands | 9 目录 | 11 | CLAUDE.md 与实际不一致 | | Zustand Stores | 15 | 14 | 文档偏差 | | SaaS API 路由 | 58 | 72+ | 文档偏高 | | Admin-v2 页面 | 12 | 11 | 文档偏低 | | 源文件 | 233 (.rs) + 122 (.tsx) + 15 (.ts store) | - | - | ### V10→V11 状态变更 | V10 ID | V11 状态 | 说明 | |--------|----------|------| | BREAK-02 | **关闭** | 记忆提取通过 MemoryMiddleware.after_completion 正常触发 | | BREAK-03 | **关闭** | approval_respond 自动 spawn tokio task 执行 Hand | | BREAK-04 | **关闭** | pipeline-complete 在 discovery.rs:165 emit,前端有监听器 | | BREAK-01 | 已修复 | 保持 CLOSED | --- ## 2. 发现项索引 ### P1: 严重级(3 项) | ID | 问题 | 文件 | 验证方法 | |----|------|------|----------| | V11-P1-01 | trigger_update 参数不匹配,更新静默失败 | `desktop/src/lib/kernel-triggers.ts:99` → `desktop/src-tauri/src/kernel_commands/trigger.rs:183-189` | 前端发 `{id, updates:{...}}` 但 Rust 期望扁平参数 | | V11-P1-02 | SaaS 配置同步不传播到 Rust Kernel | `desktop/src/store/saasStore.ts:484-541` | localStorage 写入但 Kernel 无读取路径 | | V11-P1-03 | 3 个 SQL 表零读取:prompt_sync_status, telemetry_reports, key_usage_window | `crates/zclaw-saas/src/db.rs` 迁移定义 | `grep -rn "SELECT.*FROM.*" crates/zclaw-saas/src/` 零结果 | ### P2: 高优先级(6 项) | ID | 问题 | 文件 | |----|------|------| | V11-P2-01 | saas-admin.ts 30 方法零消费者(admin-v2 独立 Axios 实现) | `desktop/src/lib/saas-admin.ts` | | V11-P2-02 | 7 个 Role/Permission 路由无前端消费者 | `crates/zclaw-saas/src/role/mod.rs` | | V11-P2-03 | deprecated gateway-storage sync 方法仍被生产代码调用 | `desktop/src/lib/gateway-storage.ts:129,196` | | V11-P2-04 | ToolDefinition 在 types 和 runtime 重复定义 | `crates/zclaw-types/src/tool.rs:8` vs `crates/zclaw-runtime/src/driver/mod.rs:94` | | V11-P2-05 | 62 个 Tauri 命令无前端调用(含 8 classroom 命令中 7 个未调用) | `desktop/src-tauri/src/lib.rs:124-323` | | V11-P2-06 | migration/service.rs config_items 查询缺少 LIMIT | `crates/zclaw-saas/src/migration/service.rs` | ### P3: 中优先级(8 项) | ID | 问题 | 文件 | |----|------|------| | V11-P3-01 | audit-logger.ts 导出但零 import | `desktop/src/lib/audit-logger.ts` | | V11-P3-02 | OFP 能力定义无消费者 | `crates/zclaw-types/src/capability.rs:28-32` | | V11-P3-03 | deprecated extract_structured_facts() 零调用但未移除 | `crates/zclaw-runtime/src/growth.rs:224` | | V11-P3-04 | SaaS knowledge 模块 3 个 handler 返回空数据 | `crates/zclaw-saas/src/knowledge/handlers.rs:91,293,321` | | V11-P3-05 | Director (multi-agent) 912 行 feature-gated 未启用 | `crates/zclaw-kernel/src/director.rs` | | V11-P3-06 | 定时任务执行结果未持久化 | `crates/zclaw-saas/src/scheduler.rs:147-225` | | V11-P3-07 | secure-storage.ts 3 个 deprecated sync 方法零调用 | `desktop/src/lib/secure-storage.ts:309,317,325` | | V11-P3-08 | SaaS config 2 个预留参数未消费 | `crates/zclaw-saas/src/config.rs:122,125` | ### P4: 低优先级(5 项) | ID | 问题 | 文件 | |----|------|------| | V11-P4-01 | ContentBlock 4 处定义(不同域,非 bug 但名称混淆) | types/message.rs, runtime/driver/mod.rs, hands/slideshow.rs, protocols/mcp_types.rs | | V11-P4-02 | Desktop ↔ Admin 13+ 类型名称不一致 | `desktop/src/lib/saas-types.ts` vs `admin-v2/src/types/index.ts` | | V11-P4-03 | 文档数字不一致(Skills 76 vs 66/75/77) | 多个文档 | | V11-P4-04 | A2A/WASM feature-gated 代码未启用 | `crates/zclaw-protocols/src/a2a.rs`, `crates/zclaw-skills/src/wasm_runner.rs` | | V11-P4-05 | embedding 生成已禁用(注释掉) | `crates/zclaw-saas/src/workers/generate_embedding.rs:92` | ### Info: 保留不变(V10 继承) | V10 ID | 状态 | 说明 | |--------|------|------| | DEAD-01 | FALSE_POSITIVE | PromptInjector 已通过 PromptBuilder 接入 | | DEAD-02 | FALSE_POSITIVE | MemoryRetriever 已通过 MemoryMiddleware 接入 | | DEAD-03 | FALSE_POSITIVE | GrowthTracker 已通过 GrowthIntegration 接入 | | SEC-V9-01 | FALSE_POSITIVE | SQL 仅构建 $N 占位符 | --- ## 3. Rust Crate 能力矩阵 | Crate | 源文件 | 行数 | 公开项 | Feature-Gate | Dead Code | Deprecated | 测试 | |-------|--------|------|--------|-------------|-----------|------------|------| | zclaw-types | 10 | 1,741 | 86 | 0 | 0 | 0 | 57 | | zclaw-memory | 5 | 1,333 | 36 | 0 | 0 | 0 | 25 | | zclaw-runtime | 35 | 9,145 | 188 | 0 | 5 | 1 | 42 | | zclaw-kernel | 25 | 8,185 | 225 | 22 (multi-agent) | 3 | 0 | 52 | | zclaw-skills | 15 | 4,057 | 116 | 4 (wasm) | 0 | 0 | 22 | | zclaw-hands | 14 | 7,501 | 140 | 0 | 0 | 0 | 155 | | zclaw-protocols | 5 | 1,697 | 104 | 2 (a2a) | 1 | 0 | 5 | | zclaw-pipeline | 23 | 7,502 | 200 | 0 | 1 | 0 | 59 | | zclaw-growth | 14 | 4,732 | 137 | 0 | 2 | 0 | 66 | | zclaw-saas | 87 | 14,949 | 489 | 0 | 2 | 0 | 17 | | **合计** | **233** | **64,842** | **1,621** | **28** | **14** | **1** | **500** | ### Trait 实现完整性 | Trait | 定义位置 | 实现数 | 状态 | |-------|----------|--------|------| | LlmDriver | zclaw-runtime/driver/mod.rs | 4 | 完整 | | Tool | zclaw-runtime/tool.rs | 7 | 完整 | | Hand | zclaw-hands/hand.rs | 9 | 完整 | | Exporter | zclaw-kernel/export/mod.rs | 4 | 完整 | | McpClient | zclaw-protocols/mcp.rs | 2 | 完整 | | A2aClient | zclaw-protocols/a2a.rs | 1 (gated) | Feature-gated | | FactStore | zclaw-memory/fact.rs | **0** | **未实现** | | Worker | zclaw-saas/workers/mod.rs | 7 | 完整 | --- ## 4. 数据流验证结果 ### Flow A: 聊天 → 记忆提取 ✅ WORKING ``` chat.rs:246 (LoopEvent::Complete) → loop_runner.rs:798 (run_after_completion) → MemoryMiddleware.after_completion (middleware/memory.rs:101) → GrowthIntegration.extract_combined (growth.rs:279) → MemoryExtractor.extract + store_memories ``` Tauri `post_conversation_hook` 不重复提取,仅处理心跳+反思。 ### Flow B: 审批 → Hand 自动执行 ✅ WORKING ``` approval.rs:52 → kernel.respond_to_approval (approvals.rs:55) → tokio::spawn (approvals.rs:71) → hands.execute (approvals.rs:99) → emit "hand-execution-complete" (approval.rs:84-137) ``` ### Flow C: Pipeline 完成事件 ✅ WORKING ``` Rust emit: discovery.rs:165 → app.emit("pipeline-complete", ...) Frontend listen: pipeline-client.ts:257 → PipelinesPanel.tsx:383 ``` ### Flow D: SaaS 配置同步 ❌ BROKEN ``` saasStore.ts:484 → saasClient.pullConfig → localStorage write ⚠️ 无传播路径到 Rust Kernel ``` 配置变更停留在 `localStorage`,Kernel 独立读取 TOML 文件,不受 SaaS 配置同步影响。 --- ## 5. Admin-v2 审计 ### 页面与 API 对齐 | 页面 | Service 文件 | API 调用数 | 状态 | |------|-------------|-----------|------| | Login | auth.ts | 2 | 完整 | | Dashboard | stats.ts | 1 | 完整 | | Accounts | accounts.ts | 4 | 完整 | | ModelServices | providers.ts + models.ts | 11 | 完整 | | Config | config.ts | 2 | 完整 | | Relay | relay.ts | 2 | 完整 | | Logs | logs.ts | 1 | 完整 | | Prompts | prompts.ts | 7 | 完整 | | Usage | usage.ts | 2 | 完整 | | Billing | billing.ts | 6 | 完整 | | AgentTemplates | agent-templates.ts | 5 | 完整 | | Knowledge | knowledge.ts | 15 | 完整(后端有 3 个 stub handler) | ### 类型一致性 Desktop ↔ Admin-v2 之间存在 13+ 类型名称不一致(详见 V11_GAP_ANALYSIS.md)。 3 个有意义的字段差异: 1. `AccountPublic.llm_routing`: desktop 可选 vs admin 必填 2. `TokenInfo` nullability: `string | null` vs `string | undefined` 3. `PromptVariable.type`: `string` vs `'string'|'number'|'select'|'boolean'` --- ## 6. 孤立路由清单 | 路由 | 模块 | 原因 | |------|------|------| | POST /api/v1/auth/logout | auth | 无消费者 | | GET /api/v1/config/analysis | migration | 无消费者 | | POST /api/v1/config/seed | migration | 无消费者 | | GET /api/v1/config/sync-logs | migration | 无消费者 | | GET /api/v1/usage (model_config) | model_config | 无消费者 | | GET/POST /api/v1/roles | role | 无 admin-v2 service | | GET/PUT/DELETE /api/v1/roles/:id | role | 无 admin-v2 service | | GET/POST /api/v1/permission-templates | role | 无 admin-v2 service | | GET/DELETE /api/v1/permission-templates/:id | role | 无 admin-v2 service | | POST /api/v1/permission-templates/:id/apply | role | 无 admin-v2 service | | GET /api/v1/roles/:id/permissions | role | 无 admin-v2 service | --- ## 7. 验证命令 ```bash # Skills 计数 ls skills/ | wc -l # 预期: 76 # Hands 计数 ls hands/ | wc -l # 预期: 9 # Tauri 命令计数 grep -c "#\[tauri::command\]" desktop/src-tauri/src/ -r --include="*.rs" # 预期: 175 # 死代码验证 grep -rn "from.*audit-logger" desktop/src/ --include="*.ts" # 预期: 0 结果 # 孤立表验证 grep -rn "SELECT.*FROM.*prompt_sync_status" crates/zclaw-saas/src/ # 预期: 0 结果 grep -rn "SELECT.*FROM.*telemetry_reports" crates/zclaw-saas/src/ # 预期: 0 结果 grep -rn "SELECT.*FROM.*key_usage_window" crates/zclaw-saas/src/ # 预期: 0 结果 # deprecated 函数调用者 grep -rn "extract_structured_facts" crates/ --include="*.rs" # 仅定义和注释引用 # trigger_update 参数不匹配 grep -A5 "trigger_update" desktop/src/lib/kernel-triggers.ts grep -A5 "trigger_update" desktop/src-tauri/src/kernel_commands/ -r --include="*.rs" ```