--- version: 1.10.0 updated: 2026-07-03 source: dev-manager-tauri --- # 蓝图更新规则 > ⚠️ 本文件由 dev-manager-tauri 统一管理,请勿手动修改。规则更新请在 dev-manager-tauri 项目中进行。 本文件定义了 `.blueprint/` 目录的维护规范,供 Claude 在对话中遵循。 ## 目录结构 ``` .blueprint/ ├── manifest.yaml ← 模块列表、关系、布局坐标 ├── CONVENTIONS.md ← 本文件(Claude 行为规则 + 全局推荐规则库) ├── rules.md ← 项目私有规则(可选,优先级高于全局规则) ├── usage.json ← 飞轮外环快照数据(炼境自动写入) └── modules/ └── .md ← 每个模块的详情 + 任务卡 ``` ## 蓝图定位(意图层) 蓝图只记录 git 永远无法自动产生的三类信息: | 类型 | 内容 | 为什么 git 做不到 | |------|------|----------------| | **结构** | 模块列表 + 关系图(dependency/related) | git 只知道文件,不知道模块意图和边界 | | **意图** | 为什么做 + 验收标准 + 复杂度 + 复盘笔记 | commit 记录"做了什么",不记录"为什么" | | **规划** | concept / planned 方向 | 还没有代码,git 里什么都没有 | **不属于蓝图的**(交给 git 信号,蓝图不手动维护): - 任务状态(in_progress / done)→ 从 branch / commit 推断 - 涉及文件(files)→ 从 git diff 读取,蓝图里为可选提示 - 进度数字(progress)→ 从任务卡完成比例自动算 - 更新时间(updated)→ 从 git log 读取 > 蓝图是项目的"架构意图层",不是任务追踪系统。任务追踪的职责交还给 git。 --- ## 何时更新蓝图 | 事件 | 操作 | |------|------| | 用户确认了新需求 | 在 manifest.yaml 新增模块,创建 modules/.md | | **开始执行任务卡(信息1)** | **任务卡前缀改为 🔵,status → in_progress(第一行代码之前)** | | **完成了功能实现(信息2)** | **任务卡前缀改为 ✅,status → done(验收通过之后)** | | 拆分了大需求为子任务 | 在 modules/.md 中添加任务卡 | | 调整了架构方向 | 更新 edges 关系,可能调整 area | | 放弃了某个方向 | 删除对应模块和文件,或标记 status: abandoned | | **重构已完成的模块(迭代)** | **manifest.iteration 递增,旧任务卡保留,新建替代任务卡,模块加 `## 迭代记录`** | ## 任务卡复杂度定义 | complexity | 含义 | 判断标准 | 推荐执行模型 | |-----------|------|--------|------------| | `S` | Simple | 单文件或机械操作;无需理解现有 pattern;可独立完成 | Haiku | | `M` | Medium | 跨 2-4 个文件;需理解现有代码风格和上下文;有隐式依赖 | Sonnet | | `L` | Large/Complex | 系统架构级;**无法直接执行,必须先 `/architect` 设计再 `/splitter` 拆分** | Opus(设计)+ Sonnet(执行) | ### 判断速查 - 改动涉及 3 个以上文件且分属不同功能区域 → 至少 M - 需要先理解现有代码的内在逻辑或约定才能动手 → 至少 M - 无法在派发时清晰描述完整实现方案 → L,需先 `/architect` - 单纯的 SQL 建表、类型文件、配置修改 → S > **注**:`/auto-execute` 技能会按此定义自动路由模型:S 卡委托 Haiku 子 agent,M 卡由当前 Sonnet 执行,L 卡直接标记 blocked 并提示走 `/architect`。 ## 模块状态定义 | 状态 | 含义 | 色标 | |------|------|------| | `done` | 已实现并验证 | 🟢 绿色 | | `in_progress` | 正在开发 | 🔵 蓝色 | | `planned` | 已规划,需求明确 | 🟡 黄色 | | `concept` | 构思中,信息不完整 | ⚪ 灰色 | | `blocked` | 执行受阻,需架构师介入 | 🔴 红色 | | `abandoned` | 方向已放弃或功能已退役,模块保留作历史记录 | ⚫ 深灰 | ## 任务卡格式 modules/.md 中的每个二级标题(`###`)是一张任务卡: ```markdown ### 📋 任务标题 - status: todo - complexity: M - files: src/path/to/file.tsx(可选,规划时填预期路径;实际文件由 git diff 追踪,无需回填) - depends: other-module-id - acceptance: 简要描述完成标准 - blocked_reason: (仅 status: blocked 时填写)执行受阻的具体原因 - iteration: 1 # 可选,省略时继承 manifest 顶层 iteration 值 - replaces: 旧任务标题 # 可选,仅重构任务填写,说明本卡替代哪张旧卡 详细说明(可选)。 ``` ### 状态前缀 | 前缀 | status | 含义 | |------|--------|------| | ✅ | done | 已完成(信息1 + 信息2 均已写入) | | 🔵 | in_progress | 执行中或被中断(只有信息1,等待信息2) | | 📋 | todo | 可派发(信息充足) | | 💭 | concept | 构思中 | | 🔴 | blocked | 执行受阻 | ### 可派发标准(📋) 任务卡同时满足以下条件时标记为 📋: 1. status 为 `todo` 2. 有明确的 `acceptance`(验收标准) 3. complexity 为 `S` 或 `M` `files` 为可选提示字段,有则帮助 agent 更快定位,无则从 git diff 推断,不作派发门槛。 不满足条件的 todo 任务保持无前缀,说明还需补充信息。 ### Acceptance 写法规范 acceptance 是 agent 自验的唯一判断依据,必须是**可执行断言**,禁止描述性语句: ``` ❌ "功能正常运行"(描述性,agent 无法判断完成) ❌ "代码正确"(主观,无可执行路径) ✅ "pnpm typecheck 无报错" ✅ "cargo test 通过(src-tauri/)" ✅ "MCP tool list_projects 返回新增项目名" ✅ "pnpm vitest run <测试文件> 全绿"(仅适用于有纯逻辑层的项目,见前端可测试性规范) ``` 最小结构:`[载体] 调用/运行什么(参数) → 断言什么`。 含 Rust 业务逻辑的 M/L 卡,acceptance 还须包含(详见 Rust 代码可测试性规范): - `cargo test 通过` + 依赖注入写法确认 > acceptance 是整个 agent 按钮体系的核心关节。可执行 = 真自验;描述性 = 假闭合。 > 完整体系见 `docs/ai-context/agent-button-system.md`。 ### 💭 concept 卡的极简写法 concept 卡是想法 inbox,**不要求 files / acceptance / complexity**,随想随记: ```markdown ### 💭 ServerManagerPanel 表格和软件块有重复逻辑 - status: concept ``` 一行就够。等某次对话中方向变清晰,再补全字段、升格为 📋。 **不要因为"信息不全就不记"而让想法消失**——concept 卡存在的意义就是承接碎片。 ## manifest.yaml 规范 ### 顶层字段 ```yaml version: 1 name: 项目名称 iteration: 1 # 当前迭代号(默认 1,重构已完成模块时手动递增) updated: YYYY-MM-DD agent_button_carrier: tauri # 项目主验证载体(见下方说明),新建蓝图时必填 ``` **`agent_button_carrier` 取值**(就近原则,与 AGENTS.md 载体谱系对应): | 值 | 适用场景 | 对应验证方式 | |----|---------|-------------| | `tauri` | Tauri 桌面应用 | `cargo test` / Tauri command 函数 | | `http` | Web 服务 / REST API | `curl` / HTTP 端点 | | `cli` | CLI 工具 / npm scripts | 命令行调用 | | `playwright` | 纯 UI 呈现层(最后手段) | Playwright 真界面驱动 | > 新建蓝图时 AI 必须根据技术栈自动推断并填入此字段。`splitter` 生成任务卡时直接从此字段继承载体,无需每次重新推断。 ### 模块字段 ```yaml - id: kebab-case-id # 唯一标识,同时是 modules/ 下的文件名 name: 显示名称 area: frontend # 所属领域 ID status: done # planned/concept 手动设;in_progress/done 优先从 git 信号推断,人工确认 progress: 100 # 由任务卡完成比例自动算,无需手填;App 根据 done 卡比例渲染 position: [x, y] # React Flow 画布坐标(可选) ``` ### 边字段 ```yaml - from: module-a to: module-b type: dependency # dependency(实线)/ related(虚线) ``` ### 领域字段 ```yaml - id: frontend name: 前端 color: "#3B82F6" # 节点边框/分组背景色 ``` ## 进度计算 模块的 progress 由其任务卡的完成比例推算: - 无任务卡的模块:手动设置 progress - 有任务卡的模块(单迭代):`完成数 / 总数 × 100`(取整) - 有任务卡的模块(多迭代):**只计当前 iteration 的任务卡**,旧迭代 done 任务不计入分母,避免历史完成率虚高 ## 迭代管理 ### 何时递增 iteration **需要递增**(重构已完成的功能): - 一个已有 ✅ done 任务卡的模块需要重新设计或重写 - 核心交互/架构方案被替换(不是在原有基础上扩展) **不需要递增**(正常演进): - 在现有模块上添加新功能 - 修复 bug - 新增模块 ### 重构时的操作步骤 1. **manifest.yaml 顶层** `iteration` +1,更新 `updated` 日期 2. **旧任务卡**:保留原位,在卡片末尾加一行注释说明被替代(不改 status、不删除): ```markdown ### ✅ 旧功能实现 - status: done - iteration: 1 ... > ⚠️ 已被迭代 2「新功能实现」替代,仅作历史记录。 ``` 3. **新任务卡**:新建替代卡,标注 `iteration` 和 `replaces`: ```markdown ### 📋 新功能实现 - status: todo - iteration: 2 - replaces: 旧功能实现 - complexity: M - files: ... - acceptance: ... ``` 4. **模块文件**:追加 `## 迭代记录` 段落(见下方格式) 5. **模块 status**:重置为 `in_progress`,progress 按当前迭代任务卡重新计算 ### 迭代记录格式 模块文件末尾追加,每次迭代一条: ```markdown ## 迭代记录 ### 迭代 2(YYYY-MM-DD) - **原因**:React Flow 在 50+ 节点时性能卡顿,重构为虚拟化渲染方案 - **替代**:「React Flow 节点图渲染(迭代1)」→「节点图虚拟化渲染」 - **保留**:迭代1的任务卡作为历史记录,不删除 ``` ### 梦核如何感知迭代 - usage.json 快照携带 `iteration` 字段(见飞轮外环章节) - 飞轮数据层按 iteration 分组计算完成率,迭代跳变(如 1→2 后完成率骤降)是正常信号 - 梦核 prompt 会展示「完成率跳变项目」摘要,Opus 据此判断是主动重构还是项目失控 ## 决策记录格式 模块文件中可添加 `## 决策记录` 段落,记录架构决策的 WHY: ```markdown ## 决策记录 - 选择阿里云 OSS 而非 GitHub Releases 作为更新源,因为国内用户访问 GitHub 不稳定 - 使用 document-driven 蓝图而非数据库存储,因为 Claude 天然支持文件读写且可版本控制 ``` 桌面 App 会以琥珀色卡片展示在模块详情面板中。 ## 飞轮工作流 Claude 在每次对话中应遵循以下流程: ### 阶段 1:进入对话 — 读取蓝图 ``` 1. 读取 .blueprint/manifest.yaml ← 项目全景和当前状态 2. 读取 .blueprint/CONVENTIONS.md ← 工作流规则 + 全局推荐规则 3. 读取 .blueprint/rules.md ← 项目私有规则(若存在,合并应用,优先级更高) ``` - 识别哪些模块 in_progress,哪些有可派发任务 - 用简短话语告诉用户当前项目进展(如 "18/22 模块已完成,2 个进行中") ### 阶段 2:讨论需求 — 同步更新蓝图 | 用户说的 | Claude 应做的 | |----------|--------------| | "我想加个 XX 功能" | 确认需求后:manifest 加模块 (status: concept),创建 modules/.md | | "XX 功能需要 A、B、C 三步" | 在模块文件中拆分为 3 张任务卡 | | "这个方案确定了" | 模块 status → planned,补充任务卡的 acceptance(files 可选,有则更准确) | | "开始做 XX" | 模块 status → in_progress | | "为什么选这个方案" | 记录到模块的 `## 决策记录` | ### 阶段 3:实现功能 — 两阶段执行锁 任务卡执行遵循**两阶段提交**:开始写第一行代码前加锁(信息1),全部完成后解锁(信息2)。只有信息1没有信息2,说明任务被中断。 ``` 📋 todo ↓ 【信息1:加锁】第一行代码改动之前,先更新任务卡 🔵 in_progress ↓ 执行代码改动 ↓ ├─ 成功 → 【信息2:解锁】更新任务卡前缀为 ✅ → status: done │ 所有任务卡完成 → 模块 status: done │ 更新 manifest.yaml 的 updated 日期 │ ├─ 失败且可自行解决 → 继续尝试,保持 🔵 │ └─ 失败且无法独立解决 → 🔴 blocked + blocked_reason → 留给架构师处理 ``` #### 锁悬空时的续接规则 新会话读蓝图发现 🔵 任务卡(只有信息1,没有信息2)时: 1. 检查任务卡的 `files` 字段,读取相关文件的**当前代码状态** 2. 判断已完成什么、还缺什么 3. 从断点继续执行,**不重头来过** 4. 完成后补写 ✅(信息2),关锁 #### 架构师处理 blocked 任务 当 Opus 读蓝图发现 🔴 blocked 任务时: 1. 分析 `blocked_reason`,定位根因 2. 根据情况采取行动: - **拆**:任务本身拆得不好 → 标记原任务 abandoned → 产出新任务卡 - **补**:缺少前置依赖 → 创建前置任务卡 → 原任务加 depends - **调**:架构方向需调整 → 更新模块设计/决策记录 → 重新拆任务卡 3. 新任务卡就绪后,原 blocked 任务可标记为 abandoned 或更新为 todo ### 阶段 4:回顾 — 用户在桌面 App 查看 用户打开蓝图可视化: - 看到全景进度 - 在「下一步」面板查看可派发任务 - 点击「复制派发」→ 粘贴给新 Claude 会话 ### 飞轮的反馈信号 Claude 应关注这些信号来决定是否更新蓝图: - 用户说"这个做完了" → 标记 done - 用户说"这个不做了" → 标记 abandoned 或删除 - 用户说"这个要拆一下" → 拆分任务卡 - 用户说"记住这个决策" → 写入决策记录 - 用户没提蓝图但在讨论功能 → 主动提议更新蓝图 - 执行模型遇到无法解决的问题 → 标记 🔴 blocked + blocked_reason - Opus 看到 blocked 任务 → 分析原因,拆/补/调后产出新任务卡 ### 对话中的复杂度漂移检测 碎片化想法在对话中自然累积,有时从样式调整演变为架构改动。Claude 应主动识别并叫停。 **漂移信号**(以下任一出现即触发): - 原始请求是样式/布局,但现在涉及组件 state、props 或后端命令 - 本次对话累计改动文件 ≥ 4 个,且分属不同功能区域 - 用户说了"顺便"、"既然这样"、"要不也把 XX" - 前端改动已延伸到 DB 结构或 Rust 命令 **Claude 的应对动作**:检测到漂移信号时暂停执行,输出: > ⚠️ 范围漂移:我们从「[原始请求]」走到了「[当前方向]」,累计涉及 [N] 个文件。建议: > A) 完成当前这步,其余记为 💭 concept 卡待下次处理 > B) 现在拉清单,走 /architect 重新规划 > C) 继续执行,我在 session 结束前汇总成任务卡 **Session 结束汇总**:任何有代码改动但无预建任务卡的会话,结束前 Claude 应输出: > 📋 本次会话实际改动:[文件列表 + 简述] > 是否整理为蓝图任务卡? ## 交互质量复盘笔记 > 本章节仅适用于**开发执行阶段**(实现代码时),初始化蓝图或同步蓝图时无需执行。 每完成一张 **M 或 L 复杂度**的任务卡后,Claude 应通过 `append_project_note`(MCP 工具)写入一条结构化复盘笔记。这是飞轮外环的原始数据来源——积累足够多条后,Claude 读一遍即可识别高频坑点和高效模式。 ### 笔记格式 ``` 【复盘】<任务标题> 任务类型: 后端命令 | 前端组件 | 数据层 | MCP工具 | 架构调整 复杂度: S | M | L 实际轮数: N轮(预估 M 轮) 是否返工: 是/否 返工原因: <若返工,一句话说明根因,如"WSL路径格式未预料"> 有效策略: <本次奏效的做法,一句话> 遗留风险: <若有,一句话> auto_applied_rules: R01, R06 ← 本次任务触发并执行了哪些规则(无则省略) rule_effectiveness: R01=有效, R06=有效 ← 规则是否阻止了问题(有效/无效/未验证) ``` **`auto_applied_rules` 填写说明**: - 仅记录本次任务实际触发(Claude 主动检查或提示)的规则 - 若规则触发但用户选择跳过,也应记录(用于统计触发频率) - `rule_effectiveness=无效` 表示规则触发了但没有阻止问题,这是最有价值的信号——梦核据此降低该规则置信度 ### 触发时机 | 情况 | 操作 | |------|------| | M/L 任务卡标记为 ✅ done | 写一条复盘笔记(source: mcp) | | 遇到非预期的系统边界或平台差异 | 额外写一条"陷阱记录",遗留风险填具体复现条件 | | 同类问题第二次出现 | 在新笔记中引用旧笔记时间戳,说明"同类问题复发" | ### 示例 ``` 【复盘】WSL项目路径检测 任务类型: 后端命令 复杂度: M 实际轮数: 6轮(预估 2 轮) 是否返工: 是 返工原因: wsl_path 字段存的是 Windows UNC 格式(\\wsl.localhost\Ubuntu-22.04\...),而非 Linux 路径,导致 wsl 子命令收到错误参数 有效策略: 在函数入口统一用 unc_to_distro_and_linux() 转换,一次解析,全程复用 遗留风险: Path::exists() 对 \\wsl.localhost\ 路径无效,所有 WSL 路径存在性检查必须走 wsl -d distro -- test -d/f auto_applied_rules: R10 rule_effectiveness: R10=未验证(任务开始前未触发,事后归因) ``` > 这些笔记不替代决策记录(决策记录记架构 WHY,复盘笔记记执行 HOW 和踩坑)。两者都写。 --- ## 飞轮外环(跨项目数据反哺) 内环描述的是单项目的执行流程。外环负责**把多个项目的执行数据聚合起来,反哺 CONVENTIONS 本身**。 ### 数据采集:usage.json 快照 每次 Claude 读取 `.blueprint/manifest.yaml`(通过炼境打开蓝图时触发),炼境自动向项目的 `.blueprint/usage.json` 追加一条当日快照: ```json { "project_name": "my-project", "snapshots": [ { "at": "2026-04-05T10:00:00Z", "conventions_version": "1.3.0", "iteration": 1, "modules": { "total": 22, "done": 18, "in_progress": 2, "planned": 1, "concept": 1, "blocked": 0, "stalled": [] }, "tasks": { "total": 45, "done": 38, "in_progress": 3, "blocked": 0, "todo": 4, "dispatched": 3 }, "blocked_reasons": [] } ] } ``` - `dispatched` = 当前满足📋可派发条件的任务数(有 acceptance + complexity S/M;files 可选) - 节流:同一 UTC 日期只写一条,避免多次打开导致数据膨胀 - 文件存于项目本地,不上传服务器 ### 数据聚合:飞轮指标 炼境跨项目读取所有 usage.json,按 `conventions_version` 分组,对每个版本队列计算 4 项指标: | 指标 | 计算方式 | 含义 | |------|----------|------| | 可派发率 | dispatched / total tasks | 任务卡规划质量,越高说明任务定义越清晰 | | 任务完成率 | done / total tasks | 整体执行进度均值 | | 飞轮持续率 | 30天内有快照的项目比例 | 外环是否在持续运转 | | 阻塞密度 | blocked / total tasks | 系统性阻塞程度,越低越好 | 迭代感知:同一项目若 `iteration` 值增大,说明发生了主动重构。飞轮数据层对此类项目单独计算「当前迭代完成率」,与历史累计值区分展示,避免虚高。梦核 prompt 中标注「完成率跳变项目」供 Opus 分析是健康重构还是项目失控。 ### 梦核分析:记忆巩固 炼境将聚合数据 + 当前 CONVENTIONS 全文格式化为提示词,发给 **Claude Opus** 做两件事: - **固化**:哪些跨项目重复出现的阻塞模式、哪些有效实践,值得写进 CONVENTIONS - **遗忘**:哪些休眠项目(90天无快照)的 AI 文档可以归档,哪些 CONVENTIONS 规则已过时 ### 闭环路径 两条并行的反馈路径,速度不同: ``` 【快速路径 — 项目级,无需发版】 执行任务 → 复盘笔记(auto_applied_rules) ↓ 梦核分析项目笔记 ↓ 输出项目私有规则草案 ↓ 用户确认 → 写入 .blueprint/rules.md ↓ 下次对话立即生效 【慢速路径 — 全局级,需发版】 执行任务 → usage.json 快照 ↓ 炼境跨项目聚合指标 ↓ 梦核提示词 → Claude Opus 分析 ↓ 用户/维护者审核建议 ↓ 更新 CONVENTIONS.md 源码 + 版本号 ↓ 发布新版炼境 ↓ 治理面板 sync_blueprint_rules → 分发到各项目 ``` > **设计意图**:快速路径响应单个项目的学习,慢速路径沉淀跨项目的共识。CONVENTIONS.md 编译进炼境二进制保证全局规则版本可追溯;rules.md 存于项目本地实现快速迭代。两条路径互补,共同构成择升环。 ## 无 MCP 环境兼容(Qwen Code / 其他 AI) 部分 AI 助手(如 Qwen Code)不支持 MCP 协议,无法调用炼境工具。此时用等价文件操作代替,行为与 MCP 调用一致: | MCP 工具 | 等价文件操作 | |---|---| | `get_project_blueprint` | 直接读取 `.blueprint/manifest.yaml` | | `get_project_file` | 直接读取对应文件路径 | | `append_project_note` | 直接编辑 `.blueprint/modules/.md`,在对应任务卡末尾追加复盘笔记 | | `get_diagnostics` | 跳过,不影响主流程 | | `list_group_projects` | 跳过,由用户告知上下文 | ### 飞轮外环的缺口 无 MCP 环境下,`usage.json` 快照**不会被炼境自动写入**(触发写入的是炼境响应 MCP 调用时的副作用)。 影响范围:飞轮外环的跨项目统计数据本次会话不计入。飞轮内环(单项目蓝图维护、任务卡状态、复盘笔记)不受影响。 补偿方式:Qwen Code 会话结束后,在炼境中手动打开该项目蓝图,触发一次快照写入即可。 --- ## 复杂功能分析流程(/architect) 当需求复杂度为 **L 级**时,在写任何代码之前执行本流程。 ### 步骤 1. 读取 `manifest.yaml`,定位相关模块和依赖关系 2. 读取受影响的核心文件,理解现有实现模式和系统边界 3. 输出设计文档,格式如下: ``` ## 设计决策:<功能名> ### 背景 <关联的现有模块> ### 方案选择 <2-3 个方案及取舍,标注选定方案> ### 受影响文件 - 新增:<路径> — <用途> - 修改:<路径> — <改动说明> ### 系统边界变更 <新增接口 / 数据表 / 字段定义> ### 风险点 - <风险>:<规避方式> ### 拆解建议 建议拆为 N 张任务卡,依赖顺序:卡A → 卡B → 卡C ``` 4. **不写任何代码**,设计文档经用户确认后再进入拆解流程 --- ## 任务拆解流程(/splitter) 在设计文档确认后执行,产出可派发任务卡并写入蓝图文件。 ### 步骤 1. 确认目标模块 id,读取对应 `modules/.md` 2. 按以下原则拆解: - **粒度**:每张卡 complexity 必须是 S 或 M,不允许 L - **依赖顺序**:数据层 → 后端命令 → 前端封装 → UI 组件 - **可派发标准**:每张卡必须有 `acceptance` + `complexity`;`files` 建议填入预期路径,有则更准确 3. 将任务卡追加到 `modules/.md` 4. 更新 `manifest.yaml`:status → `planned`,更新 `updated` 日期 5. 输出拆解摘要(卡名、complexity、执行顺序) ### 质量检查 - [ ] 每张卡有 `acceptance` - [ ] complexity 全部是 S 或 M - [ ] 有依赖的卡填了 `depends` - [ ] 任务卡按执行顺序排列 - [ ] `files` 尽量填入(建议项,有则帮助 agent 更快定位) --- ## 技能依赖 本蓝图工作流依赖以下 Claude Code 技能处理 L 级复杂任务: | 技能 | 触发词 | 用途 | |------|--------|------| | architect | `/architect` | 复杂功能架构分析,输出设计文档 | | splitter | `/splitter` | 将设计文档拆解为可派发任务卡 | ### 检测方式 在 Claude Code 中输入 `/architect`,若 Claude 开始执行架构分析步骤则已就绪。 若提示找不到技能,按以下方式安装。 ### 安装方式 技能文件随本项目分发,位于 `.claude/skills/`: ```bash # 复制到全局技能目录(任意项目均可使用) cp -r .claude/skills/architect ~/.claude/skills/ cp -r .claude/skills/splitter ~/.claude/skills/ # 或仅在当前项目使用(.claude/skills/ 已存在则无需操作) ``` > 若通过炼境同步本蓝图规则,`.claude/skills/` 会随蓝图一并分发,无需手动安装。 --- ## Rust 代码可测试性规范 > 本规范仅适用于**新增** Rust 函数,存量代码不强制回填。 ### 强制规则 **禁止在业务函数内部调用 `pool().get()`**,改为由调用方传入连接: ```rust // ❌ 禁止(无法在测试中注入 in-memory DB) pub fn my_fn(args: Vec) -> Result, String> { let conn = crate::db::pool().get()?; ... } // ✅ 正确(依赖注入,测试可传入 in-memory DB) pub fn my_fn(conn: &rusqlite::Connection, args: Vec) -> Result, String> { ... } // Tauri command 层负责获取连接并调用 #[tauri::command] pub fn my_command(args: Vec) -> Result, String> { let conn = crate::db::pool().get().map_err(|e| e.to_string())?; my_fn(&conn, args) } ``` ### 测试要求 | 函数类型 | 测试要求 | |---------|---------| | 纯逻辑函数(无 DB) | 必须附带 `#[cfg(test)]` 测试 | | 含 DB 的业务函数 | 必须使用依赖注入写法,附带 in-memory DB 测试 | | Tauri command 薄包装层 | 无需测试(只做连接获取 + 函数调用) | ### 任务卡 acceptance 模板补充 含 Rust 业务逻辑的 M/L 任务卡,acceptance 须包含: ``` - [ ] 新增函数使用依赖注入(conn 作为参数) - [ ] 附带 #[cfg(test)] 测试,覆盖主路径 + 空数据边界 - [ ] cargo test 通过 ``` ### 测试写法模板 ```rust #[cfg(test)] mod tests { use super::*; use rusqlite::Connection; fn setup() -> Connection { let conn = Connection::open_in_memory().unwrap(); // 建表语句(从 db::migrate 复制对应部分) conn.execute_batch("CREATE TABLE IF NOT EXISTS ...").unwrap(); conn } #[test] fn test_主路径() { let conn = setup(); // 插入测试数据 // 调用函数 // 断言结果 } #[test] fn test_空数据返回空集合() { let conn = setup(); let result = my_fn(&conn, vec![]); assert!(result.unwrap().is_empty()); } } ``` --- ## 前端代码可测试性规范 > **适用范围**:有独立纯逻辑层的项目(Web 服务、Node CLI 等)。 > Tauri 桌面应用的主测试路径是 `cargo test`(Rust 层); > 前端大量代码是 Tauri IPC 薄包装(`invoke()` 调用),无法在 Node 环境运行,不适合 vitest。 > 炼境自身属于 Tauri 项目,**前端暂不配置 vitest**,以下规范待引入真实纯逻辑模块时生效。 ### 何时引入 vitest 满足以下条件之一时才引入: 1. 项目有可独立运行(不依赖 Tauri 运行时)的纯逻辑模块,且该模块代码量 ≥ 200 行 2. 某个 bug 在纯逻辑层反复出现,需要回归测试固化 引入时配置 `vitest.config.ts`,使用 `pnpm add -D vitest`。 ### 测试文件位置 前端测试文件与源文件同目录,命名约定:`.test.ts(x)`。 ``` src/lib/utils.ts src/lib/utils.test.ts ← vitest 自动发现(仅纯逻辑文件) ``` ### 测试要求(适用时) | 代码类型 | 测试要求 | |---------|---------| | 纯逻辑函数(数据处理、格式化、解析、校验) | M 级任务卡强制附带测试,覆盖主路径 + 空/边界 | | Tauri IPC 薄包装层(invoke 调用) | 无需测试(主路径走 cargo test) | | React 组件 | 无需测试(UI 由人工终验) | ### 任务卡 acceptance 模板(适用时) 含前端纯逻辑的 M 级任务卡: ``` - [ ] 附带 vitest 测试,覆盖主路径 + 空数据边界 - [ ] pnpm vitest run 全绿 ``` ### 测试写法模板 ```typescript import { describe, it, expect } from "vitest"; import { myFunction } from "./utils"; describe("myFunction", () => { it("正常路径", () => { expect(myFunction("input")).toBe("expected"); }); it("空输入不报错", () => { expect(myFunction("")).toBeNull(); }); it("非法输入返回安全默认值", () => { expect(myFunction("invalid")).toBeNull(); }); }); ``` --- ## 项目私有规则(rules.md) 每个项目可以在 `.blueprint/rules.md` 中维护**仅对本项目生效**的推荐规则,格式与全局规则库完全相同。 ### 优先级 ``` 项目私有规则(.blueprint/rules.md)> 全局规则(CONVENTIONS 自动推荐规则库) ``` 项目私有规则更精准(来自该项目真实数据),全局规则更广泛(来自跨项目共识)。冲突时项目规则优先。 ### 对话开始时的读取顺序 ``` 1. manifest.yaml ← 项目全景 2. CONVENTIONS.md ← 协议定义 + 全局规则 3. .blueprint/rules.md ← 项目私有规则(若存在,合并应用) ``` ### 梦核写入路径 梦核(飞轮阶段三启动后)分析项目复盘笔记后,除了输出 CONVENTIONS 更新建议,还应输出**项目私有规则草案**,格式如下: ```markdown ## 建议新增项目私有规则 | rule_id | 触发条件 | 自动动作 | confidence | evidence_count | derived_from | |---------|---------|---------|-----------|---------------|-------------| | P01 | <本项目特有触发条件> | <自动动作> | 0.70 | 3 | <复盘笔记引用> | ``` 用户确认后,Claude 直接将规则写入 `.blueprint/rules.md`,**无需等待炼境发版**。这是项目级择升环与全局发版解耦的关键路径。 ### rules.md 文件格式 ```markdown # 项目私有规则 > 本文件由梦核分析 + 用户确认后生成,Claude 每次对话开始时读取并合并应用。 > 规则格式与 CONVENTIONS 自动推荐规则库相同,优先级高于全局规则。 ## 规则列表 ### P01 — 规则标题 - **触发条件**:xxx - **自动动作**:xxx - **confidence**: 0.70 - **evidence_count**: 3 - **derived_from**: 复盘笔记 YYYY-MM-DD,任务"xxx"中发现 ``` ### 何时创建 rules.md - 梦核首次输出项目私有规则建议时创建 - 也可手动创建,记录人工识别的项目特有模式 - 文件不存在时跳过,不影响全局规则生效 --- ## 自动推荐规则库 > 本章节定义了 Claude 在开发过程中应**主动触发**的高收益决策规则。 > 规则有置信度(confidence)和证据数(evidence_count),置信度越高越应自动执行,无需用户确认。 ### 执行策略 | confidence 范围 | 执行方式 | |----------------|---------| | ≥ 0.80 | 直接执行,仅一行说明("按 R01 检查...") | | 0.60 ~ 0.79 | 执行前单句说明原因,用户可跳过 | | < 0.60 | 仅作提醒,不自动执行 | 置信度由梦核(阶段三启动后)根据 evidence_count 和有效率自动更新;在此之前由人工在复盘中维护。 ### scope 字段 每条规则有 `scope` 字段,标明适用范围。Claude 应在应用规则前检查当前项目是否匹配: | scope 值 | 含义 | |---------|------| | `universal` | 适用于任何代码项目 | | `tauri` | 仅适用于 Tauri 项目 | | `rust` | 仅适用于含 Rust 后端的项目 | | `sqlite` | 仅适用于使用 SQLite 的项目 | | `react` | 仅适用于 React 前端项目 | 多个 scope 用 `+` 连接,如 `tauri+rust`。**scope 不匹配时跳过该规则,不作提醒。** 项目私有规则(`rules.md`)无需 scope 字段,默认对本项目全部生效。 ### boundaries 与 failure_cases 字段(可选) scope 描述规则的正向适用范围,**boundaries 描述已知的反向边界**——规则在什么条件下会失效。失败案例是边界的证据来源: ```markdown - **boundaries**: <已知不适用条件,如"squash merge 项目下 commit 数≈轮数 不成立"> - **failure_cases**: - YYYY-MM-DD:<触发条件> → <规则未能阻止的现象>(项目:xxx) ``` - 规则**没有 failure_cases ≠ 规则完美**,只说明边界还未被探测到 - 梦核分析时应把 failure_cases 视为最高价值信号:同一条件下反复失效 → 拆分规则为带条件的变体(原规则收窄 scope + 新增变体规则),而非简单降低 confidence - 边界记录使经验"细化"而不是"被推翻"——这是规则库因果自洽的核心机制 ### 规则列表 #### R01 — 新增 Tauri command 时检查前端封装层 - **scope**: `tauri` - **触发条件**:在 `src-tauri/src/commands/` 下新增 `#[tauri::command]` 函数 - **自动动作**:读取 `src/lib/commands.ts`,确认是否有对应封装;缺失则提示补写,不阻止执行 - **confidence**: 0.90 - **evidence_count**: 8 - **derived_from**: 多次发生前后端接口断层(命令已实现但 commands.ts 未同步,前端调用报错) #### R02 — 任务卡无 acceptance 时先补写再动代码 - **scope**: `universal` - **触发条件**:任务卡 `acceptance` 字段为空或缺失,但已准备开始执行 - **自动动作**:暂停执行,根据任务描述推导验收标准草稿,请用户确认后再写第一行代码 - **confidence**: 0.92 - **evidence_count**: 18 - **derived_from**: 无验收标准导致完成定义模糊,任务频繁反复("做完了但感觉不对") #### R03 — M/L 任务标记 done 后写复盘笔记 - **scope**: `universal` - **触发条件**:M 或 L 复杂度的任务卡状态变更为 ✅ done - **自动动作**:调用 `append_project_note` 写入复盘笔记(见"交互质量复盘笔记"章节格式) - **confidence**: 0.88 - **evidence_count**: 24 - **derived_from**: 飞轮外环数据来源,无复盘笔记则梦核无输入,整个飞轮断链 #### R04 — 对话改动 ≥ 4 个跨功能区文件时触发漂移警告 - **scope**: `universal` - **触发条件**:单次对话累计改动文件 ≥ 4 个,且分属不同功能区(frontend/backend/infra) - **自动动作**:输出范围漂移提示(见"对话中的复杂度漂移检测"章节),给出 A/B/C 三个选项 - **confidence**: 0.85 - **evidence_count**: 12 - **derived_from**: 多次"样式改动演变成后端重构"的失控扩散,最终要么返工要么留下技术债 #### R05 — SQLite 涉及新表或新字段时检查 migration - **scope**: `sqlite` - **触发条件**:在项目中出现 `CREATE TABLE` / `ALTER TABLE` / 新增列定义 - **自动动作**:检查是否有对应 migration 逻辑;缺失则提示添加,防止旧版本升级后 schema 断裂 - **confidence**: 0.82 - **evidence_count**: 7 - **derived_from**: 数据库 schema 变更未同步 migration,导致旧安装版本升级后启动报错 #### R06 — Rust 业务函数含 DB 操作时强制依赖注入 - **scope**: `rust+sqlite` - **触发条件**:新增 Rust 函数内部直接获取 DB 连接(`pool().get()` 或等价写法) - **自动动作**:提示改为依赖注入写法,连接由调用方传入;command 层负责获取连接 - **confidence**: 0.93 - **evidence_count**: 15 - **derived_from**: 飞轮阶段一实现时无测试导致静默 bug 上线;依赖注入是唯一能让 in-memory DB 测试覆盖业务逻辑的方式 #### R07 — 数据关键路径函数必须附带单元测试 - **scope**: `universal` - **触发条件**:新增函数负责数据采集、聚合、解析等关键路径(影响下游分析或展示的正确性) - **自动动作**:在实现函数前提醒附带单元测试,覆盖正常路径 + 空数据边界;完成后验证测试全绿 - **confidence**: 0.95 - **evidence_count**: 6 - **derived_from**: 飞轮阶段一数据采集 bug 因无测试静默上线,污染所有下游分析 #### R08 — UI 状态显示必须来自真实检测 - **scope**: `universal` - **触发条件**:前端组件显示运行状态、健康状态、操作结果等实时信息 - **自动动作**:检查对应后端是否做了真实检测而非硬编码;发现硬编码状态时标记为需修复 - **confidence**: 0.87 - **evidence_count**: 5 - **derived_from**: 设置页 MCP 状态硬编码为"运行中",注入失败时 toast 始终显示成功——UI 掩盖真实问题 #### R09 — 自动化边界:事件触发只标 🔵,不标 ✅ - **scope**: `universal` - **触发条件**:讨论或实现基于外部事件(git commit、CI 结果等)自动更新任务卡状态 - **自动动作**:确认自动化只将任务卡置为 🔵 in_progress,绝不自动置为 ✅ done;完成语义需人工或 Claude 验收确认 - **confidence**: 0.91 - **evidence_count**: 4 - **derived_from**: 代码提交 ≠ 功能验收通过,自动标完成导致数据与实际不符 #### R10 — 对接外部协议/API 前先验证客户端实际行为 - **scope**: `universal` - **触发条件**:实现与外部客户端的协议对接(MCP、LSP、WebSocket、SSE、OAuth 等) - **自动动作**:在开始实现前,先通过文档或工具(curl、抓包)确认客户端实际发出的请求格式;不基于"通用规范"假设行为 - **confidence**: 0.85 - **evidence_count**: 3 - **derived_from**: Claude Code MCP 客户端用 GET 发起 SSE 握手,炼境只接受 POST 导致 405,MCP 整体失效 #### R11 — 自动执行规则失效时必须记录失败案例 - **scope**: `universal` - **触发条件**:confidence ≥ 0.80 的规则被自动执行后,其本应阻止的问题仍然发生(返工、报错、验收失败) - **自动动作**:在该规则条目下追加一条 failure_case(日期 + 触发条件 + 现象 + 项目);若为项目私有规则写入 rules.md,全局规则则在复盘笔记中记录并标注 rule_effectiveness=无效,等梦核汇总 - **confidence**: 0.80 - **evidence_count**: 1 - **derived_from**: 规则库只有正向 scope 无反例结构,失败信息流失导致置信度虚高、边界永远探测不到(2026-07-02 经验飞轮设计评审) #### R12 — 边界单点实现:业务校验只写在能力本体层 - **scope**: `universal` - **触发条件**:实现或修改带业务边界的功能(哪些允许、什么条件下允许、非法时如何拒绝) - **自动动作**:校验逻辑只写在能力本体层(API / command / 服务函数);UI 层只呈现状态(置灰/提示),不复制业务判断。发现前端 guard 承载业务边界时标记为需下沉 - **confidence**: 0.85 - **evidence_count**: 2 - **derived_from**: 空契约生成静默 return(边界错写进 UI 层,与文案承诺冲突)、改 Token 假成功(UI 报成功但本体未执行)——两例均为"人与 agent 验证路径空间分裂"症状(2026-07-03) - **boundaries**: 纯展示逻辑(排序、折叠、格式化)属 UI 职责,不适用本规则 #### R13 — M/L 任务完成前,验收路径须被真实走通 - **scope**: `universal` - **触发条件**:M 或 L 复杂度任务卡准备标记 ✅ done - **自动动作**:acceptance 所述验证路径须由人或 agent **通过功能自身入口**真实走通一次(agent 按钮载体就近选择:Web 服务=HTTP API、CLI=命令、桌面应用=测试调用同一函数、UI 呈现层=Playwright 兜底)。禁止绕过功能手改产物冒充验证;agent 走通的关键路径顺手固化为一条测试(侦察→驻军),一次性验收不固化 - **confidence**: 0.80 - **evidence_count**: 2 - **derived_from**: noteapp manifest 被手改导致 schema 约束修复未获真实验证、autoforphone 接线被命令行代办导致 G7 按钮未走通——手动替代掩盖功能真实状态(2026-07-03 用户裁决 + MCP 治理三件套 agent 实测首证) ### 规则演进路径 ``` 人工识别(初始) ↓ evidence_count 累积 5+ 次 低置信验证期(confidence 0.60~0.79) ↓ 持续有效,evidence_count 15+ 自动执行期(confidence ≥ 0.80) ↓ 发现无效或场景已变化 降级/归档(confidence 跌至 0.4 以下) ``` 梦核(飞轮阶段三启动后)将根据复盘笔记中的 `auto_applied_rules` 和 `rule_effectiveness` 字段自动更新 confidence。 --- ## 注意事项 - 不要删除已完成的任务卡,它们是项目历史的一部分 - 模块 id 一旦确定尽量不要修改(会影响 edges 引用) - 每次更新后修改 manifest.yaml 顶部的 `updated` 日期 - progress 由桌面 App 自动从任务卡完成比例计算,不需要手动维护 - 当用户的操作隐含了蓝图变更但没有明说时,Claude 应主动提议更新(而非沉默) - **批量执行完成后须做完整性检查**:同一会话内连续完成多张任务卡时,结束前必须逐一确认:① 每张已完成的子任务 status 改为 done,前缀改为 ✅;② manifest.yaml 中对应模块的 status 已同步更新。两层缺一不可。(背景:单卡两阶段流程天然同步,批量执行时容易只改模块级 status 而漏掉子任务级更新,导致 App 看板 progress 数据失真)