diff --git a/.claude/skills/d8d-dev/modes/journey/journey-definition.md b/.claude/skills/d8d-dev/modes/journey/journey-definition.md index 133d786..50470da 100644 --- a/.claude/skills/d8d-dev/modes/journey/journey-definition.md +++ b/.claude/skills/d8d-dev/modes/journey/journey-definition.md @@ -108,6 +108,10 @@ **规则 3:前置条件必须明确且可验证** - 每个旅程必须写明"操作前系统/用户应处于什么状态" +- 遵循**自包含性原则**:前置条件只限用户状态和系统配置状态,禁止业务数据依赖 + - ✅ 允许:`用户已登录` / `用户已授权连接 TikTok` + - ❌ 禁止:`已有一个处理完成的视频` / `已有订单等待发货` +- 所有业务数据必须通过 UI 操作创建,不得跳过 - ❌ "用户提交申请"(什么用户?什么状态?) - ✅ "前置:用户已登录(有 token),且 organizer=null(无局头身份)" diff --git a/.claude/skills/d8d-dev/modes/journey/journey-execution.md b/.claude/skills/d8d-dev/modes/journey/journey-execution.md index 32666fe..d80aef1 100644 --- a/.claude/skills/d8d-dev/modes/journey/journey-execution.md +++ b/.claude/skills/d8d-dev/modes/journey/journey-execution.md @@ -186,7 +186,11 @@ curl 只用于补充数据验证(如确认数据库状态),**永远不能 - browser_resize → 正确视口(小程序 375x812 / 管理后台 1440x900) - 读取旅程定义的前置条件 - curl/API 验证前置条件(✅ 允许 curl) - - 前置条件不满足 → FAIL + - 检测到违规(前置条件包含业务数据依赖,违反 R6 自包含性原则)→ ❌ BLOCKED + - 不允许使用 curl 自动创建数据补全前置条件 + - 必须要求旅程定义重写,补充完整的 UI 上传/创建步骤 + - 旅程标记 FAIL,不进入执行阶段 + - 前置条件不满足且不违规 → FAIL 2. 执行阶段(按用户视角步骤逐一执行 — ⛔ 只能用 Playwright): - browser_navigate → 起始页(自然入口)(⛔ 禁止用 curl 替代) diff --git a/.claude/skills/d8d-dev/rules/auto-fix-engine.md b/.claude/skills/d8d-dev/rules/auto-fix-engine.md index 3dd5dca..f8e29ac 100644 --- a/.claude/skills/d8d-dev/rules/auto-fix-engine.md +++ b/.claude/skills/d8d-dev/rules/auto-fix-engine.md @@ -69,26 +69,6 @@ **核心原则**: "已知" ≠ "已修复"。任何在之前的验证轮次中被发现但未实际修复的问题,在后续轮次再次检测到时,**必须**立即触发修复,不得以任何理由跳过。 -### ⛔ "已修复标记不可信"规则(⛔ 强制 — 交互缺陷审计表专用) - -**核心原则**: 旅程文件中交互缺陷审计表的"✅ 已修复"标记**不等同于实际验证通过**。 - -1. 验证执行时遇到"✅ 已修复"的缺陷,**必须重新验证该修复是否正确**: - - 读取标记对应的源码文件,确认修复代码存在 - - 如果涉及跳转:验证跳转目标是否正确(不只是"有 handler") - - 如果涉及数据:验证数据流是否正确(不只是"不报错") - -2. **禁止行为**: - - ❌ 看到"✅ 已修复"就跳过该交互元素的验证 - - ❌ 以"上次已修复"为由跳过实际 UI 交互测试 - - ❌ 仅检查 handler 是否存在而不验证 handler 的行为是否正确 - -3. **典型案例(V19 漏检教训)**: - - 审计标记:"报名派对按钮 | 无 handler | ✅ 已修复" - - 实际修复:添加了 handleSignUp 函数 - - 但修复错误:用了 `event-detail` 而非 `venue-detail`(venue.id ≠ event.id) - - 验证 agent 信任"已修复"标记 → 漏检错误修复 - **判定流程**: ``` 检测到 FAIL → 查分类表确定修复类型 @@ -112,6 +92,26 @@ - 第 2 轮仍未修复 → **强制修复**(不得延迟,不得降级为 WARN) - 第 3+ 轮仍未修复 → **阻断当前旅程**(标记 FAIL + 输出修复失败报告) +### ⛔ "已修复标记不可信"规则(⛔ 强制 — 交互缺陷审计表专用) + +**核心原则**: 旅程文件中交互缺陷审计表的"✅ 已修复"标记**不等同于实际验证通过**。 + +1. 验证执行时遇到"✅ 已修复"的缺陷,**必须重新验证该修复是否正确**: + - 读取标记对应的源码文件,确认修复代码存在 + - 如果涉及跳转:验证跳转目标是否正确(不只是"有 handler") + - 如果涉及数据:验证数据流是否正确(不只是"不报错") + +2. **禁止行为**: + - ❌ 看到"✅ 已修复"就跳过该交互元素的验证 + - ❌ 以"上次已修复"为由跳过实际 UI 交互测试 + - ❌ 仅检查 handler 是否存在而不验证 handler 的行为是否正确 + +3. **典型案例(V19 漏检教训)**: + - 审计标记:"报名派对按钮 | 无 handler | ✅ 已修复" + - 实际修复:添加了 handleSignUp 函数 + - 但修复错误:用了 `event-detail` 而非 `venue-detail`(venue.id ≠ event.id) + - 验证 agent 信任"已修复"标记 → 漏检错误修复 + ### 关键判断流程 - API 404 → `grep` 检查路由文件是否存在 → 存在 = Bug(#2) → 不存在 = 未实现(#1) @@ -267,35 +267,6 @@ - 后端路由缺失 → `Write` 新 `route.ts` + `handler` - 图标方案未实施 → 按方案安装 Tailwind + Iconify -### AUTO-RETRY(Playwright 崩溃专用,max 3 次) - -**适用**: Playwright MCP 浏览器崩溃、超时、无响应(FAIL #22) - -**流程**: -``` -Playwright 操作返回错误/超时: - ↓ -1. 诊断: 确认是 MCP 超时/浏览器崩溃(而非业务逻辑错误) - - 特征: browser_snapshot/browser_click 返回 "timeout" / "disconnected" / 无响应 - - 非特征: 页面显示业务错误(404/500/Toast)→ 走正常 FAIL 分类 - ↓ -2. 恢复: 等待 10 秒 → 重新 browser_navigate 到当前页面 - ↓ -3. 重试: 从崩溃的步骤重新执行(不从头开始) - - 读取 verification-checklist.yaml 找到当前步骤 - - 重试当前步骤(max 3x) - ↓ -4. 重试耗尽: 仍崩溃 → 标记 journey-step-crash + 记录 crash_log - - ⛔ 禁止标记 PARTIAL PASS 跳过 - - 必须记录崩溃的具体错误信息 -``` - -**⛔ 禁止行为**: -- ❌ Playwright 崩溃后标记 PARTIAL PASS 跳过 UI 验证 -- ❌ 以"浏览器环境不稳定"为由跳过交互验证 -- ❌ 不重试直接标记 crash 并继续 -- ❌ 将业务逻辑错误(Toast/400/500)误分类为 Playwright 崩溃 - **Emoji → Iconify 替换方案(检测到 emoji 充当功能图标时使用 ⛔ 强制)**: ⛔ **完整安装配置、使用方式、禁止方案列表见 ../reference/platform-uni-app.md 第 1 节。禁止自行发明替代方案。** @@ -327,6 +298,35 @@ Playwright 操作返回错误/超时: - `handlePhoneLogin()`: 调用 `POST /api/auth/login {phone, code}`,成功后跳转首页 4. **清理**: 删除 Mock 登录按钮(`v-if="isDev" class="mock-btn"`)和 `handleMockLogin()` 函数 +### AUTO-RETRY (Playwright 崩溃专用,max 3 次) + +**适用**: Playwright MCP 浏览器崩溃、超时、无响应(FAIL #22) + +**流程**: +``` +Playwright 操作返回错误/超时: + ↓ +1. 诊断: 确认是 MCP 超时/浏览器崩溃(而非业务逻辑错误) + - 特征: browser_snapshot/browser_click 返回 "timeout" / "disconnected" / 无响应 + - 非特征: 页面显示业务错误(404/500/Toast)→ 走正常 FAIL 分类 + ↓ +2. 恢复: 等待 10 秒 → 重新 browser_navigate 到当前页面 + ↓ +3. 重试: 从崩溃的步骤重新执行(不从头开始) + - 读取 verification-checklist.yaml 找到当前步骤 + - 重试当前步骤(max 3x) + ↓ +4. 重试耗尽: 仍崩溃 → 标记 journey-step-crash + 记录 crash_log + - ⛔ 禁止标记 PARTIAL PASS 跳过 + - 必须记录崩溃的具体错误信息 +``` + +**⛔ 禁止行为**: +- ❌ Playwright 崩溃后标记 PARTIAL PASS 跳过 UI 验证 +- ❌ 以"浏览器环境不稳定"为由跳过交互验证 +- ❌ 不重试直接标记 crash 并继续 +- ❌ 将业务逻辑错误(Toast/400/500)误分类为 Playwright 崩溃 + ### AUTO-FIX #14: 即时使用数据持久化(max 1 次) **适用**: FAIL #14 — 即时使用数据(验证码等)仅通过 Toast 显示,无 console.log,下一步骤无法获取 diff --git a/.claude/skills/d8d-dev/rules/journey-authenticity-rules.md b/.claude/skills/d8d-dev/rules/journey-authenticity-rules.md index e1bc680..771eee3 100644 --- a/.claude/skills/d8d-dev/rules/journey-authenticity-rules.md +++ b/.claude/skills/d8d-dev/rules/journey-authenticity-rules.md @@ -135,7 +135,67 @@ grep -rn "import.meta.env.DEV\|process.env.NODE_ENV\|isDev" app/mini-program/src --- -## 规则 R6:用户操作可行性兜底原则 +## 规则 R6:旅程自包含性原则 + +### 核心原则 + +旅程必须是**从用户原始状态开始的完整操作序列**,禁止依赖测试环境预先存在的数据。所有业务数据必须通过用户 UI 操作创建,不得在前置条件中假设数据已存在。 + +### 规则细则 + +#### ✅ 允许的前置条件: +- 用户认证状态:`用户已登录` / `用户未登录` / `Admin 账号可用` +- 系统配置状态:`平台连接配置已完成` / `账号已授权` + +#### ❌ 禁止的前置条件(数据依赖): +- ❌ `"已有至少一个处理完成的视频"` +- ❌ `"已有订单"` +- ❌ `"数据已导入"` +- ❌ `"已有选中的封面"` + +### 为什么必须强制: +- 真实用户首次使用系统时,确实没有任何预先存在的数据 +- 测试环境定期清零,无法保证数据持久存在 +- 缺失"上传→创建"步骤会导致这部分 UI 永远得不到验证 + +### 检测方法 + +1. 扫描旅程的"前置条件"段落 +2. 匹配模式:`已有` / `存在` / `包含` + `视频/订单/数据/内容/封面/平台` +3. 如果发现数据依赖 → ❌ 违规,必须修复 + +### 修复策略 + +检测到违规 → 旅程必须从头重写: + +``` +原违规前置:"用户已登录,已有至少一个处理完成的视频" + ↓ 修复 +1. 保留:用户已登录(允许) +2. 补充完整 UI 步骤: + - 用户点击"上传视频"按钮 + - 用户选择视频文件 → browser_file_upload + - 用户等待上传完成 → 等待处理完成 + - 然后进入原有旅程步骤 +``` + +### 例外场景(允许数据依赖) + +只有以下场景允许依赖预先存在的数据: +1. **增量操作场景**:旅程本身就是"编辑已有 X",且用户必须先创建才能编辑 + - 示例:"编辑用户头像"旅程,前置条件"用户已登录且已有头像"是允许的 + - 但必须有另一条完整旅程覆盖"上传头像"操作 +2. **纯后台管理功能**:数据由批量导入产生,用户只做审核/审批操作 +3. 例外必须标注:`⚠️ 例外:本旅程是编辑操作,"上传创建"由另一条旅程覆盖` + +### 通过标准 +- 前置条件仅包含用户状态和系统状态 +- 不包含业务数据依赖 +- 所有业务数据必须通过用户 UI 操作创建 + +--- + +## 规则 R7:用户操作可行性兜底原则 > **⛔ 通用规则,不需要为每种操作类型单独定义子规则。** @@ -268,7 +328,7 @@ uni.showToast({ title: "验证码已发送", icon: "success" }) --- -## 规则 R7:约束声明必须与代码实际行为一致 +## 规则 R8:约束声明必须与代码实际行为一致 > **⛔ 通用规则,检测旅程描述和页面 UI 文案中的约束声明与代码实际验证逻辑的不一致。** @@ -356,7 +416,7 @@ A 和 B 均不满足 → 普通 FAIL #12 (ENV-ADAPT) → 按提示补填继续 --- -## 规则 R8:页面/视图覆盖深度(⛔ 强制) +## 规则 R9:页面/视图覆盖深度(⛔ 强制) ### 核心原则 @@ -382,24 +442,16 @@ A 和 B 均不满足 → 普通 FAIL #12 (ENV-ADAPT) → 按提示补填继续 1. 从 app-client.tsx 或路由配置提取所有独立视图: grep -n "currentView\|view ===\|render.*View\|component" src/components/features/app-client.tsx - ⚠️ uni-app 小程序项目:从 pages.json 提取所有页面路由 - grep -n '"path"' app/mini-program/src/pages.json - 2. 对每个视图组件,统计用户交互元素: grep -c "onClick\|handleClick\|onChange\|handleSelect\|onSubmit" src/components/features/{view-component}.tsx - ⚠️ uni-app 小程序页面:统计 @tap / @click 事件绑定 - grep -c "@tap\|@click\|@tap.stop\|@click.stop\|bindtap\|bind:tap" app/mini-program/src/pages/{page}/index.vue - 3. 具体分类: - - 按钮: onClick / handleClick / button / @click / @tap - ⚠️ uni-app: @tap / @click / bindtap(注意 uni-app 编译后 @tap 和 @click 都生效) + - 按钮: onClick / handleClick / button - 输入框: input / textarea / type="text" - 选择器: select / dropdown / combobox / Select - 分页: page / pagination / nextPage / setPage - 导出: export / download / csv / excel - 弹窗: dialog / modal / open / close - - ⚠️ uni-app 特有:navigateTo / redirectTo / switchTab(页面跳转类交互) ``` ### 检测方法 @@ -448,7 +500,7 @@ A 和 B 均不满足 → 普通 FAIL #12 (ENV-ADAPT) → 按提示补填继续 ## 自动校验执行流程(定义和验证通用) ``` -步骤 1:逐规则校验(R1 → R2 → R3 → R4 → R5 → R7 → R8) +步骤 1:逐规则校验(R1 → R2 → R3 → R4 → R5 → R6 → R7 → R8 → R9) ↓ 步骤 2:汇总结果 ├── 全部 PASS → 返回校验通过