# ZCLAW V11 差距分析报告 > **生成日期**: 2026-04-02 > **审计基线**: V10 AUDIT_TRACKER + V11 全面扫描 --- ## 1. 五种差距模式总览 | 模式 | 数量 | 最高严重度 | |------|------|-----------| | 写了没接 | 8 项 | P3 | | 接了没传 | 2 项 | **P1** | | 传了没存 | 2 项 | P3 | | 存了没用 | 3 项 | **P2** | | 双系统不同步 | 5 项 | P3 | --- ## 2. 模式 1: "写了没接" (Wrote but Not Connected) ### 2.1 audit-logger.ts — 170 行完全孤立 **文件**: `desktop/src/lib/audit-logger.ts` **严重度**: P3 完整的前端审计日志系统,包含 `FrontendAuditEntry` 类型、`AuditLogger` 类(log/logSuccess/logFailure/getLogs/clearLogs/exportLogs)、导出单例。 **验证**: ```bash grep -rn "from.*audit-logger\|import.*audit-logger" desktop/src/ --include="*.ts" --include="*.tsx" # 结果: 0 匹配 ``` **影响**: 审计日志功能完全不可用,用户无法追溯操作历史。 **建议**: - 方案 A: 在关键组件(ApprovalsPanel, AutonomyConfig, SecurityStore)中接入 - 方案 B: 如果当前不需要,标记为 `@internal reserved` 并从 barrel export 中移除 --- ### 2.2 OFP 能力 — 类型定义无消费者 **文件**: `crates/zclaw-types/src/capability.rs:28-32` **严重度**: P4 ```rust OfpDiscover, OfpConnect { peer: String }, OfpAdvertise, ``` `Capability::grants()` 方法将这些变体匹配到 `_ => false`,意味着它们无法被授予或验证。 **建议**: 移除或添加 `// Reserved for OpenFang Protocol` 注释。 --- ### 2.3 Director (multi-agent) — Feature-gated 912 行 **文件**: `crates/zclaw-kernel/src/director.rs` **严重度**: P4 (保持 V10 DEAD-04) 22 个 `cfg(feature = "multi-agent")` 条目,完整的 Director 实现(5 种调度策略)。未在 Cargo.toml 中启用。 **建议**: 延后到产品路线图中多 Agent 功能启动时启用。 --- ### 2.4 saas-admin.ts — 30 方法零消费者 **文件**: `desktop/src/lib/saas-admin.ts` **严重度**: P2 30 个 Admin API 包装方法(providers/models/keys/accounts/tokens/roles/permissions),但: - Desktop 前端不调用这些方法 - Admin-v2 有自己的 Axios service 层,不使用 saas-admin.ts **文件头注释** (line 7-9): > "Reserved for future admin UI (Next.js admin dashboard)." **建议**: 删除整个文件,admin-v2 已有独立实现。避免维护两套代码。 --- ### 2.5 Feature-gated 代码汇总 | 特性 | Crate | 代码量 | 状态 | |------|-------|--------|------| | multi-agent | zclaw-kernel | 22 cfg sites | 未启用 | | a2a | zclaw-protocols | 2 cfg sites | 未启用 | | wasm | zclaw-skills | 4 cfg sites | 未启用 | --- ### 2.6 62 个 Tauri 命令无前端调用 **分布**: | 模块 | 未调用命令数 | 备注 | |------|-------------|------| | viking_commands | 11 | 完整 Viking 模块无 UI | | pipeline_commands | 11 | 完整 Pipeline 模块无直接 invoke | | gateway::commands | 11 | Gateway 连接管理 | | classroom_commands | 7 (8 中仅 1 个被调用) | Classroom 功能 | | LLM commands | 3 | llm_complete, embedding_create, embedding_providers | | memory extractor | 2 | extract_session_memories, extract_and_store_memories | | agent commands | 3 | export, import, agent_chat | | kernel lifecycle | 2 | kernel_init, kernel_shutdown | | 其他 | 12 | health, hand_run_cancel, scheduled_task 等 | **注意**: pipeline 和 classroom 的 invoke 调用可能通过 store 或 client lib 间接调用,但 grep 未找到匹配。需手动验证。 --- ## 3. 模式 2: "接了没传" (Connected but Not Passed) ### 3.1 trigger_update 参数嵌套问题 ⚠️ P1 **前端**: `desktop/src/lib/kernel-triggers.ts:99` ```typescript return await invoke('trigger_update', { id, updates }); // updates = { name, enabled, handId, triggerType } ``` **Rust**: `desktop/src-tauri/src/kernel_commands/trigger.rs:183-189` ```rust pub async fn trigger_update( state: State<'_, KernelState>, id: String, name: Option, // 期望扁平参数 enabled: Option, hand_id: Option, ) -> Result ``` **问题**: 前端传递 `{ id, updates: { name, ... } }` 嵌套结构,但 Rust 期望 `{ id, name, enabled, hand_id }` 扁平参数。Tauri 的 serde 反序列化会忽略嵌套的 `updates` 对象,导致 name/enabled/hand_id 始终为 `None`。 **此外**: Rust 硬编码 `trigger_type: None`(trigger.rs:198),前端传递的 `triggerType` 永远被丢弃。 **影响**: Trigger 更新功能静默失败 — 用户修改 trigger 配置后不会生效。 **修复方案**: 前端改为扁平传递: ```typescript await invoke('trigger_update', { id, name: updates.name, enabled: updates.enabled, handId: updates.handId }); ``` --- ### 3.2 hand_execute 参数名映射 **前端**: `desktop/src/lib/kernel-hands.ts:82` ```typescript const result = await invoke('hand_execute', { id: name, // 前端字段名 "id" input: params || {}, ...(autonomyLevel ? { autonomyLevel } : {}), }); ``` 需验证 Rust 端是否接受 `id` 还是 `hand_name`。Tauri 自动做 camelCase ↔ snake_case 转换,但如果 Rust 使用 `name` 而前端使用 `id`,可能导致映射失败。 --- ## 4. 模式 3: "传了没存" (Passed but Not Stored) ### 4.1 定时任务执行结果未持久化 **文件**: `crates/zclaw-saas/src/scheduler.rs:147-225` `execute_scheduled_task` 执行任务后只更新 `last_run_at`、`next_run_at`、`run_count`,但不存储执行结果(成功/失败、输出、错误消息)。 `scheduled_tasks` 表 schema 缺少 `last_result`/`last_error` 列。 **影响**: 无法查看定时任务历史执行结果,无法诊断失败原因。 **建议**: 添加 `last_result TEXT` 和 `last_error TEXT` 列到 scheduled_tasks 表。 --- ### 4.2 前端审计日志滞留 localStorage `audit-logger.ts` 写入 localStorage,但无路径发送到后端或展示在 UI。数据在 `MAX_LOCAL_LOGS = 500` 条后循环覆盖。 --- ## 5. 模式 4: "存了没用" (Stored but Not Used) ### 5.1 prompt_sync_status 表 — 零读取 **迁移**: `20260329000001_initial_schema.sql:244` 数据由 OTA 同步流程写入,但全代码库中无 `SELECT FROM prompt_sync_status`。 **可能原因**: OTA check 端点直接比较版本号而不查询此表。 **建议**: 移除死表,或实现读取路径。 --- ### 5.2 telemetry_reports 表 — 零读取 **迁移**: `20260329000001_initial_schema.sql:305` 数据通过 telemetry 批量上报写入,但无查询路径。 **可能原因**: Admin dashboard 统计数据从 usage_records 聚合,不从此表读取。 **建议**: 实现读取端点供 admin-v2 telemetry 页面使用。 --- ### 5.3 key_usage_window 表 — 零读取 **迁移**: `20260329000001_initial_schema.sql:274` 写入用于限流窗口追踪,但无 SELECT 查询。限流中间件可能使用内存中的 DashMap 而非数据库查询。 **建议**: 确认是否仍需要此表,或改用纯内存方案。 --- ## 6. 模式 5: "双系统不同步" (Dual System Out of Sync) ### 6.1 Desktop ↔ Admin-v2 类型名称不一致(13+ 组) | Admin-v2 名称 | Desktop 名称 | 实际差异 | |---------------|-------------|----------| | `AccountPublic` | `SaaSAccountInfo` | 命名 + llm_routing required/optional | | `Provider` | `ProviderInfo` | 仅命名 | | `Model` | `ModelInfo` | 仅命名 | | `RelayTask` | `RelayTaskInfo` | 仅命名 | | `ConfigItem` | `SaaSConfigItem` | 仅命名 | | `OperationLog` | `OperationLogInfo` | 仅命名 | | `PromptTemplate` | `PromptTemplateInfo` | 仅命名 | | `PromptVersion` | `PromptVersionInfo` | 仅命名 | | `AgentTemplate` | `AgentTemplateFull` | 命名 + 字段差异(admin 多 5 个字段) | | `ApiError` | `SaaSErrorResponse` | 命名 + admin 多 status 字段 | | `LoginResponse` | `SaaSLoginResponse` | 结构差异(cookie vs token) | | `TokenInfo` | `TokenInfo` | nullability 差异 | | `PaginatedResponse` | `PaginatedResponse` | **一致** | ### 6.2 有意义的字段差异 **AccountPublic.llm_routing**: - Desktop: `llm_routing?: 'relay' | 'local'` (optional) - Admin: `llm_routing: 'relay' | 'local'` (required) **TokenInfo nullability**: - Desktop: `last_used_at: string | null`, `expires_at: string | null` - Admin: `last_used_at?: string`, `expires_at?: string` **PromptVariable.type**: - Desktop: `type: string` - Admin: `type: 'string' | 'number' | 'select' | 'boolean'` **AgentTemplate 字段差异**: - Admin 额外: `visibility`, `status`, `current_version`, `version`, `capabilities` - Desktop 缺少以上字段 ### 6.3 文档数字不一致 | 指标 | 实际值 | 文档值 | 差异文件 | |------|--------|--------|----------| | Skills | 76 | 66/75/77 | SYSTEM_ARCHITECTURE.md, roadmap.md, troubleshooting.md | | Hands | 9 目录 | 11 (CLAUDE.md) | CLAUDE.md 列出 11 个 Hand 配置 | | Tauri 命令 | 175 | 58+ / 130+ | 06-tauri-backend/00-backend-integration.md | | SaaS 路由 | 58 | 72+ | 08-saas-platform/00-saas-overview.md | | Stores | 15 | 14 | 00-architecture/02-state-management.md | --- ## 7. Dead Code 完整清单 | 项 | 位置 | 行数 | 严重度 | 建议 | |----|------|------|--------|------| | audit-logger.ts | desktop/src/lib/ | 170 | P3 | 接入或删除 | | saas-admin.ts | desktop/src/lib/ | 234 | P2 | 删除(admin-v2 已替代) | | extract_structured_facts() | crates/zclaw-runtime/src/growth.rs:224 | ~30 | P4 | 删除 deprecated 方法 | | secure-storage sync 方法 | desktop/src/lib/secure-storage.ts:309-325 | ~20 | P4 | 删除 | | OFP 能力变体 | crates/zclaw-types/src/capability.rs:28-32 | 5 | P4 | 注释或移除 | | Director feature-gated | crates/zclaw-kernel/src/director.rs | 912 | P4 | 保持,等路线图激活 | | A2A feature-gated | crates/zclaw-protocols/src/a2a.rs | ~400 | P4 | 保持,等路线图激活 | | WASM feature-gated | crates/zclaw-skills/src/wasm_runner.rs | ~200 | P4 | 保持,等路线图激活 | --- ## 8. Deprecated 代码状态 | 函数 | 位置 | 调用者 | 操作 | |------|------|--------|------| | `extract_structured_facts()` | growth.rs:224 | 0 | 删除 | | `getStoredGatewayToken()` | gateway-storage.ts:129 | **3 活跃调用** | 先迁移调用者再删除 | | `setStoredGatewayToken()` | gateway-storage.ts:196 | **1 活跃调用** | 先迁移调用者再删除 | | `getSync()/setSync()/deleteSync()` | secure-storage.ts:309-325 | 0 | 删除 |