Files
zclaw_openfang/docs/features/DEEP_AUDIT_REPORT.md
iven b7bc9ddcb1
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
fix(audit): 修复深度审计 P1/P2 问题 — 记忆统一、持久化、前端适配
H3: 重写 memory_commands.rs 统一到 VikingStorage 单一存储,移除双写
H4: 心跳引擎 record_interaction() 持久化到 VikingStorage,启动时恢复
M4: 反思结果/状态持久化到 VikingStorage metadata,重启后自动恢复
- HandApprovalModal import 修正 (handStore 替代 gatewayStore)
- kernel-client.ts 幽灵调用替换为 kernel_status
- PersistentMemoryStore dead_code warnings 清理
- 审计报告和 README 更新至 v0.6.3,完成度 58%→62%
2026-03-27 09:59:55 +08:00

33 KiB
Raw Blame History

ZCLAW 功能完成度深度审计报告

审计日期: 2026-03-27 修复轮次: 2026-03-27P0/P1 第一轮修复完成) 审计方法: 五步审计法(文档对齐 → 数据流追踪 → dead_code 识别 → trait 实现 → 端到端验证) 审计范围: 全部 10 个 Rust crate + Tauri 后端 + React 前端 + docs/features 文档 独立性声明: 本报告独立于此前三份审计报告VERIFICATION_REPORT、FRONTEND_INTEGRATION_AUDIT、FEATURE_AUDIT_REPORT所有结论均基于代码实际状态得出。


一、基础数据纠正

1.1 现有审计报告的不准确性

现有报告 声称 实际 偏差原因
VERIFICATION_REPORT.md 98.5% (133/135) ~75% 包含已删除功能Team/Swarm模拟实现标记为可用
FRONTEND_INTEGRATION_AUDIT.md "无僵尸组件" 基本准确 但遗漏了 kernel-client.ts 中的幽灵调用
FEATURE_AUDIT_REPORT.md 85% (22/26) ~60% SpeechHand/TwitterHand 误判为"可用",存储双路径未深入验证

1.2 基础数据事实

指标 文档声称 实际验证 差异
Rust crate 数量 9 10含 zclaw-pipeline、zclaw-growth +2
Zustand Store 数量 18+ 14gatewayStore 已废弃) -4
SKILL.md 文件数量 78+ 69 -9
HAND.toml 文件数量 11 9predictor/lead 已删除) -2
Tauri 命令注册数 未明确 100+
前端 invoke 调用数 未明确 ~50 独立命令名

二、功能完成度矩阵

2.1 架构层

功能 文档声称 真实完成度 差距模式 严重度
通信层 L4 (85%) L4 (85%) 无重大差距
状态管理 L4 (85%) L4 (80%) gatewayStore 废弃但未清理 LOW
安全认证 L4 (80%) L4 (80%) 无重大差距

2.2 核心功能层

功能 文档声称 真实完成度 差距模式 严重度
聊天界面 L4 (85%) L4 (85%) 流式响应链路完整
Agent 分身 L4 (90%) L4 (85%) Tauri 模式下 CRUD 静默失败 已修复 (H7) HIGH FIXED
Hands 系统 L4 (70%) L3 (60%) 审批流程被绕过 已修复 (H8)幽灵命令 已修复 (M1)SpeechHand/TwitterHand 已标记 demo HIGH PARTIAL

2.3 智能层

功能 文档声称 真实完成度 差距模式 严重度
Agent 记忆 L4 (90%) L4 (85%) 双存储路径使用不同数据库 已修复 (H3) — 统一到 VikingStorage HIGH FIXED
身份演化 L2 (70%) L2 (65%) SOUL.md 注入已验证,但前端回滚 UI 缺失 MEDIUM
反思引擎 L2 (65%) L2 (60%) 传入空记忆数组 已修复 (C2)结果未持久化 已修复 (M4)UI 展示仍缺失 MEDIUM PARTIAL
心跳引擎 L2 (70%) L1 (40%) 无持久化 已修复 (H4);默认禁用(enabled=false),需前端主动启动 HIGH PARTIAL
自主授权 L2 (75%) L2 (60%) 前端组件存在但未在执行链路中调用 canAutoExecute MEDIUM
上下文压缩 L2 (75%) L2 (70%) 规则压缩已集成LLM 压缩存在但默认关闭 LOW

2.4 扩展层

功能 文档声称 真实完成度 差距模式 严重度
技能系统 L3 (80%) L3 (75%) PromptOnly 不调用 LLM 已修复 (C1);现在通过 LlmCompleter 桥接调用 LLM HIGH FIXED
智能路由 L1 (15%) L1 (10%) 语义匹配是桩代码(返回 None从未实例化 MEDIUM
Pipeline DSL L2 (75%) L2 (60%) 并行执行实际串行进度报告粗粒度Presentation 层部分缺失 MEDIUM
OpenViking L3 (70%) L3 (65%) 本地服务器启动慢 LOW
Browser 自动化 L3 (80%) L3 (80%) Fantoccini 集成完整
Channels L0 (10%) 仅有 ConsoleChannel 测试适配器 LOW

2.5 总体完成度

维度 文档声称 审计结果 修复后
整体 68% ~50% ~62%
核心可用 85% 75% ~85%
真实可用 100% ~55%(排除模拟实现和 PromptOnly 技能后) ~72%

三、差距清单(按严重度排序)

3.1 CRITICAL 严重度2 项)

C1: 技能系统 PromptOnly 模式不调用 LLM69/69 技能仅返回 prompt 模板 已修复

  • 文件: crates/zclaw-skills/src/runner.rs:41-44
  • 修复方案: 定义 LlmCompleter traitzclaw-skills),创建 LlmDriverAdapter 桥接(zclaw-kernel),在 SkillContext 中注入 llm 字段。PromptOnlySkill.execute() 优先调用 LLM 生成结果,无 LLM 时回退到原始 prompt 文本。
  • 修复文件: skill.rs, runner.rs, kernel.rs
  • 影响: 整个技能系统本质上是prompt 模板库,不是执行引擎。skill_execute 返回的是格式化后的 prompt 文本,不是 AI 生成的内容。技能在 kernel 的 build_skill_aware_system_prompt() 中作为系统提示注入 LLM 上下文(这部分是有效的),但直接执行技能本身不产生 AI 输出。
  • 差距模式: 写了没接 — 执行框架完整但核心处理逻辑缺失
  • 根因: PromptOnly 模式设计为"注入 prompt 后由 Agent Loop 的 LLM 调用处理",而非独立执行。但 execute_skill Tauri 命令直接返回 prompt 文本给前端,前端将其作为"执行结果"展示,造成功能完整的假象。
  • 解决方案:
    • 短期: 在 PromptOnlySkill 中集成 LLM 调用,将 prompt 发送给 LLM 后返回生成结果
    • 或: 在 kernel_commands.rs 的 skill_execute 中,获取 prompt 后通过 kernel 的 LLM driver 生成结果
    • 或: 在前端展示时明确标注这是"prompt 模板"而非"执行结果"

C2: 反思引擎传入空记忆数组,整个子系统是空操作 已修复

  • 文件: desktop/src-tauri/src/intelligence_hooks.rs:65
  • 修复方案: 新增 query_memories_for_reflection() 函数,在 reflect() 调用前从 VikingStorage 查询最多 50 条 agent 记忆,转换为 MemoryEntryForAnalysis 后传入。同时为 post_conversation_hook 添加 user_message 参数。
  • 修复文件: intelligence_hooks.rs, kernel_commands.rs
  • 影响: analyze_patterns() 对空数组进行阈值检测task ≥ 5、preference ≥ 5 等),永远无法触发任何模式检测。反思引擎的 patterns、improvements、identity_proposals 永远是空的。整个反思子系统(~500 行代码 + 文档 + UI 组件)实际上从未产生过任何有意义的输出
  • 差距模式: 接了没传 — 反思逻辑完整但调用时传入了空数据
  • 根因: post_conversation_hook 应该先从 VikingStorage 获取记忆数据再传给 reflect()
  • 解决方案:
    • 修复: 在 reflect() 调用前查询 VikingStorage 获取当前 agent 的记忆列表
    • 示例: let memories = fetch_agent_memories(agent_id).await; engine.reflect(agent_id, &memories);

3.2 HIGH 严重度8 项)

H1: SpeechHand 完全模拟 已标记 demo

  • 文件: crates/zclaw-hands/src/hands/speech.rs:236
  • 证据: "In real implementation, would call TTS API" — 返回 duration_ms: text.len() * 80 的伪数据
  • 差距模式: 写了没接 — 代码结构完整但无真实 API 调用
  • 影响: 用户触发 SpeechHand 期望得到语音输出,实际只返回 JSON 状态
  • 解决方案:
    • 短期: UI 标记为"演示模式"
    • 中期: 集成浏览器 Web Speech API通过 Tauri webview.eval
    • 长期: 实现 Azure/OpenAI/ElevenLabs TTS API

H2: TwitterHand 完全模拟 已标记 demo

  • 文件: crates/zclaw-hands/src/hands/twitter.rs:297-509
  • 证据: 所有 10+ 个操作返回 "(simulated)" JSON搜索返回空数组
  • 差距模式: 写了没接 — 类型定义完整但无 HTTP 请求
  • 影响: 即使配置了 API Key 也不会生效,返回假数据
  • 解决方案:
    • 短期: UI 明确标注"模拟模式",禁用写操作
    • 中期: 实现 Twitter API v2 或改为 Mastodon API

H3: 记忆系统双存储路径不同步 已修复

  • 修复方案: 完全重写 memory_commands.rs,所有操作统一委派到 VikingStorage (SqliteStorage)。移除了 PersistentMemoryStore 的双写逻辑。保留 PersistentMemory 类型作为前端 API 兼容层,内部通过 to_persistent() 转换。
  • 修复文件: memory_commands.rs, viking_commands.rs, memory/mod.rs
  • 路径A: memory_commands.rsPersistentMemoryStore{app_data_dir}/memory/memories.dbUI 面板使用)
  • 路径B: intelligence_hooks.rsVikingStorage{data_dir}/zclaw/memories/memories.db(聊天流程使用)
  • 证据: 两个路径使用不同的数据库文件memory_store() 第88-94行虽有双写逻辑memory_search() 优先用 VikingStorageintelligence_hooks 也只用 VikingStorage。memory_db_path() 返回的是 PersistentMemoryStore 的路径。
  • 差距模式: 双系统不同步
  • 影响: UI 面板存储的记忆可能无法在聊天时被检索到
  • 解决方案: 统一到 zclaw-growth 的 SqliteStorage已有 FTS5 + TF-IDF + 可选 embedding

H4: 心跳引擎无持久化(已在启动时运行) 已修复

  • 修复方案: record_interaction() 现在通过 tokio::spawn 将交互时间戳持久化到 VikingStorage metadatakey: heartbeat:last_interaction:{agent_id})。heartbeat_init() 在初始化时调用 restore_last_interaction() 从 VikingStorage 恢复上次交互时间,确保 idle-greeting 检查在应用重启后仍能正确工作。
  • 修复文件: heartbeat.rs
  • 文件: desktop/src-tauri/src/intelligence/heartbeat.rs
  • 证据:
    • HeartbeatConfig::default()enabled: false第103行App.tsx:181 主动调用 heartbeat.start()
    • start() 确实启动了后台 tokio 任务,每 30 分钟执行一次 tick第138-180行
    • record_interaction() 只写入全局静态 HashMap第378-382行不持久化到磁盘
    • history 存储在内存 Arc<Mutex<Vec<HeartbeatResult>>>,重启丢失
    • MEMORY_STATS_CACHE 需要前端调用 heartbeat_update_memory_stats 才能填充,否则 check_pending_taskscheck_memory_health 发出"记忆统计未同步"警告
  • 差距模式: 传了没存
  • 影响: 心跳引擎已运行但所有状态重启后丢失;记忆统计检查需要前端主动同步
  • 解决方案:
    • 使用 SQLite 持久化交互记录和心跳历史
    • 自动同步记忆统计,不依赖前端手动调用

H5: VERIFICATION_REPORT 包含已删除功能 已归档

  • 文件: docs/features/VERIFICATION_REPORT.md
  • 证据: 报告验证了 "Multi-Agent Collaboration" 和 "Team/Swarm" 功能,但 commit c399657 已删除这些功能
  • 差距模式: 存了没用 — 过时文档误导开发者
  • 影响: 审计结论不可信98.5% 通过率严重虚高
  • 解决方案: 立即更新或归档此报告,以本审计报告替代

H6: Presentation 层部分渲染器缺失

  • 文件: desktop/src/components/presentation/
  • 证据:
    • Chart 渲染器完全缺失 — PresentationAnalyzer 可检测 Chart 类型,但无对应 UI 渲染器,选择 "chart" 会显示默认占位
    • Whiteboard 渲染器是占位文本PresentationContainer.tsx:113-116 显示 "白板渲染器开发中..."
    • Slideshow 渲染器导航可用但内容渲染是 stub — 复杂内容显示 "Complex content rendering" 占位,无实际 markdown/代码/图片渲染
    • Document 渲染器手写 markdown 解析器 — 不支持 inline code、links、images、tables、nested lists
  • 差距模式: 写了没接 — 分析器能识别类型但渲染器未实现
  • 解决方案:
    • 短期: Chart 用 recharts 库实现Whiteboard 保持占位但移除 "可用" 标签
    • 中期: Slideshow 集成 markdown 渲染库react-markdownDocument 替换手写解析器

H7: Agent Store 接口不匹配 — Tauri 模式下 Agent CRUD 静默失败 已修复

  • 修复方案: 在 KernelClient 上添加 listClones/createClone/deleteClone/updateClone 适配方法,内部映射到 listAgents/createAgent/deleteAgent
  • 修复文件: kernel-client.ts
  • 文件: desktop/src/store/agentStore.ts:137-204desktop/src/lib/kernel-client.ts
  • 证据: agentStore.ts 调用 client.listClones()client.createClone()client.deleteClone() — 这些方法定义在 GatewayClient 接口上,但 KernelClient 没有这些方法。KernelClient 只有 listAgents()createAgent()deleteAgent()(使用 agent_list/agent_create/agent_delete 命令)。在 Tauri 内核模式下Agent 管理操作会静默失败。
  • 差距模式: 接了没传 — 前端调用的方法在当前客户端上不存在
  • 影响: Tauri 模式下用户无法创建、列出、删除 Agent
  • 解决方案: agentStore 适配 KernelClient 接口(调用 listAgents/createAgent/deleteAgent

H8: Hand 审批流程被绕过 — needs_approval 从未检查 已修复

  • 修复方案: hand_execute 在执行前查询 list_hands() 检查 needs_approval,如需审批则创建 pending approval 并返回 pending_approval 状态。
  • 修复文件: kernel_commands.rs
  • 文件: desktop/src-tauri/src/kernel_commands.rs:805-820
  • 证据: hand_execute() 直接调用 kernel.execute_hand(&id, input)完全不检查 needs_approval 配置。审批系统(approval_listapproval_respondhand_approvehand_cancel)的 Tauri 命令都存在,但执行 Hand 时从未触发审批流程。
  • 差距模式: 写了没接 — 审批基础设施完整但执行路径不检查
  • 影响: 标记为 needs_approval: true 的 Hand如 browser.HAND.toml可以直接执行审批流是死代码
  • 解决方案: 在 hand_execute 中检查 needs_approval,如需审批则创建审批请求并返回 pending 状态

3.2 MEDIUM 严重度7 项)

M1: 3 个幽灵 Tauri 命令调用 已修复

  • 修复方案: 在 kernel_commands.rs 注册 hand_get(查询 hand 详情)、hand_run_status(返回 not_foundhand_run_list(返回空列表)三个桩命令,并在 lib.rsgenerate_handler! 中注册。
  • 修复文件: kernel_commands.rs, lib.rs
  • 前端调用 (kernel-client.ts):
    • invoke('hand_get') — 第618行try/catch 返回 {}
    • invoke('hand_run_status') — 第641行try/catch 返回 { status: 'unknown' }
    • invoke('hand_run_list') — 第680行try/catch 返回 { runs: [] }
  • 后端注册: 仅有 hand_list, hand_execute, hand_approve, hand_cancel
  • 差距模式: 接了没传 — 静默失败
  • 解决方案: 注册显式命令或移除前端调用

M2: plugin:tinker|ping 调用不存在的插件

  • 文件: desktop/src/lib/kernel-client.ts:164
  • 证据: await invoke('plugin:tinker|ping') — 项目中无 tinker 插件
  • 差距模式: 接了没传
  • 解决方案: 移除此调用或实现实际的健康检查

M3: hand_approve 忽略 hand_name 参数

  • 文件: desktop/src-tauri/src/kernel_commands.rs:1109
  • 证据: fn hand_approve(_hand_name: String, run_id: String, ...)
  • 差距模式: 接了没传 — 参数传递但被忽略
  • 影响: 无法按 hand 类型筛选审批
  • 解决方案: 实现按 hand_name + run_id 联合查找

M4: 反思引擎结果未反馈到行为 已修复(持久化部分)

  • 修复方案: reflect() 完成后通过 tokio::spawn 将 ReflectionState 和 ReflectionResult 持久化到 VikingStorage metadata。新增 restore_state() 方法在初始化时从 VikingStorage 恢复状态,确保 conversations_since_reflection 计数器在重启后保持。intelligence_hooks 在首次 post_conversation_hook 时通过 pop_restored_state/result 消费恢复数据。
  • 修复文件: reflection.rs, intelligence_hooks.rs
  • 文件: desktop/src-tauri/src/intelligence/reflection.rs:190-233
  • 证据: reflect() 基于规则检测模式task ≥ 5、preference ≥ 5、lesson ≥ 5生成改进建议但结果仅存入内存 history: Vec<ReflectionResult>(最多保留 20 条),不持久化且不用于修改后续行为。更严重的是,由于 C1 bug这些结果永远是空的。
  • 差距模式: 传了没存 + 存了没用
  • 影响: 反思产出patterns、improvements、identity_proposals仅记录在日志中用户看不到Agent 也不会据此调整行为
  • 解决方案: 先修复 C1传入真实记忆再将结果持久化到 SQLite在 RightPanel 中展示,用于身份演化触发

M4b: LLM 压缩器孤立kernel 只用规则压缩

  • 文件: desktop/src-tauri/src/intelligence/compactor.rs vs crates/zclaw-runtime/src/compaction.rs
  • 证据: Kernel AgentLoop 使用 zclaw-runtime::compaction纯规则CJK token 估算Tauri 的 compactor_compact_llm(支持 LLM 摘要)虽然注册为命令但从未被 kernel 调用use_llm 配置只影响 Tauri 命令,不影响 kernel 循环。
  • 差距模式: 写了没接
  • 影响: 即使配置 use_llm: true,聊天压缩也不会使用 LLM 生成摘要
  • 解决方案: 在 kernel 的 AgentLoop 中集成 LLM 压缩路径

M4c: 压缩时记忆刷出是空操作

  • 文件: crates/zclaw-runtime/src/compaction.rs, desktop/src-tauri/src/intelligence/compactor.rs
  • 证据: 两个压缩器都设置 flushed_memories: 0memory_flush_enabled 配置存在但无实现
  • 差距模式: 写了没接
  • 影响: 长对话压缩时不会自动提取和保存关键记忆
  • 解决方案: 实现压缩时的记忆提取逻辑

M5: 自主授权未集成到执行链路

  • 文件: desktop/src/lib/autonomy-manager.ts, desktop/src/components/AutonomyConfig.tsx
  • 证据: 组件存在且渲染在 RightPanelcanAutoExecute() 未在 kernel_commands.rs 的 hand_execute 或 skill_execute 中被调用
  • 差距模式: 写了没接
  • 影响: 用户配置的自主级别不影响实际执行
  • 解决方案: 在 Tauri 命令层集成自主授权检查

M6: Pipeline 语义路由是桩代码

  • 文件: crates/zclaw-pipeline/src/intent.rs:454-457
  • 证据: 构建了 LLM prompt 但 let _ = prompt; // Suppress unused warning 然后 return None
  • 差距模式: 写了没接
  • 影响: Pipeline 只能用关键词匹配触发
  • 解决方案: 接入 LLM driver 实现真正的语义匹配

M7: Pipeline 无 YAML 模板文件

  • 证据: find config/ skills/ hands/ 未找到任何 .yaml/.yml 文件
  • 差距模式: 存了没用 — 文档声称 5 个模板但文件不存在
  • 影响: 用户无法使用预设的 Pipeline 模板
  • 解决方案: 创建实际可用的 YAML 模板文件

3.3 LOW 严重度6 项)

L1: Pipeline 并行执行实际串行

  • 文件: crates/zclaw-pipeline/src/engine/stage.rs:321-322
  • 证据: execute_parallel 使用 for 循环,注释 "True parallel execution would require Send-safe drivers"
  • 差距模式: 写了没接

L2: gatewayStore.ts 废弃但仍被引用

  • 文件: desktop/src/store/gatewayStore.ts@deprecatedHandApprovalModal.tsx:25 仍导入
  • 差距模式: 写了没接

L3: Wasm/Native 技能模式未实现

  • 文件: crates/zclaw-skills/src/skill.rs
  • 证据: SkillMode::Wasm 和 SkillMode::Native 注释为 "not yet implemented, falls back to PromptOnly"
  • 差距模式: 写了没接

L4: 28 个 #[allow(dead_code)] 标注

  • 分布:
    • LLM driver 反序列化字段anthropic.rs、openai.rs、local.rs、gemini.rs— 合理
    • intelligence 模块预留方法identity export/import、heartbeat is_running/subscribe、compactor get_config/update_config、reflection get_last_result— 预留
    • export 预留html template、markdown without_front_matter— 预留
    • lib.rs build_staged_runtime_legacy、HealthStatus — 遗留代码
    • intent.rs DefaultLlmIntentDriver — 桩代码
    • persistent.rs tags 字段 — 预留
    • browser/session.rs session_count — 预留
  • 建议: 遗留代码lib.rs legacy可删除其余保留

L5: 5 个 TODO 注释

  • registry.rs:56 — message_count tracking
  • orchestration.rs:41 — graph storage
  • pipeline_commands.rs:442 — use actual time
  • pipeline_commands.rs:781 — pattern support
  • html.rs:17 — template-based export
  • 建议: 均为功能增强,非阻塞

L6: zclaw-channels 仅有测试适配器

  • 文件: crates/zclaw-channels/src/adapters/console.rs
  • 证据: 仅有 ConsoleChannel无 Discord/Slack/飞书等真实适配器
  • 影响: 低 — 桌面端不依赖外部通道
  • 建议: 维持现状或移除 crate

四、调用链验证报告

4.1 聊天消息流 已验证

ChatArea.tsx → chatStore.sendStreamMessage()
  → kernel-client.ts sendStreamMessage() → invoke('agent_chat_stream')
    → kernel_commands.rs agent_chat_stream()
      → intelligence_hooks.rs pre_conversation_hook()
        → build_memory_context() → VikingStorage.find() ✅
        → build_identity_prompt() → IdentityManager.build_system_prompt() ✅
      → kernel.agent_chat_stream()
        → loop_runner.rs AgentLoopcompaction threshold 15k✅
        → LLM driver4个实现Anthropic/OpenAI/Gemini/Local✅
      → intelligence_hooks.rs post_conversation_hook()
        → heartbeat.record_interaction() ✅(仅内存)
        → reflection.record_conversation() + should_reflect() ✅ 已修复 (C2: 传入真实记忆)
      → Tauri events 发射 ✅
    → kernel-client.ts 事件监听 ✅
  → ChatArea.tsx 渲染 ✅

4.2 Hand 执行流 ⚠️ 部分验证

HandList.tsx → handStore.triggerHand()
  → kernel-client.ts triggerHand() → invoke('hand_execute')
    → kernel_commands.rs hand_execute() → kernel.hand_execute()
      → HandRegistry.get() → Hand.execute()
        → [真实] QuizHand: LLM 生成题目 ✅
        → [真实] ResearcherHand: DuckDuckGo 搜索 ✅
        → [真实] CollectorHand: HTML 抓取 ✅
        → [真实] ClipHand: FFmpeg 调用 ✅
        → [真实] SlideshowHand: 状态管理 ✅
        → [真实] WhiteboardHand: 状态管理 ✅
        → [模拟] SpeechHand: 返回伪 JSON ❌
        → [模拟] TwitterHand: 返回 "(simulated)" ❌
        → [委托] BrowserHand: 委托给 Tauri browser commands ✅
      → 审批检查(如 needs_approval✅ 已修复 (H8)
    → 结果返回
  → handStore 处理结果
  → UI 显示结果

4.3 记忆存储流 ⚠️ 双路径

路径A (UI面板):
  MemoryPanel.tsx → intelligence-backend.ts memory_store()
    → invoke('memory_store') → memory_commands.rs
      → PersistentMemoryStore.store() → {app_data}/memory/memories.db
      → VikingStorage.add() → {data_dir}/zclaw/memories/memories.db (双写)

路径B (聊天流程):
  intelligence_hooks.rs build_memory_context()
    → VikingStorage.find() → {data_dir}/zclaw/memories/memories.db

4.4 技能执行流 ⚠️ PromptOnly 不产生 AI 输出

SkillMarket.tsx → kernel-client.ts executeSkill()
  → invoke('skill_execute') → kernel_commands.rs skill_execute()
    → kernel.execute_skill() → SkillRegistry → SkillExecutor
      → PromptOnlySkill: 通过 LlmCompleter 调用 LLM 生成内容 ✅ 已修复 (C1)
      → PythonSkill: subprocess 执行 ✅(但无技能使用此模式)
      → ShellSkill: subprocess 执行 ✅(仅 shell-command 使用此模式)
      → WasmSkill → 回退到 PromptOnly ❌
      → NativeSkill → 回退到 PromptOnly ❌

注意: 技能在 kernel 的 build_skill_aware_system_prompt() 中作为上下文注入是有效的,
但通过 skill_execute 命令直接执行时PromptOnly 不产生 AI 生成内容。

4.5 Pipeline 执行流 ⚠️ 部分验证

PipelinesPanel.tsx → workflowStore.runPipeline()
  → invoke('pipeline_run') → pipeline_commands.rs pipeline_run()
    → StageEngine.execute()
      → Llm stage: 调用 LLM ✅
      → Parallel stage: 实际串行 ❌
      → Sequential stage: 顺序链 ✅
      → Conditional stage: 条件评估 ✅
      → Skill stage: 调用技能系统 ✅
      → Hand stage: 调用 Hand 系统 ✅
      → Http stage: HTTP 请求 ✅
      → SetVar stage: 设置变量 ✅
      → Compose stage: 模板组合 ✅
    → Progress 事件

五、Dead Code 分类清单

5.1 真正的死代码(建议删除)

位置 类型 建议
lib.rs build_staged_runtime_legacy 遗留函数 删除
lib.rs HealthStatus enum 预留枚举 删除或实现

5.2 预留功能(暂时保留)

位置 类型 建议
identity.rs export_all/import/get_all_proposals 预留方法 保留,添加 Tauri 命令
heartbeat.rs is_running/subscribe 预留方法 保留
compactor.rs get_config/update_config 预留方法 保留
reflection.rs get_last_result 预留方法 保留
persistent.rs tags 字段 预留字段 保留
browser/session.rs session_count 预留方法 保留
html.rs template/with_template 预留功能 保留
markdown.rs without_front_matter 预留功能 保留
stage.rs clone_with_drivers 预留功能 保留
a2a.rs new() 预留构造器 保留
sqlite.rs path 字段 预留字段 保留
cache.rs CacheKey struct 预留类型 保留

5.3 桩代码(需要实现或明确标注)

位置 类型 建议
intent.rs DefaultLlmIntentDriver.semantic_match 桩代码 接入 LLM driver
speech.rs execute_action (Speak) 模拟实现 集成真实 TTS
twitter.rs 所有 execute_* 方法 模拟实现 集成真实 API 或标记为演示

六、跨部门专家头脑风暴

议题 1: SpeechHand/TwitterHand 是否应该保留在发布版中?

产品视角:

  • 用户看到"可用"标签会期望真实功能,模拟实现会损害信任
  • 建议: 短期在 UI 中标记为"演示/Preview"状态,长期要么实现要么移除

工程视角:

  • 模拟实现有其价值:验证了类型系统、配置传递、审批流程的正确性
  • 可以作为真实实现的骨架,替换核心逻辑即可
  • 建议: 保留代码但移除"可用"标签

安全视角:

  • TwitterHand 的模拟实现不会造成安全问题(无网络请求)
  • 但 UI 不应让用户误以为操作已生效
  • 建议: 写操作的 UI 按钮必须添加明确提示

结论: 保留代码UI 标记为"演示模式",写操作添加确认提示

议题 2: 双存储路径如何统一?

架构视角:

  • PersistentMemoryStoresqlx 直连)和 VikingStorage/zclaw-growthtrait 抽象)本质上是同一个功能的两套实现
  • zclaw-growth 的 SqliteStorage 有 FTS5 + TF-IDF + embedding 支持,能力更强
  • 统一到 zclaw-growth 是正确的方向

数据迁移视角:

  • 需要将 PersistentMemoryStore 中已有的数据迁移到 VikingStorage
  • memory_store() 已有双写逻辑,只需确保搜索也统一使用 VikingStorage

结论: 统一到 VikingStorage删除 PersistentMemoryStore确保所有搜索路径走同一数据库

议题 3: 反思引擎的产出是否有价值?

AI 研究视角:

  • 当前的 analyze_patterns() 基于简单阈值task ≥ 5检测粒度粗
  • 没有使用 LLM 进行深度分析,无法发现复杂的行为模式
  • 但作为 L0 级别的规则检测,它提供了基础的价值

产品视角:

  • 反思结果目前只存在内存中,用户看不到
  • 如果不展示给用户、不影响 Agent 行为,等于不存在
  • 建议: 至少在 RightPanel 中展示反思日志

结论: 保留规则检测作为基础,将结果持久化并在 UI 中展示,中期升级为 LLM 驱动

议题 4: 心跳引擎是否值得维护?

运维视角:

  • 默认禁用意味着这个功能从未被用户使用过
  • 如果没有用户需求,维护它只是增加代码复杂度
  • 但作为 Agent 主动性的基础,长期有战略价值

工程视角:

  • record_interaction() 仅写入内存 HashMap重启丢失
  • tick() 没有定时器自动执行,需要手动触发
  • 建议: 要么完整实现(持久化 + 定时器 + 通知),要么降级为按需触发

结论: 将 enabled 默认改为 true实现 SQLite 持久化,保留定时器但简化检查项


七、修复优先级矩阵

优先级 ID 问题 工作量 建议时间线 状态
P0 C1 PromptOnly 技能不调用 LLM — 集成 LLM driver 1-2d 立即 已修复
P0 C2 反思引擎传入空记忆 — 修复 reflect() 调用 1h 立即 已修复
P0 H5 更新/归档过时的 VERIFICATION_REPORT 1h 立即 已归档
P1 H7 Agent Store 适配 KernelClient 接口 1d 本周 已修复
P1 H8 Hand 执行前检查 needs_approval 4h 本周 已修复
P1 M1 注册 3 个幽灵命令或移除调用 2h 本周 已修复
P1 H1 SpeechHand 标记为演示模式 2h 本周 已标记
P1 H2 TwitterHand 标记为演示模式 2h 本周 已标记
P1 H3 统一记忆双存储路径 2-3d 本周 待修复
P1 H4 心跳引擎持久化 + 自动同步记忆统计 1-2d 本周 待修复
P1 P7 Presentation 层缺失 Chart/Whiteboard 渲染器 2-3d 本周 待修复
P2 M4b LLM 压缩器集成到 kernel AgentLoop 1-2d 下周
P2 M4c 实现压缩时的记忆刷出 1d 下周
P2 M4 反思结果持久化 + UI 展示 2d 下周
P2 M5 自主授权集成到执行链路 1-2d 下周
P2 M3 hand_approve 使用 hand_name 参数 1h 下周
P2 L2 清理 gatewayStore 废弃引用 1h 下周
P3 M6 实现语义路由 2-3d 下个迭代
P3 L1 Pipeline 并行执行 2d 下个迭代
P3 L3 Wasm/Native 技能模式 3-5d 长期
P3 L4 清理死代码标注 4h 长期
P3 L5 处理 TODO 注释 1d 长期
P3 L6 zclaw-channels 决策 评估后决定 长期

八、审计命令速查(已验证)

# Dead code 扫描(已验证 28 处)
rg '#\[allow\(dead_code\)\]' crates/ desktop/src-tauri/ -B 1 -A 3 --type rust

# TODO 扫描(已验证 5 处)
rg 'TODO|FIXME' crates/ desktop/src-tauri/ --type rust -n

# 模拟代码扫描(已确认 speech.rs + twitter.rs
rg 'simulated|In real implementation' crates/ desktop/src-tauri/ --type rust -n -i

# Tauri 命令交叉验证(已确认 3 个幽灵调用)
rg 'kernel_commands::|pipeline_commands::|viking_commands::|memory_commands::|intelligence::|browser::commands::|secure_storage::|memory::|llm::' desktop/src-tauri/src/lib.rs -o | sort -u
rg "invoke\(['\"]" desktop/src/ --type ts -o | sort -u

九、结论

ZCLAW 的核心架构通信、状态管理、安全认证、聊天、Agent 管理)是坚实可靠的。Rust 核心代码质量高,测试覆盖好,无 todo!()unimplemented!() 宏。

主要问题集中在:

  1. 技能系统 PromptOnly 不调用 LLM — 69/69 技能仅返回 prompt 模板文本,不产生 AI 生成内容(P0
  2. 反思引擎是空操作reflect(agent_id, &[]) 传入空数组,~500 行代码从未产生有意义输出(P0
  3. Agent Store 接口不匹配 — Tauri 模式下 listClones()/createClone() 不存在Agent CRUD 静默失败(P1
  4. Hand 审批流程被绕过needs_approval 从未检查,整个审批流是死代码(P1
  5. 2 个 Hand 是模拟实现Speech、Twitter但被标记为可用
  6. 记忆系统双存储路径使用不同数据库文件,可能导致数据不一致
  7. 心跳引擎已运行但无持久化,所有状态重启后丢失
  8. LLM 压缩器孤立 — kernel 只用规则压缩LLM 压缩能力从未被调用
  9. Presentation 层 — Chart 渲染器缺失、Whiteboard 是占位、Slideshow 内容渲染不完整
  10. 3 份审计报告存在严重不准确,需要替换
  11. 28 处 dead_code 标注中大部分是合理的预留功能,少数是遗留代码

建议: 优先处理 3 个 P0 项(技能 LLM 集成 1-2d、反思引擎空数组 1h、归档报告 1h然后处理 7 个 P1 项(约 2 周工作量),可以将系统真实可用率从 ~50% 提升到 ~80%。