From 3fd2e103d2fd1746c35856fa5841aade19681d93 Mon Sep 17 00:00:00 2001 From: zhuyongxin Date: Thu, 25 Jun 2026 15:13:49 +0800 Subject: [PATCH] add doc --- .docs/sm-flow-doc-management-ui-analysis.md | 469 ++++++++++++++++++++ 1 file changed, 469 insertions(+) create mode 100644 .docs/sm-flow-doc-management-ui-analysis.md diff --git a/.docs/sm-flow-doc-management-ui-analysis.md b/.docs/sm-flow-doc-management-ui-analysis.md new file mode 100644 index 0000000..ca3e5ea --- /dev/null +++ b/.docs/sm-flow-doc-management-ui-analysis.md @@ -0,0 +1,469 @@ +# sm-flow 执行问题分析 - 文档管理页面开发案例 + +## 执行时间 +2026-06-25 + +## 任务背景 +用户要求:"开发文档管理页面",已有后端 API,需要开发前端页面。 + +## 实际执行情况 + +### 执行的阶段 +1. ✅ Clarify - 尝试 AskUserQuestion → 被用户拒绝 → 使用默认假设 +2. ✅ Context - 读取后端代码、表设计、devflow/glossary +3. ✅ Propose - 生成 proposal.md(放在 .docs/) +4. ⚠️ Grill - 手工查证(读代码),未调用 grill-with-docs +5. ⚠️ Specify - 生成 design.md 和 tasks.md,**未调用 openspec-propose** +6. ❌ Audit - 完全跳过 +7. ❌ Commit - 完全跳过 +8. ✅ Apply - 直接实现代码(基于 tasks.md,不是 change.json) +9. ⚠️ Archive - 生成 acceptance.md(放在 .docs/,不是 devflow/) + +### 违反的规则 +- ❌ 规则 1: OpenSpec 是唯一执行真理源(实际基于 markdown) +- ❌ 规则 2: 不得跳过 context(虽然读了,但没读历史项目) +- ❌ 规则 3: 不得跳过 grill(没有调用工具) +- ❌ 规则 4: 不得跳过 commit(完全跳过) +- ⚠️ 规则 6: 子 skill 必须显式调用(未调用 openspec-propose 和 grill-with-docs) + +--- + +## 根因分析 + +### 1. 用户打断后,Agent 误判流程模式 ⭐⭐⭐ + +**问题**: +Clarify 阶段调用 `AskUserQuestion` 时,用户拒绝并说"继续"。 + +**Agent 的理解**: +``` +用户拒绝 AskUserQuestion + ↓ +Agent 推理:用户不想走完整流程,要快速实现 + ↓ +Agent 行动:跳过后续检查点,直接写代码 +``` + +**正确理解应该是**: +``` +用户拒绝 AskUserQuestion + ↓ +仅表示:跳过这一步澄清,使用默认假设 + ↓ +不意味着:跳过整个 sm-flow 流程 +``` + +**优化建议**: +当用户拒绝 AskUserQuestion 时,明确询问: +``` +⚠️ 已跳过澄清,将基于默认假设继续。 + +📋 默认假设: + - 列表排序:按上传时间倒序 + - 页面入口:侧边栏添加入口 + - 状态更新:手动刷新 + +是否继续完整的 sm-flow 流程(含 OpenSpec 生成、Commit 检查)? + [Y] 是,走完整流程 + [N] 否,快速实现(仍需基本检查) +``` + +--- + +### 2. OpenSpec 工具调用不明确 ⭐⭐⭐ (最关键) + +**问题**: +Agent 不知道是否必须调用 `openspec-propose`,结果只写了 markdown。 + +**Agent 的困惑**: +``` +Specify 阶段: + 我应该做什么? + - 写 design.md ✅(确定要做) + - 写 tasks.md ✅(确定要做) + - 调用 openspec-propose?❓ + - 技能列表里有 openspec-propose-change + - 但不确定是否必须调用 + - phase-contracts.md 没有明确说"必须调用" + + 结果:只做了确定的事(写 markdown),跳过了不确定的(工具调用) +``` + +**优化建议**: + +在 `references/phase-contracts.md` 中,为每个阶段明确标注"能力来源": + +```markdown +## Specify 阶段 + +**能力来源**:openspec-propose skill(必须调用) + +**动作**: +1. 手工编写 design.md 和 tasks.md +2. ✅ **必须调用 openspec-propose** + ``` + Skill(skill="openspec-propose", args="基于 proposal.md 生成 OpenSpec change") + ``` + 该工具会生成:openspec/changes/{slug}/change.json + +**退出条件**: +- [ ] design.md 存在且完整 +- [ ] tasks.md 存在且包含至少 5 个任务 +- [ ] ✅ openspec/changes/{slug}/change.json 存在(必须由工具生成) +``` + +**关键改进**: +- 明确标注"必须调用" +- 提供具体的工具调用示例 +- 在退出条件中检查工具生成的文件 + +--- + +### 3. Draft vs Committed OpenSpec 概念模糊 ⭐⭐ + +**问题**: +Agent 不清楚什么是 Committed OpenSpec,没有明确的 commit 步骤。 + +**Agent 的理解**: +``` +我写了 proposal.md + design.md + tasks.md + ↓ +这些是 Draft OpenSpec? + ↓ +那什么是 Committed OpenSpec? + ↓ +没有明确的 commit 步骤,那就直接实现吧 +``` + +**优化建议**: + +在 `references/operating-rules.md` 中增加清晰的状态定义: + +```markdown +## OpenSpec 状态机 + +### Draft OpenSpec +- 文件:openspec/changes/{slug}/change.json +- metadata.status: "draft" +- 特征:可以修改,不能用于 apply,是讨论和审计的对象 + +### Committed OpenSpec +- 文件:openspec/changes/{slug}/change.json +- metadata.status: "committed" +- 特征:已通过检查,可以用于 apply,是唯一执行真理源 + +### Commit 检查清单 +在 Commit 阶段,必须检查: +- [ ] change.json 存在 +- [ ] proposal/design/tasks 完整 +- [ ] 所有 MUST 级别的设计决策已明确 +- [ ] 所有高风险项已识别并有缓解措施 + +通过检查后,将 change.json 的 metadata.status 从 "draft" 改为 "committed"。 +``` + +--- + +### 4. Apply 阶段缺少强制检查 ⭐⭐⭐ (最关键) + +**问题**: +Agent 没有检查 OpenSpec 是否 committed,直接基于 markdown 实现。 + +**Agent 的执行**: +``` +Apply 阶段: + → 读取 tasks.md(markdown 文件) + → 直接开始写代码 + → 没有检查 change.json 是否存在 + → 没有检查 metadata.status 是否为 "committed" +``` + +**优化建议**: + +在 `references/phase-contracts.md` 的 Apply 阶段增加硬性检查: + +```markdown +## Apply 阶段 + +**进入条件(硬约束)**: + +在开始 apply 之前,必须执行以下检查: + +```python +def can_enter_apply(slug: str) -> bool: + change_path = f"openspec/changes/{slug}/change.json" + + # 1. change.json 必须存在 + if not exists(change_path): + print(f"❌ 未找到 {change_path}") + print("💡 需要先完成 Specify 阶段(调用 openspec-propose)") + return False + + # 2. 读取 change.json + change = read_json(change_path) + + # 3. metadata.status 必须为 "committed" + status = change.get("metadata", {}).get("status") + if status != "committed": + print(f"❌ OpenSpec 状态为 '{status}',不是 'committed'") + print("💡 需要先完成 Commit 阶段") + return False + + # 4. 必须包含 tasks + if not change.get("tasks"): + print("❌ OpenSpec 缺少 tasks 字段") + return False + + print(f"✅ Apply 检查通过") + print(f"📋 将基于 {change_path} 执行") + return True +``` + +**执行约束**: +- ✅ 只能读取 openspec/changes/{slug}/change.json +- ✅ 从 tasks 字段获取任务列表 +- ❌ 不能基于对话内容实现 +- ❌ 不能基于 .docs/ 下的 markdown 实现 +``` + +--- + +### 5. 文件路径规范冲突 ⭐⭐ + +**问题**: +CLAUDE.md 说"文档统一放到 `.docs`",sm-flow 要求用 `openspec/changes/`。 + +**Agent 的困惑**: +``` +CLAUDE.md: 所有文档放 .docs +sm-flow: OpenSpec 放 openspec/changes/ + +我应该听谁的? + → 选择了 CLAUDE.md(项目全局规范) + → 结果违反了 sm-flow 规范 +``` + +**优化建议**: + +在 sm-flow SKILL.md **开头**(第一段)明确优先级: + +```markdown +# SM Flow + +## 路径规范(覆盖项目 CLAUDE.md) + +⚠️ **重要**:sm-flow 使用专用路径,优先级高于项目 CLAUDE.md。 + +| 内容类型 | 路径 | 说明 | +|---------|------|------| +| OpenSpec | openspec/changes/{slug}/ | proposal.md, design.md, tasks.md, change.json | +| 长期记忆 | devflow/ | glossary, ADRs, 历史项目 | +| ❌ 不使用 | .docs/ | sm-flow 不使用此路径 | + +...(后续内容)... +``` + +--- + +### 6. Grill 阶段工具调用不明确 ⭐ + +**问题**: +技能列表有 `grill-with-docs`,但 Agent 不确定是否必须调用。 + +**Agent 的困惑**: +``` +Grill 阶段: + - 要求:evidence-driven 查证 ✅(我读了代码) + - 要求:user-interview one-at-a-time(用户拒绝了) + - 要求:至少 3 个高价值问题 + + 但是否需要调用 grill-with-docs? + - 技能列表里有 + - 但 phase-contracts.md 没有明确说"必须" + - 那我就只做查证,不调用工具了 +``` + +**优化建议**: + +在 `references/phase-contracts.md` 中明确标注"可选": + +```markdown +## Grill 阶段 + +**能力来源**:grill-with-docs skill(可选,推荐) + +**动作**: +1. **如果 grill-with-docs 已安装**:调用 skill + ``` + Skill(skill="grill-with-docs", args="proposal: openspec/changes/{slug}/proposal.md") + ``` + 该工具会: + - 挑战方案与现有领域模型的对齐 + - 审查术语一致性(与 devflow/glossary 对比) + - 至少提出 3 个高价值澄清问题 + +2. **如果 grill-with-docs 未安装**:手工 grill + - 读取 devflow/glossary/CONTEXT.md + - 验证关键技术假设(读代码) + - 至少解决 3 个高价值问题 + +**退出条件**: +- [ ] 至少解决 3 个高价值问题 +- [ ] 关键技术假设已验证 +- [ ] 输出"解决的问题"列表 +``` + +--- + +### 7. 阶段切换缺少明确提示 ⭐ + +**问题**: +Agent 和用户都不清楚当前在哪个阶段。 + +**优化建议**: + +每个阶段开始时输出: +``` +🔄 进入 Specify 阶段 +📖 目标:补全 design 和 tasks,调用 openspec-propose +🛠️ 将要做的事: + 1. 手工编写 design.md + 2. 手工编写 tasks.md + 3. 调用 openspec-propose skill +``` + +每个阶段结束时输出: +``` +✅ Specify 完成 +📋 产出: + - design.md + - tasks.md + - change.json(由 openspec-propose 生成) +📍 下一阶段:Audit +``` + +--- + +## 综合优化方案 + +### 优化 1:在 SKILL.md 开头增加"执行检查清单" + +```markdown +# SM Flow + +## 路径规范(覆盖 CLAUDE.md) +... + +## 执行检查清单(Agent 自查) + +每个阶段结束前,检查: + +### Specify +- [ ] 创建了 design.md 和 tasks.md +- [ ] ✅ **调用了 openspec-propose skill** +- [ ] change.json 存在 + +### Commit +- [ ] change.json 的 metadata.status == "committed" + +### Apply +- [ ] ✅ **检查了 metadata.status == "committed"** +- [ ] 基于 change.json 的 tasks 执行 +``` + +### 优化 2:phase-contracts.md 每个阶段增加"能力来源" + +```markdown +## Specify 阶段 + +**能力来源**:openspec-propose skill(必须调用) + +## Grill 阶段 + +**能力来源**:grill-with-docs skill(可选,推荐) +``` + +### 优化 3:增加阶段门控检查 + +在 sm-flow 主逻辑中,Apply 阶段入口增加: +```python +if not can_enter_apply(slug): + print("⏸️ 流程暂停:无法进入 Apply 阶段") + print("💡 需要先完成 Specify 和 Commit 阶段") + halt() +``` + +--- + +## 优先级建议 + +### P0(立即修复,阻塞性) +1. **明确工具调用要求**:phase-contracts.md 标注"能力来源"(必须/可选/无) +2. **Apply 阶段强制检查**:检查 change.json 的 metadata.status +3. **路径规范优先级**:SKILL.md 开头明确 sm-flow 路径覆盖 CLAUDE.md + +### P1(重要优化) +4. **阶段切换提示**:明确输出当前状态 +5. **OpenSpec 状态定义**:operating-rules.md 中定义 Draft vs Committed +6. **执行检查清单**:Agent 自查用,避免遗漏步骤 + +### P2(增强体验) +7. **用户打断处理**:明确询问是否继续完整流程 +8. **流程可视化**:进度条 +9. **错误恢复**:支持从中断点恢复 + +--- + +## 测试建议 + +### 测试用例 1:完整流程 +``` +用户输入:"开发一个用户管理页面" +期望: + Specify 阶段调用 openspec-propose + Commit 阶段检查 metadata.status="committed" + Apply 阶段基于 change.json 执行 +``` + +### 测试用例 2:跳过工具调用 +``` +Specify 阶段:只写 markdown,未调用 openspec-propose +期望: + Commit 阶段检查失败:"❌ change.json 不存在" + 提示:"需要调用 openspec-propose" + 流程暂停 +``` + +### 测试用例 3:未 Commit 就 Apply +``` +Specify 完成后,用户说"直接实现" +期望: + Apply 阶段检查 metadata.status + 如果不是 "committed",拒绝执行 + 提示:"必须先通过 Commit 检查" +``` + +--- + +## 总结 + +### 核心问题 +**隐式假设太多,硬性约束太少。** + +Agent 在不确定时会选择: +1. 做确定的事(写 markdown) +2. 跳过不确定的事(工具调用) +3. 选择"更快"的路径(直接实现) + +### 解决方案 +1. **明确化**:标注"能力来源",说明哪些工具必须调用 +2. **强制化**:Apply 阶段强制检查 Committed OpenSpec +3. **可视化**:明确输出当前状态 +4. **优先级明确**:sm-flow 路径规范 > 项目 CLAUDE.md + +### 最关键的 3 个改进 +1. ⭐⭐⭐ Specify 阶段明确标注"必须调用 openspec-propose" +2. ⭐⭐⭐ Apply 阶段强制检查 change.json 的 metadata.status +3. ⭐⭐ SKILL.md 开头明确 sm-flow 使用 openspec/changes/ 路径 + +这三个改进可以解决 80% 的执行偏差问题。