Files
zclaw_openfang/docs/features/V11_GAP_ANALYSIS.md
iven 8898bb399e
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
docs: audit reports + feature docs + skills + admin-v2 + config sync
Update audit tracker, roadmap, architecture docs,
add admin-v2 Roles page + Billing tests,
sync CLAUDE.md, Cargo.toml, docker-compose.yml,
add deep-research / frontend-design / chart-visualization skills

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-02 19:25:00 +08:00

297 lines
10 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.

# 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<TriggerItem>('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<String>, // 期望扁平参数
enabled: Option<bool>,
hand_id: Option<String>,
) -> Result<TriggerResponse, String>
```
**问题**: 前端传递 `{ 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 | 删除 |