# ZCLAW 上线前功能审计 — 测试执行计划 > **For agentic workers:** REQUIRED: Use superpowers:subagent-driven-development (if subagents available) or superpowers:executing-plans to implement this plan. Steps use checkbox (`- [ ]`) syntax for tracking. **Goal:** 系统性验证 ZCLAW 全部 12 个功能模块(T1-T12),发现并修复所有 P0/P1 缺陷,达到上线标准。 **Architecture:** 基于 V12 模块化审计框架,12 模块按风险排序(HIGH→MEDIUM→LOW),分 4 阶段执行。测试工具:Tauri 端用 tauri-mcp,Rust 用 cargo test,Admin 用 Playwright + vitest,SaaS API 用 HTTP + cargo test。 **Tech Stack:** Tauri 2.x + React 19 + Zustand + Rust Workspace (10 crates) + Axum + PostgreSQL + tauri-mcp **Spec:** `docs/superpowers/specs/2026-04-05-pre-launch-functional-audit-design.md` > **⚠️ 执行注意:** 计划中的 `execute_js` 代码块使用 `window.__TAURI_INTERNALS__.invoke()` 调用 Tauri 命令。V12 审计后代码已发生变更,部分命令名称/参数可能已更新。**执行前必须**: > 1. 验证每个 Tauri 命令名是否存在于 `desktop/src-tauri/src/lib.rs` 的 `invoke_handler` 注册列表中 > 2. 验证参数签名是否匹配 Rust 函数定义 > 3. V12 审计发现的部分问题(如 M4-01 双数据库、M4-02 反思 LLM)可能已在后续提交中修复,测试时应以实际代码为准 --- ## 文件结构 ### 测试结果输出 ``` docs/test-results/ ├── TEST_PLAN.md # 本文件 ├── DEFECT_LIST.md # 缺陷汇总清单 ├── RELEASE_READINESS.md # 上线评估 ├── baseline/ # 基线测试结果 │ ├── cargo-test.txt │ ├── desktop-vitest.txt │ └── admin-vitest.txt ├── T1-hands/ # 每个 T 模块一个目录 │ ├── REPORT.md │ └── screenshots/ ├── T2-intelligence/ ├── T3-agent/ ├── ... (T3-T12 同理) └── T12-e2e/ ``` ### V12 审计报告(测试基线) ``` docs/features/audit-v12/ ├── M1-intelligent-chat.md # T8 (91/100) ├── M2-agent-clones.md # T3 (67/100) ├── M3-hands-system.md # T1 (58/100) ⚠️ 最高风险 ├── M4-intelligence-layer.md # T2 (61/100) ⚠️ 含 P0 ├── M5-skill-ecosystem.md # T7 (85/100) ├── M6-pipeline-workflow.md # T5 (72/100) ├── M7-saas-desktop.md # T6 (85/100) ├── M8-admin-v2.md # T9 (82/100) ├── M9-communication-security.md # T10 (86/100) └── M11-classroom.md # T4 (70/100) ``` ### 关键源码文件 ``` # Hands (T1) desktop/src/store/handStore.ts desktop/src/store/browserHandStore.ts desktop/src/lib/kernel-hands.ts desktop/src/lib/browser-client.ts desktop/src/lib/autonomy-manager.ts desktop/src/components/Automation/ desktop/src-tauri/src/kernel_commands/hand.rs desktop/src-tauri/src/kernel_commands/approval.rs crates/zclaw-hands/src/hands/ (9 .rs) crates/zclaw-kernel/src/kernel/hands.rs crates/zclaw-kernel/src/kernel/approvals.rs hands/*.HAND.toml (9 配置) # Intelligence (T2) desktop/src/store/memoryGraphStore.ts desktop/src/lib/intelligence-client/ (memory/identity/reflection/heartbeat) desktop/src-tauri/src/intelligence/ (memory/identity/reflection/heartbeat/compactor.rs) crates/zclaw-growth/src/ crates/zclaw-runtime/src/middleware/memory.rs crates/zclaw-runtime/src/middleware/compaction.rs # Agent (T3) desktop/src/store/agentStore.ts desktop/src/lib/kernel-agent.ts desktop/src/components/AgentSelector.tsx desktop/src-tauri/src/kernel_commands/agent.rs crates/zclaw-kernel/src/kernel/agents.rs # Classroom (T4) desktop/src/store/classroomStore.ts desktop/src/components/Classroom/ desktop/src-tauri/src/kernel_commands/classroom.rs desktop/src-tauri/src/intelligence/classroom/ # Pipeline (T5) desktop/src/store/workflowStore.ts desktop/src/components/WorkflowBuilder/ crates/zclaw-pipeline/src/ # SaaS Desktop (T6) desktop/src/lib/saas-client.ts desktop/src/store/saasStore.ts desktop/src/components/SaaS/ # Skills (T7) desktop/src/lib/skill-discovery.ts crates/zclaw-skills/src/ skills/ (75 SKILL.md) # Chat (T8) desktop/src/store/chat/ (streamStore, conversationStore, messageStore, artifactStore) desktop/src/lib/kernel-chat.ts desktop/src/components/ChatArea.tsx # Admin V2 (T9) admin-v2/src/pages/ (15 页面) admin-v2/tests/ (~71 测试) # Security (T10) desktop/src/lib/secure-storage.ts desktop/src/store/connectionStore.ts crates/zclaw-saas/src/auth/ # SaaS API (T11) crates/zclaw-saas/src/ (12 modules + workers) crates/zclaw-saas/tests/ ``` --- ## Chunk 1: Phase 1 环境准备 + T1 Hands 自主能力 --- ### Task 0: 环境准备 — 基线验证 **Files:** - Verify: `Cargo.toml`, `desktop/package.json`, `admin-v2/package.json` - Output: `docs/test-results/baseline/` - [ ] **Step 1: 创建测试结果目录** ```bash mkdir -p docs/test-results/baseline mkdir -p docs/test-results/T1-hands/screenshots mkdir -p docs/test-results/T2-intelligence/screenshots mkdir -p docs/test-results/T3-agent/screenshots mkdir -p docs/test-results/T4-classroom/screenshots mkdir -p docs/test-results/T5-pipeline/screenshots mkdir -p docs/test-results/T6-saas-desktop/screenshots mkdir -p docs/test-results/T7-skills/screenshots mkdir -p docs/test-results/T8-chat/screenshots mkdir -p docs/test-results/T9-admin/screenshots mkdir -p docs/test-results/T10-security/screenshots mkdir -p docs/test-results/T11-saas-api mkdir -p docs/test-results/T12-e2e/screenshots ``` - [ ] **Step 2: 启动 PostgreSQL** ```bash docker compose up -d postgres ``` Expected: `docker compose ps` 显示 postgres healthy - [ ] **Step 3: 启动 SaaS 后端** ```bash cd crates/zclaw-saas && ZCLAW_SAAS_DEV=true cargo run ``` Expected: 服务监听 `0.0.0.0:8080`,日志无 ERROR - [ ] **Step 4: 启动 Tauri 桌面端** ```bash cd desktop && pnpm tauri dev ``` Expected: 窗口打开,无 panic - [ ] **Step 5: 验证 tauri-mcp 连接** ```python manage_window(action='list') ``` Expected: 返回至少 1 个窗口,标题含 "ZCLAW" - [ ] **Step 6: 运行 Rust 基线测试** ```bash cargo test --workspace 2>&1 | tee docs/test-results/baseline/cargo-test.txt ``` Expected: 全部 pass,记录总测试数和通过数 - [ ] **Step 7: 运行 Desktop 前端基线测试** ```bash cd desktop && pnpm vitest run 2>&1 | tee ../docs/test-results/baseline/desktop-vitest.txt ``` Expected: 全部 pass,记录总测试数 - [ ] **Step 8: 运行 Admin 前端基线测试** ```bash cd admin-v2 && pnpm vitest run 2>&1 | tee ../docs/test-results/baseline/admin-vitest.txt ``` Expected: 全部 pass,记录总测试数 - [ ] **Step 9: 确认 LLM Provider 可用** 通过 tauri-mcp 在桌面端: ```python query_page(mode='map', interactive_only=True) ``` 找到模型选择器,确认至少有 1 个模型可选。 或> 注: tauri-mcp 命令使用伪代码表示(Python kwarg 风格),实际执行时需转换为对应工具的 JSON 参数格式。execute_js 中 `window.__TAURI_INTERNALS__.invoke(cmd, args)` 为 Tauri WebView 内部调用约定,需在执行时验证确切签名。 Expected: 至少 1 个 LLM Provider 的 API Key 已配置 - [ ] **Step 10: 记录基线结果** 在 `docs/test-results/baseline/README.md` 记录: - cargo test: X/Y passed - desktop vitest: X/Y passed - admin vitest: X/Y passed - SaaS 后端: running/not running - LLM Provider: available/unavailable - [ ] **Step 11: Commit 基线** ```bash git add docs/test-results/baseline/ git commit -m "test: add pre-launch audit baseline results" git push ``` --- ### Task 1: T1 Hands 自主能力 — V12 已知问题验证 **V12 健康度:** 58/100 | **风险:** HIGH | **V12 问题:** M3-01~M3-13 **Files:** - Audit: `docs/features/audit-v12/M3-hands-system.md` - Source: `desktop/src/store/handStore.ts`, `desktop/src/lib/kernel-hands.ts`, `desktop/src-tauri/src/kernel_commands/hand.rs` - Config: `hands/*.HAND.toml` - Rust impl: `crates/zclaw-hands/src/hands/` #### TC-1-01 | Hand 列举(正常) - [ ] **Step 1: 导航到自动化面板** ```python query_page(mode='map', interactive_only=True) ``` 找到 Automation/Hands 相关导航元素。 ```python click(selector_type='ref', selector_value='{nav_ref}') ``` Expected: 自动化面板显示 9 个已启用的 Hand - [ ] **Step 2: 截图记录 Hand 列表** ```python take_screenshot(filePath='docs/test-results/T1-hands/screenshots/TC-1-01-hand-list.png') ``` Expected: 截图显示 9 个 Hand 卡片(Browser/Researcher/Collector/Clip/Twitter/Whiteboard/Slideshow/Speech/Quiz),状态为 available #### TC-1-02 | Hand 直接触发 — Researcher(正常) - [ ] **Step 3: 触发 Researcher Hand** 在自动化面板点击 Researcher Hand: ```python click(selector_type='ref', selector_value='{researcher_ref}') ``` 如有参数输入框,输入测试参数: ```python type_text(text='测试研究主题:AI Agent 框架对比') ``` 点击执行: ```python click(selector_type='ref', selector_value='{execute_ref}') ``` Expected: Hand 进入 running 状态 - [ ] **Step 4: 验证执行状态** ```python wait_for(text=['completed', 'failed', 'Running', 'running'], timeout_ms=30000) take_screenshot(filePath='docs/test-results/T1-hands/screenshots/TC-1-02-researcher-result.png') ``` Expected: Researcher Hand 完成执行,显示研究结果 #### TC-1-03 | M3-01 验证: run_id 丢失问题 **V12 问题:** hand.rs:184 丢弃 `_run_id`,前端无法跟踪执行状态 **注意:** 当前 Rust 代码 `HandResult` 已有 `run_id` 字段,但前端类型定义 `kernel-hands.ts:94` 仍使用 `{ instance_id, status }` 与实际返回不匹配 - [ ] **Step 5: 通过 tauri-mcp 检查 triggerHand 返回值** 触发任意 Hand(如 Researcher),通过 execute_js 检查返回值结构: ```javascript async () => { try { const result = await window.__TAURI_INTERNALS__.invoke('hand_execute', { id: 'quiz', input: { topic: 'run_id test' }, autonomyLevel: 'autonomous' }); return JSON.stringify({ keys: Object.keys(result), hasRunId: 'run_id' in result || 'runId' in result, runIdValue: result.run_id || result.runId }); } catch (e) { return 'Error: ' + e; } } ``` Expected: 返回值含 `run_id` 字段(Rust 端已修复),但前端 `kernel-hands.ts` 的类型定义可能仍不匹配 - [ ] **Step 6: 截图记录** ```python take_screenshot(filePath='docs/test-results/T1-hands/screenshots/TC-1-03-run-id-check.png') ``` 记录结果到报告:run_id 是否存在、前端类型是否与 Rust 端对齐。 #### TC-1-04 | M3-07 验证: hand-execution-complete 事件监听 **V12 问题:** onHandExecutionComplete 未被调用,前端不更新执行结果 - [ ] **Step 7: 触发 Hand 并观察 UI 是否自动更新** 1. 触发一个 Hand(如 Quiz) 2. 不手动刷新页面 3. 等待 30 秒 ```python # 触发 Quiz Hand click(selector_type='ref', selector_value='{quiz_ref}') type_text(text='测试 Quiz 主题') click(selector_type='ref', selector_value='{execute_ref}') # 等待完成 wait_for(text=['completed', 'Complete', 'finished'], timeout_ms=60000) ``` Expected (如未修复): UI 不自动更新执行状态,需手动刷新 Expected (如已修复): UI 自动显示执行完成状态 - [ ] **Step 8: 截图** ```python take_screenshot(filePath='docs/test-results/T1-hands/screenshots/TC-1-04-event-listener.png') ``` #### TC-1-05 | M3-02 验证: Browser Hand 双路径断裂 **V12 问题:** Rust execute() 只返回结构化指令不执行实际操作 - [ ] **Step 9: 通过 handStore 触发 Browser Hand** 在自动化面板找到 Browser Hand 并触发: ```python click(selector_type='ref', selector_value='{browser_ref}') ``` 配置参数(如打开网页): ```python type_text(text='https://example.com') click(selector_type='ref', selector_value='{execute_ref}') ``` Expected (如未修复): 返回结构化指令 JSON 但不执行浏览器操作 Expected (如已修复): 实际打开/访问网页 - [ ] **Step 10: 对比 browserHandStore 路径** 通过 tauri-mcp 检查是否有独立的浏览器面板/功能: ```python query_page(mode='map', interactive_only=True) ``` Expected: browserHandStore 有独立的浏览器操作 UI,绕过 handStore 审批流程 - [ ] **Step 11: 截图** ```python take_screenshot(filePath='docs/test-results/T1-hands/screenshots/TC-1-05-browser-hand.png') ``` #### TC-1-06 | M3-03 验证: browserHandStore 绕过审批 **V12 问题:** 无视 TOML requires_approval = true - [ ] **Step 12: 设置自主级别为非自动** 在自动化设置中,将自主级别设为"需审批"(非 autonomous)。 通过 tauri-mcp: ```python navigate(action='goto', url='tauri://localhost/settings/automation') # 或点击设置页 click(selector_type='ref', selector_value='{settings_ref}') ``` 找到自主级别滑块/下拉框,设置为"需审批"。 - [ ] **Step 13: 通过 browserHandStore 执行操作** 在浏览器面板执行一个操作(如导航到 URL)。 Expected (如未修复): 操作直接执行,不弹出审批确认 Expected (如已修复): 弹出审批确认对话框 - [ ] **Step 14: 截图** ```python take_screenshot(filePath='docs/test-results/T1-hands/screenshots/TC-1-06-bypass-approval.png') ``` #### TC-1-07 | 审批流程 — 完整闭环(正常) - [ ] **Step 15: 触发需审批的 Hand** 确认有一个 Hand 配置了 `requires_approval = true`(检查 `hands/*.HAND.toml`)。 在自主级别为"需审批"模式下触发该 Hand。 Expected: 弹出审批队列/确认对话框 - [ ] **Step 16: 审批通过** ```python click(selector_type='ref', selector_value='{approve_ref}') ``` Expected: Hand 开始执行,完成后结果出现在 UI - [ ] **Step 17: 审批拒绝(重新触发)** 再次触发需审批的 Hand,这次拒绝: ```python click(selector_type='ref', selector_value='{reject_ref}') ``` Expected: Hand 不执行,状态显示"已拒绝" - [ ] **Step 18: 截图记录审批流程** ```python take_screenshot(filePath='docs/test-results/T1-hands/screenshots/TC-1-07-approval-flow.png') ``` #### TC-1-08 | M3-04 验证: max_concurrent 未实现(边界) **V12 问题:** TOML 定义但运行时无检查 - [ ] **Step 19: 并发触发同一 Hand** 同时触发同一 Hand 3-5 次: 方式 A(如 UI 允许):快速多次点击执行按钮。 方式 B(通过 execute_js): ```javascript async () => { // 连续触发同一 Hand 多次 for (let i = 0; i < 5; i++) { await window.__TAURI_INTERNALS__.invoke('hand_execute', { id: 'researcher', input: { query: `test ${i}` }, autonomyLevel: 'autonomous' }); } return 'triggered 5 times'; } ``` Expected (如未修复): 5 个全部开始执行,无并发限制 Expected (如已修复): 达到 max_concurrent 后拒绝或排队 - [ ] **Step 20: 截图** ```python take_screenshot(filePath='docs/test-results/T1-hands/screenshots/TC-1-08-concurrent.png') ``` #### TC-1-09 | M3-05 验证: timeout_secs 未实现(边界) **V12 问题:** Hand 可无限挂起 - [ ] **Step 21: 触发可能长时间运行的 Hand** 触发一个 Hand(如 Researcher 配合复杂查询),观察是否在 timeout_secs 内终止。 如果无法构造超时场景,检查 TOML 配置: ```bash grep -r "timeout_secs" hands/*.HAND.toml ``` Expected (如未修复): Hand 无超时保护,可能无限运行 Expected (如已修复): 超过 timeout_secs 后 Hand 自动终止 - [ ] **Step 22: 截图** ```python take_screenshot(filePath='docs/test-results/T1-hands/screenshots/TC-1-09-timeout.png') ``` #### TC-1-10 | Hand 取消(正常) - [ ] **Step 23: 触发长时间 Hand 并中途取消** 触发一个 Hand,在其 running 状态时点击取消: ```python click(selector_type='ref', selector_value='{cancel_ref}') ``` Expected: Hand 停止执行,状态变为 cancelled - [ ] **Step 24: 截图** ```python take_screenshot(filePath='docs/test-results/T1-hands/screenshots/TC-1-10-cancel.png') ``` #### TC-1-11 | M3-09 验证: 重复审批路径(正常) **V12 问题:** hand_approve vs approval_respond 两条重复路径 - [ ] **Step 25: 验证两条审批路径** 通过 Rust 日志或前端行为检查: 路径 A: `hand_approve` — 通过 handStore 直接审批 路径 B: `approval_respond` — 通过审批队列审批 检查两条路径是否行为一致(都触发执行,都 emit 事件)。 ```python take_screenshot(filePath='docs/test-results/T1-hands/screenshots/TC-1-11-dual-approval.png') ``` Expected: 两条路径均能完成审批并触发执行 #### TC-1-12 | 不存在的 Hand 触发(异常) - [ ] **Step 26: 触发不存在的 Hand** 通过 execute_js: ```javascript async () => { try { const result = await window.__TAURI_INTERNALS__.invoke('hand_execute', { id: 'nonexistent-hand', input: {}, autonomyLevel: 'autonomous' }); return JSON.stringify(result); } catch (e) { return `Error: ${e}`; } } ``` Expected: 返回错误 "not found" 或类似 #### TC-1-13 | M3-08 验证: 审批条目永不过期(异常) **V12 问题:** pending_approvals Vec 无限增长 - [ ] **Step 27: 累积审批条目** 触发多个需审批的 Hand,不审批它们。观察内存中 pending_approvals 是否持续增长。 通过 execute_js 检查: ```javascript async () => { const result = await window.__TAURI_INTERNALS__.invoke('approval_list', {}); return JSON.stringify(result); } ``` Expected (如未修复): 列表持续增长,无过期清理 Expected (如已修复): 有过期机制自动清理 量化标准: 触发 5 次审批,等待 60 秒,检查是否执行了过期清理(列表长度应 <= 5) #### TC-1-14 | 各 Hand 基础触发验证(正常) - [ ] **Step 28: 逐一触发 9 个已启用 Hand** 对每个 Hand 执行基本触发测试: | Hand | 测试输入 | 预期 | |------|---------|------| | Researcher | 主题:"AI 测试" | 返回研究结果 | | Collector | URL:"https://example.com" | 收集内容 | | Quiz | 主题:"Rust 基础" | 生成测验 | | Slideshow | 主题:"ZCLAW 介绍" | 生成幻灯片 | | Speech | 文本:"你好世界" | TTS 朗读 | | Whiteboard | 主题:"架构图" | 显示白板 | | Twitter | (需 OAuth 配置) | 检查是否正确报告配置缺失 | | Clip | (需 FFmpeg) | 检查是否正确报告依赖缺失 | | Browser | URL:"https://example.com" | 返回操作结果 | 每个 Hand 截图一张: ```python take_screenshot(filePath='docs/test-results/T1-hands/screenshots/TC-1-14-{hand_name}.png') ``` Expected: 每个 Hand 至少能触发(成功或返回明确的配置缺失提示) #### TC-1-15 | Hand 执行状态查询(正常) - [ ] **Step 29: 查询正在运行的 Hand 状态** 触发一个 Hand,在其 running 时查询状态: ```javascript async () => { const result = await window.__TAURI_INTERNALS__.invoke('hand_run_status', { handName: 'researcher', runId: '{run_id_if_available}' }); return JSON.stringify(result); } ``` Expected: 返回 running/pending/completed 状态 - [ ] **Step 30: 查询已完成 Hand 的状态** Expected: 返回 completed + 结果 #### TC-1-16 | M3-06 验证: hand_execute 返回值类型不匹配(正常) **V12 问题:** 前端期望 `{ instance_id, status }`,实际返回 `{ success, output, error, durationMs }` - [ ] **Step 31: 检查 triggerHand 完整返回值** ```javascript async () => { const result = await window.__TAURI_INTERNALS__.invoke('hand_execute', { id: 'quiz', input: { topic: 'test' }, autonomyLevel: 'autonomous' }); return JSON.stringify(Object.keys(result)); } ``` Expected (如未修复): 返回 `["success","output","error","durationMs"]` Expected (如已修复): 返回包含 `runId` 字段 - [ ] **Step 32: 截图** ```python take_screenshot(filePath='docs/test-results/T1-hands/screenshots/TC-1-16-return-type.png') ``` #### TC-1-17 | M3-10 验证: tool_count/metric_count 硬编码为 0(正常) - [ ] **Step 33: 检查 hand_list 返回值** ```javascript async () => { const result = await window.__TAURI_INTERNALS__.invoke('hand_list', {}); const counts = result.map(h => ({ name: h.name, toolCount: h.tool_count, metricCount: h.metric_count })); return JSON.stringify(counts); } ``` Expected (如未修复): 所有 Hand 的 tool_count 和 metric_count 均为 0 Expected (如已修复): 返回实际工具和指标数量 #### TC-1-18 | TOML 配置加载验证(正常) - [ ] **Step 34: 验证 TOML 配置被正确读取** ```javascript async () => { const result = await window.__TAURI_INTERNALS__.invoke('hand_list', {}); // 检查每个 hand 的 enabled、requires_approval 等字段 return JSON.stringify(result.map(h => ({ name: h.name, enabled: h.enabled, requiresApproval: h.requires_approval, timeoutSecs: h.timeout_secs, maxConcurrent: h.max_concurrent }))); } ``` 对照 `hands/*.HAND.toml` 中的配置值验证一致性。 Expected: enabled/requires_approval 正确,timeout_secs/max_concurrent 定义但可能未生效 #### TC-1-19 | Hand 错误处理(异常) - [ ] **Step 35: 触发 Hand 传入无效参数** ```javascript async () => { try { const result = await window.__TAURI_INTERNALS__.invoke('hand_execute', { id: 'researcher', input: null, autonomyLevel: 'autonomous' }); return JSON.stringify(result); } catch (e) { return `Error: ${e}`; } } ``` Expected: 返回明确错误信息(非 panic) #### TC-1-20 | M3-12 验证: hand_trigger 永远不自动允许(边界) **V12 问题:** autonomy-manager.ts:268 映射错误,hand_trigger 在 autonomous 模式下也不返回 allow - [ ] **Step 35b: 验证三个自主级别下 hand_trigger 的 canAutoExecute 结果** ```javascript async () => { // 检查 autonomy-manager 中 hand_trigger 映射 const levels = ['supervised', 'assisted', 'autonomous']; const results = {}; for (const level of levels) { // 模拟不同级别的 canAutoExecute 逻辑 results[level] = '需手动在 UI 中切换级别后验证'; } return JSON.stringify(results); } ``` 实际操作:在 UI 中依次切换自主级别为 supervised → assisted → autonomous,每次触发一个 Hand(如 Quiz)。 Expected (如未修复): autonomous 模式下 Hand 仍需审批(canAutoExecute 不返回 allow) Expected (如已修复): autonomous 模式下 Hand 自动执行(canAutoExecute 返回 allow) - [ ] **截图** ```python take_screenshot(filePath='docs/test-results/T1-hands/screenshots/TC-1-20-autonomy-mapping.png') ``` #### TC-1-21 | M3-13 验证: Clip Hand 路径含单引号(边界) **V12 问题:** clip.rs:448 FFmpeg concat 文件路径单引号未转义 - [ ] **Step 35c: 触发 Clip Hand 使用含单引号的路径** ```javascript async () => { try { const result = await window.__TAURI_INTERNALS__.invoke('hand_execute', { id: 'clip', input: { files: ["C:\\User's Files\\video.mp4"], action: 'concat' }, autonomyLevel: 'autonomous' }); return JSON.stringify(result); } catch (e) { return 'Error: ' + e; } } ``` Expected (如未修复): FFmpeg 解析失败或命令注入风险 Expected (如已修复): 正确转义单引号,返回正常结果或明确的路径错误 #### TC-1-22 | 无 LLM Provider 时触发 Hand(边界) - [ ] **Step 35d: 临时移除 LLM API Key 后触发 Researcher** 1. 进入设置,移除当前 Agent 的 API Key 2. 触发 Researcher Hand 3. 恢复 API Key Expected: 返回明确错误提示("未配置 API Key" 等),非 panic/空结果 #### TC-1-23 | 超长输入触发 Hand(边界) - [ ] **Step 35e: 触发 Hand 传入超长字符串** ```javascript async () => { const longInput = 'A'.repeat(100000); try { const result = await window.__TAURI_INTERNALS__.invoke('hand_execute', { id: 'quiz', input: { topic: longInput }, autonomyLevel: 'autonomous' }); return JSON.stringify({ status: 'returned', outputLen: JSON.stringify(result).length }); } catch (e) { return 'Error: ' + e; } } ``` Expected: 拒绝超长输入或截断处理,非崩溃 - [ ] **Step 36: Commit T1 测试结果** ```bash git add docs/test-results/T1-hands/ git commit -m "test(T1): hands system functional audit results" git push ``` - [ ] **Step 37: 生成 T1 测试报告** 在 `docs/test-results/T1-hands/REPORT.md` 中记录: - 执行用例数: 19/19 - 通过/失败数 - V12 已知问题验证结果(M3-01~M3-13) - 新发现问题清单 - 健康度重新评估(基线 58/100) ```bash git add docs/test-results/T1-hands/REPORT.md git commit -m "test(T1): add hands system audit report" git push ``` --- ## Chunk 2: T2 智能层 + T3 Agent 分身 --- ### Task 2: T2 智能层(记忆/反思/心跳/自主)— V12 已知问题验证 **V12 健康度:** 61/100 | **风险:** HIGH | **V12 问题:** M4-01~M4-15 (含 2 个 P0) **Files:** - Audit: `docs/features/audit-v12/M4-intelligence-layer.md` - Source: - 记忆: `desktop/src/store/memoryGraphStore.ts`, `desktop/src/lib/intelligence-client/memory.ts`, `desktop/src-tauri/src/intelligence/memory.rs` - 身份: `desktop/src/lib/intelligence-client/identity.ts`, `desktop/src-tauri/src/intelligence/identity.rs` - 反思: `desktop/src/lib/intelligence-client/reflection.ts`, `desktop/src-tauri/src/intelligence/reflection.rs` - 心跳: `desktop/src/lib/intelligence-client/heartbeat.ts`, `desktop/src-tauri/src/intelligence/heartbeat.rs` - 自主: `desktop/src/lib/autonomy-manager.ts`, `desktop/src/components/AutonomyConfig.tsx` - 压缩: `desktop/src/lib/intelligence-client/fallback-compactor.ts`, `desktop/src-tauri/src/intelligence/compactor.rs` - Runtime 中间件: `crates/zclaw-runtime/src/middleware/memory.rs`, `crates/zclaw-runtime/src/middleware/compaction.rs` - 存储: `crates/zclaw-growth/src/storage/sqlite.rs` #### TC-2-01 | M4-01 验证: 双数据库问题(P0) **V12 问题:** PersistentMemoryStore(LIKE) vs SqliteStorage(FTS5),数据不互通 - [ ] **Step 1: 通过前端保存一条记忆** 导航到记忆面板: ```python navigate(action='goto', url='tauri://localhost/memories') # 或通过导航点击 ``` 手动保存一条记忆:"测试记忆条目 - 上线前审计"。 ```python take_screenshot(filePath='docs/test-results/T2-intelligence/screenshots/TC-2-01a-save-memory.png') ``` - [ ] **Step 2: 验证该记忆出现在对话注入中** 进入对话界面,发送消息触发记忆搜索(发送与记忆相关的问题)。 ```python type_text(text='你记得什么关于上线前审计的信息?') click(selector_type='ref', selector_value='{send_ref}') wait_for(text=['测试记忆', '审计'], timeout_ms=15000) ``` Expected (如未修复): 手动保存的记忆不出现在对话回复中(因为 Runtime 用 SqliteStorage,前端用 PersistentMemoryStore) Expected (如已修复): 对话回复引用了手动保存的记忆内容 - [ ] **Step 3: 反向验证 — Agent 自动提取的记忆是否出现在前端面板** 进行多轮对话,触发自动记忆提取。然后检查记忆面板是否显示新提取的记忆。 ```python take_screenshot(filePath='docs/test-results/T2-intelligence/screenshots/TC-2-01b-memory-panel.png') ``` Expected (如未修复): Agent 提取的记忆不出现在前端记忆面板 Expected (如已修复): Agent 提取的记忆出现在前端面板 #### TC-2-02 | M4-02 验证: 反思 LLM 未接入(P0) **V12 问题:** reflection_reflect 传入 driver=None,LLM 分析从未生效 - [ ] **Step 4: 触发反思并检查是否使用 LLM** 通过 execute_js 直接调用反思: ```javascript async () => { const result = await window.__TAURI_INTERNALS__.invoke('reflection_reflect', { agentId: '{current_agent_id}', force: true }); return JSON.stringify({ keys: Object.keys(result), analysis: result.analysis?.substring(0, 200) }); } ``` Expected (如未修复): 返回规则分析结果(基于启发式规则),无 LLM 深度分析 Expected (如已修复): 返回包含 LLM 分析内容(更丰富的洞察) - [ ] **Step 5: 检查 Rust 端日志** 查看日志中是否有 LLM 调用记录: ```bash # 如果日志输出到文件 grep -i "reflection.*driver\|reflection.*llm\|reflect.*None" /tmp/zclaw-*.log 2>/dev/null || echo "No log file found" ``` Expected (如未修复): 日志显示 driver=None Expected (如已修复): 日志显示 driver=Some(...),有 LLM API 调用 - [ ] **Step 6: 截图** ```python take_screenshot(filePath='docs/test-results/T2-intelligence/screenshots/TC-2-02-reflection.png') ``` #### TC-2-03 | 记忆 CRUD(正常) - [ ] **Step 7: 创建记忆** ```python navigate(action='goto', url='tauri://localhost/memories') ``` 创建一条新记忆: - 类型: fact - 内容: "ZCLAW 上线前审计测试记忆" - 重要性: 7 ```python take_screenshot(filePath='docs/test-results/T2-intelligence/screenshots/TC-2-03a-create-memory.png') ``` - [ ] **Step 8: 搜索记忆** 搜索关键词 "上线前审计"。 ```python type_text(text='上线前审计') click(selector_type='ref', selector_value='{search_ref}') wait_for(text=['ZCLAW 上线前审计'], timeout_ms=5000) ``` Expected: 搜索结果显示刚创建的记忆 - [ ] **Step 9: 更新记忆** 修改记忆内容为 "ZCLAW 上线前审计测试记忆 - 已更新"。 Expected: 记忆内容成功更新 - [ ] **Step 10: 删除记忆** 删除刚创建的记忆。 Expected: 记忆从列表中消失 ```python take_screenshot(filePath='docs/test-results/T2-intelligence/screenshots/TC-2-03b-memory-crud.png') ``` #### TC-2-04 | M4-05 验证: 前端记忆搜索用 LIKE 非 FTS5(正常) **V12 问题:** PersistentMemoryStore 用 LIKE 模糊匹配,非 FTS5 - [ ] **Step 11: 测试搜索精度** 1. 创建多条记忆,内容包含 "机器学习" 2. 搜索 "机器" 3. 搜索 "学习" Expected (LIKE): 两个搜索都返回结果(模糊匹配) Expected (FTS5): "机器" 返回结果,"学习" 可能不返回(分词差异) ```python take_screenshot(filePath='docs/test-results/T2-intelligence/screenshots/TC-2-04-search-like.png') ``` #### TC-2-05 | 身份演化(正常) - [ ] **Step 12: 查看当前 Agent 身份** ```javascript async () => { const result = await window.__TAURI_INTERNALS__.invoke('identity_get', { agentId: '{current_agent_id}' }); return JSON.stringify({ hasSoul: !!result.soul, hasInstructions: !!result.instructions }); } ``` Expected: 返回当前 Agent 的 Soul 和 Instructions - [ ] **Step 13: 提出身份变更提案** ```javascript async () => { const result = await window.__TAURI_INTERNALS__.invoke('identity_propose_change', { agentId: '{current_agent_id}', dimension: 'communication_style', proposedValue: '更加技术性', reason: '测试身份演化' }); return JSON.stringify(result); } ``` Expected: 创建变更提案 - [ ] **Step 14: 审批/拒绝身份变更** ```python take_screenshot(filePath='docs/test-results/T2-intelligence/screenshots/TC-2-05-identity.png') ``` #### TC-2-06 | M4-03 验证: 心跳不自动启动(正常) **V12 问题:** 需前端手动初始化 heartbeat_init + heartbeat_start - [ ] **Step 15: 检查心跳是否自动运行** 应用启动后,检查心跳状态: ```javascript async () => { const result = await window.__TAURI_INTERNALS__.invoke('heartbeat_status', {}); return JSON.stringify(result); } ``` Expected (如未修复): 心跳未运行(需手动启动) Expected (如已修复): 心跳自动启动并运行 - [ ] **Step 16: 手动启动心跳(如未自动启动)** ```javascript async () => { await window.__TAURI_INTERNALS__.invoke('heartbeat_init', { intervalMinutes: 5 }); await window.__TAURI_INTERNALS__.invoke('heartbeat_start', {}); const status = await window.__TAURI_INTERNALS__.invoke('heartbeat_status', {}); return JSON.stringify(status); } ``` Expected: 心跳开始运行,显示下次巡检时间 - [ ] **Step 17: 截图** ```python take_screenshot(filePath='docs/test-results/T2-intelligence/screenshots/TC-2-06-heartbeat.png') ``` #### TC-2-07 | M4-04 验证: 自主授权后端无强制(正常) **V12 问题:** 仅前端咨询层,后端不检查自主授权级别 - [ ] **Step 18: 验证后端不检查自主级别** 设置自主级别为 supervised,然后通过 execute_js 直接调用 Rust 命令绕过前端: ```javascript async () => { // 前端 autonomy-manager 设为 supervised // 但直接调用 Tauri 命令绕过前端检查 const result = await window.__TAURI_INTERNALS__.invoke('hand_execute', { id: 'quiz', input: { topic: 'autonomy test' }, autonomyLevel: 'supervised' // 后端是否检查? }); return JSON.stringify({ executed: result.success }); } ``` Expected (如未修复): 后端直接执行,不检查自主级别 Expected (如已修复): 后端根据自主级别决定是否需要审批 #### TC-2-08 | 上下文压缩(正常) - [ ] **Step 19: 触发上下文压缩** 进行多轮对话使上下文变长,然后触发压缩: ```javascript async () => { const result = await window.__TAURI_INTERNALS__.invoke('compaction_compact', { agentId: '{current_agent_id}', sessionId: '{current_session_id}' }); return JSON.stringify({ success: result.success, originalTokens: result.original_tokens, compressedTokens: result.compressed_tokens }); } ``` Expected: 返回压缩结果,compressedTokens < originalTokens ```python take_screenshot(filePath='docs/test-results/T2-intelligence/screenshots/TC-2-08-compaction.png') ``` #### TC-2-09 | M4-06 验证: types 参数数组 vs 单值(边界) **V12 问题:** 前端 `types?: MemoryType[]` vs 后端 `memory_type?: string` - [ ] **Step 20: 测试传入多种类型搜索** ```javascript async () => { const result = await window.__TAURI_INTERNALS__.invoke('memory_search', { query: 'test', types: ['fact', 'procedure'] // 前端传数组 }); return JSON.stringify({ count: result?.length || 0 }); } ``` Expected (如未修复): 后端只接收第一个类型或报错 Expected (如已修复): 后端正确处理多类型搜索 #### TC-2-10 | 记忆内容无长度限制(异常) **V12 问题:** M4-07 content 无长度限制 - [ ] **Step 21: 保存超长记忆** ```javascript async () => { const longContent = 'A'.repeat(1000000); // 1MB try { const result = await window.__TAURI_INTERNALS__.invoke('memory_save', { agentId: '{current_agent_id}', memory: { content: longContent, memoryType: 'fact', importance: 5 } }); return JSON.stringify({ saved: true, id: result.id }); } catch (e) { return 'Error: ' + e; } } ``` Expected: 拒绝或截断(非无限制保存导致内存问题) #### TC-2-11 | 心跳 interval 下限验证(边界) **V12 问题:** M4-09 interval_minutes 无下限验证 - [ ] **Step 22: 设置极短心跳间隔** ```javascript async () => { try { await window.__TAURI_INTERNALS__.invoke('heartbeat_init', { intervalMinutes: 0.001 }); return 'No validation - accepted 0.001 minutes'; } catch (e) { return 'Blocked: ' + e; } } ``` Expected (如未修复): 接受极短间隔,可能导致频繁心跳 Expected (如已修复): 拒绝低于最小值(如 1 分钟) #### TC-2-12 | 反思引擎边界测试(边界) - [ ] **Step 23: 在无记忆的情况下触发反思** ```javascript async () => { const result = await window.__TAURI_INTERNALS__.invoke('reflection_reflect', { agentId: 'nonexistent-agent', force: true }); return JSON.stringify(result); } ``` Expected: 返回空分析或明确的"无数据"提示,非 panic #### TC-2-13 | 两套压缩实现验证(正常) **V12 问题:** M4-13 Tauri 层和 Runtime 层各有独立压缩实现 - [ ] **Step 24: 对比两套压缩配置** 检查 Tauri 层 compactor.rs 和 Runtime 层 compaction.rs 的默认配置是否一致。 ```python take_screenshot(filePath='docs/test-results/T2-intelligence/screenshots/TC-2-13-compaction-dual.png') ``` - [ ] **Step 25: Commit T2 测试结果** ```bash git add docs/test-results/T2-intelligence/ git commit -m "test(T2): intelligence layer functional audit results" git push ``` - [ ] **Step 26: 生成 T2 测试报告** 在 `docs/test-results/T2-intelligence/REPORT.md` 中记录: - 执行用例数: 13/13 - 通过/失败数 - V12 已知问题验证结果(M4-01~M4-15) - 新发现问题清单 - 健康度重新评估(基线 61/100) ```bash git add docs/test-results/T2-intelligence/REPORT.md git commit -m "test(T2): add intelligence layer audit report" git push ``` --- ### Task 3: T3 Agent 分身 — V12 已知问题验证 **V12 健康度:** 67/100 | **风险:** HIGH | **V12 问题:** M2-01~M2-14 (含 2 个 P1) **Files:** - Audit: `docs/features/audit-v12/M2-agent-clones.md` - Source: `desktop/src/store/agentStore.ts`, `desktop/src/lib/kernel-agent.ts`, `desktop/src/components/AgentSelector.tsx` - Rust: `desktop/src-tauri/src/kernel_commands/agent.rs`, `crates/zclaw-kernel/src/kernel/agents.rs` #### TC-3-01 | Agent 列举(正常) - [ ] **Step 27: 查看 Agent 列表** ```python query_page(mode='map', interactive_only=True) ``` 找到 Agent 选择器/管理入口并点击。 Expected: 显示至少 1 个默认 Agent ```python take_screenshot(filePath='docs/test-results/T3-agent/screenshots/TC-3-01-agent-list.png') ``` #### TC-3-02 | M2-01 验证: KernelClient createClone 字段丢失(P1) **V12 问题:** kernel-agent.ts 只传 name/description/model 3 字段,丢 7+ 人格字段 - [ ] **Step 28: 通过 Kernel 模式创建 Agent(含完整人格字段)** 在 Agent 管理界面创建新 Agent,填写所有字段: - 名称: "审计测试 Agent" - 描述: "用于测试字段传递" - 表情: "🤖" - 性格: "严谨、精确" - 沟通风格: "技术导向" - 备注: "测试备注" ```python type_text(text='审计测试 Agent') # 依次填写其他字段 click(selector_type='ref', selector_value='{create_ref}') ``` - [ ] **Step 29: 检查 SQLite 中 Agent 配置** ```javascript async () => { const result = await window.__TAURI_INTERNALS__.invoke('agent_list', {}); const testAgent = result.find(a => a.name === '审计测试 Agent'); if (!testAgent) return 'Agent not found'; return JSON.stringify({ name: testAgent.name, hasEmoji: !!testAgent.config?.emoji, hasPersonality: !!testAgent.config?.personality, configKeys: Object.keys(testAgent.config || {}) }); } ``` Expected (如未修复): config 中缺少 emoji/personality/communicationStyle 等字段 Expected (如已修复): config 包含所有传入的人格字段 ```python take_screenshot(filePath='docs/test-results/T3-agent/screenshots/TC-3-02-field-loss.png') ``` #### TC-3-03 | M2-02 验证: 双通路创建不对等(P1) **V12 问题:** Gateway 构建完整 TOML manifest,Kernel 仅 3 字段 - [ ] **Step 30: 对比 Kernel 和 Gateway 两条通路的创建结果** 创建两个 Agent: 1. Agent A: 通过 Kernel 模式创建 2. Agent B: 通过 Gateway 模式创建(如 Gateway 可用) 对比两个 Agent 的配置完整度。 Expected (如未修复): Kernel 创建的 Agent 缺少人格字段,Gateway 创建的完整 Expected (如已修复): 两条通路创建结果一致 ```python take_screenshot(filePath='docs/test-results/T3-agent/screenshots/TC-3-03-dual-path.png') ``` #### TC-3-04 | Agent 更新(正常) - [ ] **Step 31: 更新 Agent 属性** 修改刚创建的 Agent: - 更新名称 - 更新描述 - 更新 system prompt - 更新模型 ```python click(selector_type='ref', selector_value='{edit_ref}') type_text(text='审计测试 Agent - 已更新') click(selector_type='ref', selector_value='{save_ref}') ``` Expected: 所有更新生效 ```python take_screenshot(filePath='docs/test-results/T3-agent/screenshots/TC-3-04-update.png') ``` #### TC-3-05 | Agent 切换(正常) - [ ] **Step 32: 切换到新创建的 Agent** ```python click(selector_type='ref', selector_value='{agent_selector_ref}') click(selector_type='ref', selector_value='{test_agent_ref}') ``` Expected: Agent 切换成功,UI 显示新 Agent 名称 - [ ] **Step 33: 发送消息验证 Agent 身份** ```python type_text(text='你好,你是谁?') click(selector_type='ref', selector_value='{send_ref}') wait_for(text=['审计测试', 'Agent'], timeout_ms=15000) ``` Expected: AI 回复体现新 Agent 的身份/个性 #### TC-3-06 | M2-06 验证: Agent 切换不通知 Kernel(正常) **V12 问题:** 切换 Agent 不更新 defaultAgentId - [ ] **Step 34: 切换 Agent 后检查 Kernel 状态** ```javascript async () => { // 切换到新 Agent 后检查 const agentId = await window.__TAURI_INTERNALS__.invoke('get_default_agent', {}); return JSON.stringify({ defaultAgentId: agentId }); } ``` Expected (如未修复): defaultAgentId 未更新为刚切换的 Agent Expected (如已修复): defaultAgentId 正确更新 #### TC-3-07 | M2-07 验证: 切换不取消流(正常) **V12 问题:** 流式中切换 Agent,消息可能追到错误对话 - [ ] **Step 35: 流式中切换 Agent** 1. 发送一条长消息(触发长时间流式响应) 2. 在流式响应进行中,切换到另一个 Agent ```python type_text(text='请详细解释 Rust 的生命周期系统') click(selector_type='ref', selector_value='{send_ref}') # 立即切换 Agent click(selector_type='ref', selector_value='{agent_selector_ref}') click(selector_type='ref', selector_value='{another_agent_ref}') ``` Expected (如未修复): 原有流继续在后台运行,响应可能出现在错误的对话 Expected (如已修复): 切换前自动取消进行中的流 ```python take_screenshot(filePath='docs/test-results/T3-agent/screenshots/TC-3-07-switch-during-stream.png') ``` #### TC-3-08 | Agent 删除(正常) - [ ] **Step 36: 删除测试 Agent** ```python click(selector_type='ref', selector_value='{delete_ref}') ``` Expected: 删除成功,Agent 从列表消失 #### TC-3-09 | M2-05 验证: 删除不检查活跃状态(异常) **V12 问题:** 删除正在使用的 Agent 无警告 - [ ] **Step 37: 删除当前活跃的 Agent** 切换到一个 Agent,然后直接删除它。 Expected (如未修复): 直接删除,无警告 Expected (如已修复): 弹出警告"该 Agent 正在使用中" ```python take_screenshot(filePath='docs/test-results/T3-agent/screenshots/TC-3-09-delete-active.png') ``` #### TC-3-10 | M2-08 验证: 无参数验证(异常) **V12 问题:** 空 name、温度越界无验证 - [ ] **Step 38: 创建空名 Agent** ```javascript async () => { try { const result = await window.__TAURI_INTERNALS__.invoke('agent_create', { name: '', description: 'test', model: 'gpt-4' }); return JSON.stringify({ created: true, id: result.id }); } catch (e) { return 'Error: ' + e; } } ``` Expected (如未修复): 成功创建空名 Agent Expected (如已修复): 拒绝空名称 - [ ] **Step 39: 设置越界 temperature** ```javascript async () => { try { const result = await window.__TAURI_INTERNALS__.invoke('agent_update', { agentId: '{test_agent_id}', updates: { temperature: 5.0 } }); return JSON.stringify({ updated: true }); } catch (e) { return 'Error: ' + e; } } ``` Expected (如未修复): 接受 temperature=5.0 Expected (如已修复): 拒绝越界值 #### TC-3-11 | M2-09 验证: 删除后 selectedAgent 引用(异常) **V12 问题:** 删除当前选中 Agent 后引用可能悬挂 - [ ] **Step 40: 删除当前选中 Agent 后检查状态** 1. 选中 Agent A 2. 删除 Agent A 3. 检查 conversationStore.currentAgent 是否有效 ```javascript async () => { // 删除后检查 const state = document.querySelector('[data-agent-name]')?.textContent; return state || 'No agent selected'; } ``` Expected (如未修复): currentAgent 指向已删除 Agent Expected (如已修复): 自动切换到第一个可用 Agent #### TC-3-12 | Agent 从模板创建(正常) - [ ] **Step 41: 从模板创建 Agent** 检查是否有模板创建功能,如有则测试。 ```python take_screenshot(filePath='docs/test-results/T3-agent/screenshots/TC-3-12-template-create.png') ``` - [ ] **Step 42: Commit T3 测试结果** ```bash git add docs/test-results/T3-agent/ git commit -m "test(T3): agent clones functional audit results" git push ``` - [ ] **Step 43: 生成 T3 测试报告** 在 `docs/test-results/T3-agent/REPORT.md` 中记录: - 执行用例数: 12/12 - 通过/失败数 - V12 已知问题验证结果(M2-01~M2-14) - 新发现问题清单 - 健康度重新评估(基线 67/100) ```bash git add docs/test-results/T3-agent/REPORT.md git commit -m "test(T3): add agent clones audit report" git push ``` > **Chunk 2 执行前必读:** 所有 `execute_js` 中的 Tauri 命令名需在执行时与 `desktop/src-tauri/src/lib.rs` 的 `invoke_handler` 注册列表核对。V12 审计后部分问题(M4-01/M4-02)可能已修复,以实际代码为准。 --- ## Chunk 3: T4 课堂系统 + T5 Pipeline 工作流 --- ### Task 4: T4 课堂系统 — V12 已知问题验证 **V12 健康度:** 70/100 | **风险:** HIGH | **V12 问题:** M11-01~M11-08 (含 3 个 P1) **Files:** - Audit: `docs/features/audit-v12/M11-classroom.md` - Source: `desktop/src/store/classroomStore.ts`, `desktop/src/components/Classroom/` - Rust: `desktop/src-tauri/src/kernel_commands/classroom.rs`, `desktop/src-tauri/src/intelligence/classroom/` #### TC-4-01 | 课堂生成(正常) - [ ] **Step 44: 触发课堂生成** 导航到课堂功能,输入主题生成课堂: ```python type_text(text='Rust 所有权系统') click(selector_type='ref', selector_value='{generate_ref}') ``` Expected: 显示生成进度,4 阶段 pipeline 逐步完成 - [ ] **Step 45: 等待生成完成** ```python wait_for(text=['completed', '生成完成', 'Complete'], timeout_ms=120000) take_screenshot(filePath='docs/test-results/T4-classroom/screenshots/TC-4-01-generation.png') ``` Expected: 课堂生成成功,显示场景列表 #### TC-4-02 | M11-01 验证: is_cancelled() blocking_lock 死锁(P1) **V12 问题:** generate.rs:141-144 async 函数中使用 blocking_lock,tokio 可能死锁 - [ ] **Step 46: 生成过程中取消课堂** 1. 开始生成一个课堂 2. 在生成过程中点击取消 ```python click(selector_type='ref', selector_value='{cancel_generation_ref}') ``` Expected (如未修复): 取消请求可能触发 tokio 死锁,应用卡住 Expected (如已修复): 取消成功,生成停止,无死锁 ```python take_screenshot(filePath='docs/test-results/T4-classroom/screenshots/TC-4-02-cancel-deadlock.png') ``` #### TC-4-03 | M11-02 验证: LLM 调用无 map_err(P1) **V12 问题:** Stage 0/1 LLM 调用无 map_err,driver 未配置时可能 panic - [ ] **Step 47: 在无 LLM 配置时生成课堂** 临时移除 LLM API Key,然后尝试生成课堂。 Expected (如未修复): 可能 panic 或返回空结果无错误提示 Expected (如已修复): 返回明确的错误信息 #### TC-4-04 | 场景播放(正常) - [ ] **Step 48: 播放已生成的课堂场景** ```python click(selector_type='ref', selector_value='{scene_1_ref}') ``` Expected: 场景自动播放,显示 speech/whiteboard/quiz actions ```python take_screenshot(filePath='docs/test-results/T4-classroom/screenshots/TC-4-04-scene-play.png') ``` #### TC-4-05 | TTS 朗读(正常) - [ ] **Step 49: 触发 TTS 朗读** 在场景播放中点击朗读按钮。 Expected: 浏览器 TTS 以 zh-CN 语言朗读场景内容 ```python take_screenshot(filePath='docs/test-results/T4-classroom/screenshots/TC-4-05-tts.png') ``` #### TC-4-06 | 白板渲染(正常) - [ ] **Step 50: 查看白板场景** 导航到含白板 action 的场景。 Expected: 白板内容正确渲染(SVG 或 Canvas) ```python take_screenshot(filePath='docs/test-results/T4-classroom/screenshots/TC-4-06-whiteboard.png') ``` #### TC-4-07 | M11-03 验证: 课堂数据仅存内存(P1) **V12 问题:** HashMap 存储,重启丢失 - [ ] **Step 51: 重启应用后检查课堂数据** 1. 确认有已生成的课堂 2. 重启 Tauri 应用 3. 检查课堂是否还在 Expected (如未修复): 重启后所有课堂消失 Expected (如已修复): 课堂数据持久化,重启后仍存在 #### TC-4-08 | 课堂聊天(正常) - [ ] **Step 52: 在课堂中进行聊天** ```python type_text(text='请解释一下这个概念') click(selector_type='ref', selector_value='{chat_send_ref}') wait_for(text=['解释'], timeout_ms=15000) ``` Expected: LLM 多 agent 响应课堂聊天 #### TC-4-09 | 课堂导出(正常) - [ ] **Step 53: 导出课堂为 JSON/Markdown** ```python click(selector_type='ref', selector_value='{export_ref}') ``` Expected: 文件下载成功 ```python take_screenshot(filePath='docs/test-results/T4-classroom/screenshots/TC-4-09-export.png') ``` #### TC-4-10 | M11-04 验证: LLM 失败静默 fallback(异常) **V12 问题:** LLM 失败静默 fallback 到 placeholder - [ ] **Step 54: 制造 LLM 失败场景** 在课堂聊天中,临时使 LLM 不可用。 Expected (如未修复): 回复是 placeholder 但用户无法区分 Expected (如已修复): 标记为 placeholder 或显示错误提示 #### TC-4-11 | M11-05 验证: 生成完成强制打开(正常) **V12 问题:** 生成完成后强制打开 player - [ ] **Step 55: 生成期间关闭 player,观察完成后行为** Expected (如未修复): player 被强制重新打开 Expected (如已修复): 尊重手动关闭状态 #### TC-4-12 | 课堂历史列表(正常) - [ ] **Step 56: 检查课堂历史列表功能** Expected: 确认 classroom_list 前端集成状态 - [ ] **Step 57: Commit T4 测试结果** ```bash git add docs/test-results/T4-classroom/ git commit -m "test(T4): classroom system functional audit results" git push ``` --- ### Task 5: T5 Pipeline 工作流 — V12 已知问题验证 **V12 健康度:** 72/100 | **风险:** MEDIUM | **V12 问题:** M6-01~M6-08 (含 2 个 P1) **Files:** - Audit: `docs/features/audit-v12/M6-pipeline-workflow.md` - Source: `desktop/src/store/workflowStore.ts`, `desktop/src/components/WorkflowBuilder/` - Rust: `crates/zclaw-pipeline/src/` #### TC-5-01 | Pipeline 列举发现(正常) - [ ] **Step 58: 查看 Pipeline 列表** ```python navigate(action='goto', url='tauri://localhost/pipelines') ``` Expected: 显示已有 Pipeline(含 10 行业模板) ```python take_screenshot(filePath='docs/test-results/T5-pipeline/screenshots/TC-5-01-pipeline-list.png') ``` #### TC-5-02 | M6-02 验证: v1/v2 解析器分裂(P1) **V12 问题:** pipeline_list 只用 v1 解析器,v2 格式被静默丢弃 - [ ] **Step 59: 检查 v2 格式 Pipeline 是否显示** ```javascript async () => { const result = await window.__TAURI_INTERNALS__.invoke('pipeline_list', {}); return JSON.stringify({ count: result?.length, names: result?.map(p => p.name) }); } ``` Expected (如未修复): 仅显示 v1 格式 Pipeline Expected (如已修复): v1 和 v2 格式都正确列举 #### TC-5-03 | Pipeline 执行(正常) - [ ] **Step 60: 执行一个 Pipeline** ```python click(selector_type='ref', selector_value='{pipeline_ref}') click(selector_type='ref', selector_value='{execute_ref}') wait_for(text=['completed', 'Running'], timeout_ms=60000) take_screenshot(filePath='docs/test-results/T5-pipeline/screenshots/TC-5-03-execution.png') ``` #### TC-5-04 | Pipeline 监控(正常) - [ ] **Step 61: 查看执行进度** Expected: 返回进度信息(百分比、当前步骤) #### TC-5-05 | M6-01 验证: route_intent 未注册(P1) **V12 问题:** route_intent Tauri 命令未注册 - [ ] **Step 62: 验证 IntentInput 组件** Expected (如未修复): IntentInput 报错或无响应 Expected (如已修复): IntentInput 返回推荐 Pipeline #### TC-5-06 | Pipeline 取消(正常) - [ ] **Step 63: 执行中取消 Pipeline** Expected: Pipeline 停止执行 #### TC-5-07 | M6-03 验证: pipeline_create Action 类型丢失(正常) **V12 问题:** 只映射 Hand 类型,丢失 LLM/Parallel/Condition - [ ] **Step 64: 创建包含多种 Action 类型的 Pipeline** Expected (如未修复): 非 Hand 类型步骤被映射为 Hand Expected (如已修复): 正确保留所有 Action 类型 #### TC-5-08 | Pipeline 导出(正常) - [ ] **Step 65: 导出 Pipeline 配置** Expected: 导出为 YAML/JSON 格式 - [ ] **Step 66: Commit T5 测试结果** ```bash git add docs/test-results/T5-pipeline/ git commit -m "test(T5): pipeline workflow functional audit results" git push ``` --- ## Chunk 4: T6 SaaS 集成 + T7 技能生态 + T8 智能对话 > **所有 execute_js 命令名需在执行时验证。** --- ### Task 6: T6 SaaS 桌面集成 **V12 健康度:** 85/100 | **风险:** MEDIUM | **V12 问题:** M7-01~M7-06 (含 2 个 P1) **Files:** - Audit: `docs/features/audit-v12/M7-saas-desktop.md` - Source: `desktop/src/lib/saas-client.ts`, `desktop/src/store/saasStore.ts`, `desktop/src/components/SaaS/` #### TC-6-01 | SaaS 登录(正常) - [ ] **Step 67: SaaS 登录流程** 导航到 SaaS 登录页面,输入凭据登录。 Expected: 登录成功,JWT Cookie 设置,session 恢复 ```python take_screenshot(filePath='docs/test-results/T6-saas-desktop/screenshots/TC-6-01-login.png') ``` #### TC-6-02 | M7-04 验证: refreshToken 未传 refresh_token body(P1) **V12 问题:** Tauri 非浏览器可能无 cookie 自动附加 - [ ] **Step 68: 验证 token 刷新** 等待 JWT 过期(或手动触发刷新),检查是否成功获取新 token。 Expected (如未修复): 刷新失败(cookie 未附加) Expected (如已修复): 刷新成功 #### TC-6-03 | M7-02 验证: ConfigMigrationWizard PUT 路径参数错误(P1) **V12 问题:** PUT 使用布尔值 exists 作为路径参数 - [ ] **Step 69: 触发配置迁移向导** Expected (如未修复): PUT 请求发送错误参数 Expected (如已修复): PUT 请求发送正确的 config item ID #### TC-6-04 | 模型列表 + 聊天中继(正常) - [ ] **Step 70: 通过 SaaS Relay 获取模型列表** Expected: 返回可用模型列表 - [ ] **Step 71: 通过 SaaS Relay 发送聊天消息** Expected: SSE 流式响应正确 #### TC-6-05 | 配置同步(正常) - [ ] **Step 72: 配置 pull + diff + sync** Expected: 配置正确同步 #### TC-6-06 | M7-01 验证: 密码长度不一致(边界) - [ ] **Step 73: 验证前端密码最少 6 字符 vs 后端 8 字符** Expected (如未修复): 前端允许 6 字符密码但后端拒绝 Expected (如已修复): 前后端统一为 8 字符 - [ ] **Step 74: Commit T6 测试结果** ```bash git add docs/test-results/T6-saas-desktop/ git commit -m "test(T6): SaaS desktop integration audit results" git push ``` --- ### Task 7: T7 技能生态 **V12 健康度:** 85/100 | **风险:** LOW | **V12 问题:** M5-01~M5-06 (含 1 个 P1) **Files:** - Audit: `docs/features/audit-v12/M5-skill-ecosystem.md` - Source: `desktop/src/lib/skill-discovery.ts`, `crates/zclaw-skills/src/`, `skills/` (75 SKILL.md) #### TC-7-01 | M5-01 验证: tags 误映射为 triggers(P1) **V12 问题:** convertFromBackend() 将 tags 映射为 triggers - [ ] **Step 75: 检查技能列表中 tags 和 triggers 字段** ```javascript async () => { const result = await window.__TAURI_INTERNALS__.invoke('skill_list', {}); const sample = result.slice(0, 5).map(s => ({ name: s.name, tags: s.tags, triggers: s.triggers, category: s.category })); return JSON.stringify(sample); } ``` 对照 `skills/*.SKILL.md` 中的 frontmatter 验证 tags 和 triggers 是否正确映射。 Expected (如未修复): tags 值出现在 triggers 字段,真实 triggers 丢失 Expected (如已修复): tags 和 triggers 各自正确 #### TC-7-02 | 技能加载 + 解析(正常) - [ ] **Step 76: 验证 75 个 SKILL.md 全部加载** ```javascript async () => { const result = await window.__TAURI_INTERNALS__.invoke('skill_list', {}); return JSON.stringify({ total: result.length }); } ``` Expected: 返回 75 个技能 #### TC-7-03 | 技能语义路由(正常) - [ ] **Step 77: 测试语义路由匹配** 发送一条消息触发技能路由,验证是否正确匹配到相关技能。 #### TC-7-04 | M5-02 验证: SKILL.md tools 字段未解析(P2) - [ ] **Step 78: 检查 skill_list 返回值中是否有 tools 字段** Expected (如未修复): 技能对象中无 tools 字段 Expected (如已修复): 技能对象包含 tools 定义 #### TC-7-05 | M5-03 验证: Python 硬编码 python3(边界) - [ ] **Step 79: 在 Windows 上执行 Python 模式技能** Expected (如未修复): Windows 上 `python3` 不存在,执行失败 Expected (如已修复): 自动检测 `python` 或 `python3` #### TC-7-06 | 技能采样执行(正常) - [ ] **Step 80: 采样执行 5 个不同执行模式的技能** | 执行模式 | 测试技能 | 预期 | |---------|---------|------| | PromptOnly | 任选 1 个 | LLM 处理 | | Python | 任选 1 个 | Python 脚本执行 | | Shell | 任选 1 个 | Shell 命令执行 | 每个技能截图一张 - [ ] **Step 81: Commit T7 测试结果** ```bash git add docs/test-results/T7-skills/ git commit -m "test(T7): skill ecosystem audit results" git push ``` --- ### Task 8: T8 智能对话 **V12 健康度:** 91/100 | **风险:** LOW | **V12 问题:** M1-01~M1-11 (全部 P2/P3) **Files:** - Audit: `docs/features/audit-v12/M1-intelligent-chat.md` 由于健康度最高(91/100),仅执行核心流程验证和已知 P2 问题抽样。 #### TC-8-01 | 流式聊天核心流程(正常) - [ ] **Step 82: 发送消息验证流式响应** ```python type_text(text='你好,请介绍一下你自己') click(selector_type='ref', selector_value='{send_ref}') wait_for(text=['AI', '助手', '你好'], timeout_ms=15000) ``` Expected: 流式响应正常显示 ```python take_screenshot(filePath='docs/test-results/T8-chat/screenshots/TC-8-01-streaming.png') ``` #### TC-8-02 | 模型切换(正常) - [ ] **Step 83: 切换模型并验证** 在模型选择器中切换到不同的 Provider/模型,发送新消息。 Expected: 切换后使用新模型响应 #### TC-8-03 | 推理模式(正常) - [ ] **Step 84: 启用推理模式发送消息** Expected: 显示推理过程(ReasoningBlock) #### TC-8-04 | 工具调用链(正常) - [ ] **Step 85: 触发工具调用的消息** Expected: 显示工具调用链(ToolCallChain) #### TC-8-05 | 取消流(正常) - [ ] **Step 86: 流式中取消** Expected: 取消成功,部分结果显示 #### TC-8-06 | 多 Provider 连通(正常) - [ ] **Step 87: 逐一验证可用 Provider** 对每个已配置的 Provider 发送一条测试消息。 Expected: 每个返回有效响应或明确的配置错误 #### TC-8-07 | Markdown 渲染(正常) - [ ] **Step 88: 请求 Markdown 格式回复** ```python type_text(text='请用 Markdown 格式列出 5 个编程语言的特点') ``` Expected: 代码块、列表、表格等正确渲染 - [ ] **Step 89: Commit T8 测试结果** ```bash git add docs/test-results/T8-chat/ git commit -m "test(T8): intelligent chat audit results" git push ``` --- ## Chunk 5: T9 Admin V2 + T10 安全 + T11 SaaS API + T12 端到端 --- ### Task 9: T9 Admin V2 管理后台 **V12 健康度:** 82/100 | **风险:** MEDIUM | **V12 问题:** M8-01~M8-08 (P2/P3) **Files:** - Audit: `docs/features/audit-v12/M8-admin-v2.md` - Source: `admin-v2/src/pages/` (15 页面), `admin-v2/tests/` (~71 测试) - Config: `admin-v2/vitest.config.ts` #### TC-9-01 | Admin 登录(正常) - [ ] **Step 90: 登录 Admin V2** 在浏览器中打开 Admin V2(默认 http://localhost:5174),使用管理员凭据登录。 Expected: 登录成功,Cookie 设置正确 #### TC-9-02 | 15 页面 CRUD(正常) - [ ] **Step 91: 逐一验证 15 个页面加载** | 页面 | 测试操作 | 预期 | |------|---------|------| | Dashboard | 查看概览 | 数据正常显示 | | Accounts | 查看/编辑账户 | CRUD 正常 | | ModelServices | CRUD 操作 | 模型配置正确保存 | | Relay | 查看中继任务 | 列表显示 | | Billing | 查看计费 | 信息显示 | | Logs | 查看日志 | 分页正常 | | Prompts | CRUD + 版本 | 版本历史正确 | | Roles | CRUD | 角色权限正确 | | Knowledge | CRUD + 搜索 | FTS5 搜索工作 | | ScheduledTasks | CRUD | 调度配置正确 | | AgentTemplates | CRUD | 模板保存正确 | | Usage | 查看 | 统计图表显示 | | Config | 查看/编辑 | 配置同步 | | Login | 登录/登出 | 认证流程完整 | 每个页面截图一张。 #### TC-9-03 | M8-02 验证: Relay 缺 retry(正常) - [ ] **Step 92: 检查 Relay 页面是否有重试按钮** Expected (如未修复): Relay 任务只有查看,无重试操作 Expected (如已修复): 有重试按钮 #### TC-9-04 | 5 页缺失测试验证(正常) - [ ] **Step 93: 确认 5 个缺测试页面的状态** | 缺测试页面 | 验证方式 | |-----------|---------| | Billing | 手动 CRUD 测试 | | ConfigSync | 手动同步测试 | | Knowledge | FTS5 搜索测试 | | Roles | CRUD + 权限测试 | | ScheduledTasks | CRUD 测试 | #### TC-9-05 | TOTP 验证(正常) - [ ] **Step 94: Admin 账户设置 TOTP** Expected: QR 码显示,TOTP 验证通过 #### TC-9-06 | M8-03 验证: ROLE_PERMISSIONS 硬编码(边界) - [ ] **Step 95: 验证前端权限是否与后端同步** Expected (如未修复): 前端硬编码权限与后端可能不一致 Expected (如已修复): 权限从 API 动态获取 - [ ] **Step 96: Commit T9 测试结果** ```bash git add docs/test-results/T9-admin/ git commit -m "test(T9): admin V2 audit results" git push ``` --- ### Task 10: T10 通信与安全 **V12 健康度:** 86/100 | **风险:** LOW | **V12 问题:** M9-01~M9-09 (P2/P3) **Files:** - Audit: `docs/features/audit-v12/M9-communication-security.md` #### TC-10-01 | 三模式连接验证(正常) - [ ] **Step 97: 验证 Kernel 模式连接** Expected: Tauri invoke 正常工作 - [ ] **Step 98: 验证 SaaS Relay 模式连接** Expected: HTTP Cookie + SSE 正常 #### TC-10-02 | M9-01/M9-02 验证: require() 混用(P2) - [ ] **Step 99: 检查 SaaS Relay 分支是否使用 require()** 在浏览器控制台观察是否有 CommonJS 错误。 Expected (如未修复): ESM+Vite 环境下 require() 报错 Expected (如已修复): 使用 await import() 替代 #### TC-10-03 | 安全基线验证(正常) - [ ] **Step 100: 运行安全相关 cargo test** ```bash cargo test --workspace -- security 2>&1 | tee docs/test-results/T10-security/cargo-security.txt ``` Expected: 安全测试全部通过 #### TC-10-04 | JWT/TOTP/限流验证(正常) - [ ] **Step 101: 验证 JWT password_version 机制** 修改密码后,旧 JWT 应失效。 - [ ] **Step 102: 验证登录限流(5次/分钟)** 快速尝试 6 次登录。 Expected: 第 6 次被限流拒绝 - [ ] **Step 103: Commit T10 测试结果** ```bash git add docs/test-results/T10-security/ git commit -m "test(T10): communication and security audit results" git push ``` --- ### Task 11: T11 SaaS 后端 API **V12 健康度:** N/A | **风险:** MEDIUM | **无 V12 审计报告** **Files:** - Source: `crates/zclaw-saas/src/` (12 modules + workers), `crates/zclaw-saas/tests/` #### TC-11-01 | SaaS 集成测试基线(正常) - [ ] **Step 104: 运行 SaaS 集成测试** ```bash cd crates/zclaw-saas && cargo test 2>&1 | tee ../../../docs/test-results/T11-saas-api/cargo-test.txt ``` Expected: 全部 pass #### TC-11-02 | 核心 API 端点抽样验证(正常) - [ ] **Step 105: 验证关键端点** | 端点 | 方法 | 预期 | |------|------|------| | /api/v1/auth/login | POST | 返回 JWT | | /api/v1/auth/me | GET | 返回用户信息 | | /api/v1/relay/models | GET | 返回模型列表 | | /api/v1/relay/chat/completions | POST | SSE 流 | | /api/v1/admin/accounts | GET | 返回账户列表 | | /api/v1/admin/dashboard/stats | GET | 返回统计数据 | 每个端点用 curl 验证: ```bash # 示例 curl -s -X POST http://localhost:8080/api/v1/auth/login \ -H "Content-Type: application/json" \ -d '{"username":"admin","password":"test"}' | jq . ``` #### TC-11-03 | 权限检查验证(正常) - [ ] **Step 106: 验证非管理员无法访问 admin 端点** Expected: 返回 403 Forbidden #### TC-11-04 | 数据库迁移验证(正常) - [ ] **Step 107: 验证数据库 schema 版本** ```bash PGPASSWORD=zclaw psql -h localhost -U zclaw -d zclaw -c "SELECT * FROM _schema_version;" 2>&1 ``` Expected: schema_version = 14(当前版本) - [ ] **Step 108: Commit T11 测试结果** ```bash git add docs/test-results/T11-saas-api/ git commit -m "test(T11): SaaS backend API audit results" git push ``` --- ### Task 12: T12 端到端用户场景 **V12 健康度:** N/A | **风险:** HIGH | **跨模块集成** #### TC-12-01 | E2E-01: 新用户首次对话 - [ ] **Step 109: 完整新用户对话流程** 1. 打开应用 → 首次引导 2. 选择模型 → 发送消息 3. 验证流式响应 涉及模块: T8, T3, T7 ```python take_screenshot(filePath='docs/test-results/T12-e2e/screenshots/TC-12-01-first-chat.png') ``` #### TC-12-02 | E2E-02: Agent 创建与使用 - [ ] **Step 110: 创建 Agent → 配置 → 切换 → 验证身份** 涉及模块: T3, T8, T2 #### TC-12-03 | E2E-03: Hand 触发与审批 - [ ] **Step 111: 对话中触发 Hand → 审批 → 查看结果** 涉及模块: T1, T2, T8 #### TC-12-04 | E2E-04: SaaS 登录与订阅 - [ ] **Step 112: SaaS 登录 → 订阅状态 → 配置同步** 涉及模块: T6, T10 #### TC-12-05 | E2E-05: Pipeline 创建与执行 - [ ] **Step 113: 创建 Pipeline → 配置 → 执行 → 导出** 涉及模块: T5, T1 #### TC-12-06 | E2E-06: 记忆与反思闭环 - [ ] **Step 114: 多轮对话 → 记忆提取 → 验证存储 → 反思触发** 涉及模块: T2, T3, T8 #### TC-12-07 | E2E-07: Admin 管理全流程 - [ ] **Step 115: Admin 登录 → 管理 → 配置 → 日志** 涉及模块: T9, T11 #### TC-12-08 | E2E-08: 离线与重连 - [ ] **Step 116: 断开 SaaS 后端 → 离线模式 → 恢复 → 重连** 1. 关闭 SaaS 后端进程 2. 验证应用降级到 Kernel 模式 3. 恢复 SaaS 后端 4. 验证自动重连 涉及模块: T1, T2, T6, T8 #### TC-12-09 | E2E-09: 课堂场景播放 - [ ] **Step 117: 进入课堂 → 播放 → TTS → 白板 → 笔记** 涉及模块: T4, T1 #### TC-12-10 | E2E-10: 技能发现与执行 - [ ] **Step 118: 浏览技能 → 安装 → 触发 → 验证结果** 涉及模块: T7, T8 #### TC-12-11 | 回归验证 - [ ] **Step 119: 重新运行基线测试** ```bash cargo test --workspace 2>&1 | tee docs/test-results/T12-e2e/regression-cargo.txt cd desktop && pnpm vitest run 2>&1 | tee ../docs/test-results/T12-e2e/regression-vitest.txt cd admin-v2 && pnpm vitest run 2>&1 | tee ../docs/test-results/T12-e2e/regression-admin.txt ``` Expected: 通过率不低于基线 - [ ] **Step 120: 生成最终缺陷清单** 在 `docs/test-results/DEFECT_LIST.md` 中汇总所有 T1-T12 发现的缺陷: - P0 缺陷数(目标: 0) - P1 缺陷数(目标: <= 2) - P2/P3/P4 缺陷列表 - [ ] **Step 121: 生成上线评估报告** 在 `docs/test-results/RELEASE_READINESS.md` 中对照达标标准: | 强制达标项 | 标准 | 结果 | |-----------|------|------| | P0 缺陷 | 0 | ? | | P1 缺陷 | <= 2 | ? | | 核心流程通过 | 100% | ? | | 自动化测试 | 全部通过 | ? | | 安全 | 无 HIGH 缺陷 | ? | - [ ] **Step 122: Commit 最终结果** ```bash git add docs/test-results/ git commit -m "test: complete pre-launch functional audit T1-T12" git push ``` --- ## 执行总结 ### 测试用例统计 | 模块 | 风险 | 测试用例数 | 预计时间 | |------|------|-----------|---------| | T0 环境准备 | - | 11 步 | 0.5 天 | | T1 Hands | HIGH | 23 用例 | 1 天 | | T2 智能层 | HIGH | 13 用例 | 1 天 | | T3 Agent | HIGH | 12 用例 | 0.5 天 | | T4 课堂 | HIGH | 12 用例 | 0.5 天 | | T5 Pipeline | MEDIUM | 8 用例 | 0.5 天 | | T6 SaaS 集成 | MEDIUM | 6 用例 | 0.5 天 | | T7 技能 | LOW | 6 用例 | 0.5 天 | | T8 对话 | LOW | 7 用例 | 0.5 天 | | T9 Admin | MEDIUM | 6 用例 | 0.5 天 | | T10 安全 | LOW | 4 用例 | 0.5 天 | | T11 SaaS API | MEDIUM | 4 用例 | 0.5 天 | | T12 E2E | HIGH | 11 用例 | 1.5 天 | | **总计** | | **~123 用例** | **8-10 天** | > 注: 实际用例数 ~123 低于 spec 估计的 170-230,因为本计划聚焦于 V12 已知问题验证和核心流程测试,而非穷举测试。每个模块的边界和异常用例可在执行中根据发现的问题补充。 ### 执行顺序 ``` Phase 1: Task 0 (环境准备) → 阻塞门控 Phase 2: T1 → T2 → T3 → T4 (高风险模块) Phase 3: T5 → T6 → T7 → T8 → T9 → T10 → T11 (中低风险) Phase 4: T12 (E2E 集成) 最终: DEFECT_LIST.md + RELEASE_READINESS.md ``` ### 上线达标门控 在 Phase 2 完成后(T1-T4),检查: - [ ] P0 缺陷 = 0 - [ ] P1 缺陷 <= 2 - [ ] 聊天/Agent CRUD/Hand 触发/SaaS 登录 4 条主路径通过 如果未达标,暂停 Phase 3,优先修复 P0/P1。