Commit 4706a8d99679b299d7827109ea3ac090f6669d5f

Authored by zichun
1 parent e69a699e

refactor(plugin): 标准化 skill 命名 + 精简 A 阶段流程 + 统一术语

- 去 erp- 前缀:project-init / scope-lock / skeleton-gen / db-design-gen / db-init / downstream-gen / plan-start / coding-start / module-start / feature-* / module-report / mr-create / cross-module-log
- 红旗 → 中断:red-flag-check → interrupt-check;命中 → 触发(中断语境)
- local-test-gate → test-gate
- docs/01-需求清单 的 README.md → index.md(原先改名过 abstract.md,再改 index.md)
- CLAUDE-template.md 大幅精简:删 § ⚡ Skill 索引 / § 🧪 自测要求 / § 🔄 统一响应格式 / § 通用工作准则 等冗余;§ 🏷️ 覆盖 3 类占位符;§ 📐 从 27 条压到 14 条;§ ✅ 模块完成判定规则 缩到 27 行;§ 🚩 改名中断机制
- A0 project-init:步骤 A/B 互换(先 cp 模板创建 docs/08,再做依赖检查),修复首次运行 bootstrap bug;docs/04-stack-template.md 归 project-init 持有
- scope-lock 合并 D+E 为单步;step A 加 CLAUDE.md § 🎯 的 Grep 占位校验
- skeleton-gen:test.sh 骨架抽成模板(scripts-test-template.sh);step E 占位符处理从 130 行压到 34 行;删除内联 Flyway 说明;勾选分布到每个子步骤
- req-card 模板三段式:目标引言 + 字段表 + 元数据 list;字段级 vs REQ 级规则用 field_rules/rules 区分
- 模块级依赖模块 / 涉及表 改 TBD,由 A3/A5 回填(和 REQ 级 依赖表/依赖接口 同模式)
- cross-module 留痕策略:hook 落存根不弹提示;所有 TBD 统一延到 module-report § ⑦ 一次性批量补齐
- 其他:feature-verify 删除孤儿 Write 权限;Git commit type 解读表;软规则 S1 技术栈外组件;docs/08 § 二 加 REQ 功能子项由 feature-review approve 时勾选

72 files changed, 1556 insertions(+), 1745 deletions(-)
Showing 71 changed files with 1438 additions and 1627 deletions
README.md
@@ -2,43 +2,34 @@ @@ -2,43 +2,34 @@
2 2
3 Claude Code 插件:ERP / 后端管理系统全流程开发框架。 3 Claude Code 插件:ERP / 后端管理系统全流程开发框架。
4 4
5 -把"从零到 N 个模块上线"的整个流程固化成 **19 个 skill + 2 个 hook + 38 份模板**,让 CC 在 schema 演化用 Flyway migration、需求可追溯、人工审核可控的前提下推进编码。 5 +把"从零到 N 个模块上线"的整个流程固化成 **21 个 skill + 1 个 agent + 2 个 hook + 37 份模板**,让 CC 在 schema 演化用 Flyway migration、需求可追溯、人工审核可控的前提下推进编码。
6 6
7 ## 这个插件做什么 7 ## 这个插件做什么
8 8
9 ``` 9 ```
10 -📋 阶段 A:规划(一次性,入口 /erp-workflow:erp-plan-start)  
11 - 初始化项目 → 锁范围(REQ 卡片生成)  
12 - ↓  
13 - ⏸ 审阅 REQ 卡片 → 重新运行 /erp-plan-start 继续  
14 - ↓  
15 - 生成骨架 → 初始化 DB(V1 migration + seed)→ 生成 DB 设计 → 生成下游文档  
16 - ↓  
17 - 用户显式 /erp-workflow:erp-coding-start  
18 -  
19 -🔁 阶段 B:编码(按模块循环,入口 /erp-workflow:erp-coding-start) 10 +📋 阶段 A:规划(一次性,入口 /erp-workflow:plan-start)
  11 +
  12 + A0 初始化项目 → A1 锁范围(生成 REQ 卡片)
  13 + ↓
  14 + ⏸ 审阅 REQ → 重新运行 /plan-start
  15 + ↓
  16 + A2 生成骨架 → A3 生成 DB 设计(REQ → docs/03 + 回填依赖表)
  17 + ↓
  18 + ⏸ 审阅 docs/03 → 重新运行 /plan-start
  19 + ↓
  20 + A4 初始化 DB(docs/03 → V1 migration → 自动 apply 到本地 MySQL)
  21 + ↓
  22 + A5 生成下游文档(docs/02 / docs/05 / docs/06 § 五 / docs/10)
  23 + ↓
  24 + 用户显式 /erp-workflow:coding-start
  25 +
  26 +🔁 阶段 B:编码(按模块循环,入口 /erp-workflow:coding-start)
20 功能循环:Brainstorm → Plan → TDD → Verify → Review 27 功能循环:Brainstorm → Plan → TDD → Verify → Review
21 模块循环:本地测试闸门 → 写模块报告 → 创建 GitLab MR → ⏸ 用户 Approve+Merge → 下次 coding-start 自动扫描 MR 状态为 merged → 下一模块 28 模块循环:本地测试闸门 → 写模块报告 → 创建 GitLab MR → ⏸ 用户 Approve+Merge → 下次 coding-start 自动扫描 MR 状态为 merged → 下一模块
22 29
23 -⚙️ 后台守门:占位符未填 / 红旗触发 / 跨模块改动未记录 30 +⚙️ 后台守门:占位符未填 / 中断触发 / 跨模块改动未记录
24 ``` 31 ```
25 32
26 -## 安装  
27 -  
28 -### 方式 1:本地测试(开发期)  
29 -  
30 -```bash  
31 -claude --plugin-dir /path/to/erp-workflow-plugin  
32 -```  
33 -  
34 -### 方式 2:从 marketplace 安装(发布后)  
35 -  
36 -```  
37 -/plugin install erp-workflow@<your-marketplace>  
38 -```  
39 -  
40 -详见官方文档 [Discover and install plugins](https://code.claude.com/docs/en/discover-plugins)。  
41 -  
42 ## 首次使用 33 ## 首次使用
43 34
44 1. **进入空项目目录并启动 Claude Code**: 35 1. **进入空项目目录并启动 Claude Code**:
@@ -49,25 +40,30 @@ claude --plugin-dir /path/to/erp-workflow-plugin @@ -49,25 +40,30 @@ claude --plugin-dir /path/to/erp-workflow-plugin
49 40
50 2. **Plan 阶段入口**(一次性规划): 41 2. **Plan 阶段入口**(一次性规划):
51 ``` 42 ```
52 - /erp-workflow:erp-plan-start 43 + /erp-workflow:plan-start
53 ``` 44 ```
54 - Plan 阶段**两段式**执行,中间有一个 REQ 审阅断点: 45 + Plan 阶段**三段式**执行,中间有两个人工审阅断点:
  46 +
  47 + - **第一段(首次运行)**:执行 **A0 → A1**(创建骨架 / 锁技术栈 / 填需求 / 生成 REQ 卡片)后**停下**,等你审阅 `docs/01-需求清单/*.md` 里的 REQ 卡片(Plan 阶段第一个人工关口:业务范围)
  48 + - **第二段(REQ 审阅完重新运行)**:继续 **A2 → A3**(生成骨架 / 从 REQ 正向设计 `docs/03-数据库设计文档.md` 并回填 REQ 依赖表)后再次**停下**,等你审阅 docs/03 的表 / 字段 / 索引 / 外键(第二个人工关口:数据库 schema —— A4 会基于它翻译 DDL 并 apply 到 MySQL,所以这关口与 REQ 审阅同等重要)
  49 + - **第三段(docs/03 审阅完重新运行)**:执行 **A4 → A5**(解析 docs/03 → 生成 V1 migration → 自动 `DROP+CREATE` 本地 schema 并 apply → 生成下游文档),Plan 完成后再次**停下**
55 50
56 - - **第一段(首次运行)**:执行 **A0 → A1**(创建骨架 / 锁技术栈 / 填需求 / 生成 REQ 卡片)后**停下**,等你审阅 `docs/01-需求清单/*.md` 里的 REQ 卡片(这是 Plan 阶段最关键的人工关口)  
57 - - **第二段(审阅完重新运行同一命令)**:继续 **A2 → A5**(生成骨架 / 初始化 DB / 生成设计 / 生成下游文档),Plan 完成后再次**停下** 51 + 每次运行都会自动接上次停下的地方继续;中途可以随时关闭 CC,下次运行同样的命令即可恢复。Plan 完成后**不会自动进入编码**,需要你手动运行 `/erp-workflow:coding-start`。
58 52
59 - 每次运行都会自动接上次停下的地方继续;中途可以随时关闭 CC,下次运行同样的命令即可恢复。Plan 完成后**不会自动进入编码**,需要你手动运行 `/erp-workflow:erp-coding-start` 53 + > 两个审阅断点的勾选位置都在 `docs/08-模块任务管理.md § 一`:A1 审阅完后系统已自动勾选 A1 全部子项;A3 审阅完后需要手动勾选「用户已审阅 docs/03 表结构」+ A3 父项 `[ ]` → `[x]`,下次 `/plan-start` 才会派发到 A4
60 54
61 3. **Coding 阶段入口**(模块循环): 55 3. **Coding 阶段入口**(模块循环):
62 ``` 56 ```
63 - /erp-workflow:erp-coding-start 57 + /erp-workflow:coding-start
64 ``` 58 ```
65 Plan 全部完成后由你显式触发。**按 `docs/02 § 二` REQ 开发顺序清单**扫描,决定当前模块: 59 Plan 全部完成后由你显式触发。**按 `docs/02 § 二` REQ 开发顺序清单**扫描,决定当前模块:
66 - 对每个 REQ 所属模块查询 `docs/08` 的 `MR:` 字段 + GitLab API `state`:  
67 - - `state == merged` → 模块已完成,跳过  
68 - - `MR: —` / opened / closed / 查不到 → 该模块是当前模块 60 + 对每个 REQ 所属模块查询 `docs/08` 的 `MR:` 字段,必要时调 GitLab API 取 `state`:
  61 + - `MR: —` → 该模块是当前模块(未建过 MR)
  62 + - `MR: !<iid>` 且 API `state == merged` → 模块已完成,跳过
  63 + - `MR: !<iid>` 且 API `state ∈ {opened, closed}` → 该模块是当前模块
  64 + - `MR: !<iid>` 但 API HTTP 非 200 / 查不到 / state 非法 → **停下报错**让用户排查 token / API URL / project ID / iid(绝不静默假设未 merged)
69 65
70 - 之后 `git checkout main` + `git pull --ff-only` 同步远程 main(保证下次 module 分支切出时 base 新鲜),再派发到 `erp-module-start`。 66 + 之后**自动探测远程默认分支** → `git checkout <默认分支>` + `git pull --ff-only` 同步远程 → 派发到 `module-start`。
71 67
72 **`docs/08 § 二` 每模块占一行 bullet**,完成信号由 MR merged state 判定;即使用户提前触发 coding-start,未 merged 的模块仍会被选中,不会跳过。 68 **`docs/08 § 二` 每模块占一行 bullet**,完成信号由 MR merged state 判定;即使用户提前触发 coding-start,未 merged 的模块仍会被选中,不会跳过。
73 69
@@ -78,150 +74,165 @@ claude --plugin-dir /path/to/erp-workflow-plugin @@ -78,150 +74,165 @@ claude --plugin-dir /path/to/erp-workflow-plugin
78 ``` 74 ```
79 erp-workflow-plugin/ 75 erp-workflow-plugin/
80 ├── .claude-plugin/ 76 ├── .claude-plugin/
81 -│ └── plugin.json # 插件清单,声明 skills 三个子目录  
82 -├── README.md # 本文档 77 +│ └── plugin.json # 插件清单,声明 skills 四个子目录
  78 +├── README.md # 本文档
83 ├── hooks/ 79 ├── hooks/
84 -│ ├── hooks.json # hook 注册表(2 个 hook)  
85 -│ └── scripts/*.sh # 2 个 hook 脚本 80 +│ ├── hooks.json # hook 注册表(2 个 hook)
  81 +│ └── scripts/*.sh # 2 个 hook 脚本
  82 +├── agents/
  83 +│ └── superpower-code-reviewer.md # code-reviewer agent(feature-review 调用)
86 └── skills/ 84 └── skills/
87 - ├── plan/ # 阶段 A:6 个一次性规划 skill  
88 - ├── coding/ # 阶段 B:9 个模块/功能循环 skill  
89 - └── crosscut/ # 横切:2 个入口 + 1 红旗 + 1 留痕 skill 85 + ├── plan/ # 阶段 A:6 个一次性规划 skill
  86 + ├── coding/ # 阶段 B:9 个模块/功能循环 skill
  87 + ├── crosscut/ # 横切:2 个入口 + 1 中断守门 + 1 留痕 skill
  88 + └── internal/ # superpowers 本地 fork:2 个无门 brainstorming / writing-plans
90 ``` 89 ```
91 90
92 -插件加载时按 `plugin.json` 的 `skills: ["./skills/plan", "./skills/coding", "./skills/crosscut"]` 扫描。skill 名称不含子目录前缀(如 `/erp-workflow:erp-scope-lock`)。  
93 -  
94 ## Hook 清单(2 个,全部在 hooks/hooks.json 注册) 91 ## Hook 清单(2 个,全部在 hooks/hooks.json 注册)
95 92
96 | Hook | 脚本 | 事件 | 触发条件 | 作用 | 93 | Hook | 脚本 | 事件 | 触发条件 | 作用 |
97 |---|---|---|---|---| 94 |---|---|---|---|---|
98 | 拒绝 no-verify | `deny-no-verify.sh` | PreToolUse / Bash | CC 尝试 `git push --no-verify` | 硬拦截,强制 `.githooks/pre-push` 生效 | 95 | 拒绝 no-verify | `deny-no-verify.sh` | PreToolUse / Bash | CC 尝试 `git push --no-verify` | 硬拦截,强制 `.githooks/pre-push` 生效 |
99 -| 跨模块改动留痕 | `log-cross-module.sh` | PostToolUse / Edit \| Write | 当前处于 `module-*` 分支 且 编辑目标路径落在 `docs/08 § 二` 中**非当前模块**的 path 范围内(无论目标模块 MR 是否已 merged) | 把改动追加为 `TBD(CC 补)` 存根到 `<current_module>-cross-module.md`;通过 `additionalContext` 软提示 CC 调 `erp-cross-module-log` skill **自主推断**补「原因 / 影响评估」两列。即时性由 CC 自己决定;**最迟在 `erp-module-report` § ⑦ 硬闸门处**(TBD 未清空会阻断模块完成报告),保证模块完成前所有 TBD 必被 CC 填实 |  
100 -  
101 -**流程使用情况**:2 个 hook 全部在 hooks.json 注册、被 CC 自动触发。 96 +| 跨模块改动留痕 | `log-cross-module.sh` | PostToolUse / Edit \| Write | 当前处于 `module-*` 分支 且 编辑目标路径落在 `docs/08 § 二` 中**非当前模块**的 path 范围内(无论目标模块 MR 是否已 merged) | 把改动追加为 `TBD(CC 补)` 存根到 `<current_module>-cross-module.md`;通过 `additionalContext` 软提示 CC 调 `cross-module-log` skill **自主推断**补「原因 / 影响评估」两列。即时性由 CC 自己决定;**最迟在 `module-report` § ⑦ 硬闸门处**(TBD 未清空会阻断模块完成报告),保证模块完成前所有 TBD 必被 CC 填实 |
102 97
103 -## Skill 清单(19 个) 98 +## Skill 清单(21 个)
104 99
105 ### Plan 阶段(6 个,`skills/plan/`) 100 ### Plan 阶段(6 个,`skills/plan/`)
106 101
107 | # | Skill | 作用 | 流程中谁调用 | 102 | # | Skill | 作用 | 流程中谁调用 |
108 |---|---|---|---| 103 |---|---|---|---|
109 -| A0 | `erp-project-init` | • 依赖检查(`mysql` / `mysqldump` 在 PATH,缺失则尝试自动安装)<br>• 空目录初始化:`cp` 模板创建 CLAUDE.md / docs/01/README.md / docs/08<br>• `git init` | `erp-plan-start` |  
110 -| A1 | `erp-scope-lock` | • 引导填项目概述 / 技术栈 / 需求索引<br>• 生成 REQ 卡片(`schema_refs=TBD(A4 自动补)`、`api_refs=TBD(A5 自动补)`)<br>• **停下**等人工审阅 REQ 卡片,审阅完毕用 `/erp-plan-start` 恢复续进 A2 | A0 |  
111 -| A2 | `erp-skeleton-gen` | • 生成架构文档:docs/04 § 一+ / docs/06 / docs/07 / docs/09<br>• 生成工具脚本:scripts/*.sh、.githooks/pre-push、.env.local<br>• 创建 `sql/migrations/` 空目录(Flyway 准备)<br>• 合并 .gitignore(逐行判重) | `erp-plan-start` |  
112 -| A3 | `erp-db-init` | • 验证 MySQL 连接<br>• 导出 schema 为 `sql/migrations/V1__initial_schema.sql`(DDL only)<br>• 导出数据为 `sql/seed-data.sql`(INSERT only) | A2 |  
113 -| A4 | `erp-db-design-gen` | • 生成 `docs/03-数据库设计文档.md`<br>• 回填 REQ 卡片依赖表(`TBD(A4 自动补)` → 实际表名)<br>• schema 一致性检查 | A3 |  
114 -| A5 | `erp-downstream-gen` | • 一次性生成 docs/02 / docs/05 / docs/06 § 五 / docs/10<br>• 回填 REQ 卡片依赖接口(`TBD(A5 自动补)` → 实际 endpoint)<br>• 追加模块清单到 docs/08 § 二<br>• 最终占位符扫描(TBD 自动补 + `【人工填写:】` QA 循环)<br>• 打印 Plan 完成横幅并**停下**(不自动进 B) | A4 | 104 +| A0 | `project-init` | • 依赖检查(`mysql` 在 PATH,缺失则尝试自动安装)<br>• 空目录初始化:`cp` 模板创建 CLAUDE.md / docs/01/index.md / docs/08<br>• `git init` | `plan-start` |
  105 +| A1 | `scope-lock` | • 引导填项目概述 / 技术栈 / 需求索引<br>• 生成 REQ 卡片(`schema_refs=TBD(A3 自动补)`、`api_refs=TBD(A5 自动补)`)<br>• **停下**等人工审阅 REQ 卡片,审阅完毕用 `/plan-start` 恢复续进 A2 | A0 |
  106 +| A2 | `skeleton-gen` | • 生成架构文档:docs/04 § 一+ / docs/06 / docs/07 / docs/09<br>• 生成工具脚本:scripts/*.sh、.githooks/pre-push、.env.local<br>• 创建 `sql/migrations/` 空目录(Flyway 准备)<br>• 合并 .gitignore(逐行判重) | `plan-start` |
  107 +| A3 | `db-design-gen` | • 从 docs/01 REQ 卡片正向设计 `docs/03-数据库设计文档.md`(schema SSoT)<br>• 回填 REQ 卡片依赖表(`TBD(A3 自动补)` → 实际表名)<br>• **停下**等人工审阅 docs/03,审阅完毕用 `/plan-start` 恢复续进 A4 | A2 |
  108 +| A4 | `db-init` | • LLM 解析 docs/03 → `sql/migrations/V1__initial_schema.sql`(DDL only)<br>• **5 维度全量校验** DDL ↔ docs/03(表名 / 列名+列序 / 类型+nullable+默认值 / 索引名 / FK 名),fail-closed<br>• 验证 MySQL 连接<br>• 调 `scripts/setup-test-db.sh` 复用三层防护(与 B 阶段 test.sh 共用)→ DROP+CREATE 空库<br>• apply V1 + `SHOW TABLES` 行数自检 | A3 |
  109 +| A5 | `downstream-gen` | • 一次性生成 docs/02 / docs/05 / docs/06 § 五 / docs/10<br>• 回填 REQ 卡片依赖接口(`TBD(A5 自动补)` → 实际 endpoint)<br>• 追加模块清单到 docs/08 § 二<br>• 最终占位符扫描(TBD 自动补 + `【人工填写:】` QA 循环)<br>• 打印 Plan 完成横幅并**停下**(不自动进 B) | A4 |
115 110
116 ### Coding 阶段(9 个,`skills/coding/`) 111 ### Coding 阶段(9 个,`skills/coding/`)
117 112
118 -**触发与顺序**(`erp-coding-start` 是唯一由用户手动触发的入口,下面所有 skill 都由 skill 链自动调用): 113 +**触发与顺序**(`coding-start` 是唯一由用户手动触发的入口,下面所有 skill 都由 skill 链自动调用):
119 114
120 ``` 115 ```
121 -/erp-workflow:erp-coding-start ← 用户每次手动触发 116 +/erp-workflow:coding-start ← 用户每次手动触发
122 117
123 │ 扫描 docs/02 REQ 序 + docs/08 MR 字段 + GitLab API state 判定当前模块: 118 │ 扫描 docs/02 REQ 序 + docs/08 MR 字段 + GitLab API state 判定当前模块:
124 │ - 所有模块都 merged → 打印"所有模块已完成" 119 │ - 所有模块都 merged → 打印"所有模块已完成"
125 │ - 找到第一个非 merged 模块 → 派发 120 │ - 找到第一个非 merged 模块 → 派发
126 - │ 派发前 git checkout main + git pull --ff-only(同步远程 base) 121 + │ 派发前自动探测远程默认分支(main / master),git checkout + git pull --ff-only 同步远程 base
127 122
128 - └─→ erp-module-start(幂等可重入,切 module-<id> 分支) 123 + └─→ module-start(幂等可重入,切 module-<id> 分支)
129 124
130 │ 对每个未完成 REQ,按序串链: 125 │ 对每个未完成 REQ,按序串链:
131 - │ erp-feature-brainstorm → -plan → -tdd → -verify → -review 126 + │ feature-brainstorm → -plan → -tdd → -verify → -review
132 127
133 - │ review approve → 回 erp-module-start(推进下一 REQ)  
134 - │ review request-changes (<5) → fix commit → 回 erp-feature-verify 重新执行 128 + │ review approve → 回 module-start(推进下一 REQ)
  129 + │ review request-changes (<5) → fix commit → 回 feature-verify 重新执行
135 │ review request-changes (=5) → 停下(升级给人) 130 │ review request-changes (=5) → 停下(升级给人)
136 131
137 │ 模块全部 REQ approve → 132 │ 模块全部 REQ approve →
138 - │ erp-local-test-gate(commit test-gate.md)  
139 - │ → erp-module-report(commit 模块报告 + cross-module log)  
140 - │ → erp-mr-create(worktree clean 校验 → push 代码+evidence → 创建 MR 133 + │ test-gate(commit test-gate.md)
  134 + │ → module-report(commit 模块报告 + cross-module log)
  135 + │ → mr-create(worktree clean 校验 → push 代码+evidence → 创建 MR
141 │ → 追 MR URL 到报告 + commit → 写 MR iid 到 docs/08 + commit 136 │ → 追 MR URL 到报告 + commit → 写 MR iid 到 docs/08 + commit
142 │ → 再 push) 137 │ → 再 push)
143 138
144 └─ ⏸ 停下等人工 Approve + Merge 139 └─ ⏸ 停下等人工 Approve + Merge
145 (人工合并后再次运行 coding-start,扫描到 state=merged 自动跳过 140 (人工合并后再次运行 coding-start,扫描到 state=merged 自动跳过
146 - → pull main → 推进下一模块) 141 + → pull 默认分支 → 推进下一模块)
147 ``` 142 ```
148 143
149 | Skill | 做什么 | 谁触发它 | 144 | Skill | 做什么 | 谁触发它 |
150 |---|---|---| 145 |---|---|---|
151 -| `erp-module-start` | 定位当前模块(docs/02 REQ 序)+ 切换或创建 `module-<id>` 分支 + 扫描 `docs/superpowers/reviews/*.md` 的 `verdict=approve` 计算已完成 REQ + 推进第一个未完成 REQ 的功能循环。全部完成 → `erp-local-test-gate`。**幂等可重入**(中途断开后重新运行会自动跳过已 approve 的 REQ) | `erp-coding-start` 派发;`erp-feature-review` approve 后回调 |  
152 -| `erp-feature-brainstorm` | 功能循环步骤 1:交互 brainstorm → 生成 `docs/superpowers/specs/*.md` | `erp-module-start` 推进 REQ 时调用 |  
153 -| `erp-feature-plan` | 功能循环步骤 2:spec → 任务级 plan(含文件路径 + 完整代码),输出 `docs/superpowers/plans/*.md` | `erp-feature-brainstorm` 链式调用 |  
154 -| `erp-feature-tdd` | 功能循环步骤 3:红绿循环(写失败测试 → 实现 → 子会话验证通过 → commit 到 `module-<id>` 分支) | `erp-feature-plan` 链式调用 |  
155 -| `erp-feature-verify` | 功能循环步骤 4:将全量测试派发到子会话执行一次,用模板渲染 evidence | `erp-feature-tdd` 链式调用;`erp-feature-review` 在 request-changes 修复后重新调用 |  
156 -| `erp-feature-review` | 功能循环步骤 5:AI 自审,写 `docs/superpowers/reviews/*.md`。approve → 回 `erp-module-start`;request-changes → 逐项 Edit + fix commit → 回 `erp-feature-verify` 重新执行(最多 5 轮,第 5 轮仍 request-changes 则停下) | `erp-feature-verify` 链式调用 |  
157 -| `erp-local-test-gate` | MR 前硬闸门:子会话执行 `scripts/test.sh`(脚本内部 drop+create 空库、Flyway apply `sql/migrations/V*.sql`、再执行测试);通过 → 写 `<module_id>-test-gate.md` 并 `git add + commit`(evidence 提交到 module 分支);失败停下 | `erp-module-start` 在本模块所有 REQ approve 后调用 |  
158 -| `erp-module-report` | 红旗检查 → 生成 12 节模块完成报告 `docs/superpowers/module-reports/<date>-<module_id>.md` → `git add + commit`(报告 + cross-module log 提交到 module 分支,erp-mr-create 的 worktree clean 前置条件依赖此步) | `erp-local-test-gate` 链式调用 |  
159 -| `erp-mr-create` | 红旗检查 → 验证当前分支 = `module-<id>` 且 `git status --porcelain` worktree 干净 → `git push` 推代码与全部 evidence → 用 curl 调 GitLab REST API 创建 MR(模块报告嵌入 MR 描述)→ 追加 MR URL 到报告并 commit → 把 docs/08 该模块的 `MR: —` 回写为 `MR: !<iid>` 并 commit → 再次 push;**停下等人工 Approve+Merge**。完成由 MR state 判定 | `erp-module-report` 链式调用 | 146 +| `module-start` | 定位当前模块(docs/02 REQ 序)+ 切换或创建 `module-<id>` 分支 + 扫描 `docs/superpowers/reviews/*.md` 的 `verdict=approve` 计算已完成 REQ + 推进第一个未完成 REQ 的功能循环。全部完成 → `test-gate`。**幂等可重入**(中途断开后重新运行会自动跳过已 approve 的 REQ) | `coding-start` 派发;`feature-review` approve 后回调 |
  147 +| `feature-brainstorm` | 功能循环步骤 1:交互 brainstorm → 生成 `docs/superpowers/specs/*.md` | `module-start` 推进 REQ 时调用 |
  148 +| `feature-plan` | 功能循环步骤 2:spec → 任务级 plan(文件路径 + API 签名 + 测试意图 + 完成判据,代码由 TDD 阶段产出),输出 `docs/superpowers/plans/*.md` | `feature-brainstorm` 链式调用 |
  149 +| `feature-tdd` | 功能循环步骤 3:红绿循环(写失败测试 → 实现 → 子会话验证通过 → commit 到 `module-<id>` 分支) | `feature-plan` 链式调用 |
  150 +| `feature-verify` | 功能循环步骤 4:将全量测试派发到子会话执行一次,用模板渲染 evidence | `feature-tdd` 链式调用;`feature-review` 在 request-changes 修复后重新调用 |
  151 +| `feature-review` | 功能循环步骤 5:AI 自审,写 `docs/superpowers/reviews/*.md`。approve → 回 `module-start`;request-changes → 逐项 Edit + fix commit → 回 `feature-verify` 重新执行(最多 5 轮,第 5 轮仍 request-changes 则停下) | `feature-verify` 链式调用 |
  152 +| `test-gate` | MR 前硬闸门:子会话执行 `scripts/test.sh`(脚本内部 drop+create 空库、Flyway apply `sql/migrations/V*.sql`、再执行测试);通过 → 写 `<module_id>-test-gate.md` 并 `git add + commit`(evidence 提交到 module 分支);失败停下 | `module-start` 在本模块所有 REQ approve 后调用 |
  153 +| `module-report` | 中断检查 → 生成 12 节模块完成报告 `docs/superpowers/module-reports/<date>-<module_id>.md` → `git add + commit`(报告 + cross-module log 提交到 module 分支,mr-create 的 worktree clean 前置条件依赖此步) | `test-gate` 链式调用 |
  154 +| `mr-create` | 中断检查 → 验证当前分支 = `module-<id>` 且 `git status --porcelain` worktree 干净 → `git push` 推代码与全部 evidence → 用 curl 调 GitLab REST API 创建 MR(模块报告嵌入 MR 描述)→ 追加 MR URL 到报告并 commit → 把 docs/08 该模块的 `MR: —` 回写为 `MR: !<iid>` 并 commit → 再次 push;**停下等人工 Approve+Merge**。完成由 MR state 判定 | `module-report` 链式调用 |
160 155
161 ### Crosscut(4 个,`skills/crosscut/`) 156 ### Crosscut(4 个,`skills/crosscut/`)
162 157
163 | Skill | 作用 | 流程中谁调用 | 158 | Skill | 作用 | 流程中谁调用 |
164 |---|---|---| 159 |---|---|---|
165 -| `erp-plan-start` | **A 阶段入口**。读取 docs/08 § 一 找第一个未勾 A 子项 → 派发对应 A skill;A 全部完成时提示运行 coding-start | **用户手动**运行 `/erp-workflow:erp-plan-start` |  
166 -| `erp-coding-start` | **B 阶段入口**。先验证 Plan 已完成;**按 `docs/02 § 二` REQ 序扫描**,对每个 REQ 所属模块查询 `MR:` 字段 + GitLab API `state`:`merged` 跳过;`—`/opened/closed/查不到 选为当前模块。派发前 `git checkout main + git pull --ff-only` 同步远程 base,然后调用 `erp-module-start` | **用户手动**运行 `/erp-workflow:erp-coding-start` |  
167 -| `erp-red-flag-check` | 检查 CLAUDE.md 的 3 项红旗清单;命中则追加 Blocker 到计划文件并停下 | 功能循环各步骤和生成重要制品前自动调用 |  
168 -| `erp-cross-module-log` | 给 `log-cross-module.sh` 追加的跨模块改动存根补「原因 / 影响评估」 | 用户看到 hook 提示后调用;`erp-module-start` 初始化日志文件时也会用其模板 | 160 +| `plan-start` | **A 阶段入口**。读取 docs/08 § 一 找第一个未勾 A 子项 → 派发对应 A skill;A 全部完成时提示运行 coding-start | **用户手动**运行 `/erp-workflow:plan-start` |
  161 +| `coding-start` | **B 阶段入口**。先验证 Plan 已完成;**按 `docs/02 § 二` REQ 序扫描**,对每个 REQ 所属模块查询 `MR:` 字段 + GitLab API `state`:`merged` 跳过;`—`/opened/closed 选为当前模块;查不到则停下报错。派发前自动探测远程默认分支(main / master),`git checkout + git pull --ff-only` 同步远程 base,然后调用 `module-start` | **用户手动**运行 `/erp-workflow:coding-start` |
  162 +| `interrupt-check` | 检查 CLAUDE.md 的 3 项中断清单;触发则追加 Blocker 到计划文件并停下 | 功能循环各步骤和生成重要制品前自动调用 |
  163 +| `cross-module-log` | 给 `log-cross-module.sh` 追加的跨模块改动存根批量补「原因 / 影响评估」 | `module-report` § ⑦ 硬验收时一次性调用(CC 编辑中途不主动调);`module-start` 初始化日志文件时也会用其模板 |
  164 +
  165 +### Internal / Superpowers Fork(2 个,`skills/internal/`)
  166 +
  167 +`superpowers:brainstorming` / `superpowers:writing-plans` 原版内含 `<HARD-GATE>` 与"等用户 approve 设计 / review spec / Which approach?"等用户等待点,与本插件"除真正卡死外不停"目标冲突。fork 进来剥掉门控后作为 `feature-brainstorm` / `feature-plan` 的内部实现用。
  168 +
  169 +| Skill | 源(superpowers 版本) | 剥掉了什么 |
  170 +|---|---|---|
  171 +| `superpower-brainstorming` | `superpowers:brainstorming` 5.0.7 | `<HARD-GATE>` 整块、Anti-Pattern 段、Checklist 里 Visual Companion / approve-design / review-spec 三项、User Review Gate、Visual Companion 整节、终点 `invoke writing-plans` |
  172 +| `superpower-writing-plans` | `superpowers:writing-plans` 5.0.7 | Execution Handoff 整节("Which approach?" 问询)、"Complete code in every step" 硬要求(改为"API 签名 + 测试意图"粒度,完整代码留给 TDD) |
  173 +
  174 +## Agent 清单(1 个)
  175 +
  176 +| Agent | 源 | 用途 | 谁调用 |
  177 +|---|---|---|---|
  178 +| `superpower-code-reviewer` | `superpowers:code-reviewer` 5.0.7 agent,仅改 name | 对 REQ diff 做 AI 自审,产出 `must_fix[]` / `nice_to_have[]` / `gaps` | `feature-review` 步骤 1:`Agent(subagent_type=superpower-code-reviewer)` |
169 179
170 -## Templates 清单(38 份) 180 +## Templates 清单(37 份)
171 181
172 | 所属 Skill | 模板文件 | 用途 | 182 | 所属 Skill | 模板文件 | 用途 |
173 |---|---|---| 183 |---|---|---|
174 -| erp-project-init | `CLAUDE-template.md` | 项目根的 CLAUDE.md(4 条通用准则 + ERP 专属约定) |  
175 -| erp-project-init | `docs-01-readme-template.md` | 需求清单索引骨架,等用户填模块表 |  
176 -| erp-project-init | `docs-08-initial-template.md` | 工作流进度文件骨架(Plan A0~A5 checkbox) |  
177 -| erp-scope-lock | `req-card-template.md` | 单张 REQ-XXX-NNN 卡片字段结构 |  
178 -| erp-scope-lock | `docs-01-module-template.md` | 单模块 `<code>-<name>.md` 外壳 |  
179 -| erp-skeleton-gen | `docs-04-skeleton-template.md` | docs/04 § 一+ 编码规范大纲(HTML 注释引导 LLM) |  
180 -| erp-skeleton-gen | `docs-06-static-template.md` | docs/06 § 一~四 UI 模式大纲 |  
181 -| erp-skeleton-gen | `docs-07-env-template.md` | docs/07 环境配置大纲 |  
182 -| erp-skeleton-gen | `docs-09-structure-template.md` | docs/09 目录结构大纲 |  
183 -| erp-skeleton-gen | `scripts-setup-test-db-template.sh` | 运行时 drop + create 空库脚本(0 槽位);schema apply 交给 Flyway |  
184 -| erp-skeleton-gen | `githooks-pre-push-template.sh` | pre-push → 调 scripts/test.sh(0 槽位) |  
185 -| erp-skeleton-gen | `env-local-template` | 6 字段凭据模板(DB_* + JWT_SECRET) |  
186 -| erp-skeleton-gen | `gitignore-append-template` | 插件推荐忽略项(`.env.local`、`.tmp/`、构建产物等) |  
187 -| erp-db-init | `migration-v1-header-template.sql` | V1 initial migration 文件头部注释 |  
188 -| erp-db-init | `seed-data-sql-template.sql` | seed-data.sql 文件头部注释 |  
189 -| erp-db-design-gen | `docs-03-header-template.md` | docs/03 数据库设计头部 |  
190 -| erp-db-design-gen | `docs-03-table-template.md` | docs/03 单表小节模板 |  
191 -| erp-downstream-gen | `docs-02-template.md` | docs/02 开发计划 |  
192 -| erp-downstream-gen | `docs-05-header-template.md` | docs/05 API 契约头部 |  
193 -| erp-downstream-gen | `docs-05-endpoint-template.md` | docs/05 单接口小节 |  
194 -| erp-downstream-gen | `docs-06-module-pagelist-template.md` | docs/06 § 五 单模块页面清单 |  
195 -| erp-downstream-gen | `docs-08-module-row-template.md` | docs/08 § 二 单模块 bullet 行 |  
196 -| erp-downstream-gen | `docs-10-header-template.md` | docs/10 验收清单头部 |  
197 -| erp-downstream-gen | `docs-10-module-template.md` | docs/10 单模块验收项 |  
198 -| erp-module-start | `module-start-banner-template.md` | 模块启动横幅 |  
199 -| erp-module-start | `cross-module-log-template.md` | cross-module 日志头(副本) |  
200 -| erp-feature-brainstorm | `feature-spec-template.md` | 功能 spec 结构 |  
201 -| erp-feature-plan | `feature-plan-template.md` | 功能 plan 结构 |  
202 -| erp-feature-tdd | `commit-message-template.md` | TDD 每步 commit 信息 |  
203 -| erp-feature-verify | `feature-verify-evidence-template.md` | 验证证据渲染模板 |  
204 -| erp-feature-review | `feature-review-template.md` | 自审报告结构 |  
205 -| erp-local-test-gate | `test-gate-result-template.md` | 闸门结果渲染 |  
206 -| erp-module-report | `module-report-template.md` | 12 节模块报告 |  
207 -| erp-mr-create | `mr-title-template.md` | MR 标题模板 |  
208 -| erp-mr-create | `mr-description-template.md` | MR 描述模板(嵌入模块报告) |  
209 -| erp-red-flag-check | `red-flag-block-template.md` | Blocker 节追加模板 |  
210 -| erp-cross-module-log | `cross-module-log-template.md` | cross-module 日志头(主本) |  
211 -| erp-cross-module-log | `cross-module-log-row-template.md` | 单条改动行模板 | 184 +| project-init | `CLAUDE-template.md` | 项目根的 CLAUDE.md(4 条通用准则 + ERP 专属约定) |
  185 +| project-init | `docs-01-index-template.md` | 需求清单索引骨架,等用户填模块表 |
  186 +| project-init | `docs-08-initial-template.md` | 工作流进度文件骨架(Plan A0~A5 checkbox) |
  187 +| project-init | `docs-04-stack-template.md` | docs/04 § 零 默认技术栈总览(零槽位,cp 即可) |
  188 +| scope-lock | `req-card-template.md` | 单张 REQ-XXX-NNN 卡片字段结构 |
  189 +| scope-lock | `docs-01-module-template.md` | 单模块 `<code>-<name>.md` 外壳 |
  190 +| skeleton-gen | `docs-04-skeleton-template.md` | docs/04 § 一+ 编码规范大纲(HTML 注释引导 LLM) |
  191 +| skeleton-gen | `docs-06-static-template.md` | docs/06 § 一~四 UI 模式大纲 |
  192 +| skeleton-gen | `docs-07-env-template.md` | docs/07 环境配置大纲 |
  193 +| skeleton-gen | `docs-09-structure-template.md` | docs/09 目录结构大纲 |
  194 +| skeleton-gen | `scripts-setup-test-db-template.sh` | 运行时 drop + create 空库脚本(0 槽位);schema apply 交给 Flyway |
  195 +| skeleton-gen | `scripts-test-template.sh` | test.sh 骨架(4 个命令槽位:{{build_cmd}} / {{lint_cmd}} / {{test_cmd}} / {{e2e_cmd}},由 skeleton-gen 按技术栈推断填充) |
  196 +| skeleton-gen | `githooks-pre-push-template.sh` | pre-push → 调 scripts/test.sh(0 槽位) |
  197 +| skeleton-gen | `env-local-template` | 6 字段凭据模板(DB_* + JWT_SECRET) |
  198 +| skeleton-gen | `gitignore-append-template` | 插件推荐忽略项(`.env.local`、`.tmp/`、构建产物等) |
  199 +| db-init | `migration-v1-header-template.sql` | V1 initial migration 文件头部注释 |
  200 +| db-design-gen | `docs-03-header-template.md` | docs/03 数据库设计头部 |
  201 +| db-design-gen | `docs-03-table-template.md` | docs/03 单表小节模板 |
  202 +| downstream-gen | `docs-02-template.md` | docs/02 开发计划 |
  203 +| downstream-gen | `docs-05-header-template.md` | docs/05 API 契约头部 |
  204 +| downstream-gen | `docs-05-endpoint-template.md` | docs/05 单接口小节 |
  205 +| downstream-gen | `docs-06-module-pagelist-template.md` | docs/06 § 五 单模块页面清单 |
  206 +| downstream-gen | `docs-08-module-row-template.md` | docs/08 § 二 单模块 bullet 行 |
  207 +| downstream-gen | `docs-10-header-template.md` | docs/10 验收清单头部 |
  208 +| downstream-gen | `docs-10-module-template.md` | docs/10 单模块验收项 |
  209 +| module-start | `module-start-banner-template.md` | 模块启动横幅 |
  210 +| module-start | `cross-module-log-template.md` | cross-module 日志头(副本) |
  211 +| feature-brainstorm | `feature-spec-template.md` | 功能 spec 结构 |
  212 +| feature-plan | `feature-plan-template.md` | 功能 plan 结构 |
  213 +| feature-tdd | `commit-message-template.md` | TDD 每步 commit 信息 |
  214 +| feature-verify | `feature-verify-evidence-template.md` | 验证证据渲染模板 |
  215 +| feature-review | `feature-review-template.md` | 自审报告结构 |
  216 +| test-gate | `test-gate-result-template.md` | 闸门结果渲染 |
  217 +| module-report | `module-report-template.md` | 12 节模块报告 |
  218 +| mr-create | `mr-title-template.md` | MR 标题模板 |
  219 +| mr-create | `mr-description-template.md` | MR 描述模板(嵌入模块报告) |
  220 +| interrupt-check | `interrupt-block-template.md` | Blocker 节追加模板 |
  221 +| cross-module-log | `cross-module-log-template.md` | cross-module 日志头(主本) |
  222 +| cross-module-log | `cross-module-log-row-template.md` | 单条改动行模板 |
212 223
213 **流程使用情况**:所有模板都被对应 skill 的 `SKILL.md` 引用,没有孤儿模板。 224 **流程使用情况**:所有模板都被对应 skill 的 `SKILL.md` 引用,没有孤儿模板。
214 225
215 ## 前置依赖 226 ## 前置依赖
216 227
217 -- **MySQL 8.x** 实例已就绪(CC 不执行 DDL;schema 由人工初始化)  
218 -- **`mysql` / `mysqldump` 命令行**:`erp-db-init` (A3) 验证连接 + 导出 V1 initial migration + 导出 seed-data.sql;`scripts/setup-test-db.sh` 在测试闸门前后 drop+create 空库 228 +- **MySQL 8.x** 实例已就绪(推荐本地 / `*.local` host;A4 `db-init` 的安全守护要求 host 在白名单且 schema 名含 `test`/`dev`/`local`,避免误删生产库)
  229 +- **`mysql` 命令行**:A4 `db-init` 验证连接 + 自动 `DROP+CREATE` schema 后 apply V1;`scripts/setup-test-db.sh` 在测试闸门前后 drop+create 空库
219 - **Spring Boot + Flyway**(**必需**):pom.xml 声明 `flyway-core` + `flyway-mysql`;Spring 启动时自动 apply `sql/migrations/V*.sql`。本插件生成的 `setup-test-db.sh` 只清库,schema 必须由 Flyway 应用 230 - **Spring Boot + Flyway**(**必需**):pom.xml 声明 `flyway-core` + `flyway-mysql`;Spring 启动时自动 apply `sql/migrations/V*.sql`。本插件生成的 `setup-test-db.sh` 只清库,schema 必须由 Flyway 应用
220 -- **GitLab v3 API + Private Token**:`erp-mr-create` 用 `curl` POST `/projects/:id/merge_requests` 建 MR;`erp-coding-start` / `erp-module-start` 用 `curl` GET `/projects/:id/merge_requests?iid=<iid>` 判定 state(v3 路径参数 `:merge_request_id` 要内部数字 id,所以统一用 iid 过滤列表)。HTTP 头用 `PRIVATE-TOKEN`;凭据(`GITLAB_API_URL=.../api/v3` / `GITLAB_TOKEN` / `GITLAB_PROJECT_ID`)放 `.env.local`  
221 -- **本地可运行 `mvn test` / `pnpm test`**:测试闸门 `scripts/test.sh` 由 `erp-skeleton-gen` 生成 231 +- **GitLab v3 API + Private Token**:`mr-create` 用 `curl` POST `/projects/:id/merge_requests` 建 MR;`coding-start` / `module-start` 用 `curl` GET `/projects/:id/merge_requests?iid=<iid>` 判定 state(v3 路径参数 `:merge_request_id` 要内部数字 id,所以统一用 iid 过滤列表)。HTTP 头用 `PRIVATE-TOKEN`;凭据(`GITLAB_API_URL=.../api/v3` / `GITLAB_TOKEN` / `GITLAB_PROJECT_ID`)放 `.env.local`
  232 +- **本地可运行 `mvn test` / `pnpm test`**:测试闸门 `scripts/test.sh` 由 `skeleton-gen` 生成
222 233
223 ## 设计原则 234 ## 设计原则
224 235
225 -参见 `erp-project-init/templates/CLAUDE-template.md` 末尾的「🧭 通用工作准则」4 条:① Think Before Coding ② Simplicity First ③ Surgical Changes ④ Goal-Driven Execution。 236 +参见 `project-init/templates/CLAUDE-template.md` 末尾的「🧭 通用工作准则」4 条:① Think Before Coding ② Simplicity First ③ Surgical Changes ④ Goal-Driven Execution。
226 237
227 最关键的 1 条:"**所有测试与验证派发到全新子会话执行,主会话只接收结构化结论**"——避免主会话被测试输出污染,并让测试结果作为独立证据存档。 238 最关键的 1 条:"**所有测试与验证派发到全新子会话执行,主会话只接收结构化结论**"——避免主会话被测试输出污染,并让测试结果作为独立证据存档。
hooks/scripts/deny-no-verify.sh
@@ -11,7 +11,7 @@ cmd=&quot;$(printf &#39;%s&#39; &quot;$input&quot; | jq -r &#39;.tool_input.command // empty&#39;)&quot; @@ -11,7 +11,7 @@ cmd=&quot;$(printf &#39;%s&#39; &quot;$input&quot; | jq -r &#39;.tool_input.command // empty&#39;)&quot;
11 [ -n "$cmd" ] || exit 0 11 [ -n "$cmd" ] || exit 0
12 12
13 if printf '%s' "$cmd" | grep -qE '\bgit[[:space:]]+push\b.*--no-verify\b'; then 13 if printf '%s' "$cmd" | grep -qE '\bgit[[:space:]]+push\b.*--no-verify\b'; then
14 - echo "BLOCKED: --no-verify bypasses the local test.sh gate (唯一硬闸门). If test.sh is failing, fix the root cause; do not skip the gate. Use /erp-local-test-gate to run the gate properly." >&2 14 + echo "BLOCKED: --no-verify bypasses the local test.sh gate (唯一硬闸门). If test.sh is failing, fix the root cause; do not skip the gate. Use /test-gate to run the gate properly." >&2
15 exit 2 15 exit 2
16 fi 16 fi
17 17
hooks/scripts/log-cross-module.sh
@@ -19,7 +19,7 @@ docs08=&quot;$project_dir/docs/08-模块任务管理.md&quot; @@ -19,7 +19,7 @@ docs08=&quot;$project_dir/docs/08-模块任务管理.md&quot;
19 case "$file_path" in *"/docs/08-模块任务管理.md") exit 0 ;; esac 19 case "$file_path" in *"/docs/08-模块任务管理.md") exit 0 ;; esac
20 20
21 # 当前模块 = 当前 git 分支名去掉 `module-` 前缀。 21 # 当前模块 = 当前 git 分支名去掉 `module-` 前缀。
22 -# erp-module-start 步骤 3 保证模块循环期间处于 module-<id> 分支; 22 +# module-start 步骤 3 保证模块循环期间处于 module-<id> 分支;
23 # 非 module-* 分支(如 main、feature/*、docs/*)不在模块循环内,不触发 S2 留痕。 23 # 非 module-* 分支(如 main、feature/*、docs/*)不在模块循环内,不触发 S2 留痕。
24 current_branch="$(cd "$project_dir" 2>/dev/null && git branch --show-current 2>/dev/null || echo '')" 24 current_branch="$(cd "$project_dir" 2>/dev/null && git branch --show-current 2>/dev/null || echo '')"
25 case "$current_branch" in 25 case "$current_branch" in
@@ -78,4 +78,4 @@ rel_path=&quot;${file_path#$project_dir/}&quot; @@ -78,4 +78,4 @@ rel_path=&quot;${file_path#$project_dir/}&quot;
78 echo "| ${ts} | ${hit_module} | ${rel_path} | ${tool_name} | TBD(CC 补) | TBD(CC 补) |" >> "$log_file" 78 echo "| ${ts} | ${hit_module} | ${rel_path} | ${tool_name} | TBD(CC 补) | TBD(CC 补) |" >> "$log_file"
79 79
80 jq -n --arg m "$hit_module" --arg f "$log_file" --arg p "$rel_path" \ 80 jq -n --arg m "$hit_module" --arg f "$log_file" --arg p "$rel_path" \
81 - '{hookSpecificOutput:{hookEventName:"PostToolUse",additionalContext:("跨模块改动检测:\($p) 属于模块 [\($m)](非当前模块)。存根已写入 \($f),含 TBD(CC 补) 占位。请由 CC 调用 erp-cross-module-log skill 自主推断并补填原因与影响评估(软规则 S2,CC 自主维护,非人工填写)。")}}' 81 + '{hookSpecificOutput:{hookEventName:"PostToolUse",additionalContext:("跨模块改动检测:\($p) 属于模块 [\($m)](非当前模块)。存根已写入 \($f),含 TBD(CC 补) 占位。**不需要现在处理**——所有 TBD 由 module-report § ⑦ 一次性调用 cross-module-log skill 批量补齐(软规则 S2)。")}}'
skills/coding/erp-feature-brainstorm/SKILL.md renamed to skills/coding/feature-brainstorm/SKILL.md
1 --- 1 ---
2 -name: erp-feature-brainstorm 2 +name: feature-brainstorm
3 description: 功能循环第 1 步。针对单个 REQ-XXX-NNN 进行交互式头脑风暴,产出功能规格文件到 docs/superpowers/specs/。 3 description: 功能循环第 1 步。针对单个 REQ-XXX-NNN 进行交互式头脑风暴,产出功能规格文件到 docs/superpowers/specs/。
4 user-invocable: false 4 user-invocable: false
5 allowed-tools: Read Write Skill Bash(mysql *) 5 allowed-tools: Read Write Skill Bash(mysql *)
@@ -7,7 +7,7 @@ allowed-tools: Read Write Skill Bash(mysql *) @@ -7,7 +7,7 @@ allowed-tools: Read Write Skill Bash(mysql *)
7 7
8 **所有输出必须使用中文。** 8 **所有输出必须使用中文。**
9 9
10 -# erp-feature-brainstorm 10 +# feature-brainstorm
11 11
12 ## 说明 12 ## 说明
13 13
@@ -15,7 +15,7 @@ allowed-tools: Read Write Skill Bash(mysql *) @@ -15,7 +15,7 @@ allowed-tools: Read Write Skill Bash(mysql *)
15 15
16 ## 执行步骤 16 ## 执行步骤
17 17
18 -1. **红旗检查**:调用 `erp-red-flag-check`。如果命中 → 停止。 18 +1. **中断检查**:调用 `interrupt-check`。如果触发 → 停止。
19 2. 确定输入: 19 2. 确定输入:
20 - 当前 REQ-XXX-NNN(从对话中获取,或 `docs/08` 当前模块下一个未完成的 REQ)。 20 - 当前 REQ-XXX-NNN(从对话中获取,或 `docs/08` 当前模块下一个未完成的 REQ)。
21 - REQ 卡片:`docs/01-需求清单/<module>.md` 中对应的 REQ-XXX-NNN 节。 21 - REQ 卡片:`docs/01-需求清单/<module>.md` 中对应的 REQ-XXX-NNN 节。
@@ -30,10 +30,10 @@ allowed-tools: Read Write Skill Bash(mysql *) @@ -30,10 +30,10 @@ allowed-tools: Read Write Skill Bash(mysql *)
30 30
31 ## 衔接 31 ## 衔接
32 32
33 -立即调用 `Skill(erp-feature-plan)` 进入下一步。 33 +立即调用 `Skill(feature-plan)` 进入下一步。
34 34
35 ## 参考 35 ## 参考
36 36
37 - `${CLAUDE_SKILL_DIR}/templates/feature-spec-template.md` 37 - `${CLAUDE_SKILL_DIR}/templates/feature-spec-template.md`
38 - 委托:`superpower-brainstorming`(本插件 `skills/internal/superpower-brainstorming/`,superpowers:brainstorming 的无门 fork) 38 - 委托:`superpower-brainstorming`(本插件 `skills/internal/superpower-brainstorming/`,superpowers:brainstorming 的无门 fork)
39 -- 守门:`erp-red-flag-check` 39 +- 守门:`interrupt-check`
skills/coding/erp-feature-brainstorm/templates/feature-spec-template.md renamed to skills/coding/feature-brainstorm/templates/feature-spec-template.md
skills/coding/erp-feature-plan/SKILL.md renamed to skills/coding/feature-plan/SKILL.md
1 --- 1 ---
2 -name: erp-feature-plan 2 +name: feature-plan
3 description: 功能循环第 2 步。将规格转化为任务级计划(每任务 2-5 分钟,含文件路径和完整代码),输出到 docs/superpowers/plans/。 3 description: 功能循环第 2 步。将规格转化为任务级计划(每任务 2-5 分钟,含文件路径和完整代码),输出到 docs/superpowers/plans/。
4 user-invocable: false 4 user-invocable: false
5 allowed-tools: Read Write Grep Skill 5 allowed-tools: Read Write Grep Skill
@@ -7,11 +7,11 @@ allowed-tools: Read Write Grep Skill @@ -7,11 +7,11 @@ allowed-tools: Read Write Grep Skill
7 7
8 **所有输出必须使用中文。** 8 **所有输出必须使用中文。**
9 9
10 -# erp-feature-plan 10 +# feature-plan
11 11
12 ## 执行步骤 12 ## 执行步骤
13 13
14 -1. **红旗检查**:调用 `erp-red-flag-check`。 14 +1. **中断检查**:调用 `interrupt-check`。
15 2. 确定输入: 15 2. 确定输入:
16 - 当前 REQ-XXX-NNN 及其规格文件 `docs/superpowers/specs/YYYY-MM-DD-<REQ>.md`(规格不存在则报错)。 16 - 当前 REQ-XXX-NNN 及其规格文件 `docs/superpowers/specs/YYYY-MM-DD-<REQ>.md`(规格不存在则报错)。
17 - 相关代码指针(已有的待修改文件,通过 Grep 发现)。 17 - 相关代码指针(已有的待修改文件,通过 Grep 发现)。
@@ -25,10 +25,10 @@ allowed-tools: Read Write Grep Skill @@ -25,10 +25,10 @@ allowed-tools: Read Write Grep Skill
25 25
26 ## 衔接 26 ## 衔接
27 27
28 -立即调用 `Skill(erp-feature-tdd)` 进入下一步。 28 +立即调用 `Skill(feature-tdd)` 进入下一步。
29 29
30 ## 参考 30 ## 参考
31 31
32 - `${CLAUDE_SKILL_DIR}/templates/feature-plan-template.md` 32 - `${CLAUDE_SKILL_DIR}/templates/feature-plan-template.md`
33 - 委托:`superpower-writing-plans`(本插件 `skills/internal/superpower-writing-plans/`,superpowers:writing-plans 的无门 fork) 33 - 委托:`superpower-writing-plans`(本插件 `skills/internal/superpower-writing-plans/`,superpowers:writing-plans 的无门 fork)
34 -- 守门:`erp-red-flag-check` 34 +- 守门:`interrupt-check`
skills/coding/erp-feature-plan/templates/feature-plan-template.md renamed to skills/coding/feature-plan/templates/feature-plan-template.md
skills/coding/erp-feature-review/SKILL.md renamed to skills/coding/feature-review/SKILL.md
1 --- 1 ---
2 -name: erp-feature-review  
3 -description: 功能循环第 5 步。AI 自审,输出审阅报告到 docs/superpowers/reviews/。approve 回调 erp-module-start;request-changes 则编辑代码并 fix commit,重新执行 verify。自修复循环上限 5 轮。 2 +name: feature-review
  3 +description: 功能循环第 5 步。AI 自审,输出审阅报告到 docs/superpowers/reviews/。approve 回调 module-start;request-changes 则编辑代码并 fix commit,重新执行 verify。自修复循环上限 5 轮。
4 user-invocable: false 4 user-invocable: false
5 allowed-tools: Read Write Edit Skill Agent Bash(git add *) Bash(git commit *) 5 allowed-tools: Read Write Edit Skill Agent Bash(git add *) Bash(git commit *)
6 --- 6 ---
7 7
8 **所有输出必须使用中文。** 8 **所有输出必须使用中文。**
9 9
10 -# erp-feature-review 10 +# feature-review
11 11
12 ## 执行步骤 12 ## 执行步骤
13 13
@@ -17,25 +17,25 @@ allowed-tools: Read Write Edit Skill Agent Bash(git add *) Bash(git commit *) @@ -17,25 +17,25 @@ allowed-tools: Read Write Edit Skill Agent Bash(git add *) Bash(git commit *)
17 4. 写入报告。 17 4. 写入报告。
18 18
19 5. 分发: 19 5. 分发:
20 - - **`verdict = approve`** → 输出 `feature-review: <REQ> round <N> 通过`,然后调用 `Skill(erp-module-start)` 回模块主循环(module-start 会自动把本 REQ 识别为 done 并推进下一个 REQ)。 20 + - **`verdict = approve`** → 用 `Edit` 在 `docs/08-模块任务管理.md § 二` 本模块 bullet 下找到 ` - [ ] <REQ-id> ...` 行勾选为 ` - [x] <REQ-id> ...`(功能级进度可视化;模块完成仍由 `MR:` + GitLab API state 判定,不依赖本勾选)。然后输出 `feature-review: <REQ> round <N> 通过`,调用 `Skill(module-start)` 回模块主循环(module-start 会自动把本 REQ 识别为 done 并推进下一个 REQ)。
21 - **`verdict = request-changes`** → 执行"自修复子流程": 21 - **`verdict = request-changes`** → 执行"自修复子流程":
22 - 逐项处理 `must_fix[]`:对每个条目用 `Edit` 修改其指向的代码文件。 22 - 逐项处理 `must_fix[]`:对每个条目用 `Edit` 修改其指向的代码文件。
23 - - 所有 Must-fix 修复后,拼 commit 消息(格式与 `erp-feature-tdd` 一致,单行):`fix(<module_id>): 修复 review round <N> must-fix <REQ-id>`。 23 + - 所有 Must-fix 修复后,拼 commit 消息(格式与 `feature-tdd` 一致,单行):`fix(<module_id>): 修复 review round <N> must-fix <REQ-id>`。
24 - `Bash`: `git add <修改的代码文件>` + `git commit -m "<上一步拼出的消息>"`。 24 - `Bash`: `git add <修改的代码文件>` + `git commit -m "<上一步拼出的消息>"`。
25 - - 调用 `Skill(erp-feature-verify)` 重新执行验证;verify 通过后会再次链到本 skill,作为 round `<N+1>` 重审。 25 + - 调用 `Skill(feature-verify)` 重新执行验证;verify 通过后会再次链到本 skill,作为 round `<N+1>` 重审。
26 26
27 6. 上限:**5 轮**。第 5 轮仍为 `request-changes` → 停止并打印摘要(升级给用户手工介入),不再自动修复,不回调 module-start。 27 6. 上限:**5 轮**。第 5 轮仍为 `request-changes` → 停止并打印摘要(升级给用户手工介入),不再自动修复,不回调 module-start。
28 28
29 ## 衔接 29 ## 衔接
30 30
31 -- `approve` → `Skill(erp-module-start)` 回主循环。  
32 -- `request-changes`(round < 5)→ `Skill(erp-feature-verify)` 重新执行。 31 +- `approve` → `Skill(module-start)` 回主循环。
  32 +- `request-changes`(round < 5)→ `Skill(feature-verify)` 重新执行。
33 - `request-changes`(round == 5)→ 停止。 33 - `request-changes`(round == 5)→ 停止。
34 34
35 ## 参考 35 ## 参考
36 36
37 - `${CLAUDE_SKILL_DIR}/templates/feature-review-template.md` 37 - `${CLAUDE_SKILL_DIR}/templates/feature-review-template.md`
38 -- Fix commit 格式与 `erp-feature-tdd` 的 `commit-message-template.md` 对齐(`fix(<scope>): <subject> <req_id>`) 38 +- Fix commit 格式与 `feature-tdd` 的 `commit-message-template.md` 对齐(`fix(<scope>): <subject> <req_id>`)
39 - 委托:`superpower-code-reviewer`(本插件 `agents/superpower-code-reviewer.md`,superpowers:code-reviewer 的本地 fork) 39 - 委托:`superpower-code-reviewer`(本插件 `agents/superpower-code-reviewer.md`,superpowers:code-reviewer 的本地 fork)
40 -- 上游:`erp-feature-verify`  
41 -- 下游:`erp-module-start`(approve)或 `erp-feature-verify`(request-changes) 40 +- 上游:`feature-verify`
  41 +- 下游:`module-start`(approve)或 `feature-verify`(request-changes)
skills/coding/erp-feature-review/templates/feature-review-template.md renamed to skills/coding/feature-review/templates/feature-review-template.md
skills/coding/erp-feature-tdd/SKILL.md renamed to skills/coding/feature-tdd/SKILL.md
1 --- 1 ---
2 -name: erp-feature-tdd 2 +name: feature-tdd
3 description: 功能循环第 3 步。逐任务执行计划:写失败测试 → 实现代码 → 测试通过 → 提交。所有测试运行均派发到子会话执行。 3 description: 功能循环第 3 步。逐任务执行计划:写失败测试 → 实现代码 → 测试通过 → 提交。所有测试运行均派发到子会话执行。
4 user-invocable: false 4 user-invocable: false
5 allowed-tools: Read Write Edit Agent Skill Bash(git add *) Bash(git commit *) 5 allowed-tools: Read Write Edit Agent Skill Bash(git add *) Bash(git commit *)
@@ -7,25 +7,27 @@ allowed-tools: Read Write Edit Agent Skill Bash(git add *) Bash(git commit *) @@ -7,25 +7,27 @@ allowed-tools: Read Write Edit Agent Skill Bash(git add *) Bash(git commit *)
7 7
8 **所有输出必须使用中文。** 8 **所有输出必须使用中文。**
9 9
10 -# erp-feature-tdd 10 +# feature-tdd
11 11
12 ## 执行步骤 12 ## 执行步骤
13 13
14 -1. **红旗检查**:调用 `erp-red-flag-check`。 14 +1. **中断检查**:调用 `interrupt-check`。
15 2. 加载计划文件 `docs/superpowers/plans/YYYY-MM-DD-<REQ>.md`。 15 2. 加载计划文件 `docs/superpowers/plans/YYYY-MM-DD-<REQ>.md`。
16 -3. **Schema 改动优先(如果计划声明了需要)**:若 plan 标注 "本 REQ 需要 schema 改动",**第一个任务必须是写 migration 文件**: 16 +3. **Schema 改动优先(如果计划声明了需要)**:若 plan 标注 "本 REQ 需要 schema 改动",**第一个任务必须是写 migration 文件 + 同步更新 docs/03**:
17 - `ls sql/migrations/V*.sql` 得最大版本号 n_max,新文件版本号 = n_max + 1 17 - `ls sql/migrations/V*.sql` 得最大版本号 n_max,新文件版本号 = n_max + 1
18 - 文件名格式 `V<n>__<snake_case_desc>.sql`,例 `V5__add_user_email.sql` 18 - 文件名格式 `V<n>__<snake_case_desc>.sql`,例 `V5__add_user_email.sql`
19 - - `Write` 该文件(只含 DDL:`ALTER TABLE ... ADD COLUMN ...` / `CREATE TABLE ...` 等),commit 19 + - `Write` 该文件(只含 DDL:`ALTER TABLE ... ADD COLUMN ...` / `CREATE TABLE ...` 等)
  20 + - **同步把新 CREATE/ALTER 反向更新到 `docs/03-数据库设计文档.md` 对应表小节**(字段表格 / 索引 / 外键 / 业务注记),保持 docs/03 仍是 schema SSoT;新增表则按 `docs-03-table-template.md` 格式追加一节
  21 + - 把 migration + docs/03 改动**一起 commit**(避免 SSoT 与 migration 分裂)
20 - 之后的代码任务(entity / DAO / service / 测试)在此之后做;测试运行时 Spring Boot 启动会由 Flyway 自动 apply 这个新 migration(`scripts/setup-test-db.sh` 只负责清空库) 22 - 之后的代码任务(entity / DAO / service / 测试)在此之后做;测试运行时 Spring Boot 启动会由 Flyway 自动 apply 这个新 migration(`scripts/setup-test-db.sh` 只负责清空库)
21 4. 按顺序处理每个(代码类)任务: 23 4. 按顺序处理每个(代码类)任务:
22 a. 在 `test_file::test_name` 处编写失败测试。 24 a. 在 `test_file::test_name` 处编写失败测试。
23 b. **派发子会话**(通过 `Agent`,general-purpose)运行测试并确认失败;子会话只返回 `{command, exit_code, failing_assertion}`。主会话**不直接**运行测试。 25 b. **派发子会话**(通过 `Agent`,general-purpose)运行测试并确认失败;子会话只返回 `{command, exit_code, failing_assertion}`。主会话**不直接**运行测试。
24 c. 在 `impl_file` 处实现最小代码使测试通过。 26 c. 在 `impl_file` 处实现最小代码使测试通过。
25 d. **再次派发子会话**运行测试并确认通过。 27 d. **再次派发子会话**运行测试并确认通过。
26 - e. 持续失败(同一测试 >10 次修复尝试)→ 调用 `erp-red-flag-check`(红旗 #1)。 28 + e. 持续失败(同一测试 >10 次修复尝试)→ 调用 `interrupt-check`(中断 #1)。
27 f. 暂存变更并使用 `${CLAUDE_SKILL_DIR}/templates/commit-message-template.md` 提交;`scope` 匹配任务的模块,`subject` ≤50 字符,`req_id` 必填。 29 f. 暂存变更并使用 `${CLAUDE_SKILL_DIR}/templates/commit-message-template.md` 提交;`scope` 匹配任务的模块,`subject` ≤50 字符,`req_id` 必填。
28 -5. 所有任务完成后 → 交接给 `erp-feature-verify`。 30 +5. 所有任务完成后 → 交接给 `feature-verify`。
29 31
30 ## 护栏 32 ## 护栏
31 33
@@ -36,10 +38,10 @@ allowed-tools: Read Write Edit Agent Skill Bash(git add *) Bash(git commit *) @@ -36,10 +38,10 @@ allowed-tools: Read Write Edit Agent Skill Bash(git add *) Bash(git commit *)
36 38
37 ## 衔接 39 ## 衔接
38 40
39 -立即调用 `Skill(erp-feature-verify)` 进入下一步。 41 +立即调用 `Skill(feature-verify)` 进入下一步。
40 42
41 ## 参考 43 ## 参考
42 44
43 - `${CLAUDE_SKILL_DIR}/templates/commit-message-template.md` 45 - `${CLAUDE_SKILL_DIR}/templates/commit-message-template.md`
44 - 原则参考:`superpowers:test-driven-development`(本插件未镜像;仅作为 TDD 原则手册参考,不做运行时 invoke — 本 skill 已把"子会话跑测试 + REQ tag commit"流程直接写死) 46 - 原则参考:`superpowers:test-driven-development`(本插件未镜像;仅作为 TDD 原则手册参考,不做运行时 invoke — 本 skill 已把"子会话跑测试 + REQ tag commit"流程直接写死)
45 -- 守门:`erp-red-flag-check` 47 +- 守门:`interrupt-check`
skills/coding/erp-feature-tdd/templates/commit-message-template.md renamed to skills/coding/feature-tdd/templates/commit-message-template.md
skills/coding/erp-feature-verify/SKILL.md renamed to skills/coding/feature-verify/SKILL.md
1 --- 1 ---
2 -name: erp-feature-verify 2 +name: feature-verify
3 description: 功能循环第 4 步。将本功能的测试派发到子会话执行,用模板渲染验证证据。无证据不得声称完成。 3 description: 功能循环第 4 步。将本功能的测试派发到子会话执行,用模板渲染验证证据。无证据不得声称完成。
4 user-invocable: false 4 user-invocable: false
5 -allowed-tools: Skill Read Write Agent 5 +allowed-tools: Skill Read Agent
6 --- 6 ---
7 7
8 **所有输出必须使用中文。** 8 **所有输出必须使用中文。**
9 9
10 -# erp-feature-verify 10 +# feature-verify
11 11
12 ## 执行步骤 12 ## 执行步骤
13 13
@@ -23,7 +23,7 @@ allowed-tools: Skill Read Write Agent @@ -23,7 +23,7 @@ allowed-tools: Skill Read Write Agent
23 23
24 3. 解析 JSON;用 `Read` 读取 `${CLAUDE_SKILL_DIR}/templates/feature-verify-evidence-template.md`,填充槽位(包括 `subagent_id` 和 `conclusion`)。 24 3. 解析 JSON;用 `Read` 读取 `${CLAUDE_SKILL_DIR}/templates/feature-verify-evidence-template.md`,填充槽位(包括 `subagent_id` 和 `conclusion`)。
25 4. 如果 `exit_code != 0` 或 `failed > 0` → 打印填充后的证据到会话并**停止**,不进入审阅。 25 4. 如果 `exit_code != 0` 或 `failed > 0` → 打印填充后的证据到会话并**停止**,不进入审阅。
26 -5. 通过 → 打印证据,交接给 `erp-feature-review`。 26 +5. 通过 → 打印证据,交接给 `feature-review`。
27 27
28 ## 护栏 28 ## 护栏
29 29
@@ -32,7 +32,7 @@ allowed-tools: Skill Read Write Agent @@ -32,7 +32,7 @@ allowed-tools: Skill Read Write Agent
32 32
33 ## 衔接 33 ## 衔接
34 34
35 -立即调用 `Skill(erp-feature-review)` 进入下一步。 35 +立即调用 `Skill(feature-review)` 进入下一步。
36 36
37 ## 参考 37 ## 参考
38 38
skills/coding/erp-feature-verify/templates/feature-verify-evidence-template.md renamed to skills/coding/feature-verify/templates/feature-verify-evidence-template.md
skills/coding/erp-module-report/SKILL.md renamed to skills/coding/module-report/SKILL.md
1 --- 1 ---
2 -name: erp-module-report 2 +name: module-report
3 description: 本地测试闸门通过后,生成标准化 12 节模块完成报告,嵌入本模块新增的 migration 清单和跨模块改动日志。 3 description: 本地测试闸门通过后,生成标准化 12 节模块完成报告,嵌入本模块新增的 migration 清单和跨模块改动日志。
4 user-invocable: false 4 user-invocable: false
5 allowed-tools: Read Write Glob Grep Skill Bash(git diff *) Bash(git log *) Bash(git add *) Bash(git commit *) 5 allowed-tools: Read Write Glob Grep Skill Bash(git diff *) Bash(git log *) Bash(git add *) Bash(git commit *)
@@ -7,13 +7,13 @@ allowed-tools: Read Write Glob Grep Skill Bash(git diff *) Bash(git log *) Bash( @@ -7,13 +7,13 @@ allowed-tools: Read Write Glob Grep Skill Bash(git diff *) Bash(git log *) Bash(
7 7
8 **所有输出必须使用中文。** 8 **所有输出必须使用中文。**
9 9
10 -# erp-module-report 10 +# module-report
11 11
12 ## 执行步骤 12 ## 执行步骤
13 13
14 -0. **红旗检查**:调用 `Skill(erp-red-flag-check)` → 命中则停止(与 `erp-red-flag-check` SKILL 描述"生成模块级制品前"对齐)。 14 +0. **中断检查**:调用 `Skill(interrupt-check)` → 触发则停止(与 `interrupt-check` SKILL 描述"生成模块级制品前"对齐)。
15 15
16 -1. 验证上游:`erp-local-test-gate` 返回了绿色。否则停止。 16 +1. 验证上游:`test-gate` 返回了绿色。否则停止。
17 2. 收集输入(优先 shell 摘要,避免把 diff 正文读进上下文): 17 2. 收集输入(优先 shell 摘要,避免把 diff 正文读进上下文):
18 - **文件变更 § ③** — 只用摘要,**不**读 diff 正文: 18 - **文件变更 § ③** — 只用摘要,**不**读 diff 正文:
19 - `git diff --stat <module-start-commit>..HEAD` → 每文件增减行数 19 - `git diff --stat <module-start-commit>..HEAD` → 每文件增减行数
@@ -25,30 +25,30 @@ allowed-tools: Read Write Glob Grep Skill Bash(git diff *) Bash(git log *) Bash( @@ -25,30 +25,30 @@ allowed-tools: Read Write Glob Grep Skill Bash(git diff *) Bash(git log *) Bash(
25 - `docs/superpowers/module-reports/<module_id>-test-gate.md` → § ⑤ 25 - `docs/superpowers/module-reports/<module_id>-test-gate.md` → § ⑤
26 - § ④(读写的表):**用 `grep -rlE "(SELECT|INSERT|UPDATE|DELETE).*FROM|INTO"` 定位涉及 SQL 的文件,再按需读取片段**。不要全量读取 docs/03。 26 - § ④(读写的表):**用 `grep -rlE "(SELECT|INSERT|UPDATE|DELETE).*FROM|INTO"` 定位涉及 SQL 的文件,再按需读取片段**。不要全量读取 docs/03。
27 3. 用 `Read` 读取 `${CLAUDE_SKILL_DIR}/templates/module-report-template.md`,填充全部 12 节。 27 3. 用 `Read` 读取 `${CLAUDE_SKILL_DIR}/templates/module-report-template.md`,填充全部 12 节。
28 -4. **硬性验证**:  
29 - - § ⑦:如果 cross-module 有任何行含 `TBD(CC 补)` → **停止**,调用 `Skill(erp-cross-module-log)` 让 CC **自主推断**补齐,补完再回本步骤重验。  
30 - - § ⑦:如果非空但某行缺少影响评估(被填成空/敷衍)→ 同样调 `erp-cross-module-log` 重补。 28 +4. **硬性验证 + 批量补齐跨模块 TBD**:
  29 + - § ⑦:这是整模块周期里**唯一补齐 `TBD(CC 补)` 的时机**(编辑中途 CC 不应主动调 `cross-module-log`)。如果 cross-module 有任何行含 `TBD(CC 补)` → 调用 `Skill(cross-module-log)` 一次性批量补齐所有 TBD,补完再回本步骤重验。
  30 + - § ⑦:如果非空但某行缺少影响评估(被填成空/敷衍)→ 同样调 `cross-module-log` 重补。
31 - § ⑧ 必须列举所有偏离规格之处;如果没有,明确写"无偏离"。 31 - § ⑧ 必须列举所有偏离规格之处;如果没有,明确写"无偏离"。
32 5. 写入 `docs/superpowers/module-reports/$(date +%F)-<module_id>.md`。 32 5. 写入 `docs/superpowers/module-reports/$(date +%F)-<module_id>.md`。
33 33
34 -5b. **commit 模块报告 + cross-module 日志到 module 分支**(确保审计证据随 MR 合并进默认分支;erp-mr-create 的 worktree clean 前置条件依赖此步): 34 +5b. **commit 模块报告 + cross-module 日志到 module 分支**(确保审计证据随 MR 合并进默认分支;mr-create 的 worktree clean 前置条件依赖此步):
35 35
36 ```bash 36 ```bash
37 git add docs/superpowers/module-reports/$(date +%F)-<module_id>.md 37 git add docs/superpowers/module-reports/$(date +%F)-<module_id>.md
38 - # cross-module log 若存在且有改动(erp-cross-module-log 补齐过 TBD)也一并提交 38 + # cross-module log 若存在且有改动(cross-module-log 补齐过 TBD)也一并提交
39 [ -f "docs/superpowers/module-reports/<module_id>-cross-module.md" ] && \ 39 [ -f "docs/superpowers/module-reports/<module_id>-cross-module.md" ] && \
40 git add docs/superpowers/module-reports/<module_id>-cross-module.md 40 git add docs/superpowers/module-reports/<module_id>-cross-module.md
41 git commit -m "docs(<module_id>): add module completion report + cross-module log" 41 git commit -m "docs(<module_id>): add module completion report + cross-module log"
42 ``` 42 ```
43 43
44 -6. 交接给 `erp-mr-create`。 44 +6. 交接给 `mr-create`。
45 45
46 ## 衔接 46 ## 衔接
47 47
48 -立即调用 `Skill(erp-mr-create)` 推送并创建 MR。 48 +立即调用 `Skill(mr-create)` 推送并创建 MR。
49 49
50 ## 参考 50 ## 参考
51 51
52 - `${CLAUDE_SKILL_DIR}/templates/module-report-template.md`(12 节) 52 - `${CLAUDE_SKILL_DIR}/templates/module-report-template.md`(12 节)
53 -- 上游:`erp-local-test-gate`  
54 -- 下游:`erp-mr-create` 53 +- 上游:`test-gate`
  54 +- 下游:`mr-create`
skills/coding/erp-module-report/templates/module-report-template.md renamed to skills/coding/module-report/templates/module-report-template.md
skills/coding/erp-module-start/SKILL.md renamed to skills/coding/module-start/SKILL.md
1 --- 1 ---
2 -name: erp-module-start  
3 -description: 启动/恢复模块循环。按 docs/02 § 二 REQ 清单定位当前模块及其 REQ 序列,确保处于模块分支,扫描 docs/superpowers/reviews/ 计算已完成 REQ,驱动第一个未完成 REQ 的功能循环;全部完成则调用 erp-local-test-gate。幂等可重入。 2 +name: module-start
  3 +description: 启动/恢复模块循环。按 docs/02 § 二 REQ 清单定位当前模块及其 REQ 序列,确保处于模块分支,扫描 docs/superpowers/reviews/ 计算已完成 REQ,驱动第一个未完成 REQ 的功能循环;全部完成则调用 test-gate。幂等可重入。
4 user-invocable: false 4 user-invocable: false
5 allowed-tools: Read Write Skill Glob Grep Bash(git branch *) Bash(git checkout *) Bash(git rev-parse *) Bash(curl *) Bash(jq *) Bash(mkdir -p .tmp) Bash(rm -f .tmp/*) 5 allowed-tools: Read Write Skill Glob Grep Bash(git branch *) Bash(git checkout *) Bash(git rev-parse *) Bash(curl *) Bash(jq *) Bash(mkdir -p .tmp) Bash(rm -f .tmp/*)
6 --- 6 ---
7 7
8 **所有输出必须使用中文。** 8 **所有输出必须使用中文。**
9 9
10 -# erp-module-start 10 +# module-start
11 11
12 ## 执行步骤 12 ## 执行步骤
13 13
14 ### 步骤 1:按 `docs/02 § 二` REQ 序 + MR state 定位当前模块 + 本模块 REQ 列表 14 ### 步骤 1:按 `docs/02 § 二` REQ 序 + MR state 定位当前模块 + 本模块 REQ 列表
15 15
16 -与 `erp-coding-start` 步骤 3 同构(完成判定以 `MR:` 字段 + GitLab API `state` 为准;curl 调用,凭据读 `.env.local` 的 `GITLAB_API_URL` / `GITLAB_TOKEN` / `GITLAB_PROJECT_ID`): 16 +> `MR:` 字段 × GitLab API state 的三组合判定规则见 `CLAUDE.md § ✅ 模块完成判定规则 § 模块状态语义`。
  17 +
  18 +与 `coding-start` 步骤 3 同构(完成判定以 `MR:` 字段 + GitLab API `state` 为准;curl 调用,凭据读 `.env.local` 的 `GITLAB_API_URL` / `GITLAB_TOKEN` / `GITLAB_PROJECT_ID`):
17 19
18 - 用 `Read` 读取 `docs/02-开发计划.md`,用 `Grep`(pattern `^\|\s*[0-9]+\s*\|\s*\*\*(REQ-[A-Z0-9]+-[0-9]+)\*\*\s*\|\s*(module_\w+)`)抽取 § 二 表格数据行,按行号升序得 `req_order[]`。 20 - 用 `Read` 读取 `docs/02-开发计划.md`,用 `Grep`(pattern `^\|\s*[0-9]+\s*\|\s*\*\*(REQ-[A-Z0-9]+-[0-9]+)\*\*\s*\|\s*(module_\w+)`)抽取 § 二 表格数据行,按行号升序得 `req_order[]`。
19 - 若 `req_order` 为空 → 打印"⚠️ docs/02 § 二 REQ 开发顺序清单为空或无法解析,请检查"并停止。 21 - 若 `req_order` 为空 → 打印"⚠️ docs/02 § 二 REQ 开发顺序清单为空或无法解析,请检查"并停止。
@@ -22,14 +24,14 @@ allowed-tools: Read Write Skill Glob Grep Bash(git branch *) Bash(git checkout * @@ -22,14 +24,14 @@ allowed-tools: Read Write Skill Glob Grep Bash(git branch *) Bash(git checkout *
22 - `module_merged[module_id]` 已缓存为 `false` → `current_module = module_id`,结束遍历。 24 - `module_merged[module_id]` 已缓存为 `false` → `current_module = module_id`,结束遍历。
23 - 未缓存 → 读取 docs/08 § 二 该模块条目的 ` - MR:` 字段: 25 - 未缓存 → 读取 docs/08 § 二 该模块条目的 ` - MR:` 字段:
24 - `MR: —` → `module_merged[module_id] = false`,`current_module = module_id`,结束遍历。 26 - `MR: —` → `module_merged[module_id] = false`,`current_module = module_id`,结束遍历。
25 - - `MR: !<iid>` → 先 `Bash`: `set -a; . ./.env.local; set +a`,然后**分步校验 HTTP + 返回条数 + state 枚举**(语义与 `erp-coding-start` 步骤 3 严格一致): 27 + - `MR: !<iid>` → 先 `Bash`: `set -a; . ./.env.local; set +a`,然后**分步校验 HTTP + 返回条数 + state 枚举**(语义与 `coding-start` 步骤 3 严格一致):
26 ```bash 28 ```bash
27 mkdir -p .tmp 29 mkdir -p .tmp
28 HTTP_CODE=$(curl -sS -o .tmp/mr.json -w '%{http_code}' \ 30 HTTP_CODE=$(curl -sS -o .tmp/mr.json -w '%{http_code}' \
29 --header "PRIVATE-TOKEN: ${GITLAB_TOKEN}" \ 31 --header "PRIVATE-TOKEN: ${GITLAB_TOKEN}" \
30 "${GITLAB_API_URL}/projects/${GITLAB_PROJECT_ID}/merge_requests?iid=<iid>") 32 "${GITLAB_API_URL}/projects/${GITLAB_PROJECT_ID}/merge_requests?iid=<iid>")
31 ``` 33 ```
32 - 硬停条件(任一命中 → 打印与 `erp-coding-start` 同款诊断横幅后**停下**,不进入下游 skill): 34 + 硬停条件(任一触发 → 打印与 `coding-start` 同款诊断横幅后**停下**,不进入下游 skill):
33 1. `HTTP_CODE != 200` 35 1. `HTTP_CODE != 200`
34 2. `HTTP_CODE == 200` 但 `jq 'length' .tmp/mr.json != 1` 36 2. `HTTP_CODE == 200` 但 `jq 'length' .tmp/mr.json != 1`
35 3. state 不在 `{merged, opened, closed}` 里 37 3. state 不在 `{merged, opened, closed}` 里
@@ -71,9 +73,9 @@ allowed-tools: Read Write Skill Glob Grep Bash(git branch *) Bash(git checkout * @@ -71,9 +73,9 @@ allowed-tools: Read Write Skill Glob Grep Bash(git branch *) Bash(git checkout *
71 ### 步骤 7:推进主循环 73 ### 步骤 7:推进主循环
72 74
73 - 从 `req_list[]` 取第一个不在 `done_reqs[]` 中的 REQ 作为 `next_req`。 75 - 从 `req_list[]` 取第一个不在 `done_reqs[]` 中的 REQ 作为 `next_req`。
74 -- **没有 `next_req`**(全部完成)→ 调用 `Skill(erp-local-test-gate)` 进入模块闸门。  
75 -- **有 `next_req`** → 调用 `Skill(erp-feature-brainstorm)` 启动该 REQ 的功能循环。功能循环链(brainstorm → plan → tdd → verify → review)完成后,`erp-feature-review` 在 `verdict=approve` 分支会回调 `Skill(erp-module-start)` —— 再次进入本 skill 时,步骤 5 会把刚通过的 REQ 加入 `done_reqs[]`,步骤 7 自动取下一 REQ,形成可重入推进。  
76 -- 任何中断(红旗 / 测试持续失败 / review 5 轮仍 request-changes)→ 停止本模块,不要静默跳下一 REQ。 76 +- **没有 `next_req`**(全部完成)→ 调用 `Skill(test-gate)` 进入模块闸门。
  77 +- **有 `next_req`** → 调用 `Skill(feature-brainstorm)` 启动该 REQ 的功能循环。功能循环链(brainstorm → plan → tdd → verify → review)完成后,`feature-review` 在 `verdict=approve` 分支会回调 `Skill(module-start)` —— 再次进入本 skill 时,步骤 5 会把刚通过的 REQ 加入 `done_reqs[]`,步骤 7 自动取下一 REQ,形成可重入推进。
  78 +- 任何停止条件触发(中断触发 / 测试持续失败 / review 5 轮仍 request-changes)→ 停止本模块,不要静默跳下一 REQ。
77 79
78 ## 参考 80 ## 参考
79 81
@@ -82,4 +84,4 @@ allowed-tools: Read Write Skill Glob Grep Bash(git branch *) Bash(git checkout * @@ -82,4 +84,4 @@ allowed-tools: Read Write Skill Glob Grep Bash(git branch *) Bash(git checkout *
82 - `docs/superpowers/reviews/*.md`(REQ 级进度事实——verdict=approve 即完成) 84 - `docs/superpowers/reviews/*.md`(REQ 级进度事实——verdict=approve 即完成)
83 - `${CLAUDE_SKILL_DIR}/templates/module-start-banner-template.md` 85 - `${CLAUDE_SKILL_DIR}/templates/module-start-banner-template.md`
84 - `${CLAUDE_SKILL_DIR}/templates/cross-module-log-template.md` 86 - `${CLAUDE_SKILL_DIR}/templates/cross-module-log-template.md`
85 -- 下游:`erp-feature-*`、`erp-local-test-gate` 87 +- 下游:`feature-*`、`test-gate`
skills/coding/erp-module-start/templates/cross-module-log-template.md renamed to skills/coding/module-start/templates/cross-module-log-template.md
1 # 跨模块改动日志 — {{module_name}} 1 # 跨模块改动日志 — {{module_name}}
2 2
3 -软规则 S2:本模块开发期间对**非当前模块**代码的改动(无论目标模块是否已 MR merged)记录在此;模块完成报告必须单列「跨模块改动」节完整贴入。漏留痕或未评估影响 → 升级为红旗 3 +软规则 S2:本模块开发期间对**非当前模块**代码的改动(无论目标模块是否已 MR merged)记录在此;模块完成报告必须单列「跨模块改动」节完整贴入。漏留痕或未评估影响 → 升级为中断
4 4
5 -**本日志由 CC 自主维护**——hook `log-cross-module.sh` 自动落存根(含 `TBD(CC 补)` 占位),CC 调 `erp-cross-module-log` skill 自主推断补「原因 / 影响评估」两列。**不需要人工填写**。 5 +**本日志由 CC 自主维护**——hook `log-cross-module.sh` 自动落存根(含 `TBD(CC 补)` 占位),CC 调 `cross-module-log` skill 自主推断补「原因 / 影响评估」两列。**不需要人工填写**。
6 6
7 | 时间戳 | 目标模块 | 文件 | 改动摘要 | 原因 | 影响评估 | 7 | 时间戳 | 目标模块 | 文件 | 改动摘要 | 原因 | 影响评估 |
8 |---|---|---|---|---|---| 8 |---|---|---|---|---|---|
skills/coding/erp-module-start/templates/module-start-banner-template.md renamed to skills/coding/module-start/templates/module-start-banner-template.md
@@ -8,4 +8,4 @@ @@ -8,4 +8,4 @@
8 - [{{status}}] {{req_id}} — {{title}} 8 - [{{status}}] {{req_id}} — {{title}}
9 {{/each}} 9 {{/each}}
10 10
11 -开始/恢复功能循环(Layer 3),本次处理清单中第一个未完成 REQ。命中红旗 → 停;所有 REQ 完成 → 进入模块闸门。 11 +开始/恢复功能循环(Layer 3),本次处理清单中第一个未完成 REQ。触发中断 → 停;所有 REQ 完成 → 进入模块闸门。
skills/coding/erp-mr-create/SKILL.md renamed to skills/coding/mr-create/SKILL.md
1 --- 1 ---
2 -name: erp-mr-create 2 +name: mr-create
3 description: 模块报告完成后,验证当前分支为 module-<id> 且 worktree 干净,push 推代码和所有 evidence,创建 GitLab MR(报告嵌入描述),把 MR URL 追加到模块报告 § ⑫ 并 commit,把 MR iid 回写到 docs/08 该模块 `MR:` 字段并 commit,再次 push 同步。完成信号由 MR merged state 判定。停下等待人工审核。 3 description: 模块报告完成后,验证当前分支为 module-<id> 且 worktree 干净,push 推代码和所有 evidence,创建 GitLab MR(报告嵌入描述),把 MR URL 追加到模块报告 § ⑫ 并 commit,把 MR iid 回写到 docs/08 该模块 `MR:` 字段并 commit,再次 push 同步。完成信号由 MR merged state 判定。停下等待人工审核。
4 user-invocable: false 4 user-invocable: false
5 allowed-tools: Read Write Edit Skill Bash(git *) Bash(curl *) Bash(jq *) Bash(sed *) Bash(awk *) Bash(cat *) Bash(echo *) Bash(mkdir -p .tmp) Bash(mv .tmp/*) Bash(rm -f .tmp/*) 5 allowed-tools: Read Write Edit Skill Bash(git *) Bash(curl *) Bash(jq *) Bash(sed *) Bash(awk *) Bash(cat *) Bash(echo *) Bash(mkdir -p .tmp) Bash(mv .tmp/*) Bash(rm -f .tmp/*)
@@ -7,24 +7,24 @@ allowed-tools: Read Write Edit Skill Bash(git *) Bash(curl *) Bash(jq *) Bash(se @@ -7,24 +7,24 @@ allowed-tools: Read Write Edit Skill Bash(git *) Bash(curl *) Bash(jq *) Bash(se
7 7
8 **所有输出必须使用中文。** 8 **所有输出必须使用中文。**
9 9
10 -# erp-mr-create 10 +# mr-create
11 11
12 ## 前置条件 12 ## 前置条件
13 13
14 -- `erp-module-report` 已生成报告文件并 commit 到 module 分支。  
15 -- `erp-local-test-gate` 返回了绿色,test-gate.md 已 commit 到 module 分支。  
16 -- 当前分支 = `module-<module_id>`(由 `erp-module-start` 步骤 3 负责切入)。 14 +- `module-report` 已生成报告文件并 commit 到 module 分支。
  15 +- `test-gate` 返回了绿色,test-gate.md 已 commit 到 module 分支。
  16 +- 当前分支 = `module-<module_id>`(由 `module-start` 步骤 3 负责切入)。
17 17
18 ## 执行步骤 18 ## 执行步骤
19 19
20 -### 步骤 0:红旗检查 20 +### 步骤 0:中断检查
21 21
22 -调用 `Skill(erp-red-flag-check)` → 命中则停止。 22 +调用 `Skill(interrupt-check)` → 触发则停止。
23 23
24 ### 步骤 1:验证当前分支 24 ### 步骤 1:验证当前分支
25 25
26 - `Bash`: `git branch --show-current` → `current_branch`。 26 - `Bash`: `git branch --show-current` → `current_branch`。
27 -- `current_branch` 必须匹配 `module-*`;否则打印错误并**停止**(不自动创建分支——分支职责在 `erp-module-start` 步骤 3)。 27 +- `current_branch` 必须匹配 `module-*`;否则打印错误并**停止**(不自动创建分支——分支职责在 `module-start` 步骤 3)。
28 - 从 `current_branch` 取 `module_id = current_branch` 去掉 `"module-"` 前缀。 28 - 从 `current_branch` 取 `module_id = current_branch` 去掉 `"module-"` 前缀。
29 29
30 ### 步骤 2:验证 worktree 干净(防止 evidence 文件漏 commit) 30 ### 步骤 2:验证 worktree 干净(防止 evidence 文件漏 commit)
@@ -33,17 +33,17 @@ allowed-tools: Read Write Edit Skill Bash(git *) Bash(curl *) Bash(jq *) Bash(se @@ -33,17 +33,17 @@ allowed-tools: Read Write Edit Skill Bash(git *) Bash(curl *) Bash(jq *) Bash(se
33 - 输出非空 → 打印 dirty 文件清单并**停止**: 33 - 输出非空 → 打印 dirty 文件清单并**停止**:
34 ``` 34 ```
35 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 35 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
36 - [erp-mr-create] ⚠️ worktree 不干净,无法 push 36 + [mr-create] ⚠️ worktree 不干净,无法 push
37 37
38 以下文件有未提交改动: 38 以下文件有未提交改动:
39 <git status 输出> 39 <git status 输出>
40 40
41 push 前所有 evidence 必须已 commit 到 module 分支。检查点: 41 push 前所有 evidence 必须已 commit 到 module 分支。检查点:
42 - - erp-local-test-gate 步骤 3b 是否已 commit test-gate.md?  
43 - - erp-module-report 步骤 5b 是否已 commit 模块报告 + cross-module log? 42 + - test-gate 步骤 3b 是否已 commit test-gate.md?
  43 + - module-report 步骤 5b 是否已 commit 模块报告 + cross-module log?
44 - 本 skill 前没人跑过额外的 Edit/Write? 44 - 本 skill 前没人跑过额外的 Edit/Write?
45 45
46 - 修复方式:`git add <files> && git commit -m "..."`,然后重新运行 /erp-workflow:erp-coding-start。 46 + 修复方式:`git add <files> && git commit -m "..."`,然后重新运行 /erp-workflow:coding-start。
47 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 47 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
48 ``` 48 ```
49 49
@@ -51,7 +51,7 @@ allowed-tools: Read Write Edit Skill Bash(git *) Bash(curl *) Bash(jq *) Bash(se @@ -51,7 +51,7 @@ allowed-tools: Read Write Edit Skill Bash(git *) Bash(curl *) Bash(jq *) Bash(se
51 51
52 `git push -u origin <current_branch>` — **不要**使用 `--no-verify`(hook `deny-no-verify.sh` 会拦截)。 52 `git push -u origin <current_branch>` — **不要**使用 `--no-verify`(hook `deny-no-verify.sh` 会拦截)。
53 53
54 -此 push 包含:代码 commit(erp-feature-tdd 产出)+ 模块 review fix commit(erp-feature-review 产出)+ test-gate evidence commit(erp-local-test-gate 产出)+ 模块完成报告 commit(erp-module-report 产出)。 54 +此 push 包含:代码 commit(feature-tdd 产出)+ 模块 review fix commit(feature-review 产出)+ test-gate evidence commit(test-gate 产出)+ 模块完成报告 commit(module-report 产出)。
55 55
56 ### 步骤 4:读取 MR 标题模板 56 ### 步骤 4:读取 MR 标题模板
57 57
@@ -87,13 +87,13 @@ mv .tmp/mr-desc.final &quot;$DESC_FILE&quot; @@ -87,13 +87,13 @@ mv .tmp/mr-desc.final &quot;$DESC_FILE&quot;
87 # 加载 .env.local 中的 GITLAB_API_URL / GITLAB_TOKEN / GITLAB_PROJECT_ID 87 # 加载 .env.local 中的 GITLAB_API_URL / GITLAB_TOKEN / GITLAB_PROJECT_ID
88 set -a; . ./.env.local; set +a 88 set -a; . ./.env.local; set +a
89 for v in GITLAB_API_URL GITLAB_TOKEN GITLAB_PROJECT_ID; do 89 for v in GITLAB_API_URL GITLAB_TOKEN GITLAB_PROJECT_ID; do
90 - eval "val=\${$v:-}"; [ -n "$val" ] || { echo "[erp-mr-create] ⚠️ .env.local 缺少 $v"; exit 1; } 90 + eval "val=\${$v:-}"; [ -n "$val" ] || { echo "[mr-create] ⚠️ .env.local 缺少 $v"; exit 1; }
91 done 91 done
92 92
93 -# 探测默认分支作为 target_branch(与 erp-coding-start 同策略) 93 +# 探测默认分支作为 target_branch(与 coding-start 同策略)
94 TARGET_BRANCH=$(git symbolic-ref refs/remotes/origin/HEAD 2>/dev/null | sed 's|refs/remotes/origin/||') 94 TARGET_BRANCH=$(git symbolic-ref refs/remotes/origin/HEAD 2>/dev/null | sed 's|refs/remotes/origin/||')
95 [ -n "$TARGET_BRANCH" ] || TARGET_BRANCH=$(git branch -r --format='%(refname:short)' | grep -E '^origin/(main|master)$' | head -1 | sed 's|^origin/||') 95 [ -n "$TARGET_BRANCH" ] || TARGET_BRANCH=$(git branch -r --format='%(refname:short)' | grep -E '^origin/(main|master)$' | head -1 | sed 's|^origin/||')
96 -[ -n "$TARGET_BRANCH" ] || { echo "[erp-mr-create] ⚠️ 无法探测默认分支(origin/main 或 origin/master)"; exit 1; } 96 +[ -n "$TARGET_BRANCH" ] || { echo "[mr-create] ⚠️ 无法探测默认分支(origin/main 或 origin/master)"; exit 1; }
97 ``` 97 ```
98 98
99 ### 步骤 5.5:幂等守门——检查 source branch 是否已有 opened MR 99 ### 步骤 5.5:幂等守门——检查 source branch 是否已有 opened MR
@@ -106,7 +106,7 @@ HTTP_CODE=$(curl -sS -o .tmp/existing.json -w &#39;%{http_code}&#39; \ @@ -106,7 +106,7 @@ HTTP_CODE=$(curl -sS -o .tmp/existing.json -w &#39;%{http_code}&#39; \
106 --header "PRIVATE-TOKEN: ${GITLAB_TOKEN}" \ 106 --header "PRIVATE-TOKEN: ${GITLAB_TOKEN}" \
107 "${GITLAB_API_URL}/projects/${GITLAB_PROJECT_ID}/merge_requests?source_branch=${current_branch}&state=opened") 107 "${GITLAB_API_URL}/projects/${GITLAB_PROJECT_ID}/merge_requests?source_branch=${current_branch}&state=opened")
108 if [ "$HTTP_CODE" != "200" ]; then 108 if [ "$HTTP_CODE" != "200" ]; then
109 - echo "[erp-mr-create] ⚠️ 查询已有 opened MR 失败 (HTTP $HTTP_CODE)" >&2 109 + echo "[mr-create] ⚠️ 查询已有 opened MR 失败 (HTTP $HTTP_CODE)" >&2
110 jq -r '.message // .error // .' .tmp/existing.json | head -c 200 >&2; echo >&2 110 jq -r '.message // .error // .' .tmp/existing.json | head -c 200 >&2; echo >&2
111 echo " 请核对 .env.local 的 GITLAB_API_URL / GITLAB_TOKEN / GITLAB_PROJECT_ID 后重跑" >&2 111 echo " 请核对 .env.local 的 GITLAB_API_URL / GITLAB_TOKEN / GITLAB_PROJECT_ID 后重跑" >&2
112 rm -f .tmp/existing.json 112 rm -f .tmp/existing.json
@@ -117,7 +117,7 @@ EXISTING_URL=$(jq -r &#39;.[0].web_url // empty&#39; .tmp/existing.json) @@ -117,7 +117,7 @@ EXISTING_URL=$(jq -r &#39;.[0].web_url // empty&#39; .tmp/existing.json)
117 rm -f .tmp/existing.json 117 rm -f .tmp/existing.json
118 ``` 118 ```
119 119
120 -- `EXISTING_IID` 非空 → 打印 `[erp-mr-create] 检测到已有 opened MR: !${EXISTING_IID}`,**跳过步骤 6**,直接用 `EXISTING_IID` / `EXISTING_URL` 进入步骤 7。 120 +- `EXISTING_IID` 非空 → 打印 `[mr-create] 检测到已有 opened MR: !${EXISTING_IID}`,**跳过步骤 6**,直接用 `EXISTING_IID` / `EXISTING_URL` 进入步骤 7。
121 - `EXISTING_IID` 为空 → 正常走步骤 6 创建新 MR。 121 - `EXISTING_IID` 为空 → 正常走步骤 6 创建新 MR。
122 122
123 ### 步骤 6:创建 MR(仅当 5.5 未命中时) 123 ### 步骤 6:创建 MR(仅当 5.5 未命中时)
@@ -138,7 +138,7 @@ CREATE_RESP=$(curl -sS -X POST \ @@ -138,7 +138,7 @@ CREATE_RESP=$(curl -sS -X POST \
138 138
139 MR_IID=$(echo "$CREATE_RESP" | jq -r '.iid // empty') 139 MR_IID=$(echo "$CREATE_RESP" | jq -r '.iid // empty')
140 MR_URL=$(echo "$CREATE_RESP" | jq -r '.web_url // empty') 140 MR_URL=$(echo "$CREATE_RESP" | jq -r '.web_url // empty')
141 -[ -n "$MR_IID" ] || { echo "[erp-mr-create] ⚠️ MR 创建失败,API 响应:"; echo "$CREATE_RESP" | jq . >&2; exit 1; } 141 +[ -n "$MR_IID" ] || { echo "[mr-create] ⚠️ MR 创建失败,API 响应:"; echo "$CREATE_RESP" | jq . >&2; exit 1; }
142 rm -f "$DESC_FILE" 142 rm -f "$DESC_FILE"
143 ``` 143 ```
144 144
@@ -166,7 +166,7 @@ rm -f &quot;$DESC_FILE&quot; @@ -166,7 +166,7 @@ rm -f &quot;$DESC_FILE&quot;
166 166
167 ### 步骤 11:停止 — 等待人工 Approve + Merge 167 ### 步骤 11:停止 — 等待人工 Approve + Merge
168 168
169 -用户合并后再次运行 `/erp-workflow:erp-coding-start`,入口会自动检测 MR merged → 探测默认分支(`main` 或 `master`)→ `git checkout <默认分支>` + `git pull --ff-only origin <默认分支>` 同步远程 → 派发下一模块。 169 +用户合并后再次运行 `/erp-workflow:coding-start`,入口会自动检测 MR merged → 探测默认分支(`main` 或 `master`)→ `git checkout <默认分支>` + `git pull --ff-only origin <默认分支>` 同步远程 → 派发下一模块。
170 170
171 ## 设计要点 171 ## 设计要点
172 172
@@ -178,6 +178,6 @@ rm -f &quot;$DESC_FILE&quot; @@ -178,6 +178,6 @@ rm -f &quot;$DESC_FILE&quot;
178 178
179 - `${CLAUDE_SKILL_DIR}/templates/mr-title-template.md` 179 - `${CLAUDE_SKILL_DIR}/templates/mr-title-template.md`
180 - `${CLAUDE_SKILL_DIR}/templates/mr-description-template.md` 180 - `${CLAUDE_SKILL_DIR}/templates/mr-description-template.md`
181 -- 上游:`erp-module-report`  
182 -- 守门:`erp-red-flag-check` 181 +- 上游:`module-report`
  182 +- 守门:`interrupt-check`
183 - 下游闸门:用户手工 MR Approve + Merge 183 - 下游闸门:用户手工 MR Approve + Merge
skills/coding/erp-mr-create/templates/mr-description-template.md renamed to skills/coding/mr-create/templates/mr-description-template.md
@@ -15,4 +15,4 @@ @@ -15,4 +15,4 @@
15 ## 审核入口 15 ## 审核入口
16 16
17 - 本 MR = 模块 `{{module_id}}` 的唯一人工介入点 17 - 本 MR = 模块 `{{module_id}}` 的唯一人工介入点
18 -- Approve + Merge 后,下次用户运行 `/erp-workflow:erp-coding-start` 时入口会自动扫描到 GitLab API `state=merged`,探测默认分支后 `git pull --ff-only` 同步并推进下一模块 18 +- Approve + Merge 后,下次用户运行 `/erp-workflow:coding-start` 时入口会自动扫描到 GitLab API `state=merged`,探测默认分支后 `git pull --ff-only` 同步并推进下一模块
skills/coding/erp-mr-create/templates/mr-title-template.md renamed to skills/coding/mr-create/templates/mr-title-template.md
skills/coding/erp-local-test-gate/SKILL.md renamed to skills/coding/test-gate/SKILL.md
1 --- 1 ---
2 -name: erp-local-test-gate 2 +name: test-gate
3 description: MR 创建前的唯一硬闸门。子会话执行 scripts/test.sh(setup-test-db.sh 清库后,Spring Boot 启动时 Flyway 自动 apply 当前 sql/migrations/V*.sql),任一失败则停止。 3 description: MR 创建前的唯一硬闸门。子会话执行 scripts/test.sh(setup-test-db.sh 清库后,Spring Boot 启动时 Flyway 自动 apply 当前 sql/migrations/V*.sql),任一失败则停止。
4 user-invocable: false 4 user-invocable: false
5 allowed-tools: Read Write Skill Agent Bash(git add *) Bash(git commit *) 5 allowed-tools: Read Write Skill Agent Bash(git add *) Bash(git commit *)
@@ -7,7 +7,7 @@ allowed-tools: Read Write Skill Agent Bash(git add *) Bash(git commit *) @@ -7,7 +7,7 @@ allowed-tools: Read Write Skill Agent Bash(git add *) Bash(git commit *)
7 7
8 **所有输出必须使用中文。** 8 **所有输出必须使用中文。**
9 9
10 -# erp-local-test-gate 10 +# test-gate
11 11
12 ## 执行步骤 12 ## 执行步骤
13 13
@@ -32,13 +32,13 @@ allowed-tools: Read Write Skill Agent Bash(git add *) Bash(git commit *) @@ -32,13 +32,13 @@ allowed-tools: Read Write Skill Agent Bash(git add *) Bash(git commit *)
32 git commit -m "chore(<module_id>): add local test-gate evidence" 32 git commit -m "chore(<module_id>): add local test-gate evidence"
33 ``` 33 ```
34 34
35 -4. 如果 `exit_code = 0` → 交接给 `erp-module-report`(输出 `local-test-gate: 通过`)。 35 +4. 如果 `exit_code = 0` → 交接给 `module-report`(输出 `test-gate: 通过`)。
36 36
37 5. 否则打印以下横幅并**停下**(不自动重试、不自动修复——失败分类需人工判断): 37 5. 否则打印以下横幅并**停下**(不自动重试、不自动修复——失败分类需人工判断):
38 38
39 ``` 39 ```
40 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 40 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
41 - [erp-local-test-gate] ⚠️ 未通过 41 + [test-gate] ⚠️ 未通过
42 42
43 失败清单: <失败测试清单(来自子会话 JSON)> 43 失败清单: <失败测试清单(来自子会话 JSON)>
44 stdout 摘录: <最后 30 行 / FAIL 摘要> 44 stdout 摘录: <最后 30 行 / FAIL 摘要>
@@ -47,19 +47,19 @@ allowed-tools: Read Write Skill Agent Bash(git add *) Bash(git commit *) @@ -47,19 +47,19 @@ allowed-tools: Read Write Skill Agent Bash(git add *) Bash(git commit *)
47 请根据失败类型选择下一步: 47 请根据失败类型选择下一步:
48 48
49 ① 测试脆弱(flakey,偶发) 49 ① 测试脆弱(flakey,偶发)
50 - → 重新运行 /erp-workflow:erp-coding-start 50 + → 重新运行 /erp-workflow:coding-start
51 (module-start 幂等:reviews 已全 approve 会跳过功能循环,直接重新执行本闸门) 51 (module-start 幂等:reviews 已全 approve 会跳过功能循环,直接重新执行本闸门)
52 52
53 ② 真有回归(某个 REQ 破坏了其他 REQ/已合并模块) 53 ② 真有回归(某个 REQ 破坏了其他 REQ/已合并模块)
54 → 定位到具体 REQ,删除其 review 记录: 54 → 定位到具体 REQ,删除其 review 记录:
55 rm docs/superpowers/reviews/*-<REQ-id>.md 55 rm docs/superpowers/reviews/*-<REQ-id>.md
56 - → 重新运行 /erp-workflow:erp-coding-start 56 + → 重新运行 /erp-workflow:coding-start
57 (module-start 把该 REQ 视为未完成,重走 brainstorm→...→review 循环修复) 57 (module-start 把该 REQ 视为未完成,重走 brainstorm→...→review 循环修复)
58 58
59 ③ 环境/依赖问题(DB 连不上、外部 API 失败、证书失效) 59 ③ 环境/依赖问题(DB 连不上、外部 API 失败、证书失效)
60 - → 命中红旗 #3(外部接口不可达)  
61 - → 调用 Skill(erp-red-flag-check) 追加 Blocker 到本模块任一 plan 文件  
62 - → 修复环境后重新运行 /erp-workflow:erp-coding-start 60 + → 触发中断 #3(外部接口不可达)
  61 + → 调用 Skill(interrupt-check) 追加 Blocker 到本模块任一 plan 文件
  62 + → 修复环境后重新运行 /erp-workflow:coding-start
63 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 63 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
64 ``` 64 ```
65 65
@@ -72,7 +72,7 @@ allowed-tools: Read Write Skill Agent Bash(git add *) Bash(git commit *) @@ -72,7 +72,7 @@ allowed-tools: Read Write Skill Agent Bash(git add *) Bash(git commit *)
72 72
73 ## 衔接 73 ## 衔接
74 74
75 -立即调用 `Skill(erp-module-report)` 生成模块报告。 75 +立即调用 `Skill(module-report)` 生成模块报告。
76 76
77 ## 参考 77 ## 参考
78 78
skills/coding/erp-local-test-gate/templates/test-gate-result-template.md renamed to skills/coding/test-gate/templates/test-gate-result-template.md
skills/crosscut/erp-coding-start/SKILL.md renamed to skills/crosscut/coding-start/SKILL.md
1 --- 1 ---
2 -name: erp-coding-start  
3 -description: B 阶段(Coding)入å£ã€‚å…ˆéªŒè¯ Plan 已完æˆï¼›æŒ‰ docs/02 § 二 REQ å¼€å‘é¡ºåºæ¸…啿‰«æï¼Œå¯¹æ¯ä¸ª REQ 所属模å—用 docs/08 çš„ `MR:` 字段 + GitLab API state 判定是å¦å®Œæˆâ€”—merged 跳过,`—` 或 opened/closed é€‰ä¸ºå½“å‰æ¨¡å—å¹¶æ´¾å‘到 erp-module-start。派å‘å‰è‡ªåŠ¨æŽ¢æµ‹é»˜è®¤åˆ†æ”¯ï¼ˆmain / master)并 git checkout + pull --ff-only ä¿æŒ base 最新。 2 +name: coding-start
  3 +description: B 阶段(Coding)入å£ã€‚å…ˆéªŒè¯ Plan 已完æˆï¼›æŒ‰ docs/02 § 二 REQ å¼€å‘é¡ºåºæ¸…啿‰«æï¼Œå¯¹æ¯ä¸ª REQ 所属模å—用 docs/08 çš„ `MR:` 字段 + GitLab API state 判定是å¦å®Œæˆâ€”—merged 跳过,`—` 或 opened/closed é€‰ä¸ºå½“å‰æ¨¡å—å¹¶æ´¾å‘到 module-start。派å‘å‰è‡ªåŠ¨æŽ¢æµ‹é»˜è®¤åˆ†æ”¯ï¼ˆmain / master)并 git checkout + pull --ff-only ä¿æŒ base 最新。
4 user-invocable: true 4 user-invocable: true
5 allowed-tools: Skill Read Glob Grep Bash(curl *) Bash(jq *) Bash(git branch *) Bash(git checkout *) Bash(git pull *) Bash(git status *) Bash(git symbolic-ref *) Bash(sed *) Bash(mkdir -p .tmp) Bash(rm -f .tmp/*) 5 allowed-tools: Skill Read Glob Grep Bash(curl *) Bash(jq *) Bash(git branch *) Bash(git checkout *) Bash(git pull *) Bash(git status *) Bash(git symbolic-ref *) Bash(sed *) Bash(mkdir -p .tmp) Bash(rm -f .tmp/*)
6 --- 6 ---
7 7
8 **所有输出必须使用中文。** 8 **所有输出必须使用中文。**
9 9
10 -B 阶段(Coding)的入å£åˆ†å‘器。èŒè´£ï¼š**éªŒè¯ Plan å·²å®Œæˆ â†’ 按 docs/02 § 二 REQ åº + MR state 定ä½å½“剿¨¡å— → åˆ‡å›žé»˜è®¤åˆ†æ”¯å¹¶åŒæ­¥è¿œç¨‹ → æ´¾å‘ erp-module-start**。ä¸ç›´æŽ¥ç”Ÿæˆä»»ä½•文件。开å‘顺åºä»¥ `docs/02 § 二` 为准;完æˆåˆ¤å®šä»¥ `docs/08 æ¡ç›®çš„ MR: 字段 + GitLab API state` 为准(curl 调用,凭æ®è¯» `.env.local` çš„ `GITLAB_API_URL` / `GITLAB_TOKEN` / `GITLAB_PROJECT_ID`)。默认分支(`main` 或 `master`)在步骤 4 自动探测,ä¸ç¡¬ç¼–ç ã€‚ 10 +B 阶段(Coding)的入å£åˆ†å‘器。èŒè´£ï¼š**éªŒè¯ Plan å·²å®Œæˆ â†’ 按 docs/02 § 二 REQ åº + MR state 定ä½å½“剿¨¡å— → åˆ‡å›žé»˜è®¤åˆ†æ”¯å¹¶åŒæ­¥è¿œç¨‹ → æ´¾å‘ module-start**。ä¸ç›´æŽ¥ç”Ÿæˆä»»ä½•文件。开å‘顺åºä»¥ `docs/02 § 二` 为准;完æˆåˆ¤å®šä»¥ `docs/08 æ¡ç›®çš„ MR: 字段 + GitLab API state` 为准(curl 调用,凭æ®è¯» `.env.local` çš„ `GITLAB_API_URL` / `GITLAB_TOKEN` / `GITLAB_PROJECT_ID`)。默认分支(`main` 或 `master`)在步骤 4 自动探测,ä¸ç¡¬ç¼–ç ã€‚
11 11
12 ## 执行步骤 12 ## 执行步骤
13 13
14 ### 步骤 1:确认 docs/08 存在 14 ### 步骤 1:确认 docs/08 存在
15 15
16 用 `Glob` 检查 `docs/08-模å—任务管ç†.md`。 16 用 `Glob` 检查 `docs/08-模å—任务管ç†.md`。
17 -- ä¸å­˜åœ¨ → 打å°"âš ï¸ é¡¹ç›®å°šæœªåˆå§‹åŒ–,请先è¿è¡Œ `/erp-workflow:erp-plan-start`"å¹¶åœä¸‹ã€‚ 17 +- ä¸å­˜åœ¨ → 打å°"âš ï¸ é¡¹ç›®å°šæœªåˆå§‹åŒ–,请先è¿è¡Œ `/erp-workflow:plan-start`"å¹¶åœä¸‹ã€‚
18 18
19 ### 步骤 2:Plan å®Œæˆæ€§æ£€æŸ¥ 19 ### 步骤 2:Plan å®Œæˆæ€§æ£€æŸ¥
20 20
@@ -23,10 +23,10 @@ B 阶段(Coding)的入å£åˆ†å‘器。èŒè´£ï¼š**éªŒè¯ Plan å·²å®Œæˆ â†’ æŒ @@ -23,10 +23,10 @@ B 阶段(Coding)的入å£åˆ†å‘器。èŒè´£ï¼š**éªŒè¯ Plan å·²å®Œæˆ â†’ æŒ
23 - **命中任一 A 未勾** → 打å°ï¼š 23 - **命中任一 A 未勾** → 打å°ï¼š
24 ``` 24 ```
25 â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â” 25 â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”
26 - [erp-coding-start] âš ï¸ Plan å°šæœªå®Œæˆ 26 + [coding-start] âš ï¸ Plan 尚未完æˆ
27 27
28 docs/08 § 一 还有未勾选项,请先è¿è¡Œï¼š 28 docs/08 § 一 还有未勾选项,请先è¿è¡Œï¼š
29 - /erp-workflow:erp-plan-start 29 + /erp-workflow:plan-start
30 30
31 ç»§ç»­ Plan 阶段直到 A5 下游文档生æˆå®Œæˆï¼Œå†å›žæ¥è¿è¡Œ coding-start。 31 ç»§ç»­ Plan 阶段直到 A5 下游文档生æˆå®Œæˆï¼Œå†å›žæ¥è¿è¡Œ coding-start。
32 â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â” 32 â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”
@@ -37,6 +37,8 @@ B 阶段(Coding)的入å£åˆ†å‘器。èŒè´£ï¼š**éªŒè¯ Plan å·²å®Œæˆ â†’ æŒ @@ -37,6 +37,8 @@ B 阶段(Coding)的入å£åˆ†å‘器。èŒè´£ï¼š**éªŒè¯ Plan å·²å®Œæˆ â†’ æŒ
37 37
38 ### 步骤 3:按 docs/02 REQ åº + MR state æ‰¾å½“å‰æ¨¡å— 38 ### 步骤 3:按 docs/02 REQ åº + MR state æ‰¾å½“å‰æ¨¡å—
39 39
  40 +> `MR:` 字段 × GitLab API state 的三组åˆåˆ¤å®šè§„åˆ™è§ `CLAUDE.md § ✅ 模å—完æˆåˆ¤å®šè§„则 § 模å—状æ€è¯­ä¹‰`。
  41 +
40 1. 用 `Read` è¯»å– `docs/02-å¼€å‘计划.md` çš„ § 二;用 `Grep`(pattern `^\|\s*[0-9]+\s*\|\s*\*\*(REQ-[A-Z0-9]+-[0-9]+)\*\*\s*\|\s*(module_\w+)`,`-n`ï¼‰æŠ½å–æ‰€æœ‰è¡¨æ ¼æ•°æ®è¡Œï¼ŒæŒ‰è¡Œå·å‡åºå¾— `req_order[]`,æ¯é¡¹å« `req_id` + `module_id`。 42 1. 用 `Read` è¯»å– `docs/02-å¼€å‘计划.md` çš„ § 二;用 `Grep`(pattern `^\|\s*[0-9]+\s*\|\s*\*\*(REQ-[A-Z0-9]+-[0-9]+)\*\*\s*\|\s*(module_\w+)`,`-n`ï¼‰æŠ½å–æ‰€æœ‰è¡¨æ ¼æ•°æ®è¡Œï¼ŒæŒ‰è¡Œå·å‡åºå¾— `req_order[]`,æ¯é¡¹å« `req_id` + `module_id`。
41 2. è‹¥ `req_order` 为空 → 打å°é”™è¯¯å¹¶**åœä¸‹**(与原逻辑相åŒï¼Œç•¥ï¼‰ã€‚ 43 2. è‹¥ `req_order` 为空 → 打å°é”™è¯¯å¹¶**åœä¸‹**(与原逻辑相åŒï¼Œç•¥ï¼‰ã€‚
42 3. **åˆå§‹åŒ–模å—完æˆç¼“å­˜ `module_merged[module_id → bool]`**(空)。 44 3. **åˆå§‹åŒ–模å—完æˆç¼“å­˜ `module_merged[module_id → bool]`**(空)。
@@ -53,7 +55,7 @@ B 阶段(Coding)的入å£åˆ†å‘器。èŒè´£ï¼š**éªŒè¯ Plan å·²å®Œæˆ â†’ æŒ @@ -53,7 +55,7 @@ B 阶段(Coding)的入å£åˆ†å‘器。èŒè´£ï¼š**éªŒè¯ Plan å·²å®Œæˆ â†’ æŒ
53 --header "PRIVATE-TOKEN: ${GITLAB_TOKEN}" \ 55 --header "PRIVATE-TOKEN: ${GITLAB_TOKEN}" \
54 "${GITLAB_API_URL}/projects/${GITLAB_PROJECT_ID}/merge_requests?iid=<iid>") 56 "${GITLAB_API_URL}/projects/${GITLAB_PROJECT_ID}/merge_requests?iid=<iid>")
55 ``` 57 ```
56 - **ç¡¬åœæ¡ä»¶**(命中任一则打å°è¯Šæ–­æ¨ªå¹…å¹¶**åœä¸‹**ï¼Œä¸æ´¾å‘;任何"查ä¸åˆ°å°±å‡è®¾æœª merged"çš„é™é»˜å¤„ç†éƒ½ç¦æ­¢ï¼‰ï¼š 58 + **ç¡¬åœæ¡ä»¶**(触å‘任一则打å°è¯Šæ–­æ¨ªå¹…å¹¶**åœä¸‹**ï¼Œä¸æ´¾å‘;任何"查ä¸åˆ°å°±å‡è®¾æœª merged"çš„é™é»˜å¤„ç†éƒ½ç¦æ­¢ï¼‰ï¼š
57 1. `HTTP_CODE != 200`:API ä¸å¯è¾¾ / token é”™ / URL é”™ 59 1. `HTTP_CODE != 200`:API ä¸å¯è¾¾ / token é”™ / URL é”™
58 2. `HTTP_CODE == 200` 但 `jq 'length' .tmp/mr.json != 1`:docs/08 记了 `!<iid>` 但远程查ä¸åˆ°å¯¹åº” MR(数æ®ä¸ä¸€è‡´ï¼‰ 60 2. `HTTP_CODE == 200` 但 `jq 'length' .tmp/mr.json != 1`:docs/08 记了 `!<iid>` 但远程查ä¸åˆ°å¯¹åº” MR(数æ®ä¸ä¸€è‡´ï¼‰
59 3. `state = jq -r '.[0].state' .tmp/mr.json` ä¸åœ¨ `{merged, opened, closed}` ä¸‰ä¸ªåˆæ³•值里 61 3. `state = jq -r '.[0].state' .tmp/mr.json` ä¸åœ¨ `{merged, opened, closed}` ä¸‰ä¸ªåˆæ³•值里
@@ -61,7 +63,7 @@ B 阶段(Coding)的入å£åˆ†å‘器。èŒè´£ï¼š**éªŒè¯ Plan å·²å®Œæˆ â†’ æŒ @@ -61,7 +63,7 @@ B 阶段(Coding)的入å£åˆ†å‘器。èŒè´£ï¼š**éªŒè¯ Plan å·²å®Œæˆ â†’ æŒ
61 诊断横幅模æ¿ï¼š 63 诊断横幅模æ¿ï¼š
62 ``` 64 ```
63 â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â” 65 â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”
64 - [erp-coding-start] âš ï¸ æ— æ³•ç¡®å®š MR !<iid>ï¼ˆæ¨¡å— <module_id>ï¼‰çš„çŠ¶æ€ 66 + [coding-start] âš ï¸ æ— æ³•ç¡®å®š MR !<iid>ï¼ˆæ¨¡å— <module_id>)的状æ€
65 67
66 原因: <HTTP <code> | 查ä¸åˆ° MR | state=<异常值>> 68 原因: <HTTP <code> | 查ä¸åˆ° MR | state=<异常值>>
67 API : ${GITLAB_API_URL}/projects/${GITLAB_PROJECT_ID} 69 API : ${GITLAB_API_URL}/projects/${GITLAB_PROJECT_ID}
@@ -73,7 +75,7 @@ B 阶段(Coding)的入å£åˆ†å‘器。èŒè´£ï¼š**éªŒè¯ Plan å·²å®Œæˆ â†’ æŒ @@ -73,7 +75,7 @@ B 阶段(Coding)的入å£åˆ†å‘器。èŒè´£ï¼š**éªŒè¯ Plan å·²å®Œæˆ â†’ æŒ
73 3. GITLAB_PROJECT_ID æ˜¯å¦æ˜¯è¯¥é¡¹ç›®çš„ URL-encoded 路径或数字 ID 75 3. GITLAB_PROJECT_ID æ˜¯å¦æ˜¯è¯¥é¡¹ç›®çš„ URL-encoded 路径或数字 ID
74 4. docs/08 è®°çš„ iid 是å¦å­˜åœ¨äºŽ GitLab 项目的 MR 列表 76 4. docs/08 è®°çš„ iid 是å¦å­˜åœ¨äºŽ GitLab 项目的 MR 列表
75 77
76 - 修正åŽé‡è·‘ /erp-workflow:erp-coding-start。 78 + 修正åŽé‡è·‘ /erp-workflow:coding-start。
77 â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â” 79 â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”
78 ``` 80 ```
79 清ç†ï¼š`rm -f .tmp/mr.json`。 81 清ç†ï¼š`rm -f .tmp/mr.json`。
@@ -84,7 +86,7 @@ B 阶段(Coding)的入å£åˆ†å‘器。èŒè´£ï¼š**éªŒè¯ Plan å·²å®Œæˆ â†’ æŒ @@ -84,7 +86,7 @@ B 阶段(Coding)的入å£åˆ†å‘器。èŒè´£ï¼š**éªŒè¯ Plan å·²å®Œæˆ â†’ æŒ
84 5. å…¨éåŽ†å®Œä»æ— å‘½ä¸­ï¼ˆæ‰€æœ‰æ¨¡å—都 merged) → 打å°ï¼š 86 5. å…¨éåŽ†å®Œä»æ— å‘½ä¸­ï¼ˆæ‰€æœ‰æ¨¡å—都 merged) → 打å°ï¼š
85 ``` 87 ```
86 â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â” 88 â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”
87 - [erp-coding-start] ✅ 所有模å—å·²å®Œæˆ 89 + [coding-start] ✅ 所有模å—已完æˆ
88 90
89 docs/02 § 二 清å•中æ¯ä¸ª REQ 所属模å—çš„ MR 都已 merged。项目结æŸã€‚ 91 docs/02 § 二 清å•中æ¯ä¸ª REQ 所属模å—çš„ MR 都已 merged。项目结æŸã€‚
90 â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â” 92 â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”
@@ -113,11 +115,11 @@ fi @@ -113,11 +115,11 @@ fi
113 - `Bash`: `git status --porcelain`ï¼›éžç©º → 打å°ï¼š 115 - `Bash`: `git status --porcelain`ï¼›éžç©º → 打å°ï¼š
114 ``` 116 ```
115 â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â” 117 â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”
116 - [erp-coding-start] âš ï¸ å½“å‰åˆ†æ”¯ <current_branch> 有未æäº¤æ”¹åŠ¨ï¼Œæ— æ³•åˆ‡æ¢åˆ° <DEFAULT_BRANCH> 118 + [coding-start] âš ï¸ å½“å‰åˆ†æ”¯ <current_branch> 有未æäº¤æ”¹åŠ¨ï¼Œæ— æ³•åˆ‡æ¢åˆ° <DEFAULT_BRANCH>
117 119
118 <git status 输出> 120 <git status 输出>
119 121
120 - 请手工处ç†åŽé‡æ–°è¿è¡Œ /erp-workflow:erp-coding-start。 122 + 请手工处ç†åŽé‡æ–°è¿è¡Œ /erp-workflow:coding-start。
121 â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â” 123 â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”
122 ``` 124 ```
123 å¹¶**åœä¸‹**。 125 å¹¶**åœä¸‹**。
@@ -126,13 +128,13 @@ fi @@ -126,13 +128,13 @@ fi
126 - å¤±è´¥ï¼ˆéž fast-forward / 网络 / 冲çªï¼‰â†’ 打å°é”™è¯¯æ¨ªå¹…: 128 - å¤±è´¥ï¼ˆéž fast-forward / 网络 / 冲çªï¼‰â†’ 打å°é”™è¯¯æ¨ªå¹…:
127 ``` 129 ```
128 â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â” 130 â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”
129 - [erp-coding-start] âš ï¸ åŒæ­¥ <DEFAULT_BRANCH> 失败 131 + [coding-start] âš ï¸ åŒæ­¥ <DEFAULT_BRANCH> 失败
130 132
131 本地 <DEFAULT_BRANCH> 无法 fast-forward 到 remote。请手工处ç†ï¼š 133 本地 <DEFAULT_BRANCH> 无法 fast-forward 到 remote。请手工处ç†ï¼š
132 git status 134 git status
133 git log <DEFAULT_BRANCH>..origin/<DEFAULT_BRANCH> # 远程领先的 commit 135 git log <DEFAULT_BRANCH>..origin/<DEFAULT_BRANCH> # 远程领先的 commit
134 git log origin/<DEFAULT_BRANCH>..<DEFAULT_BRANCH> # 本地未推的 commit 136 git log origin/<DEFAULT_BRANCH>..<DEFAULT_BRANCH> # 本地未推的 commit
135 - ä¿®å¤åŽé‡æ–°è¿è¡Œ /erp-workflow:erp-coding-start。 137 + ä¿®å¤åŽé‡æ–°è¿è¡Œ /erp-workflow:coding-start。
136 â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â” 138 â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”
137 ``` 139 ```
138 å¹¶**åœä¸‹**。 140 å¹¶**åœä¸‹**。
@@ -141,17 +143,17 @@ fi @@ -141,17 +143,17 @@ fi
141 143
142 ``` 144 ```
143 â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â” 145 â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”
144 - [erp-coding-start] 146 + [coding-start]
145 阶段:B ç¼–ç  147 阶段:B ç¼–ç 
146 当剿¨¡å—:<current_module> 148 当剿¨¡å—:<current_module>
147 MR 状æ€ï¼š<未建 | opened | closed | 查ä¸åˆ°> 149 MR 状æ€ï¼š<未建 | opened | closed | 查ä¸åˆ°>
148 - 下一步:invoke erp-module-start 150 + 下一步:invoke module-start
149 â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â” 151 â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”
150 ``` 152 ```
151 153
152 -ç„¶åŽç«‹å³ç”¨ `Skill` 工具调用 `erp-module-start`。 154 +ç„¶åŽç«‹å³ç”¨ `Skill` 工具调用 `module-start`。
153 155
154 -> 分å‘å‰å…ˆè°ƒç”¨ `erp-red-flag-check`;命中红旗则åœåœ¨æ­¤ä¸åˆ†å‘。 156 +> 分å‘å‰å…ˆè°ƒç”¨ `interrupt-check`;触å‘中断则åœåœ¨æ­¤ä¸åˆ†å‘。
155 157
156 ## 设计è¦ç‚¹ 158 ## 设计è¦ç‚¹
157 159
@@ -160,7 +162,7 @@ fi @@ -160,7 +162,7 @@ fi
160 162
161 ## å‚考 163 ## å‚考
162 164
163 -- `docs/02-å¼€å‘计划.md § 二 å¼€å‘é¡ºåºæ¸…å•`ï¼ˆåˆ†å‘æƒå¨ï¼‰ 165 +- `docs/02-å¼€å‘计划.md § 二 å¼€å‘é¡ºåºæ¸…å•`(分å‘追踪)
164 - `docs/08-模å—任务管ç†.md § 二`(模å—元数æ®ï¼Œå« `MR:` 字段) 166 - `docs/08-模å—任务管ç†.md § 二`(模å—元数æ®ï¼Œå« `MR:` 字段)
165 - `CLAUDE.md`(项目指令) 167 - `CLAUDE.md`(项目指令)
166 -- `erp-plan-start`(姊妹入å£ï¼ŒA 阶段) 168 +- `plan-start`(姊妹入å£ï¼ŒA 阶段)
skills/crosscut/erp-cross-module-log/SKILL.md renamed to skills/crosscut/cross-module-log/SKILL.md
1 --- 1 ---
2 -name: erp-cross-module-log  
3 -description: 为 log-cross-module.sh hook 自动追加到跨模块改动日志中的条目补填「原因」和「影响评估」。覆盖对"非当前模块"文件的编辑(无论目标模块是否已 MR merged)。 2 +name: cross-module-log
  3 +description: 为 log-cross-module.sh hook 自动追加到跨模块改动日志中的条目批量补填「原因」和「影响评估」。**仅由 module-report § ⑦ 硬验收时调用**,CC 编辑中途不主动调用(节省 LLM 调用次数)。
4 user-invocable: false 4 user-invocable: false
5 allowed-tools: Read Write Edit Bash(git branch *) 5 allowed-tools: Read Write Edit Bash(git branch *)
6 --- 6 ---
7 7
8 **所有输出必须使用中文。** 8 **所有输出必须使用中文。**
9 9
10 -# erp-cross-module-log 10 +# cross-module-log
11 11
12 ## 说明 12 ## 说明
13 13
14 软规则 S2 执行:对**非当前模块**文件的每次编辑(无论目标模块是否已 MR merged)必须记录原因 + 影响评估。 14 软规则 S2 执行:对**非当前模块**文件的每次编辑(无论目标模块是否已 MR merged)必须记录原因 + 影响评估。
15 15
16 -**本日志由 CC 自主维护**——hook 自动落存根、CC 自主推断补齐两列,**不需要人工填写**。人工只在最终看 MR 描述时复核。 16 +**本日志由 hook + skill 协作维护**——hook 自动落存根(4 列机械数据),CC 不主动处理 TBD;由 `module-report` § ⑦ 硬验收阶段统一调用本 skill,一次性推断补齐「原因 / 影响评估」两列。**不需要人工填写**,人工只在最终看 MR 描述时复核。
17 17
18 ## 执行步骤 18 ## 执行步骤
19 19
20 -1. 确定当前模块(从当前 git 分支名推导:`git branch --show-current` → `module-<module_id>` → 取 `module_id`。`erp-module-start` 步骤 3 保证本 skill 执行时一定处于 `module-*` 分支)。 20 +1. 确定当前模块(从当前 git 分支名推导:`git branch --show-current` → `module-<module_id>` → 取 `module_id`。`module-start` 步骤 3 保证本 skill 执行时一定处于 `module-*` 分支)。
21 2. 打开 `docs/superpowers/module-reports/<current>-cross-module.md`(不存在则从 `${CLAUDE_SKILL_DIR}/templates/cross-module-log-template.md` 初始化)。 21 2. 打开 `docs/superpowers/module-reports/<current>-cross-module.md`(不存在则从 `${CLAUDE_SKILL_DIR}/templates/cross-module-log-template.md` 初始化)。
22 3. 找到「原因」或「影响评估」列中含 `TBD(CC 补)` 的行。 22 3. 找到「原因」或「影响评估」列中含 `TBD(CC 补)` 的行。
23 4. 对每个 TBD 行,CC **自主推断**填写以下两列(基于当前 session 的改动上下文 + REQ 卡片 + 目标模块的代码): 23 4. 对每个 TBD 行,CC **自主推断**填写以下两列(基于当前 session 的改动上下文 + REQ 卡片 + 目标模块的代码):
@@ -28,7 +28,7 @@ allowed-tools: Read Write Edit Bash(git branch *) @@ -28,7 +28,7 @@ allowed-tools: Read Write Edit Bash(git branch *)
28 28
29 ## 下游 29 ## 下游
30 30
31 -填充后的日志会被 `erp-module-report` 原文嵌入到 `module-report-template.md` § ⑦。 31 +填充后的日志会被 `module-report` 原文嵌入到 `module-report-template.md` § ⑦。
32 32
33 ## 参考 33 ## 参考
34 34
skills/crosscut/erp-cross-module-log/templates/cross-module-log-row-template.md renamed to skills/crosscut/cross-module-log/templates/cross-module-log-row-template.md
skills/crosscut/erp-cross-module-log/templates/cross-module-log-template.md renamed to skills/crosscut/cross-module-log/templates/cross-module-log-template.md
1 # 跨模块改动日志 — {{module_name}} 1 # 跨模块改动日志 — {{module_name}}
2 2
3 -软规则 S2:本模块开发期间对**非当前模块**代码的改动(无论目标模块是否已 MR merged)记录在此;模块完成报告必须单列「跨模块改动」节完整贴入。漏留痕或未评估影响 → 升级为红旗 3 +软规则 S2:本模块开发期间对**非当前模块**代码的改动(无论目标模块是否已 MR merged)记录在此;模块完成报告必须单列「跨模块改动」节完整贴入。漏留痕或未评估影响 → 升级为中断
4 4
5 -**本日志由 CC 自主维护**——hook `log-cross-module.sh` 自动落存根(含 `TBD(CC 补)` 占位),CC 调 `erp-cross-module-log` skill 自主推断补「原因 / 影响评估」两列。**不需要人工填写**。 5 +**本日志由 CC 自主维护**——hook `log-cross-module.sh` 自动落存根(含 `TBD(CC 补)` 占位),CC 调 `cross-module-log` skill 自主推断补「原因 / 影响评估」两列。**不需要人工填写**。
6 6
7 | 时间戳 | 目标模块 | 文件 | 改动摘要 | 原因 | 影响评估 | 7 | 时间戳 | 目标模块 | 文件 | 改动摘要 | 原因 | 影响评估 |
8 |---|---|---|---|---|---| 8 |---|---|---|---|---|---|
skills/crosscut/erp-red-flag-check/SKILL.md renamed to skills/crosscut/interrupt-check/SKILL.md
1 --- 1 ---
2 -name: erp-red-flag-check  
3 -description: 在每个功能循环步骤和生成重要制品前运行。检查 CLAUDE.md 中的 3 项红旗清单,命中任一项则追加 Blocker 到计划文件并停止。 2 +name: interrupt-check
  3 +description: 在每个功能循环步骤和生成重要制品前运行。检查 CLAUDE.md 中的 3 项中断清单,触发任一项则追加 Blocker 到计划文件并停止。
4 user-invocable: false 4 user-invocable: false
5 allowed-tools: Read Write Bash(mysql *) 5 allowed-tools: Read Write Bash(mysql *)
6 --- 6 ---
7 7
8 **所有输出必须使用中文。** 8 **所有输出必须使用中文。**
9 9
10 -# erp-red-flag-check 10 +# interrupt-check
11 11
12 ## 说明 12 ## 说明
13 13
14 -验证 CLAUDE.md § 🚩 静默执行红旗清单中的 3 项均未触发。命中任一项则中断。 14 +验证 CLAUDE.md § 🚩 中断机制中的 3 项均未触发。触发任一项则中断。
15 15
16 -> 需求歧义 / schema 缺口 / 技术栈外组件引入等场景由各 feature-* skill 的 `AskUserQuestion` 流程承接,不进入本清单,不会在这里命中 16 +> 需求歧义 / schema 缺口 / 技术栈外组件引入等场景由各 feature-* skill 的 `AskUserQuestion` 流程承接,不进入本清单,不会在这里触发
17 17
18 ## 调用时机 18 ## 调用时机
19 19
@@ -30,20 +30,20 @@ allowed-tools: Read Write Bash(mysql *) @@ -30,20 +30,20 @@ allowed-tools: Read Write Bash(mysql *)
30 ## 执行步骤 30 ## 执行步骤
31 31
32 1. 读取当前功能的规格/计划文件路径(从对话或 `docs/08` 获取)。 32 1. 读取当前功能的规格/计划文件路径(从对话或 `docs/08` 获取)。
33 -2. 逐项检查 3 个红旗。如果全部未命中 → 输出 `red-flag-check: 通过`,退出。  
34 -3. 命中时:  
35 - - 用 `Read` 读取 `${CLAUDE_SKILL_DIR}/templates/red-flag-block-template.md`  
36 - - 填充槽位(flag_number、flag_name、description、affected_scope、recommendation、decision_needed) 33 +2. 逐项检查 3 个中断。如果全部未触发 → 输出 `interrupt-check: 通过`,退出。
  34 +3. 触发时:
  35 + - 用 `Read` 读取 `${CLAUDE_SKILL_DIR}/templates/interrupt-block-template.md`
  36 + - 填充槽位(interrupt_number、interrupt_name、description、affected_scope、recommendation、decision_needed)
37 - 将渲染后的块追加到当前计划文件:`docs/superpowers/plans/YYYY-MM-DD-<REQ-id>.md` 37 - 将渲染后的块追加到当前计划文件:`docs/superpowers/plans/YYYY-MM-DD-<REQ-id>.md`
38 - 向会话打印一句话摘要 + 指向计划文件的路径 38 - 向会话打印一句话摘要 + 指向计划文件的路径
39 - **停止** — 在用户决策前不调用任何后续 skill 39 - **停止** — 在用户决策前不调用任何后续 skill
40 40
41 ## 输出 41 ## 输出
42 42
43 -`red-flag-check: 通过`(仅会话),或一个 `## 🚩 Blocker` 块追加到功能计划文件。 43 +`interrupt-check: 通过`(仅会话),或一个 `## 🚩 Blocker` 块追加到功能计划文件。
44 44
45 ## 参考 45 ## 参考
46 46
47 -- `${CLAUDE_SKILL_DIR}/templates/red-flag-block-template.md`  
48 -- `CLAUDE.md` § 🚩 静默执行红旗清单(权威 3 条)  
49 -- `CLAUDE.md` § 🟡 软规则(S2 跨模块改动,不触发红旗但需留痕) 47 +- `${CLAUDE_SKILL_DIR}/templates/interrupt-block-template.md`
  48 +- `CLAUDE.md` § 🚩 中断机制(权威 3 条)
  49 +- `CLAUDE.md` § 🟡 软规则(S2 跨模块改动,不触发中断但需留痕)
skills/crosscut/erp-red-flag-check/templates/red-flag-block-template.md renamed to skills/crosscut/interrupt-check/templates/interrupt-block-template.md
1 ## 🚩 Blocker 1 ## 🚩 Blocker
2 2
3 -**红旗编号**: {{flag_number}} (1-3,对应 CLAUDE.md 🚩 静默执行红旗清单)  
4 -**红旗名称**: {{flag_name}} 3 +**中断编号**: {{interrupt_number}} (1-3,对应 CLAUDE.md 🚩 中断机制)
  4 +**中断名称**: {{interrupt_name}}
5 **问题描述**: {{description}} 5 **问题描述**: {{description}}
6 **影响范围**: {{affected_scope}} 6 **影响范围**: {{affected_scope}}
7 **我的建议**: {{recommendation}} 7 **我的建议**: {{recommendation}}
skills/crosscut/erp-plan-start/SKILL.md renamed to skills/crosscut/plan-start/SKILL.md
1 --- 1 ---
2 -name: erp-plan-start  
3 -description: A 阶段(Plan)入口与分发器。根据 docs/08 § 一 的 checkbox 状态派发到 A0~A5 对应 skill(§ 二是 B 阶段模块元数据,本 skill 不读)。Plan 全部完成(A5 已勾)时打印提示让用户运行 /erp-workflow:erp-coding-start 进入 B 阶段。 2 +name: plan-start
  3 +description: A 阶段(Plan)入口与分发器。根据 docs/08 § 一 的 checkbox 状态派发到 A0~A5 对应 skill。Plan 全部完成(A5 已勾)时打印提示让用户运行 /erp-workflow:coding-start 进入 B 阶段。
4 user-invocable: true 4 user-invocable: true
5 allowed-tools: Skill Read Glob Grep 5 allowed-tools: Skill Read Glob Grep
6 --- 6 ---
7 7
8 -**所有输出必须使用中文。** 用户是中文用户,所有对话、横幅、提示、报告一律用中文。 8 +**所有输出必须使用中文。**
9 9
10 -你是 ERP 项目**规划阶段的编排器**。你**只派发 A 阶段(A0~A5)的 skill**;docs/08 § 一 全部勾选后即停下,提示用户显式运行 `/erp-workflow:erp-coding-start` 进入 B 阶段,**不直接派发任何 B 阶段 skill**。你不直接生成任何文件。 10 +你是 ERP 项目**规划阶段的编排器**。你**只派发 A 阶段(A0~A5)的 skill**;docs/08 § 一 全部勾选后即停下,提示用户显式运行 `/erp-workflow:coding-start` 进入 B 阶段。你不直接生成任何文件。
11 11
12 -## 第一步:读取 docs/08 + 决定分发目标 + `mark_line` 12 +## 第一步:读取 docs/08 + 决定分发目标
13 13
14 -docs/08 § 一 是**Plan 阶段进度权威**(A0~A5 的 checkbox)。不做其他文件存在性检查——文件在不等于做完,只有 checkbox 是做完的证据。§ 二的模块元数据由 erp-coding-start 消费,本 skill 不读。 14 +docs/08 § 一 是**Plan 阶段进度追踪**(A0~A5 的 checkbox)。§ 二的模块元数据由 coding-start 读写,本 skill 不读。
15 15
16 ### 分发判定 16 ### 分发判定
17 17
18 1. **docs/08 是否存在** 18 1. **docs/08 是否存在**
19 用 `Glob` 检查 `docs/08-模块任务管理.md`。 19 用 `Glob` 检查 `docs/08-模块任务管理.md`。
20 - - 不存在 → `target=erp-project-init`、`mark_line=A0`、`unchecked_line=""`(流程开始) 20 + - 如果不存在 → 后续 = `project-init`
21 21
22 -2. **找 § 一 第一个未勾的 A 子项**  
23 - 用 `Grep`(pattern `^[[:space:]]*- \[ \].*A[0-5]`,`-n`)在 `docs/08-模块任务管理.md` 的 § 一 Plan 段搜索,取**最小行号**那一行作为 `unchecked_line`。  
24 - 注:§ 二 的模块行是纯 bullet(形如 `- module_id ...`),不会被此 pattern 匹配。 22 +2. **根据 § 一 找到当前进度**
25 23
26 -3. **把 `unchecked_line` 映射到 `target_skill` + `mark_line`**:  
27 -  
28 -| `unchecked_line` 特征 | `target_skill` | `mark_line` | 24 +| `进度` | `后续` | `阶段` |
29 |---|---|---| 25 |---|---|---|
30 -| 无 docs/08 | `erp-project-init` | `A0` |  
31 -| 含 `A0` / A0 子项 | `erp-project-init` | `A0` |  
32 -| 含 `A1` / A1 子项 | `erp-scope-lock` | `A1` |  
33 -| 含 `A2` / A2 子项 | `erp-skeleton-gen` | `A2` |  
34 -| 含 `A3` / A3 子项 | `erp-db-init` | `A3` |  
35 -| 含 `A4` / A4 子项 | `erp-db-design-gen` | `A4` |  
36 -| 含 `A5` / A5 子项 | `erp-downstream-gen` | `A5` |  
37 -| 无命中(A 全勾,Plan 阶段结束) | **无分发** | `plan-done` |  
38 -  
39 -项目完成状态(B 阶段所有模块 MR merged)由 `erp-coding-start` 扫描 MR state 判定并打印,本 skill 不处理。 26 +| 无 docs/08 | `project-init` | `A0` |
  27 +| 含 `A0` / `A0 子项` | `project-init` | `A0` |
  28 +| 含 `A1` / `A1 子项` | `scope-lock` | `A1` |
  29 +| 含 `A2` / `A2 子项` | `skeleton-gen` | `A2` |
  30 +| 含 `A3` / `A3 子项` | `db-design-gen` | `A3` |
  31 +| 含 `A4` / `A4 子项` | `db-init` | `A4` |
  32 +| 含 `A5` / `A5 子项` | `downstream-gen` | `A5` |
  33 +| `A` 全勾,Plan 阶段结束 | **无分发** | - |
40 34
41 ## 第二步:分发通知 + 调用目标 skill 35 ## 第二步:分发通知 + 调用目标 skill
42 36
43 -本入口**不画完整流程图**——目标 A skill 会在自己的步骤 0 打印带 `▶` 当前位置的流程图。本步骤只做分发决策与通知。  
44 -  
45 -### 2.1 Plan 已完成(`mark_line=plan-done`) 37 +### 2.1 Plan 已完成
46 38
47 -A 阶段所有 checkbox 均 `[x]`。因无下游 A skill 接手,本步骤**自行打印流程图**(`▶` 标在"规划阶段到此结束")并给出提示,然后**停下**;项目整体完成状态由 `erp-coding-start` 扫描 MR state 判定,本 skill 不负责 39 +A 阶段所有 checkbox 均 `[x]`。无后续 skill,本步骤**自行打印流程图**,然后**停下**
48 40
49 ``` 41 ```
50 ┌──────────────────────────────────────────────────────┐ 42 ┌──────────────────────────────────────────────────────┐
@@ -52,18 +44,18 @@ A 阶段所有 checkbox 均 `[x]`。因无下游 A skill 接手,本步骤**自 @@ -52,18 +44,18 @@ A 阶段所有 checkbox 均 `[x]`。因无下游 A skill 接手,本步骤**自
52 │ │ 44 │ │
53 │ A0 初始化项目 → A1 锁范围(REQ 卡片) │ 45 │ A0 初始化项目 → A1 锁范围(REQ 卡片) │
54 │ ↓ │ 46 │ ↓ │
55 -│ ⏸ 等你审阅 REQ,重新运行 /erp-plan-start 继续 │ 47 +│ ⏸ 等你审阅 REQ,重新运行 /plan-start 继续 │
56 │ ↓ │ 48 │ ↓ │
57 -│ A2 生成骨架 → A3 初始化 DB → A4 生成 DB 设计 → A5 生成下游文档│ 49 +│ A2 生成骨架 → A3 生成 DB 设计 → A4 初始化 DB → A5 生成下游文档│
58 │ ↓ │ 50 │ ↓ │
59 │ ▶ 规划阶段到此结束 │ 51 │ ▶ 规划阶段到此结束 │
60 └──────────────────────────────────────────────────────┘ 52 └──────────────────────────────────────────────────────┘
61 53
62 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 54 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
63 - [erp-plan-start] ✅ Plan 阶段全部完成 55 + [plan-start] ✅ Plan 阶段全部完成
64 56
65 ⚠️ 进入 B 阶段前必须完成: 57 ⚠️ 进入 B 阶段前必须完成:
66 - 1. 人工通读 docs/01~10 + CLAUDE.md + sql/migrations/V1 + 各 scripts/* 58 + 1. 人工通读 docs/* + CLAUDE.md + sql/migrations/V1 + 各 scripts/*
67 59
68 2. 把全部 Plan 产物 commit: 60 2. 把全部 Plan 产物 commit:
69 git add -A && git commit -m "chore: plan phase A0~A5 done" 61 git add -A && git commit -m "chore: plan phase A0~A5 done"
@@ -71,33 +63,28 @@ A 阶段所有 checkbox 均 `[x]`。因无下游 A skill 接手,本步骤**自 @@ -71,33 +63,28 @@ A 阶段所有 checkbox 均 `[x]`。因无下游 A skill 接手,本步骤**自
71 3. 推到远程: 63 3. 推到远程:
72 git remote add origin <gitlab-url> # 若尚未添加 64 git remote add origin <gitlab-url> # 若尚未添加
73 git -c core.hooksPath=/dev/null push -u origin master 65 git -c core.hooksPath=/dev/null push -u origin master
74 - # 首次 push 本地 DB 尚未就位、scripts/test.sh 必然失败。  
75 - # `-c core.hooksPath=/dev/null` 临时把 hooksPath 指到空目录,  
76 - # 跳过 .githooks/pre-push 但不动 repo 的 core.hooksPath 配置,  
77 - # 也不用 --no-verify(后者被 CC 的 deny-no-verify hook 硬拦)。  
78 - # push 完成后到 GitLab UI 把 master(或 main)设为 protected  
79 66
80 - 4. main(或 master)就绪后,再运行 /erp-workflow:erp-coding-start 67 + 4. main(或 master)就绪后,再运行 /erp-workflow:coding-start
81 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 68 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
82 ``` 69 ```
83 70
84 不调任何下游 skill。 71 不调任何下游 skill。
85 72
86 -### 2.2 正常派发(`target_skill` 非空) 73 +### 2.2 正常派发(`后续` 非空)
87 74
88 打印简短分发通知: 75 打印简短分发通知:
89 76
90 ``` 77 ```
91 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 78 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
92 - [erp-plan-start] → 派发到 <target_skill> 79 + [plan-start] → 派发到 <后续>
93 未勾项:<docs/08 中第一个 - [ ] 行内容> 80 未勾项:<docs/08 中第一个 - [ ] 行内容>
94 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 81 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
95 ``` 82 ```
96 83
97 -立即用 `Skill` 工具调用 `target_skill`。 84 +立即用 `Skill` 工具调用 `后续`。
98 85
99 ## 参考 86 ## 参考
100 87
101 -- `docs/08-模块任务管理.md`(唯一进度权威 88 +- `docs/08-模块任务管理.md`(进度追踪
102 - `CLAUDE.md`(项目指令) 89 - `CLAUDE.md`(项目指令)
103 -- 下游 skills(通过 `Skill` 工具按名称调用) 90 +- 后续 skills(通过 `Skill` 工具按名称调用)
skills/internal/superpower-writing-plans/SKILL.md
@@ -6,7 +6,7 @@ user-invocable: false @@ -6,7 +6,7 @@ user-invocable: false
6 6
7 # Writing Plans (Internal, Gate-Free) 7 # Writing Plans (Internal, Gate-Free)
8 8
9 -Write task-level implementation plans that tell the TDD executor **what to do**, not **how to write the code**. The executor is `erp-feature-tdd` (Claude itself with full context), not a mechanical copy-paster — so the plan captures file boundaries, test intent, API shapes and completion criteria, and lets the executor produce the actual code in the red-green cycle. DRY. YAGNI. TDD. Frequent commits. 9 +Write task-level implementation plans that tell the TDD executor **what to do**, not **how to write the code**. The executor is `feature-tdd` (Claude itself with full context), not a mechanical copy-paster — so the plan captures file boundaries, test intent, API shapes and completion criteria, and lets the executor produce the actual code in the red-green cycle. DRY. YAGNI. TDD. Frequent commits.
10 10
11 **Do NOT dump full file contents (pom.xml, entity classes, config files) into the plan.** The plan and the code end up as two sources of truth that drift; 2000+ line plans also waste context. Code is produced during TDD, not pre-written here. 11 **Do NOT dump full file contents (pom.xml, entity classes, config files) into the plan.** The plan and the code end up as two sources of truth that drift; 2000+ line plans also waste context. Code is produced during TDD, not pre-written here.
12 12
@@ -44,7 +44,7 @@ This structure informs the task decomposition. Each task should produce self-con @@ -44,7 +44,7 @@ This structure informs the task decomposition. Each task should produce self-con
44 ```markdown 44 ```markdown
45 # [Feature Name] Implementation Plan 45 # [Feature Name] Implementation Plan
46 46
47 -> **Execution:** Parent skill `erp-feature-tdd` executes this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. 47 +> **Execution:** Parent skill `feature-tdd` executes this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
48 48
49 **Goal:** [One sentence describing what this builds] 49 **Goal:** [One sentence describing what this builds]
50 50
@@ -104,7 +104,7 @@ Every step must contain the actual content an engineer needs. These are **plan f @@ -104,7 +104,7 @@ Every step must contain the actual content an engineer needs. These are **plan f
104 - "Similar to Task N"(相似任务各自写清楚测试意图 + 完成判据,不互相链接) 104 - "Similar to Task N"(相似任务各自写清楚测试意图 + 完成判据,不互相链接)
105 - References to types, functions, or methods not defined in any task(类/方法首次出现的 task 要给出 API 签名) 105 - References to types, functions, or methods not defined in any task(类/方法首次出现的 task 要给出 API 签名)
106 106
107 -> 散文级"做什么"是 OK 的——执行器(erp-feature-tdd)会在 TDD 循环里决定"怎么写"。plan 的义务是**约束范围**,不是**替 TDD 写代码**。 107 +> 散文级"做什么"是 OK 的——执行器(feature-tdd)会在 TDD 循环里决定"怎么写"。plan 的义务是**约束范围**,不是**替 TDD 写代码**。
108 108
109 ## Remember 109 ## Remember
110 110
skills/plan/db-design-gen/SKILL.md 0 → 100644
  1 +---
  2 +name: db-design-gen
  3 +description: A3 DB 设计 + REQ 回填——基于 docs/01-需求清单 REQ 卡片正向设计 docs/03-数据库设计文档.md(业务实体 → 表 + 字段 + 索引 + 外键 + 业务注记),并把回填值写入 REQ 卡片的「依赖表: TBD(A3 自动补)」占位。生成完毕停下等人工审阅。
  4 +user-invocable: false
  5 +allowed-tools: Read Write Edit Grep Glob Skill AskUserQuestion
  6 +---
  7 +
  8 +**所有输出必须使用中文。**
  9 +
  10 +# db-design-gen
  11 +
  12 +## 前置条件
  13 +
  14 +- A1 `scope-lock` 已完成:`docs/01-需求清单/<module>-*.md` REQ 卡片存在,含 `TBD(A3 自动补)` 占位。
  15 +- A2 `skeleton-gen` 已完成:`docs/04-技术规范.md § 一+` 命名规范已生成(本 skill 推导表/字段命名时严格遵循)。
  16 +
  17 +## 执行步骤
  18 +
  19 +### 步骤 0:打印当前位置流程图
  20 +
  21 +向用户展示当前在 A 阶段流程中的位置(A-only,`▶` 标在 A3):
  22 +
  23 +```
  24 +┌──────────────────────────────────────────────────────┐
  25 +│ 📋 阶段 A:规划(一次性) │
  26 +│ │
  27 +│ A0 初始化项目 → A1 锁范围(REQ 卡片) │
  28 +│ ↓ │
  29 +│ ⏸ 等你审阅 REQ,重新运行 /plan-start 继续 │
  30 +│ ↓ │
  31 +│ A2 生成骨架 → ▶ A3 生成 DB 设计 → A4 初始化 DB → A5 生成下游文档│
  32 +│ ↓ │
  33 +│ ⏸ 等你审阅 docs/03,重新运行 /plan-start 继续 │
  34 +└──────────────────────────────────────────────────────┘
  35 +```
  36 +
  37 +### A. 读取设计输入
  38 +
  39 +用 `Read` / `Glob` 读取:
  40 +
  41 +- `docs/04-技术规范.md` § 一+ 命名规范(表名 / 字段名 / 索引名 / 外键名约定,及主键 / 时间戳 / 软删等审计列约定)
  42 +- `docs/01-需求清单/index.md` 模块索引(模块代码 ↔ 中文名)
  43 +- `docs/01-需求清单/*.md`(排除 `index.md`)所有 REQ 卡片,提取 `req_id` / `goal` / `input` / `output` / `rules` / `constraints` / `acceptance`
  44 +
  45 +### B. LLM 推导 schema
  46 +
  47 +基于步骤 A 读到的 REQ + 命名规范,**正向推导**业务实体 → 表 + 字段 + 索引 + 外键。要求:
  48 +
  49 +1. **表名 / 列名 / 索引名 / 外键名** 严格套用 `docs/04 § 一+` 的命名规范
  50 +2. **审计列**:除明确不需要的辅助表外,每张业务表至少含 `created_at` / `updated_at`;如 `docs/04 § 一+` 约定了 `created_by` / `updated_by` / 软删 `deleted_at`,一并补全
  51 +3. **主键**:默认 `id BIGINT UNSIGNED PRIMARY KEY AUTO_INCREMENT`,除非 REQ 明确要求复合主键 / UUID / 业务主键
  52 +4. **外键**:依据 REQ 中的引用关系(如「订单引用客户」),明确列出 `ON DELETE` / `ON UPDATE` 策略;不能确定时默认 `RESTRICT`
  53 +5. **索引**:根据 REQ 的查询模式(如"按时间范围查"、"按状态筛选")推导业务索引;外键列默认建索引
  54 +6. **业务注记**:对每张表用一两句话说明业务用途、关键约束、与其他表的关系
  55 +
  56 +如果某 REQ 表述模糊以致无法推断关键 schema 细节(如:枚举值范围 / 字段长度上限 / 必填性),先按合理默认推导并在该字段「业务含义」列加 `[需用户审阅]` 标注,待步骤 E 用户审阅时调整;**不打断本次推导**。
  57 +
  58 +### C. 渲染 docs/03
  59 +
  60 +1. 用 `Read` 读取 `${CLAUDE_SKILL_DIR}/templates/docs-03-header-template.md`,填充 `schema_name`(从 `.env.local` 读 `DB_SCHEMA`,无则填 `【人工填写:DB_SCHEMA】`)、`er_overview`(基于步骤 B 表关系生成的纯文本 ER 概览)。
  61 +2. 渲染「表清单」:每行 `- \`<table_name>\` — <一句话用途>`。
  62 +3. 对每张表:用 `Read` 读取 `${CLAUDE_SKILL_DIR}/templates/docs-03-table-template.md`,填充字段 / 索引 / 外键 / 业务注记。
  63 +4. 用 `Write` 写入 `docs/03-数据库设计文档.md`。
  64 +
  65 +### D. 回填模块头 + REQ 卡片的 TBD 字段
  66 +
  67 +1. 用 `Glob` 列出 `docs/01-需求清单/*.md`(排除 `index.md`)。
  68 +2. 用 `Grep` 在这些文件中搜索 `TBD(A3 自动补)` 的**行号**(不读全文)。两种行命中:
  69 + - `涉及表: TBD(A3 自动补)` → 模块级(文件头部,每文件一次)
  70 + - `依赖表: TBD(A3 自动补)` → REQ 级(每 REQ 一次)
  71 +3. 对每个命中行按类型回填:
  72 + - **模块级 `涉及表`**:用 `Read` 取该文件 `{{module_code}}` + `{{module_name}}`,聚合步骤 B 中所有归属该模块的表(多表用 `, ` 分隔);`Edit` 替换为 `涉及表: <table1>, <table2>, ...`
  73 + - **REQ 级 `依赖表`**:用 `Read` 仅读取该 REQ 卡片所在片段(标题前后约 20 行)取 `req_id`;根据步骤 B 推导结果定位该 REQ 关联的表;`Edit` 替换为 `依赖表: <table1>, <table2>`
  74 + - **不动** `TBD(A5 自动补)` 的两种行(`依赖接口` REQ 级 / `依赖模块` 模块级)—— 由 A5 `downstream-gen` 生成 docs/05 + 完成模块 DAG 后回填
  75 +4. 用 `Grep` 再次扫 `TBD(A3 自动补)` 应 0 命中;仍有残留则打印残留位置清单并停下。
  76 +5. 打印回填统计:`A3 回填 <M> 处模块涉及表 + <N> 处 REQ schema_refs`。
  77 +
  78 +### E. 勾选 docs/08 自动项 + 停下等人工审阅
  79 +
  80 +1. 用 `Edit` 在 `docs/08-模块任务管理.md` 勾选 2 个自动项(**不勾**第 3 个人工闸门,由用户审阅后自己勾):
  81 + - ` - [ ] docs/03-数据库设计文档.md 已生成` → `[x]`
  82 + - ` - [ ] docs/01 各 REQ 卡片"涉及数据表"已回填` → `[x]`
  83 + - ` - [ ] 用户已审阅 docs/03 表结构` 保持 `[ ]`(人工勾)
  84 + - `- [ ] A3 DB 设计 + REQ 回填 — db-design-gen` 保持 `[ ]`(最后一个子项勾后再勾父项)
  85 +
  86 +2. 输出 `db-design-gen: docs/03 已生成 + N 处 REQ 已回填依赖表`。
  87 +
  88 +3. 打印停下横幅并**停下**(**不调** `Skill(db-init)`,A4 由用户审阅后手动恢复):
  89 +
  90 + ```
  91 + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  92 + [db-design-gen] ✅ A3 DB 设计完成
  93 +
  94 + 产出:
  95 + ✓ docs/03-数据库设计文档.md
  96 + ✓ docs/01-需求清单/<module>-*.md 依赖表已回填
  97 +
  98 + ⏸ 现在请你审阅 docs/03(表 / 字段 / 索引 / 外键 / 业务注记)。
  99 + 重点关注:
  100 + - 业务实体覆盖是否完整
  101 + - 字段类型 / 长度 / 是否可空 / 默认值是否合理
  102 + - 索引是否覆盖主要查询模式
  103 + - 外键 ON DELETE / ON UPDATE 策略是否符合业务
  104 + - 字段「业务含义」列含 `[需用户审阅]` 标注的位置需逐一确认
  105 +
  106 + 审阅完成后,到 docs/08 § 一 把 A3 的「用户已审阅 docs/03 表结构」
  107 + 手动勾上(`[ ]` → `[x]`),然后再勾父项 `- [ ] A3 DB 设计 + REQ 回填`,
  108 + 再运行:
  109 + /erp-workflow:plan-start
  110 +
  111 + (入口会读取 docs/08 进度,自动派发到 A4 db-init)
  112 + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  113 + ```
  114 +
  115 + **停止**,不调用任何下游 skill。
  116 +
  117 +## 不变量
  118 +
  119 +- 本 skill **不连接任何数据库**,纯文档驱动;MySQL 连接验证 / DDL apply 由 A4 `db-init` 负责
  120 +- REQ 卡片的 `依赖接口` 字段不在此处填充,留给 A5 `downstream-gen` 在生成 docs/05 后按 `TBD(A5 自动补)` 回填
  121 +- DB 设计与 REQ 卡片同等重要,必须留出人工审阅闸门,避免 LLM 推导的表结构未经把关就被 A4 翻译成 DDL 并 apply 到 MySQL
  122 +
  123 +## 参考
  124 +
  125 +- `${CLAUDE_SKILL_DIR}/templates/docs-03-header-template.md`
  126 +- `${CLAUDE_SKILL_DIR}/templates/docs-03-table-template.md`
  127 +- `docs/04-技术规范.md` § 一+(命名规范输入)
  128 +- `docs/01-需求清单/*.md`(REQ 输入 + 回填目标)
skills/plan/erp-db-design-gen/templates/docs-03-header-template.md renamed to skills/plan/db-design-gen/templates/docs-03-header-template.md
@@ -2,7 +2,7 @@ @@ -2,7 +2,7 @@
2 2
3 Schema: `{{schema_name}}` 3 Schema: `{{schema_name}}`
4 Migration 清单: `sql/migrations/V*.sql`(由 Flyway 顺序 apply) 4 Migration 清单: `sql/migrations/V*.sql`(由 Flyway 顺序 apply)
5 -生成方式: 通过 `mysql` 命令行从 live schema 反查生成 5 +生成方式: 由 A3 `db-design-gen` 基于 `docs/01-需求清单/*.md` REQ 卡片正向设计生成(schema SSoT)
6 6
7 ## ER 关系概览 7 ## ER 关系概览
8 8
skills/plan/erp-db-design-gen/templates/docs-03-table-template.md renamed to skills/plan/db-design-gen/templates/docs-03-table-template.md
skills/plan/db-init/SKILL.md 0 → 100644
  1 +---
  2 +name: db-init
  3 +description: A4 DB 初始化——LLM 解析 docs/03-数据库设计文档.md → 生成 sql/migrations/V1__initial_schema.sql(DDL only,Flyway 初始 migration)→ 全量校验 DDL ↔ docs/03 一致性 → 验证 MySQL 连接 → 调 scripts/setup-test-db.sh 复用三层防护并 DROP+CREATE 空库 → apply V1。
  4 +user-invocable: false
  5 +allowed-tools: Read Write Edit Glob Skill Bash(mkdir *) Bash(mysql *) Bash(set *) Bash(. .env.local) Bash(sed *) Bash(cat *) Bash(grep *) Bash(./scripts/setup-test-db.sh)
  6 +---
  7 +
  8 +**所有输出必须使用中文。**
  9 +
  10 +# db-init
  11 +
  12 +## 前置条件
  13 +
  14 +- A3 `db-design-gen` 已完成:`docs/03-数据库设计文档.md` 已生成,用户已审阅,docs/08 § 一 A3 全部 checkbox 均 `[x]`。
  15 +- A2 `skeleton-gen` 已完成:`.env.local` 已存在(含 `DB_HOST` / `DB_PORT` / `DB_USER` / `DB_PASSWORD` / `DB_SCHEMA`)。
  16 +
  17 +## 执行步骤
  18 +
  19 +### 步骤 0:打印当前位置流程图
  20 +
  21 +向用户展示当前在 A 阶段流程中的位置(A-only,`▶` 标在 A4):
  22 +
  23 +```
  24 +┌──────────────────────────────────────────────────────┐
  25 +│ 📋 阶段 A:规划(一次性) │
  26 +│ │
  27 +│ A0 初始化项目 → A1 锁范围(REQ 卡片) │
  28 +│ ↓ │
  29 +│ ⏸ 等你审阅 REQ,重新运行 /plan-start 继续 │
  30 +│ ↓ │
  31 +│ A2 生成骨架 → A3 生成 DB 设计 → ▶ A4 初始化 DB → A5 生成下游文档│
  32 +│ ↓ │
  33 +│ 规划阶段最后一步:A5 由本 skill 末尾自动调起 │
  34 +└──────────────────────────────────────────────────────┘
  35 +```
  36 +
  37 +### A. DDL 生成(不依赖数据库连接)
  38 +
  39 +#### A.1 读 docs/03 并 LLM 翻译为 DDL
  40 +
  41 +用 `Read` 读取 `docs/03-数据库设计文档.md`,按字段 / 索引 / 外键 / 业务注记**严格翻译**为:
  42 +
  43 +- 每张表一段 `CREATE TABLE \`<name>\` (...) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='<业务用途>';`
  44 +- 字段顺序与 docs/03 表格行序一致;`Nullable` 列直接映射 `NOT NULL` / `NULL`;`默认` 列映射 `DEFAULT <value>`;列尾用 `COMMENT '<业务含义>'` 写注释
  45 +- 索引:在表创建后追加 `CREATE [UNIQUE] INDEX \`<name>\` ON \`<table>\` (<cols>);`(主键 / 唯一约束已在 CREATE TABLE 内联的不重复声明)
  46 +- 外键:在所有表创建完成后**统一追加**:`ALTER TABLE \`<from_table>\` ADD CONSTRAINT \`<name>\` FOREIGN KEY (\`<from_col>\`) REFERENCES \`<to_table>\` (\`<to_col>\`) ON DELETE <policy>;`(避免顺序问题)
  47 +
  48 +要求:
  49 +- **严禁臆造** docs/03 中没有的表 / 字段 / 索引 / 外键
  50 +- **严禁省略** docs/03 中已有的列、注释或约束
  51 +- 字符集统一 `utf8mb4` + `utf8mb4_unicode_ci`,引擎统一 `InnoDB`,除非 docs/03 业务注记明确要求其他设置
  52 +
  53 +#### A.2 拼装 V1 文件
  54 +
  55 +用 `Bash` 拼装最终文件:
  56 +
  57 +```bash
  58 +mkdir -p sql/migrations
  59 +PROJECT="<从 CLAUDE.md 读到的项目名称>"
  60 +TS="$(date -u +%FT%TZ)"
  61 +set -a; . .env.local; set +a
  62 +{
  63 + sed -e "s|{{project_name}}|$PROJECT|g" \
  64 + -e "s|{{timestamp}}|$TS|g" \
  65 + -e "s|{{schema_name}}|$DB_SCHEMA|g" \
  66 + "${CLAUDE_SKILL_DIR}/templates/migration-v1-header-template.sql"
  67 + echo ""
  68 + cat <<'DDL_EOF'
  69 +<把 A.1 推导出的 CREATE TABLE / CREATE INDEX / ALTER ADD FK 全部按顺序粘贴在此>
  70 +DDL_EOF
  71 +} > sql/migrations/V1__initial_schema.sql
  72 +```
  73 +
  74 +#### A.3 全量校验 DDL ↔ docs/03 一致性
  75 +
  76 +5 维度全量校验。**任一不一致** → 报错停下,**列出全部差异明细**;V1.sql 保留以便人工 diff。
  77 +
  78 +1. **表名集合相等**
  79 + - `S_doc` = grep `^## \`<name>\`` of docs/03
  80 + - `S_sql` = grep `CREATE TABLE \`<name>\`` of V1
  81 + - `S_doc - S_sql` 非空(漏表)/ `S_sql - S_doc` 非空(多表)→ 报错列出差集
  82 +
  83 +2. **每张表全列名 + 列序相等**(**遍历 S_sql 全部表,无抽样**)
  84 + - 对每张表 t:
  85 + - 从 docs/03 抽该表 `### 字段` 表格行序,得 `cols_doc[t]`
  86 + - 从 V1 抽该 `CREATE TABLE` 段内 `\`<col>\`` 出现序,得 `cols_sql[t]`
  87 + - **数组相等**(含顺序);不等则列出 `<table>: docs=[...], sql=[...]`
  88 +
  89 +3. **每个字段类型 / Nullable / 默认值一致**
  90 + - 对每个 `<table>.<col>`,归一化后字符串比对。归一化规则:
  91 + - 类型主词转小写(`BIGINT` → `bigint`)
  92 + - `UNSIGNED` 保留为小写
  93 + - 显示宽度 `INT(11)` → `int`(去括号)
  94 + - Nullable:docs/03 `否` ↔ DDL `NOT NULL`;docs/03 `是` ↔ DDL 无 `NOT NULL`
  95 + - 默认值:去多余空格 + 统一大小写
  96 + - **`COMMENT` / `COLLATE` / `CHARSET` 不参与比对**(避免装饰差异误报)
  97 + - 不一致 → 列出 `<table>.<col>: docs=<X>, ddl=<Y>`
  98 +
  99 +4. **每张表索引名集合相等**
  100 + - `idx_doc[t]` = docs/03 该表 `### 索引` 列表的名字
  101 + - `idx_sql[t]` = V1 中归属该表的 `CREATE INDEX <name>` + inline `KEY \`<name>\` / UNIQUE KEY \`<name>\``(排除 `PRIMARY` 自动名)
  102 + - 集合不等 → 报错列出差集
  103 +
  104 +5. **外键名集合相等**(全局,不分表)
  105 + - `fk_doc` = docs/03 各表 `### 外键` 列表的所有名字
  106 + - `fk_sql` = V1 中所有 `ADD CONSTRAINT \`<name>\` FOREIGN KEY` 的名字
  107 + - 集合不等 → 报错列出差集
  108 +
  109 +校验全部通过 → 进入步骤 B。**任一维度不通过都不许继续**;提示用户 diff `docs/03` ↔ `V1.sql` 后修正 docs/03(SSoT),重跑 A3 让 `db-design-gen` / 本 skill 重新生成 V1。
  110 +
  111 +### B. 数据库环境检查
  112 +
  113 +#### B.1 检查 .env.local 凭据
  114 +
  115 +用 `Glob` 检查 `.env.local` 是否存在;不存在 → 提示用户重新运行 A2 `skeleton-gen` 重建并停下。
  116 +
  117 +用 `Bash` 加载并校验 5 个必填字段非空:
  118 +
  119 +```bash
  120 +set -a; . .env.local; set +a
  121 +for v in DB_HOST DB_PORT DB_USER DB_PASSWORD DB_SCHEMA; do
  122 + eval val=\${$v:-}
  123 + [ -z "$val" ] && echo "MISSING: $v"
  124 +done
  125 +```
  126 +
  127 +任一缺失 → 打印缺失字段名并停下,提示用户编辑 `.env.local` 后重跑。
  128 +
  129 +> 注:密码中含 `$`、`` ` ``、空格、`!` 等字符时,`.env.local` 需用单引号包裹,例如 `DB_PASSWORD='p@ss$w0rd!'`。`set -a; . file; set +a` 与 `source` 行为一致但更明确,配合单引号可避免特殊字符被 shell 展开。
  130 +
  131 +#### B.2 验证 MySQL 连接
  132 +
  133 +```bash
  134 +set -a; . .env.local; set +a
  135 +mysql -h"$DB_HOST" -P"$DB_PORT" -u"$DB_USER" -p"$DB_PASSWORD" -e "SELECT 1;"
  136 +```
  137 +
  138 +- **成功** → 进入步骤 C
  139 +- **失败** → 打印具体错误(认证 / 主机不可达 / 端口拒接等),提示检查 `.env.local`,**停下**。`sql/migrations/V1__initial_schema.sql` 已在步骤 A 落盘,用户可在修复连接后手动 `mysql < V1.sql`,无需重跑 A4 的 DDL 生成
  140 +
  141 +### C. 自动导入 MySQL
  142 +
  143 +#### C.1 调 setup-test-db.sh 做防护 + DROP+CREATE 空库
  144 +
  145 +A2 `skeleton-gen` 已生成 `scripts/setup-test-db.sh`,内置三层防护(**单一真相源,与 B 阶段 test.sh 共用同款规则**):
  146 +- 防护 1:host 白名单(默认 `localhost / 127.0.0.1 / ::1`,严格相等匹配;可通过 `.env.local` 的 `TEST_DB_ALLOWED_HOSTS` 显式扩展)
  147 +- 防护 2:schema 命名后缀检查(必须含 `test` 或以 `_dev / _local / _ci` 结尾)
  148 +- 防护 3:远程 host DROP 警告横幅
  149 +
  150 +直接调用,由它处理凭据加载 + 三层防护 + DROP+CREATE:
  151 +
  152 +```bash
  153 +./scripts/setup-test-db.sh
  154 +```
  155 +
  156 +任一防护失败 → 脚本自身停下并打印明细(host 不在白名单 / schema 名不像测试库 / `.env.local` 缺失等),本 skill **立即停下不做后续步骤**。
  157 +`sql/migrations/V1__initial_schema.sql` 已在步骤 A 落盘,用户调整 `.env.local`(如 `TEST_DB_ALLOWED_HOSTS` 加 host)或 schema 命名后可直接重跑 A4,无需重新生成 V1。
  158 +
  159 +#### C.2 把 V1 灌入已清空的 schema
  160 +
  161 +```bash
  162 +set -a; . .env.local; set +a
  163 +mysql -h"$DB_HOST" -P"$DB_PORT" -u"$DB_USER" -p"$DB_PASSWORD" "$DB_SCHEMA" \
  164 + < sql/migrations/V1__initial_schema.sql
  165 +```
  166 +
  167 +非零退出 → 报错停下,打印 mysql stderr。
  168 +
  169 +#### C.3 自检 SHOW TABLES
  170 +
  171 +```bash
  172 +set -a; . .env.local; set +a
  173 +ACTUAL=$(mysql -N -B -h"$DB_HOST" -P"$DB_PORT" -u"$DB_USER" -p"$DB_PASSWORD" \
  174 + -e "SHOW TABLES;" "$DB_SCHEMA" | wc -l | tr -d ' ')
  175 +EXPECTED=$(grep -c '^## `' docs/03-数据库设计文档.md)
  176 +[ "$ACTUAL" = "$EXPECTED" ] || { echo "MISMATCH: actual=$ACTUAL expected=$EXPECTED"; exit 1; }
  177 +```
  178 +
  179 +行数不一致 → 报错停下;一致 → 进入步骤 D。
  180 +
  181 +### D. 勾选 docs/08 进度 + 进入 A5
  182 +
  183 +1. 用 `Edit` 在 `docs/08-模块任务管理.md` 勾选 5 个 checkbox(A4 的 4 个子项 + A4 父项):
  184 + - ` - [ ] sql/migrations/V1__initial_schema.sql 已生成` → `[x]`
  185 + - ` - [ ] .env.local 凭据已验证(mysql -e "SELECT 1" OK)` → `[x]`
  186 + - ` - [ ] setup-test-db.sh 防护通过 + DROP+CREATE + apply V1 已执行` → `[x]`
  187 + - ` - [ ] SHOW TABLES 行数 == docs/03 表数量` → `[x]`
  188 + - `- [ ] A4 DB 初始化 — db-init` → `[x]`
  189 +
  190 +2. 输出 `db-init: 完成(V1 ✓, schema=<名称>, tables=<T>,已 apply 到本地 MySQL)`。
  191 +
  192 +3. 立即调用 `Skill(downstream-gen)` 进入 A5,不等用户手动输入。
  193 +
  194 +## 不变量
  195 +
  196 +- **DDL 来源唯一**:V1 完全由 docs/03 翻译而来;docs/03 是 schema 单一真相源(SSoT)。后续 V2/V3 由 B 阶段 `feature-tdd` 在 REQ 实现时写入,并**同步**回写 docs/03 对应表小节
  197 +- **测试夹具归属 B 阶段**:测试数据由 B 阶段每个 REQ 在自己的测试代码 / Spring `@Sql` / testcontainers fixture 中按需提供
  198 +- **安全守护单一真相源**:DROP / 写操作的防护逻辑统一在 `scripts/setup-test-db.sh`(三层防护:host 白名单 + schema 命名后缀 + 远程 host 横幅),本 skill 与 B 阶段 `test.sh` 共用同一份规则;本 skill 不重复实现防护
  199 +- **DDL 校验 fail-closed**:A.3 5 维度全量校验任一不通过都不许进入 apply 阶段
  200 +- **失败可恢复**:每次重跑都从空库 `DROP+CREATE` 开始;中途失败重跑无状态残留
  201 +
  202 +## 参考
  203 +
  204 +- `${CLAUDE_SKILL_DIR}/templates/migration-v1-header-template.sql`(V1 头部注释)
  205 +- `docs/03-数据库设计文档.md`(DDL 翻译输入,SSoT)
  206 +- `.env.local`(DB 凭据)
  207 +- 产物:`sql/migrations/V1__initial_schema.sql`(由 Flyway 在 Spring Boot 启动时验证 / apply)
skills/plan/erp-db-init/templates/migration-v1-header-template.sql renamed to skills/plan/db-init/templates/migration-v1-header-template.sql
1 -- Flyway migration V1 — initial schema for {{project_name}} 1 -- Flyway migration V1 — initial schema for {{project_name}}
2 -- Generated: {{timestamp}} 2 -- Generated: {{timestamp}}
3 --- Source: mysqldump --no-data {{schema_name}} 3 +-- Source: 由 A4 `db-init` 从 `docs/03-数据库设计文档.md` 翻译生成(schema SSoT 是 docs/03)
4 -- This is the FIRST migration; subsequent schema changes must be written 4 -- This is the FIRST migration; subsequent schema changes must be written
5 -- as new files sql/migrations/V2__<desc>.sql, V3__..., etc. 5 -- as new files sql/migrations/V2__<desc>.sql, V3__..., etc.
6 -- Apply: Flyway runs this automatically at Spring Boot startup. 6 -- Apply: Flyway runs this automatically at Spring Boot startup.
skills/plan/erp-downstream-gen/SKILL.md renamed to skills/plan/downstream-gen/SKILL.md
1 --- 1 ---
2 -name: erp-downstream-gen 2 +name: downstream-gen
3 description: A5 下游文档生成——基于 docs/01 和 docs/03 推导,一次性生成 docs/02 + docs/05 + docs/06 § 五 + docs/10,回填 REQ 卡片依赖接口,把模块清单追加到 docs/08 § 二。 3 description: A5 下游文档生成——基于 docs/01 和 docs/03 推导,一次性生成 docs/02 + docs/05 + docs/06 § 五 + docs/10,回填 REQ 卡片依赖接口,把模块清单追加到 docs/08 § 二。
4 user-invocable: false 4 user-invocable: false
5 allowed-tools: Read Write Edit Glob Grep Skill AskUserQuestion Bash(cat *) Bash(git remote *) 5 allowed-tools: Read Write Edit Glob Grep Skill AskUserQuestion Bash(cat *) Bash(git remote *)
@@ -7,13 +7,14 @@ allowed-tools: Read Write Edit Glob Grep Skill AskUserQuestion Bash(cat *) Bash( @@ -7,13 +7,14 @@ allowed-tools: Read Write Edit Glob Grep Skill AskUserQuestion Bash(cat *) Bash(
7 7
8 **所有输出必须使用中文。** 8 **所有输出必须使用中文。**
9 9
10 -# erp-downstream-gen 10 +# downstream-gen
11 11
12 ## 前置条件 12 ## 前置条件
13 13
14 -- `docs/01-需求清单/*.md` 完整 REQ 卡片已就绪(A1 生成 + 人工审阅过)。  
15 -- `docs/03-数据库设计文档.md` 已就绪(A4 生成)。  
16 -- `docs/05` / `docs/06` / `docs/10` / `sql/seed-data.sql` 等下游文件尚不存在(本 skill 创建)。 14 +- `docs/01-需求清单/*.md` 完整 REQ 卡片已就绪(A1 生成 + 人工审阅过 + A3 已回填依赖表)。
  15 +- `docs/03-数据库设计文档.md` 已就绪(A3 生成 + 人工审阅过)。
  16 +- `sql/migrations/V1__initial_schema.sql` 已生成并 apply(A4 完成)。
  17 +- `docs/05` / `docs/06 § 五` / `docs/10` 等下游文件尚不存在(本 skill 创建)。
17 18
18 ## 执行步骤 19 ## 执行步骤
19 20
@@ -27,9 +28,9 @@ allowed-tools: Read Write Edit Glob Grep Skill AskUserQuestion Bash(cat *) Bash( @@ -27,9 +28,9 @@ allowed-tools: Read Write Edit Glob Grep Skill AskUserQuestion Bash(cat *) Bash(
27 │ │ 28 │ │
28 │ A0 初始化项目 → A1 锁范围(REQ 卡片) │ 29 │ A0 初始化项目 → A1 锁范围(REQ 卡片) │
29 │ ↓ │ 30 │ ↓ │
30 -│ ⏸ 等你审阅 REQ,重新运行 /erp-plan-start 继续 │ 31 +│ ⏸ 等你审阅 REQ,重新运行 /plan-start 继续 │
31 │ ↓ │ 32 │ ↓ │
32 -│ A2 生成骨架 → A3 初始化 DB → A4 生成 DB 设计 → ▶ A5 生成下游文档│ 33 +│ A2 生成骨架 → A3 生成 DB 设计 → A4 初始化 DB → ▶ A5 生成下游文档│
33 │ ↓ │ 34 │ ↓ │
34 │ 规划阶段到此结束 │ 35 │ 规划阶段到此结束 │
35 └──────────────────────────────────────────────────────┘ 36 └──────────────────────────────────────────────────────┘
@@ -41,7 +42,7 @@ allowed-tools: Read Write Edit Glob Grep Skill AskUserQuestion Bash(cat *) Bash( @@ -41,7 +42,7 @@ allowed-tools: Read Write Edit Glob Grep Skill AskUserQuestion Bash(cat *) Bash(
41 42
42 1. 构建**模块依赖 DAG**: 43 1. 构建**模块依赖 DAG**:
43 - docs/03 中的外键(表 A → 表 B ⇒ A 的模块依赖 B 的模块) 44 - docs/03 中的外键(表 A → 表 B ⇒ A 的模块依赖 B 的模块)
44 - - docs/01 README 中的显式 `depends_on` 提示 45 + - docs/01 index 中的显式 `depends_on` 提示
45 2. 对模块 DAG 做拓扑排序得 `module_topo_order[]`。 46 2. 对模块 DAG 做拓扑排序得 `module_topo_order[]`。
46 3. 对**每个模块内部**构建 REQ 间依赖(从 REQ 卡片 `goal` / `rules` / `依赖表` 推断 REQ-A 是 REQ-B 的前置),得到模块内 REQ 顺序。 47 3. 对**每个模块内部**构建 REQ 间依赖(从 REQ 卡片 `goal` / `rules` / `依赖表` 推断 REQ-A 是 REQ-B 的前置),得到模块内 REQ 顺序。
47 4. 合成 `req_order[]`:按 `module_topo_order[]` 依次铺开每个模块内的 REQ 序列(**同模块 REQ 连续**)。 48 4. 合成 `req_order[]`:按 `module_topo_order[]` 依次铺开每个模块内的 REQ 序列(**同模块 REQ 连续**)。
@@ -63,29 +64,35 @@ allowed-tools: Read Write Edit Glob Grep Skill AskUserQuestion Bash(cat *) Bash( @@ -63,29 +64,35 @@ allowed-tools: Read Write Edit Glob Grep Skill AskUserQuestion Bash(cat *) Bash(
63 1. 用 `Read` 读取 `${CLAUDE_SKILL_DIR}/templates/docs-05-header-template.md`,写入 `docs/05-API接口契约.md` 头部。 64 1. 用 `Read` 读取 `${CLAUDE_SKILL_DIR}/templates/docs-05-header-template.md`,写入 `docs/05-API接口契约.md` 头部。
64 2. 对所有模块的每个 REQ:用 `Read` 读取 `${CLAUDE_SKILL_DIR}/templates/docs-05-endpoint-template.md`,推断 method / path / auth / permission / 请求和响应 schema(不明确的询问用户),追加到 docs/05。 65 2. 对所有模块的每个 REQ:用 `Read` 读取 `${CLAUDE_SKILL_DIR}/templates/docs-05-endpoint-template.md`,推断 method / path / auth / permission / 请求和响应 schema(不明确的询问用户),追加到 docs/05。
65 66
66 -### B2. 回填 REQ 卡片 依赖接口 67 +### B2. 回填模块头 + REQ 卡片的 TBD(A5) 字段
67 68
68 -1. 用 `Glob` 列出 `docs/01-需求清单/*.md`(排除 `README.md`)。  
69 -2. 用 `Grep` 在这些文件中搜索 `TBD(A5 自动补)` 的行号(不读全文)。  
70 -3. 对每个命中的 REQ:  
71 - - 用 `Read` 仅读取该 REQ 卡片所在的片段(REQ 标题行前后 20 行),提取 `req_id`。  
72 - - 在步骤 B 刚生成的 `docs/05-API接口契约.md` 里 Grep 属于该 REQ 的 endpoint(通过 REQ 标签或 req_id 关联)。  
73 - - 用 `Edit`:`依赖接口: TBD(A5 自动补)` → `依赖接口: POST /api/xxx, GET /api/yyy`(具体 method + path 列表,多个用 `,` 分隔)。  
74 -4. 打印回填统计:`A5 回填 N 处 api_refs`。 69 +1. 用 `Glob` 列出 `docs/01-需求清单/*.md`(排除 `index.md`)。
  70 +2. 用 `Grep` 在这些文件中搜索 `TBD(A5 自动补)` 的行号(不读全文)。两种行命中:
  71 + - `依赖模块: TBD(A5 自动补)` → 模块级(文件头部,每文件一次)
  72 + - `依赖接口: TBD(A5 自动补)` → REQ 级(每 REQ 一次)
  73 +3. 对每个命中行按类型回填:
  74 + - **模块级 `依赖模块`**:用 `Read` 取该文件 `{{module_code}}` + `{{module_name}}`,从步骤 A 的 `module_topo_order[]` + DAG 查该模块的上游依赖(多模块用 `, ` 分隔);`Edit` 替换为 `依赖模块: <module_x>, <module_y>`(无依赖填 `—`)
  75 + - **REQ 级 `依赖接口`**:用 `Read` 仅读取该 REQ 卡片所在片段(REQ 标题行前后 20 行),提取 `req_id`;在步骤 B 刚生成的 `docs/05-API接口契约.md` 里 Grep 属于该 REQ 的 endpoint;`Edit` 替换为 `依赖接口: POST /api/xxx, GET /api/yyy`(多个用 `, ` 分隔)
  76 +4. 打印回填统计:`A5 回填 <M> 处模块依赖 + <N> 处 REQ api_refs`。
75 77
76 ### C. docs/06 — 页面清单 78 ### C. docs/06 — 页面清单
77 79
78 1. 对每个有前端页面的模块:用 `Read` 读取 `${CLAUDE_SKILL_DIR}/templates/docs-06-module-pagelist-template.md`,填充 `pages[]`(page_name、route、page_type、req_ids、menu_path、interactions)。 80 1. 对每个有前端页面的模块:用 `Read` 读取 `${CLAUDE_SKILL_DIR}/templates/docs-06-module-pagelist-template.md`,填充 `pages[]`(page_name、route、page_type、req_ids、menu_path、interactions)。
79 2. 将每个渲染块追加到 `docs/06-UI交互规范.md` § 五。 81 2. 将每个渲染块追加到 `docs/06-UI交互规范.md` § 五。
80 82
81 -### D. docs/08 § 二 — 追加模块清单 83 +### D. docs/08 § 二 — 追加模块清单(含 REQ 子项)
82 84
83 -docs/08 已由 A0 erp-project-init 创建(含 Plan 进度骨架)。本步骤只往 § 二 追加模块行,**不重写整个文件**。 85 +docs/08 已由 A0 project-init 创建(含 Plan 进度骨架)。本步骤只往 § 二 追加模块行,**不重写整个文件**。
84 86
85 1. 用 `Read` 读取 `${CLAUDE_SKILL_DIR}/templates/docs-08-module-row-template.md`(单模块 bullet 行模板)。 87 1. 用 `Read` 读取 `${CLAUDE_SKILL_DIR}/templates/docs-08-module-row-template.md`(单模块 bullet 行模板)。
86 -2. **按 `module_id` 字母序**对每个模块:渲染一行 bullet,填充 `module_id` / `module_name` / `depends_on` / `path_scopes`(不含 REQ 列表——REQ 级顺序以 docs/02 § 二 为准;模块完成信号由 `MR:` 字段 + GitLab API `state` 判定)。  
87 -  
88 - > 注意:docs/08 § 二 的行序**不决定分发顺序**——分发以 docs/02 § 二 为准,此处按字母序仅方便查找。 88 +2. **按 `module_id` 字母序**对每个模块:
  89 + - 从步骤 A `req_order[]` 过滤出 `module_id` 匹配的 REQ 列表(保持步骤 A 算出的模块内 REQ 顺序)。
  90 + - 对每个 REQ 从 `docs/01-需求清单/<module>.md` 读出其一句话标题(REQ 卡片标题行或 `goal` 字段)。
  91 + - 渲染 `{{req_checklist}}` 块:每行 ` - [ ] <req_id> <title>`(4 空格缩进对齐 `- 功能:`)。
  92 + - 渲染整条 bullet,填充 `module_id` / `module_name` / `depends_on` / `path_scopes` / `req_checklist`。
  93 +
  94 + > 注意一:docs/08 § 二 的**模块行序**不决定分发顺序——分发以 docs/02 § 二 REQ 清单为准,此处模块按字母序仅方便查找。
  95 + > 注意二:REQ 子项的 `[ ]` 由 `feature-review` 在 `verdict=approve` 时自动勾选,作为功能级进度可视化;**模块完成判定仍由 `MR:` 字段 + GitLab API state 单独决定**,不依赖子项勾选状态。
89 3. 所有模块行拼成一段文本,用 `Edit` 在 `docs/08-模块任务管理.md` 的 `## 二、Coding 阶段(按模块循环)` 标题后插入(定位用下一行注释"(A5 填入后..."作为锚,把模块清单插到该注释之前)。 96 3. 所有模块行拼成一段文本,用 `Edit` 在 `docs/08-模块任务管理.md` 的 `## 二、Coding 阶段(按模块循环)` 标题后插入(定位用下一行注释"(A5 填入后..."作为锚,把模块清单插到该注释之前)。
90 97
91 ### E. docs/10 — 验收清单 98 ### E. docs/10 — 验收清单
@@ -99,11 +106,11 @@ docs/08 已由 A0 erp-project-init 创建(含 Plan 进度骨架)。本步骤 @@ -99,11 +106,11 @@ docs/08 已由 A0 erp-project-init 创建(含 Plan 进度骨架)。本步骤
99 - docs/01 的每个 REQ 都出现在 docs/05(作为接口,如适用)、docs/10(作为验收项)。 106 - docs/01 的每个 REQ 都出现在 docs/05(作为接口,如适用)、docs/10(作为验收项)。
100 - `docs/02 § 二` 开发顺序清单的 `module_id` 集合 = `docs/08 § 二` 的 `module_id` 集合(数量、ID 全等);不相等 → 报错停下,列出差集。 107 - `docs/02 § 二` 开发顺序清单的 `module_id` 集合 = `docs/08 § 二` 的 `module_id` 集合(数量、ID 全等);不相等 → 报错停下,列出差集。
101 108
102 -2. **最终占位符扫描**(覆盖 Plan 阶段全部产出:`docs/01-需求清单/*.md` + `docs/02` / `docs/05` / `docs/06` / `docs/10` + `sql/seed-data.sql`): 109 +2. **最终占位符扫描**(覆盖 Plan 阶段全部产出:`docs/01-需求清单/*.md` + `docs/02` / `docs/03` / `docs/05` / `docs/06` / `docs/10`):
103 110
104 - a. **`TBD` → CC 自动补齐**:用 `Grep` 搜索 `TBD(A4 自动补)` 和 `TBD(A5 自动补)`。有命中则按 A4 / B2 同样逻辑就地补填(A4 查 docs/03 填 `依赖表:`;A5 查 docs/05 按 REQ-ID 填 `依赖接口:`),再 Grep 确认 0 命中;仍残留报错停下。 111 + a. **`TBD` → CC 自动补齐**:用 `Grep` 搜索 `TBD(A3 自动补)` 和 `TBD(A5 自动补)`。有命中则按 A3 / B2 同样逻辑就地补填(A3 查 docs/03 填 `依赖表:`;A5 查 docs/05 按 REQ-ID 填 `依赖接口:`),再 Grep 确认 0 命中;仍残留报错停下。
105 112
106 - b. **`【人工填写:...】` → QA 循环等用户补**(与 A2 erp-skeleton-gen 步骤 E 同风格): 113 + b. **`【人工填写:...】` → QA 循环等用户补**(与 A2 skeleton-gen 步骤 E 同风格):
107 114
108 循环执行直到两个条件**同时满足**:(1) 扫描 0 命中;(2) 用户选「继续」 115 循环执行直到两个条件**同时满足**:(1) 扫描 0 命中;(2) 用户选「继续」
109 116
@@ -111,7 +118,7 @@ docs/08 已由 A0 erp-project-init 创建(含 Plan 进度骨架)。本步骤 @@ -111,7 +118,7 @@ docs/08 已由 A0 erp-project-init 创建(含 Plan 进度骨架)。本步骤
111 - **b.2 打印汇总横幅**: 118 - **b.2 打印汇总横幅**:
112 ``` 119 ```
113 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 120 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
114 - [erp-downstream-gen] 最终占位符审阅 121 + [downstream-gen] 最终占位符审阅
115 122
116 <N=0 时打印:✅ 全部填完> 123 <N=0 时打印:✅ 全部填完>
117 <N>0 时打印:⚠️ 还有 N 处待填: 124 <N>0 时打印:⚠️ 还有 N 处待填:
@@ -142,7 +149,7 @@ docs/08 已由 A0 erp-project-init 创建(含 Plan 进度骨架)。本步骤 @@ -142,7 +149,7 @@ docs/08 已由 A0 erp-project-init 创建(含 Plan 进度骨架)。本步骤
142 - ` - [ ] docs/10 验收清单已生成` → `[x]` 149 - ` - [ ] docs/10 验收清单已生成` → `[x]`
143 - ` - [ ] 下方模块列表已填入` → `[x]` 150 - ` - [ ] 下方模块列表已填入` → `[x]`
144 - ` - [ ] REQ 卡片依赖接口已回填` → `[x]` 151 - ` - [ ] REQ 卡片依赖接口已回填` → `[x]`
145 - - `- [ ] A5 下游文档生成 — erp-downstream-gen` → `[x]` 152 + - `- [ ] A5 下游文档生成 — downstream-gen` → `[x]`
146 153
147 4. **从 `origin` 远程派生 GitLab 凭据并回填 `.env.local`** 154 4. **从 `origin` 远程派生 GitLab 凭据并回填 `.env.local`**
148 155
@@ -179,7 +186,7 @@ docs/08 已由 A0 erp-project-init 创建(含 Plan 进度骨架)。本步骤 @@ -179,7 +186,7 @@ docs/08 已由 A0 erp-project-init 创建(含 Plan 进度骨架)。本步骤
179 186
180 ``` 187 ```
181 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 188 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
182 - [erp-downstream-gen] ✅ Plan 阶段(A0~A5)全部完成 189 + [downstream-gen] ✅ Plan 阶段(A0~A5)全部完成
183 190
184 所有规划文档已就绪,docs/08 § 一 全部勾选。 191 所有规划文档已就绪,docs/08 § 一 全部勾选。
185 192
@@ -209,9 +216,9 @@ docs/08 已由 A0 erp-project-init 创建(含 Plan 进度骨架)。本步骤 @@ -209,9 +216,9 @@ docs/08 已由 A0 erp-project-init 创建(含 Plan 进度骨架)。本步骤
209 - `GITLAB_TOKEN`(必填):去 GitLab Profile → Account → Private token 生成后粘贴 216 - `GITLAB_TOKEN`(必填):去 GitLab Profile → Account → Private token 生成后粘贴
210 - `GITLAB_API_URL` / `GITLAB_PROJECT_ID`:步骤 4 已从 origin 远程自动回填(若仍显示 217 - `GITLAB_API_URL` / `GITLAB_PROJECT_ID`:步骤 4 已从 origin 远程自动回填(若仍显示
211 `TBD(A5 自动补)`,说明 origin 没配,手动填;若 scheme 错请改 http↔https) 218 `TBD(A5 自动补)`,说明 origin 没配,手动填;若 scheme 错请改 http↔https)
212 - B 阶段 erp-mr-create 用 token 通过 curl 创建 MR。 219 + B 阶段 mr-create 用 token 通过 curl 创建 MR。
213 220
214 - 5. main(或 master)就绪后,再运行 /erp-workflow:erp-coding-start 221 + 5. main(或 master)就绪后,再运行 /erp-workflow:coding-start
215 进入 B 阶段。届时 .env.local 应指向本地 MySQL(非共享远程 DB), 222 进入 B 阶段。届时 .env.local 应指向本地 MySQL(非共享远程 DB),
216 否则 B 阶段每次测试闸门都会因 setup-test-db.sh 的防护失败。 223 否则 B 阶段每次测试闸门都会因 setup-test-db.sh 的防护失败。
217 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 224 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
skills/plan/erp-downstream-gen/templates/docs-02-template.md renamed to skills/plan/downstream-gen/templates/docs-02-template.md
@@ -10,7 +10,7 @@ @@ -10,7 +10,7 @@
10 10
11 ## 二、开发顺序清单(CC 分发权威) 11 ## 二、开发顺序清单(CC 分发权威)
12 12
13 -> 本清单由 A5 `erp-downstream-gen` 一次性生成。**每行是一个 REQ**,不是模块。CC 按表格行序从上到下扫描,对每个 REQ 所属模块查 `docs/08 § 二` 的 `MR:` 字段 + GitLab API `state`:`merged` 跳过,其他(`—` / opened / closed / 查不到)选为当前模块;`erp-module-start` 会把该模块的所有 REQ 一次做完。 13 +> 本清单由 A5 `downstream-gen` 一次性生成。**每行是一个 REQ**,不是模块。CC 按表格行序从上到下扫描,对每个 REQ 所属模块查 `docs/08 § 二` 的 `MR:` 字段 + GitLab API `state`:`merged` 跳过,其他(`—` / opened / closed / 查不到)选为当前模块;`module-start` 会把该模块的所有 REQ 一次做完。
14 > 14 >
15 > **约束**:同一模块的所有 REQ 必须**连续排列**。允许打破依赖拓扑(如环依赖、业务必须先做),但必须在「备注」列写明原因。 15 > **约束**:同一模块的所有 REQ 必须**连续排列**。允许打破依赖拓扑(如环依赖、业务必须先做),但必须在「备注」列写明原因。
16 16
skills/plan/erp-downstream-gen/templates/docs-05-endpoint-template.md renamed to skills/plan/downstream-gen/templates/docs-05-endpoint-template.md
skills/plan/erp-downstream-gen/templates/docs-05-header-template.md renamed to skills/plan/downstream-gen/templates/docs-05-header-template.md
@@ -27,4 +27,4 @@ BasePath: `{{base_path}}` @@ -27,4 +27,4 @@ BasePath: `{{base_path}}`
27 {{pagination_note}} 27 {{pagination_note}}
28 28
29 ## 接口清单 29 ## 接口清单
30 -(各模块接口段落见下方,由 `erp-downstream-gen` 按 REQ 填入) 30 +(各模块接口段落见下方,由 `downstream-gen` 按 REQ 填入)
skills/plan/erp-downstream-gen/templates/docs-06-module-pagelist-template.md renamed to skills/plan/downstream-gen/templates/docs-06-module-pagelist-template.md
skills/plan/erp-downstream-gen/templates/docs-08-module-row-template.md renamed to skills/plan/downstream-gen/templates/docs-08-module-row-template.md
@@ -2,3 +2,5 @@ @@ -2,3 +2,5 @@
2 - 依赖: {{depends_on}} 2 - 依赖: {{depends_on}}
3 - 路径: {{path_scopes}} 3 - 路径: {{path_scopes}}
4 - MR: — 4 - MR: —
  5 + - 功能:
  6 +{{req_checklist}}
skills/plan/erp-downstream-gen/templates/docs-10-header-template.md renamed to skills/plan/downstream-gen/templates/docs-10-header-template.md
@@ -11,4 +11,4 @@ @@ -11,4 +11,4 @@
11 - [ ] 前端不存敏感信息到 localStorage 11 - [ ] 前端不存敏感信息到 localStorage
12 12
13 ## 模块专项 13 ## 模块专项
14 -(各模块验收段落见下方,由 `erp-downstream-gen` 按模块填入) 14 +(各模块验收段落见下方,由 `downstream-gen` 按模块填入)
skills/plan/erp-downstream-gen/templates/docs-10-module-template.md renamed to skills/plan/downstream-gen/templates/docs-10-module-template.md
skills/plan/erp-db-design-gen/SKILL.md deleted
1 ----  
2 -name: erp-db-design-gen  
3 -description: A4 DB 设计生成 + REQ 回填——用 mysql CLI 反查 schema 生成 docs/03-数据库设计文档.md;然后用 Grep 在 docs/01-需求清单/*.md 定位 TBD(A4 自动补) 替换为实际表/字段引用。  
4 -user-invocable: false  
5 -allowed-tools: Read Write Edit Grep Glob Skill Bash(mysql *) Bash(set *) Bash(. .env.local)  
6 ----  
7 -  
8 -**所有输出必须使用中文。**  
9 -  
10 -# erp-db-design-gen  
11 -  
12 -## 前置条件  
13 -  
14 -- `erp-db-init` 已完成:`.env.local` 凭据已填,`sql/migrations/V1__initial_schema.sql` 和 `sql/seed-data.sql` 都已生成。  
15 -- `erp-scope-lock` 已完成:`docs/01-需求清单/<module>-*.md` REQ 卡片存在,含 `TBD(A4 自动补)` 占位。  
16 -  
17 -## 执行步骤  
18 -  
19 -### 步骤 0:打印当前位置流程图  
20 -  
21 -向用户展示当前在 A 阶段流程中的位置(A-only,`▶` 标在 A4):  
22 -  
23 -```  
24 -┌──────────────────────────────────────────────────────┐  
25 -│ 📋 阶段 A:规划(一次性) │  
26 -│ │  
27 -│ A0 初始化项目 → A1 锁范围(REQ 卡片) │  
28 -│ ↓ │  
29 -│ ⏸ 等你审阅 REQ,重新运行 /erp-plan-start 继续 │  
30 -│ ↓ │  
31 -│ A2 生成骨架 → A3 初始化 DB → ▶ A4 生成 DB 设计 → A5 生成下游文档│  
32 -│ ↓ │  
33 -│ 规划阶段到此结束 │  
34 -└──────────────────────────────────────────────────────┘  
35 -```  
36 -  
37 -### A. 查询实时 schema  
38 -  
39 -用 `Bash` 加载 `.env.local` 后查询(用 `set -a; . ...; set +a` 替代 `source`,避免密码中的 shell 特殊字符被展开):  
40 -  
41 -```bash  
42 -set -a; . .env.local; set +a  
43 -MYSQL_CMD="mysql -h${DB_HOST} -P${DB_PORT} -u${DB_USER} -p${DB_PASSWORD} -N -B"  
44 -  
45 -# 表列表 + 注释  
46 -$MYSQL_CMD -e "SELECT table_name, table_comment FROM information_schema.tables WHERE table_schema='${DB_SCHEMA}' AND table_type='BASE TABLE' ORDER BY table_name;"  
47 -  
48 -# 字段详情  
49 -$MYSQL_CMD -e "SELECT table_name, column_name, column_type, is_nullable, column_default, column_comment FROM information_schema.columns WHERE table_schema='${DB_SCHEMA}' ORDER BY table_name, ordinal_position;"  
50 -  
51 -# 外键  
52 -$MYSQL_CMD -e "SELECT table_name, column_name, referenced_table_name, referenced_column_name FROM information_schema.key_column_usage WHERE table_schema='${DB_SCHEMA}' AND referenced_table_name IS NOT NULL;"  
53 -  
54 -# 索引  
55 -$MYSQL_CMD -e "SELECT table_name, index_name, GROUP_CONCAT(column_name ORDER BY seq_in_index) AS cols, non_unique FROM information_schema.statistics WHERE table_schema='${DB_SCHEMA}' GROUP BY table_name, index_name, non_unique;"  
56 -```  
57 -  
58 -在内存中将结果解析为结构化列表,**只保留表名、字段名与关键元信息,不把查询结果完整写入会话上下文**。  
59 -  
60 -### B. 生成 docs/03  
61 -  
62 -1. 用 `Read` 读取 `${CLAUDE_SKILL_DIR}/templates/docs-03-header-template.md`,填充 `schema_name`、`er_overview`、`tables[]`。  
63 -2. 对每张表,用 `Read` 读取 `${CLAUDE_SKILL_DIR}/templates/docs-03-table-template.md`,填充并追加。  
64 -3. 每个字段的业务含义:  
65 - - 如果 `column_comment` 非空,直接用  
66 - - 否则从 A1 生成的 REQ 卡片上下文推断  
67 -4. 用 `Write` 写入 `docs/03-数据库设计文档.md`。  
68 -  
69 -### C. 回填 REQ 卡片的 TBD 字段  
70 -  
71 -1. 用 `Glob` 列出 `docs/01-需求清单/*.md`(排除 `README.md`)。  
72 -2. 用 `Grep` 在这些文件中搜索 `TBD(A4 自动补)` 的**行号**(不读全文)。  
73 -3. 对每个命中的 REQ:  
74 - - 用 `Read` 仅读取该 REQ 卡片所在的片段(REQ 标题行前后 20 行)  
75 - - 根据 `goal` / `input` / `output` 推断引用的表  
76 - - 用 `Edit`:`依赖表: TBD(A4 自动补)` → `依赖表: <table1>, <table2>`(具体表名)  
77 - - **不动** `依赖接口: TBD(A5 自动补)`——那行由 A5 `erp-downstream-gen` 生成 docs/05 后回填  
78 -4. 打印回填统计:`A4 回填 N 处 schema_refs`。  
79 -  
80 -### D. 一致性检查  
81 -  
82 -1. 用 `Grep` 在 `docs/01-需求清单/*.md` 搜索 `依赖表:`,抽取所有表名。  
83 -2. 用 `Grep` 在 `docs/03-数据库设计文档.md` 搜索表标题(每张表一行 `### table_name`)。  
84 -3. 比对:  
85 - - REQ 提到但 docs/03 没有的表 → 报错停下(schema 与需求不一致;请确认是 REQ 理解错误还是需要新增 migration)  
86 - - docs/03 有但没 REQ 引用 → 警告但不停下(可能是未使用表)  
87 -4. 用 `Grep` 在 `docs/01-需求清单/*.md` 中搜索 `TBD(A4 自动补)`:应 0 命中(A4 已把所有 schema_refs 回填完);若仍有,打印残留 REQ 清单并停下。  
88 -  
89 -### E. 勾选 docs/08 进度 + 进入 A5  
90 -  
91 -用 `Edit` 在 `docs/08-模块任务管理.md` 勾选 4 个 checkbox(A4 的 3 个子项 + A4 父项):  
92 -- ` - [ ] docs/03 数据库设计已生成` → `[x]`  
93 -- ` - [ ] REQ 卡片依赖表已回填` → `[x]`  
94 -- ` - [ ] schema 一致性检查通过` → `[x]`  
95 -- `- [ ] A4 DB 设计 + REQ 回填 — erp-db-design-gen` → `[x]`  
96 -  
97 -输出 `db-design-gen: 完成(<T> 张表, <R> 个 REQ 已回填依赖表;依赖接口留给 A5)`。  
98 -  
99 -立即调用 `Skill(erp-downstream-gen)` 进入 A5,不等用户手动输入。  
100 -  
101 -## 不变量  
102 -  
103 -- REQ 卡片的 `依赖接口` 字段不在此处填充,留给 A5 的 `erp-downstream-gen` 先生成 docs/05 API 契约后按 `TBD(A5 自动补)` 回填。  
104 -  
105 -## 参考  
106 -  
107 -- `${CLAUDE_SKILL_DIR}/templates/docs-03-header-template.md`  
108 -- `${CLAUDE_SKILL_DIR}/templates/docs-03-table-template.md`  
109 -- `.env.local`(DB 凭据)  
110 -- `docs/01-需求清单/*.md`(回填目标)  
skills/plan/erp-db-init/SKILL.md deleted
1 ----  
2 -name: erp-db-init  
3 -description: A3 验证 MySQL 连接 + 导出当前 schema 为 `sql/migrations/V1__initial_schema.sql`(Flyway 初始 migration,DDL only)+ 导出当前数据为 `sql/seed-data.sql`(INSERT only)。不执行任何 DDL。  
4 -user-invocable: false  
5 -allowed-tools: Read Write Edit Glob Skill Bash(mkdir *) Bash(mysql *) Bash(mysqldump *) Bash(set *) Bash(. .env.local) Bash(sed *) Bash(cat *) Bash(rm sql/migrations/*.raw) Bash(rm sql/*.raw) Bash(grep *)  
6 ----  
7 -  
8 -**所有输出必须使用中文。**  
9 -  
10 -# erp-db-init  
11 -  
12 -## 执行步骤  
13 -  
14 -### 步骤 0:打印当前位置流程图  
15 -  
16 -向用户展示当前在 A 阶段流程中的位置(A-only,`▶` 标在 A3):  
17 -  
18 -```  
19 -┌──────────────────────────────────────────────────────┐  
20 -│ 📋 阶段 A:规划(一次性) │  
21 -│ │  
22 -│ A0 初始化项目 → A1 锁范围(REQ 卡片) │  
23 -│ ↓ │  
24 -│ ⏸ 等你审阅 REQ,重新运行 /erp-plan-start 继续 │  
25 -│ ↓ │  
26 -│ A2 生成骨架 → ▶ A3 初始化 DB → A4 生成 DB 设计 → A5 生成下游文档│  
27 -│ ↓ │  
28 -│ 规划阶段到此结束 │  
29 -└──────────────────────────────────────────────────────┘  
30 -```  
31 -  
32 -### A. 防御性检查 .env.local  
33 -  
34 -用 `Glob` 检查 `.env.local` 是否存在。  
35 -  
36 -- **存在** → 进入步骤 B。  
37 -- **不存在** → 向用户输出:  
38 -  
39 - ```  
40 - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━  
41 - [erp-db-init] ⚠️ .env.local 缺失  
42 -  
43 - 可能是被误删。请先重新运行 erp-skeleton-gen 重建,  
44 - 或手动从 .env.local.example 复制并填写 DB_HOST / DB_PORT / DB_USER / DB_PASSWORD / DB_SCHEMA。  
45 - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━  
46 - ```  
47 -  
48 -### B. 验证 MySQL 连接  
49 -  
50 -用 `Bash` 执行(先加载 `.env.local` 变量,用 `set -a; . ...; set +a` 避免 shell 展开密码中的特殊字符):  
51 -  
52 -```bash  
53 -set -a; . .env.local; set +a  
54 -mysql -h"$DB_HOST" -P"$DB_PORT" -u"$DB_USER" -p"$DB_PASSWORD" -e "USE \`$DB_SCHEMA\`; SHOW TABLES;"  
55 -```  
56 -  
57 -> 注:密码中含 `$`、`` ` ``、空格、`!` 等字符时,`.env.local` 需用单引号包裹值,例如 `DB_PASSWORD='p@ss$w0rd!'`。`set -a; . file; set +a` 与 `source` 行为一致但更明确地声明"按 KEY=VALUE 加载并导出",配合单引号可避免展开。  
58 -  
59 -- **成功** → 记录表列表,继续步骤 C。  
60 -- **失败** → 向用户输出具体错误(认证失败 / schema 不存在 / 主机不可达等),提示检查 `.env.local`,**停下**。  
61 -  
62 -### C. 导出当前 schema 为 V1 initial migration  
63 -  
64 -用 `Bash` 执行 mysqldump(**仅 DDL,不含数据**):  
65 -  
66 -```bash  
67 -mkdir -p sql/migrations  
68 -set -a; . .env.local; set +a  
69 -mysqldump --no-data --skip-comments -h"$DB_HOST" -P"$DB_PORT" -u"$DB_USER" -p"$DB_PASSWORD" "$DB_SCHEMA" > sql/migrations/V1__initial_schema.sql.raw  
70 -```  
71 -  
72 -如果 `mysqldump` 命令不存在,向用户输出具体错误(提示安装 `mysql-client` / `brew install mysql-client` 等)并**停下**(mysql 和 mysqldump 是 A0 `erp-project-init` 的前置依赖,正常情况下应已就绪)。  
73 -  
74 -### D. 加头部写入 V1 最终 migration 文件  
75 -  
76 -**严禁**用 `Read` 读取 `.sql.raw`(dump 可能有几千行,会撑爆上下文)。用纯 shell 拼接:  
77 -  
78 -```bash  
79 -PROJECT="<从 CLAUDE.md 读到的项目名称>"  
80 -TS="$(date -u +%FT%TZ)"  
81 -set -a; . .env.local; set +a  
82 -{  
83 - sed -e "s|{{project_name}}|$PROJECT|g" \  
84 - -e "s|{{timestamp}}|$TS|g" \  
85 - -e "s|{{schema_name}}|$DB_SCHEMA|g" \  
86 - "${CLAUDE_SKILL_DIR}/templates/migration-v1-header-template.sql"  
87 - cat sql/migrations/V1__initial_schema.sql.raw  
88 -} > sql/migrations/V1__initial_schema.sql  
89 -rm sql/migrations/V1__initial_schema.sql.raw  
90 -```  
91 -  
92 -说明:  
93 -- `sed` 替换 header 模板里的 3 个槽位  
94 -- `cat` 追加 dump 内容  
95 -- 全程不经过 LLM 上下文  
96 -  
97 -### E. 导出当前数据为 seed-data.sql  
98 -  
99 -用 `Bash` 执行 mysqldump(**仅数据,INSERT only**):  
100 -  
101 -```bash  
102 -set -a; . .env.local; set +a  
103 -mysqldump --no-create-info --complete-insert --skip-comments --skip-extended-insert \  
104 - -h"$DB_HOST" -P"$DB_PORT" -u"$DB_USER" -p"$DB_PASSWORD" "$DB_SCHEMA" > sql/seed-data.sql.raw  
105 -```  
106 -  
107 -拼接 header 模板 + raw:  
108 -  
109 -```bash  
110 -PROJECT="<从 CLAUDE.md 读到的项目名称>"  
111 -TS="$(date -u +%FT%TZ)"  
112 -set -a; . .env.local; set +a  
113 -{  
114 - sed -e "s|{{project_name}}|$PROJECT|g" \  
115 - -e "s|{{timestamp}}|$TS|g" \  
116 - -e "s|{{schema_name}}|$DB_SCHEMA|g" \  
117 - "${CLAUDE_SKILL_DIR}/templates/seed-data-sql-template.sql"  
118 - echo ""  
119 - echo "SET FOREIGN_KEY_CHECKS = 0;"  
120 - echo ""  
121 - cat sql/seed-data.sql.raw  
122 - echo ""  
123 - echo "SET FOREIGN_KEY_CHECKS = 1;"  
124 -} > sql/seed-data.sql  
125 -rm sql/seed-data.sql.raw  
126 -```  
127 -  
128 -说明:  
129 -- 本地 MySQL 里已有的数据就是测试数据集,直接 dump 下来  
130 -- `--complete-insert` 让 INSERT 含列名,schema 演化后仍可读  
131 -- `--skip-extended-insert` 让每行一条 INSERT,diff 友好  
132 -- 全程不经过 LLM 上下文  
133 -  
134 -### F. 验证 + 勾选 docs/08 进度 + 进入 A4  
135 -  
136 -1. 用 `Bash` 执行 `grep -c "CREATE TABLE" sql/migrations/V1__initial_schema.sql` 统计表数量,与步骤 B 记录的表数对比。不一致 → 报错停下。  
137 -  
138 -2. 用 `Bash` 执行 `grep -c "INSERT INTO" sql/seed-data.sql` 统计数据行数:  
139 - - > 0:正常  
140 - - = 0:提示"本地 DB 无数据,seed-data.sql 为空(只有 header 注释);如需测试数据,请在本地 MySQL 插入后重新运行 A3",允许继续  
141 -  
142 -3. 用 `Edit` 在 `docs/08-模块任务管理.md` 勾选 5 个 checkbox(A3 的 4 个子项 + A3 父项):  
143 - - ` - [ ] .env.local 凭据验证通过` → `[x]`  
144 - - ` - [ ] MySQL 连接验证通过` → `[x]`  
145 - - ` - [ ] V1 initial migration 已生成(sql/migrations/V1__initial_schema.sql,DDL only)` → `[x]`  
146 - - ` - [ ] sql/seed-data.sql 已导出(本地数据快照,INSERT only)` → `[x]`  
147 - - `- [ ] A3 DB 初始化 — erp-db-init` → `[x]`  
148 -  
149 -4. 输出 `db-init: 完成(schema=<名称>, tables=<T>, V1 migration ✓, seed rows=<R>)`。  
150 -  
151 -5. 立即调用 `Skill(erp-db-design-gen)` 进入 A4,不等用户手动输入。  
152 -  
153 -## 不变量  
154 -  
155 -- 密码通过 `.env.local` 以 `set -a; . .env.local; set +a` 方式导出到环境变量,不硬编码在命令里;特殊字符需用单引号包裹。  
156 -- 本 skill **只** 产生 V1 initial migration 和 seed-data.sql 快照;后续 V2/V3 及业务数据变化由 B 阶段 `erp-feature-tdd` 在 REQ 实现时写入。  
157 -  
158 -## 参考  
159 -  
160 -- `${CLAUDE_SKILL_DIR}/templates/migration-v1-header-template.sql`  
161 -- `${CLAUDE_SKILL_DIR}/templates/seed-data-sql-template.sql`  
162 -- 产物 1:`sql/migrations/V1__initial_schema.sql`(由 Flyway 在 Spring Boot 启动时自动 apply)  
163 -- 产物 2:`sql/seed-data.sql`(由开发者选一种方式装载:@Sql / R__seed / data.sql)  
skills/plan/erp-db-init/templates/seed-data-sql-template.sql deleted
1 --- sql/seed-data.sql — 初始测试数据(INSERT only,无 DDL)  
2 --- Project: {{project_name}}  
3 --- Generated: {{timestamp}}  
4 --- Source: mysqldump --no-create-info --complete-insert {{schema_name}}  
5 --- 由 A3 erp-db-init 从本地 MySQL 导出;本地即是测试数据集。  
6 --- 装载方式由开发者选:  
7 --- (a) Spring Boot 测试基类 @Sql(scripts = "file:sql/seed-data.sql")  
8 --- (b) 改名 R__seed_data.sql 放到 sql/migrations/(Flyway repeatable)  
9 --- (c) classpath:data.sql(Spring Boot 启动自动应用)  
10 --- ==========================================================  
skills/plan/erp-project-init/templates/CLAUDE-template.md deleted
1 -# CLAUDE.md — ERP项目 Claude Code 主指令文件  
2 -  
3 -> 本文件是 Claude Code 的"操作手册"。Claude Code 启动时会自动读取此文件。  
4 -  
5 ----  
6 -  
7 -## 🎯 项目概述  
8 -  
9 -- **项目名称**: 【人工填写:公司 + 项目名,例如"XX 公司 ERP 管理系统"】  
10 -- **项目简述**: 【人工填写:一句话描述项目目标,例如"面向中小制造企业的全流程 ERP,涵盖采购/库存/生产/销售/财务"】  
11 -- **目标用户**: 【人工填写:谁会用,例如"企业内部管理人员(采购员、仓管员、生产主管、销售员、财务人员、管理层)"】  
12 -- **部署方式**: 【人工填写:私有化部署 / 云部署 / Docker 容器化 等】  
13 -  
14 ----  
15 -  
16 -## ✅ 模块完成判定规则  
17 -  
18 -`docs/08-模块任务管理.md § 二` 是**模块元数据表**——每个模块一行 bullet,记录依赖 / 路径 / MR iid。**模块完成由 `MR:` 字段 + `GitLab API state=merged` 判定**。  
19 -  
20 -### 规则定义  
21 -  
22 -每个模块在 docs/08 § 二 中长这样:  
23 -  
24 -```markdown  
25 -- module_0 系统管理  
26 - - 依赖: —  
27 - - 路径: backend/module/sys/, frontend/pages/sys/  
28 - - MR: —  
29 -```  
30 -  
31 -`MR:` 字段由 `erp-mr-create` 在创建 MR 时从 `—` 改为 `!<iid>`。  
32 -  
33 -### 模块状态语义  
34 -  
35 -| `MR:` 字段 | `GitLab API state` | 含义 | 你(Claude Code)的行为 |  
36 -|---|---|---|---|  
37 -| `—` | — | 模块未开始(未创建 MR) | ✅ 开始本模块开发 |  
38 -| `!<iid>` | `opened` / `closed` | 模块开发中 / 打回 | ✅ 继续推进该模块 |  
39 -| `!<iid>` | `merged` | 模块**已完成** | 🟢 进入下一未完成模块 |  
40 -  
41 -### 工作流规则  
42 -  
43 -- **开发顺序权威在 `docs/02-开发计划.md § 二 开发顺序清单`**,不是 `docs/08 § 二` 的物理行序  
44 -- **下一个要做的模块** = `docs/02 § 二` 清单中**第一个所属模块 MR 状态非 merged 的 REQ** 的 `module_id`(由 `erp-coding-start` 步骤 3 扫描 `docs/08` 的 `MR:` 字段 + GitLab API state 判定)  
45 -- `docs/02 § 二` 清单由 A5 `erp-downstream-gen` 生成阶段一次性确定(会交互询问业务偏好),之后通常不改;若开发中途需要调整顺序,重新触发 A5 生成阶段而非直接编辑文件  
46 -- **已完成模块**(`MR: !<iid>` + `GitLab API state=merged`):**默认不改**(不是禁止,是已交付无需改)  
47 -- 如果在当前模块开发中发现某个**已完成模块**(MR merged)有 bug:  
48 - - **不停下当前工作**,按软规则 S2 直接修复该模块代码;hook `log-cross-module.sh` 会自动留痕,调用 `erp-cross-module-log` 补「原因 / 影响评估」  
49 - - 修复随当前模块 MR 一起合并——不需要改 `docs/08`(模块已是 merged 状态,本插件不会标记重开;修复是以"当前模块依赖他的代码"的方式进入)  
50 - - 在当前模块的《模块完成报告》第 ⑦ 节「跨模块改动」明确记录:哪个模块、哪个文件、什么问题、修复范围、影响评估  
51 -  
52 -### 模块完成流程  
53 -  
54 -```  
55 -1. 对每个 REQ 跑完整功能循环:  
56 - brainstorm → plan → TDD(红绿循环,每步 commit)→ verify(子会话执行 REQ 级测试)→ 自审  
57 -2. 所有 REQ 完成后,erp-local-test-gate 派子会话按顺序跑:  
58 - a. schema 一致性检查(erp-local-test-gate 步骤 1 内联,schema 未漂移)+ 占位符扫描  
59 - b. scripts/test.sh 全套:build → lint → **unit + integration(全量重新运行当前模块所有  
60 - REQ 的功能测试 + 所有已完成模块的回归测试)** → e2e  
61 - 任一失败停下修复再来  
62 -3. 测试全绿 → erp-module-report 输出《模块完成报告》  
63 -4. 自动 git push(.githooks/pre-push 会再执行一遍 scripts/test.sh 作为硬闸门)  
64 - + 通过 GitLab API (curl) 创建 MR,报告嵌入 MR 描述  
65 -5. 人工 review MR → Approve + Merge(人工动作,唯一人工介入点)  
66 -6. 下次用户运行 `/erp-workflow:erp-coding-start` 时,入口自动检测到本模块 `GitLab API state=merged`,探测默认分支(main / master)后 `git checkout <默认分支> && git pull --ff-only` 同步远程 → 扫描下一模块并派发  
67 -7. 你**不需要**手工 Edit docs/08(模块元数据不变;下次 coding-start 自动扫描 MR state 判定是否完成)  
68 -```  
69 -  
70 -> 两道测试闸门:功能级(`erp-feature-tdd` + `erp-feature-verify`,每 REQ 一遍)+ 模块级(`erp-local-test-gate` + pre-push hook,每模块一遍)。所有测试/验证都派发到子会话执行,主会话只接收结构化结论。  
71 -  
72 -### 模块完成报告  
73 -  
74 -由 `erp-module-report` skill 产出,模板位于 由 erp-module-report skill 持有(12 节标准化,含跨模块改动等 CLAUDE.md 软规则映射节)。CC 不手写模块报告,仅填模板。  
75 -  
76 ----  
77 -  
78 -## 🏷️ 占位符统一约定(`【人工填写:...】`)  
79 -  
80 -所有"只有人工能决定"的位置(密钥 / 账密 / 包名 / 命名约定 / 小版本号 等)一律使用以下纯文本标记:  
81 -  
82 -```  
83 -【人工填写:<简短说明>】  
84 -```  
85 -  
86 -### CC 行为规则  
87 -  
88 -- **生成文档 / 模板时**:凡是项目专属值、敏感值、技术栈小版本号一律用此标记,不要自行编造  
89 -- **不要用 HTML 注释**(`<!-- ... -->`),因为后者在 Obsidian 渲染视图被隐藏,开发者会漏填  
90 -- **必须带简短说明**:例如 `【人工填写:JWT 签名密钥,256+ bit 随机串】`,而不是空 `【人工填写】`  
91 -- **项目专属标识**(Java 根包名 / C# 命名空间 / Python 顶层模块等)只在 `docs/07-环境配置.md` 引入一次占位,其他文件**复用**已有的占位,不重复创建  
92 -  
93 ----  
94 -  
95 -## 🔄 开发流程(模块循环 + 功能循环)  
96 -  
97 -两层嵌套循环的详细步骤**全部固化到 skills**,CLAUDE.md 不展开。入口调 `/erp-workflow:erp-coding-start`,自动分发:  
98 -  
99 -- **模块循环(外层,Layer 2)** → `erp-module-start` → `erp-local-test-gate`(commit test-gate.md)→ `erp-module-report`(commit 模块报告 + cross-module log)→ `erp-mr-create`(worktree clean 校验 → push → 创建 MR → 追加 MR URL 到报告并 commit → 写 `MR: !<iid>` 到 docs/08 并 commit → 再次 push)→ 人工 Approve+Merge → 下次运行 `/erp-workflow:erp-coding-start` 扫描到本模块 GitLab API `state=merged` → 探测默认分支并 `git pull --ff-only` → 推进下一模块  
100 -- **功能循环(内层,Layer 3,每个 REQ-XXX-NNN 走一遍)** → `erp-feature-brainstorm` → `erp-feature-plan` → `erp-feature-tdd` → `erp-feature-verify` → `erp-feature-review`  
101 -  
102 -**本地测试闸门**: `erp-local-test-gate` 是 MR 前的唯一硬闸门,子会话执行 `scripts/test.sh`:脚本先由 `setup-test-db.sh` 清空库 → build / lint → 执行测试(Spring Boot 启动时 Flyway 自动 apply `sql/migrations/V*.sql`)→ e2e → 再次清库。详见 § 🧪 自测要求。`.githooks/pre-push` 在 push 时会再次执行 `scripts/test.sh` 作为兜底;`git push --no-verify` 被 hook `deny-no-verify.sh` 硬拦截。本项目不配置 GitLab CI/CD。  
103 -  
104 -> 占位符扫描 / schema 一致性校验都不在此闸门:前者在 A 阶段 skill 生成期完成;schema 演化通过 Flyway migration 保证一致(每次测试启动,Spring Boot 的 Flyway 从空库按序 apply V1~Vn,不存在"漂移"概念)。hook 产生的 `TBD(CC 补)` 存根由 CC 自主调 `erp-cross-module-log` 补齐,并在 `erp-module-report` § ⑦ 硬验收(非人工填写)。  
105 -  
106 ----  
107 -  
108 -## 📐 编码行为约束  
109 -  
110 -### 你必须做的 ✅  
111 -  
112 -1. **严格遵循** `docs/04-技术规范.md` 中的命名和编码规范  
113 -2. **严格遵循** `docs/09-项目目录结构.md` 中的目录规范,文件放对位置  
114 -3. **每个后端接口** 必须先在 `docs/05-API接口契约.md` 中定义,再编码实现  
115 -4. **每个功能** 必须可追溯到 `docs/01-需求清单.md` 中的需求编号  
116 -5. **代码注释** 必须包含对应的需求编号,如 `// REQ-001: 用户登录`  
117 -6. **数据库 schema 走 migration**:所有业务 schema 改动(CREATE/ALTER/DROP TABLE/INDEX/VIEW)必须写成 `sql/migrations/V_n__<snake_case_desc>.sql` 文件,由 Flyway 顺序 apply;**禁止**在主会话直接 `mysql -e` 跑业务 DDL(只读查询 / 临时本地调试探索除外)。详见 § Schema 演化规约  
118 -7. **提交代码前** 确保无编译错误、无明显运行时错误  
119 -8. **每个Controller方法** 必须有统一的响应格式包装  
120 -9. **异常处理** 使用全局异常处理器,不在业务代码中catch后吞掉异常  
121 -10. **分页查询** 统一使用 MyBatis-Plus 的 Page 对象  
122 -  
123 -### 你禁止做的 🚫  
124 -  
125 -1. **默认禁止** 修改"非当前模块"(其他 REQ 所属模块)的代码;确为实现当前模块所必需时,按软规则 S2 执行(留痕 + 模块报告单列说明)  
126 -2. **禁止** 引入`docs/04-技术规范.md` 技术栈表以外的框架或中间件(如需要必须先报告)  
127 -3. **禁止** 硬编码配置(数据库连接、端口号等必须放在配置文件中)  
128 -4. **禁止** 在前端直接写SQL或直接操作数据库  
129 -5. **禁止** 跳过模块开发(必须按顺序)  
130 -6. **禁止** 删除或覆盖他人代码(如有冲突必须报告)  
131 -7. **禁止** 使用 `SELECT *`,必须显式列出需要的字段  
132 -8. **禁止** 在循环中执行数据库查询(N+1问题)  
133 -9. **禁止** 前端存储敏感信息到 localStorage  
134 -10. **禁止** 返回后端异常堆栈给前端  
135 -  
136 -### Schema 演化规约(Flyway migration)  
137 -  
138 -1. **文件命名**:`sql/migrations/V<n>__<snake_case_desc>.sql`,例:`V5__add_user_email_unique_index.sql`  
139 -2. **版本号分配**:建文件前 `ls sql/migrations/V*.sql` 查当前最大 n,新文件 `n_max + 1`  
140 -3. **Apply 方式**:Spring Boot 启动 / 测试启动时 Flyway 自动 apply(项目必须在 `pom.xml` 声明 `flyway-core` + `flyway-mysql` 依赖)。`scripts/setup-test-db.sh` 只负责清空库,不做 apply  
141 -4. **已合并的 migration 永不修改**:发现错了写一个补救 migration(如 `V7__fix_V5_index_name.sql`),绝不编辑 git 历史里的旧 `V_n.sql`  
142 -5. **临时调试 DDL ≠ 业务 DDL**:临时在本地试字段/索引可手动 `mysql -e`,但不写 migration;下次 `setup-test-db.sh` 会 drop+create 清掉  
143 -6. **A3 生成的 V1**:`V1__initial_schema.sql` 是 A 阶段由 `erp-db-init` 从人工初始化的 schema 导出的初始版本;后续 V2/V3/... 由 B 阶段每个 REQ 按需写入  
144 -  
145 ----  
146 -  
147 -## 🔄 统一响应格式  
148 -  
149 -所有后端接口必须返回以下格式:  
150 -  
151 -```json  
152 -{  
153 - "code": 200,  
154 - "message": "操作成功",  
155 - "data": {},  
156 - "timestamp": 1700000000000  
157 -}  
158 -```  
159 -  
160 -错误响应:  
161 -  
162 -```json  
163 -{  
164 - "code": 40001,  
165 - "message": "用户名或密码错误",  
166 - "data": null,  
167 - "timestamp": 1700000000000  
168 -}  
169 -```  
170 -  
171 -错误码规范:  
172 -  
173 -| 错误码范围 | 含义 |  
174 -|-----------|------|  
175 -| 200 | 成功 |  
176 -| 400xx | 客户端参数错误 |  
177 -| 401xx | 认证/授权错误 |  
178 -| 403xx | 权限不足 |  
179 -| 404xx | 资源不存在 |  
180 -| 500xx | 服务端内部错误 |  
181 -  
182 ----  
183 -  
184 -## 🗂️ Git 提交规范  
185 -  
186 -每次提交必须遵循以下格式:  
187 -  
188 -```  
189 -<type>(<scope>): <subject>  
190 -  
191 -type: feat|fix|refactor|docs|style|test|chore  
192 -scope: 模块名,如 user, inventory, order  
193 -subject: 简短描述,中文可  
194 -  
195 -示例:  
196 -feat(user): 实现用户登录接口 REQ-001  
197 -fix(order): 修复订单金额计算精度问题  
198 -refactor(common): 统一响应格式包装  
199 -```  
200 -  
201 ----  
202 -  
203 -## 🧪 自测要求  
204 -  
205 -- 所有测试与验证(`scripts/test.sh` / `mvn test` / `pnpm test` / DB 测试集 diff 等)**一律派发到全新子会话 via `Agent` 执行**,主会话只接收结构化结论(命令 / 退出码 / 通过数 / 失败项 / 关键 stdout ≤30 行)。不在主会话直接执行测试。  
206 -- 由 `erp-feature-verify`(功能级)+ `erp-local-test-gate`(模块级)两道 skill 统一承接。前者每个 REQ 执行一次,后者模块闸门执行一次。  
207 -- 声称"完成"前必须贴出子会话返回的 evidence(模板:由 erp-feature-verify skill 持有)。  
208 -  
209 ----  
210 -  
211 -## 🚩 静默执行红旗清单(中断机制)  
212 -  
213 -功能循环(每个功能 REQ-XXX 的 Brainstorm → Plan → TDD → Verify → AI 自审)默认 **静默跑不打扰人**,但命中以下任何一条必须**立刻停下、记录原因、等人决策**,不得自行绕过:  
214 -  
215 -| # | 红旗 | 例子 |  
216 -| - | --- | --- |  
217 -| 1 | **测试反复失败** | 同一测试同一功能内连续 **10 次**修复失败 |  
218 -| 2 | **要改密钥 / 账密 / 包名** | `docs/07-环境配置.md` 里由人工标注必须填的字段 |  
219 -| 3 | **外部接口不可达** | 第三方 API 无法连接、证书失效等环境问题 |  
220 -  
221 -> 其余需要人类判断的场景(需求歧义 / schema 缺口 / 技术栈外组件引入)一律走普通 `AskUserQuestion` Q&A,不升格为红旗、不写 Blocker 文件。见下方「📘 技术栈外组件的处理规则」与各 feature-* skill 的 Q&A 流程。  
222 -  
223 -**命中红旗时的固定动作:**  
224 -  
225 -1. 在当前功能的 plan 文件里追加一节 `## 🚩 Blocker`,描述红旗编号、现象、初步判断  
226 -2. 停止后续所有功能的静默执行  
227 -3. 在主会话输出一句话摘要 + 指向 blocker 文件的路径,等人回复  
228 -  
229 -**报告格式:**  
230 -  
231 -```markdown  
232 -## ⚠️ 需要人工决策  
233 -  
234 -**红旗编号**: [1–3 中的某一条]  
235 -**问题描述**: [详细描述]  
236 -**影响范围**: [影响哪些模块 / 功能]  
237 -**我的建议**: [初步判断,可选]  
238 -**等待决策**: [需要人工做什么决定]  
239 -```  
240 -  
241 ----  
242 -  
243 -## 📘 技术栈外组件的处理规则  
244 -  
245 -brainstorm / plan 阶段若发现需要 `docs/04-技术规范.md § 零` 技术栈表之外的框架、中间件或关键库:  
246 -  
247 -1. 用 `AskUserQuestion` 询问用户(选项至少含:接受引入 / 换方案 / 拒绝)  
248 -2. **接受** → 同会话直接在 `docs/04 § 零` 追加一行 → 继续流程  
249 -3. **换方案 / 拒绝** → 视为常规歧义澄清,继续 Q&A 收敛  
250 -  
251 -不写 Blocker 文件,不中断流程。  
252 -  
253 ----  
254 -  
255 -## 🟡 软规则(允许继续,但有强制后续动作)  
256 -  
257 -以下情况 **不触发中断**,CC 可自行继续推进,但必须在约定位置留痕,模块完成时统一审计。漏留痕 = 红旗。  
258 -  
259 -| # | 软规则 | 允许动作 | 强制后续 |  
260 -| - | ----- | ------- | ------- |  
261 -| S2 | **跨模块改动**(动到非当前模块的代码——无论该模块是否已 MR merged) | 允许修改,但范围受限:仅为当前模块实现所必需 | ① 当次修改立即追加到 `docs/superpowers/module-reports/<current>-cross-module.md`(含文件路径、改动原因、对目标模块功能/API 的影响评估)② 《模块完成报告》必须单列「跨模块改动」节完整贴入 ③ 漏留痕或未评估影响 → 升级为红旗 |  
262 -  
263 ----  
264 -  
265 -## 🧭 通用工作准则(General Principles)  
266 -  
267 -### 1. Think Before Coding  
268 -  
269 -**Don't assume. Don't hide confusion. Surface tradeoffs.**  
270 -  
271 -Before implementing:  
272 -- State your assumptions explicitly. If uncertain, ask.  
273 -- If multiple interpretations exist, present them - don't pick silently.  
274 -- If a simpler approach exists, say so. Push back when warranted.  
275 -- If something is unclear, stop. Name what's confusing. Ask.  
276 -  
277 -### 2. Simplicity First  
278 -  
279 -**Minimum code that solves the problem. Nothing speculative.**  
280 -  
281 -- No features beyond what was asked.  
282 -- No abstractions for single-use code.  
283 -- No "flexibility" or "configurability" that wasn't requested.  
284 -- No error handling for impossible scenarios.  
285 -- If you write 200 lines and it could be 50, rewrite it.  
286 -  
287 -Ask yourself: "Would a senior engineer say this is overcomplicated?" If yes, simplify.  
288 -  
289 -### 3. Surgical Changes  
290 -  
291 -**Touch only what you must. Clean up only your own mess.**  
292 -  
293 -When editing existing code:  
294 -- Don't "improve" adjacent code, comments, or formatting.  
295 -- Don't refactor things that aren't broken.  
296 -- Match existing style, even if you'd do it differently.  
297 -- If you notice unrelated dead code, mention it - don't delete it.  
298 -  
299 -When your changes create orphans:  
300 -- Remove imports/variables/functions that YOUR changes made unused.  
301 -- Don't remove pre-existing dead code unless asked.  
302 -  
303 -The test: Every changed line should trace directly to the user's request.  
304 -  
305 -### 4. Goal-Driven Execution  
306 -  
307 -**Define success criteria. Loop until verified.**  
308 -  
309 -Transform tasks into verifiable goals:  
310 -- "Add validation" → "Write tests for invalid inputs, then make them pass"  
311 -- "Fix the bug" → "Write a test that reproduces it, then make it pass"  
312 -- "Refactor X" → "Ensure tests pass before and after"  
313 -  
314 -For multi-step tasks, state a brief plan:  
315 -```  
316 -1. [Step] → verify: [check]  
317 -2. [Step] → verify: [check]  
318 -3. [Step] → verify: [check]  
319 -```  
320 -  
321 -Strong success criteria let you loop independently. Weak criteria ("make it work") require constant clarification.  
322 -  
323 ----  
324 -  
325 -## ⚡ Skill & 模板入口索引  
326 -  
327 -CC 会话启动请直接调 **`/erp-plan-start`** —— 顶层编排器会自动探测当前阶段(计划 / 模块循环 / 功能循环 / blocker)并分发到下一个 skill。  
328 -  
329 -### Skills(20 个,详细动作见各 `SKILL.md` 正文)  
330 -  
331 -| Layer | Skill |  
332 -|---|---|  
333 -| **0 入口** | `erp-plan-start` / `erp-project-init` |  
334 -| **1 计划阶段** | `erp-scope-lock` / `erp-skeleton-gen` / `erp-db-init` / `erp-db-design-gen` / `erp-downstream-gen` |  
335 -| **2 模块循环(外)** | `erp-module-start` / `erp-local-test-gate` / `erp-module-report` / `erp-mr-create` |  
336 -| **3 功能循环(内)** | `erp-feature-brainstorm` / `erp-feature-plan` / `erp-feature-tdd` / `erp-feature-verify` / `erp-feature-review` |  
337 -| **4 横切守门** | `erp-red-flag-check` / `erp-cross-module-log`(软规则 S2) |  
338 -  
339 -### Hooks(3 个,由插件 `hooks/hooks.json` + `hooks/scripts/*.sh` 提供)  
340 -  
341 -- `deny-no-verify.sh` — 拒 `git push --no-verify`  
342 -- `log-cross-module.sh` — 跨模块改动自动留痕(S2)  
343 -  
344 -### 模板(分散在各 skill 的 插件 `skills/erp-*/templates/*`)  
345 -  
346 -每个生成文件都对应一个模板(设计原则 #5)。模板保持纯净(原则 #6),帮助文本由 skill 通过 `AskUserQuestion` 交互引导。模板按"谁用谁拥有"原则分散到各自的 skill 目录下,便于打包成 plugin。一份共享模板(`cross-module-log-template.md`)在 `erp-module-start` 与 `erp-cross-module-log` 中各有一份副本。  
347 -  
skills/plan/erp-project-init/templates/docs-08-initial-template.md deleted
1 -# 08-工作流进度  
2 -  
3 -> 全流程进度跟踪。CC 每完成一项产出就勾选一项。  
4 -> - **§ 一 Plan(A0~A5)**:`erp-plan-start` 找第一个未勾 A 子项分发到对应 skill  
5 -> - **§ 二 Coding(模块)**:分发以 `docs/02-开发计划.md § 二 开发顺序清单` 为准;`erp-coding-start` 按 docs/02 顺序扫描,对每个 REQ 所属模块查询本 § 二的 `MR:` 字段 + GitLab API `state`,找第一个非 merged 模块分发。本 § 二 行序无语义,仅作模块元数据表  
6 -  
7 -## 一、Plan 阶段(一次性)  
8 -  
9 -- [ ] A0 项目初始化 — erp-project-init  
10 - - [ ] 项目文件骨架已创建(CLAUDE.md + docs/01-需求清单/README.md)  
11 -  
12 -- [ ] A1 范围锁定 — erp-scope-lock  
13 - - [ ] 项目概述已填写(CLAUDE.md § 🎯 项目概述)  
14 - - [ ] 技术栈已确认(docs/04 § 零)  
15 - - [ ] 需求清单索引已填写(docs/01-需求清单/README.md)  
16 - - [ ] REQ 卡片已生成(docs/01-需求清单/*.md,schema/api 字段标记为 TBD)  
17 -  
18 -- [ ] A2 骨架生成 — erp-skeleton-gen  
19 - - [ ] 架构文档已生成(docs/04 § 一+、docs/06、docs/07、docs/09)  
20 - - [ ] 工具脚本已生成(scripts/*.sh、.githooks/pre-push、.env.local)  
21 - - [ ] .gitignore 已配置  
22 -  
23 -- [ ] A3 DB 初始化 — erp-db-init  
24 - - [ ] .env.local 凭据验证通过  
25 - - [ ] MySQL 连接验证通过  
26 - - [ ] V1 initial migration 已生成(sql/migrations/V1__initial_schema.sql,DDL only)  
27 - - [ ] sql/seed-data.sql 已导出(本地数据快照,INSERT only)  
28 -  
29 -- [ ] A4 DB 设计 + REQ 回填 — erp-db-design-gen  
30 - - [ ] docs/03 数据库设计已生成  
31 - - [ ] REQ 卡片依赖表已回填  
32 - - [ ] schema 一致性检查通过  
33 -  
34 -- [ ] A5 下游文档生成 — erp-downstream-gen  
35 - - [ ] docs/02 开发计划已生成  
36 - - [ ] docs/05 API 契约已生成  
37 - - [ ] docs/06 § 五 页面清单已填入  
38 - - [ ] docs/10 验收清单已生成  
39 - - [ ] 下方模块列表已填入  
40 - - [ ] REQ 卡片依赖接口已回填  
41 -  
42 -## 二、Coding 阶段(按模块循环)  
43 -  
44 -(A5 填入后,每个模块一行 bullet。每个模块的 `MR:` 字段在 `—` 和 `!<iid>` 之间变化,完成由 GitLab API `state=merged` 判定。`erp-coding-start` 每次按 docs/02 REQ 序扫每模块的 MR state 决定派发。)  
45 -  
46 -<!-- 模块格式示例(由 A5 erp-downstream-gen 追加):  
47 -- module_0 系统管理  
48 - - 依赖: —  
49 - - 路径: backend/module/sys/, frontend/pages/sys/  
50 - - MR: —  
51 --->  
skills/plan/erp-scope-lock/SKILL.md deleted
1 ----  
2 -name: erp-scope-lock  
3 -description: A1 计划范围锁定——引导用户填写项目概述 + 技术栈 + 需求索引,并自动扩展 REQ 卡片待人工评审。`schema_refs` 填 `TBD(A4 自动补)`(A4 回填依赖表),`api_refs` 填 `TBD(A5 自动补)`(A5 回填依赖接口)。  
4 -user-invocable: false  
5 -allowed-tools: Read Write Edit Grep Skill AskUserQuestion  
6 ----  
7 -  
8 -**所有输出必须使用中文。**  
9 -  
10 -# erp-scope-lock  
11 -  
12 -## 执行步骤  
13 -  
14 -### 步骤 0:打印当前位置流程图  
15 -  
16 -向用户展示当前在 A 阶段流程中的位置(A-only,`▶` 标在 A1):  
17 -  
18 -```  
19 -┌──────────────────────────────────────────────────────┐  
20 -│ 📋 阶段 A:规划(一次性) │  
21 -│ │  
22 -│ A0 初始化项目 → ▶ A1 锁范围(REQ 卡片) │  
23 -│ ↓ │  
24 -│ ⏸ 等你审阅 REQ,重新运行 /erp-plan-start 继续 │  
25 -│ ↓ │  
26 -│ A2 生成骨架 → A3 初始化 DB → A4 生成 DB 设计 → A5 生成下游文档│  
27 -│ ↓ │  
28 -│ 规划阶段到此结束 │  
29 -└──────────────────────────────────────────────────────┘  
30 -```  
31 -  
32 -### A. 提示用户填写项目概述并等待  
33 -  
34 -向用户输出:  
35 -  
36 -```  
37 -━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━  
38 - [erp-scope-lock] 请填写项目概述  
39 -  
40 - 📄 文件位置: ./CLAUDE.md  
41 - 📌 编辑位置: § 🎯 项目概述  
42 -  
43 - 请将以下占位符替换为实际值:  
44 - - 项目名称  
45 - - 项目简述  
46 - - 目标用户  
47 - - 部署方式  
48 - 改完后回来选择「继续」。  
49 -━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━  
50 -```  
51 -  
52 -用 `AskUserQuestion` 询问:  
53 -- **question**: `项目概述填写完毕了吗?`  
54 -- **options** (每项为对象):  
55 - - `{"label": "继续", "description": "已完成检查"}`  
56 - - `{"label": "有疑问想先沟通", "description": "需要讨论或修改"}`  
57 -  
58 -- 用户选择「有疑问想先沟通」→ 回答用户问题后,再次弹出同样的 QA。  
59 -- 用户选择「继续」→ 进入步骤 B。  
60 -  
61 -### B. 保存默认技术栈到 docs/04  
62 -  
63 -用 `Write` 将以下默认技术栈表写入 `docs/04-技术规范.md`:  
64 -  
65 -```markdown  
66 -# 04-技术规范  
67 -  
68 -## 零、技术栈总览  
69 -  
70 -| 分层模块 | 技术 | 版本要求 | 说明 |  
71 -|---|---|---|---|  
72 -| 前端基础框架 | React | 18.x | 构建前端应用 |  
73 -| 前端 UI 组件 | Ant Design | 5.x | 页面组件与交互控件 |  
74 -| 前端状态管理 | Redux Toolkit | 最新稳定版 | 管理全局状态 |  
75 -| 前端路由管理 | React Router | v6 | 页面路由与导航 |  
76 -| 前端工程化构建 | Vite | 最新稳定版 | 前端开发与打包构建 |  
77 -| 前端接口通信 | Axios | 最新稳定版 | 调用后端 API |  
78 -| 后端基础框架 | Spring Boot | 3.x | 构建后端服务 |  
79 -| 后端数据访问 | MyBatis-Plus | 最新稳定版 | 数据库访问与 ORM 增强 |  
80 -| 工作流引擎 | Activiti | 6.x | 审批流、流程流转 |  
81 -| 缓存服务 | Redis | 最新稳定版 | 缓存、会话、分布式能力 |  
82 -| 报表打印 | JXLS | 2.8.1 | 基于 Excel 模板生成报表 |  
83 -| Excel 导入导出 | EasyExcel | 4.0.3 | Excel 数据导入导出 |  
84 -| 关系型数据库 | MySQL | 8.x | 核心业务数据存储 |  
85 -| 数据库 schema 迁移 | Flyway (`flyway-core` + `flyway-mysql`) | 10.x / 最新稳定版 | `sql/migrations/V_n__*.sql` 顺序 apply;Spring Boot 启动时自动应用 |  
86 -| 接口风格 | RESTful API | 统一规范 | 前后端接口设计规范 |  
87 -| 权限认证 | Spring Security / JWT | 最新稳定版 | 登录认证、权限控制 |  
88 -| API 文档 | OpenAPI / Swagger | 最新稳定版 | 接口文档与调试 |  
89 -| 项目构建管理 | Maven | 3.9.x | Java 项目依赖与构建 |  
90 -| JDK 运行环境 | Java | 17 / 21 | Spring Boot 3 推荐版本 |  
91 -| 部署容器 | Docker | 最新稳定版 | 容器化部署 |  
92 -| Web 服务器 / 反向代理 | Nginx | 最新稳定版 | 前端托管、反向代理、负载分发 |  
93 -| 日志管理 | Logback | 默认集成 / 最新稳定版 | 应用日志输出 |  
94 -| 对象映射工具 | MapStruct | 最新稳定版 | DTO / VO / Entity 转换 |  
95 -| 工具类库 | Hutool / Apache Commons | 最新稳定版 | 常用工具方法支持 |  
96 -  
97 -> 本表由 erp-scope-lock 锁定。后续所有规范基于此表推导。  
98 -```  
99 -  
100 -### C. 提示用户检查并等待  
101 -  
102 -向用户输出:  
103 -  
104 -```  
105 -━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━  
106 - [erp-scope-lock] 技术栈已保存  
107 -  
108 - 📄 文件位置: ./docs/04-技术规范.md  
109 - 📌 编辑位置: § 零、技术栈总览  
110 -  
111 - 请检查技术栈表:  
112 - - 不需要的行直接删除(如纯后端项目删前端行)  
113 - - 需要替换的技术直接改  
114 - - 需要新增的条目直接加行  
115 - 改完后回来选择「继续」。  
116 -━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━  
117 -```  
118 -  
119 -用 `AskUserQuestion` 询问:  
120 -- **question**: `技术栈检查完毕了吗?`  
121 -- **options** (每项为对象):  
122 - - `{"label": "继续", "description": "已完成检查"}`  
123 - - `{"label": "有疑问想先沟通", "description": "需要讨论或修改"}`  
124 -  
125 -- 用户选择「有疑问想先沟通」→ 回答用户问题后,再次弹出同样的 QA。  
126 -- 用户选择「继续」→ 进入步骤 D。  
127 -  
128 -### D. 提示用户填写需求清单并等待  
129 -  
130 -`docs/01-需求清单/README.md` 已由 `erp-project-init` 写入占位符模板,这里让用户补齐模块清单。  
131 -  
132 -向用户输出:  
133 -  
134 -```  
135 -━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━  
136 - [erp-scope-lock] 请填写需求清单模块索引  
137 -  
138 - 📄 文件位置: ./docs/01-需求清单/README.md  
139 - 📌 编辑位置: § 模块索引(表格)  
140 -  
141 - 请按业务列出所有模块:  
142 - - 每行一个模块(如 SYS 系统管理 / PUR 采购 / SAL 销售)  
143 - - 「核心功能点」只需关键词,CC 会扩展为完整 REQ 卡片  
144 - 改完后回来选择「继续」。  
145 -━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━  
146 -```  
147 -  
148 -用 `AskUserQuestion` 询问:  
149 -- **question**: `需求清单模块索引填写完毕了吗?`  
150 -- **options** (每项为对象):  
151 - - `{"label": "继续", "description": "已完成检查"}`  
152 - - `{"label": "有疑问想先沟通", "description": "需要讨论或修改"}`  
153 -  
154 -- 用户选择「有疑问想先沟通」→ 回答用户问题后,再次弹出同样的 QA。  
155 -- 用户选择「继续」→ 进入步骤 E。  
156 -  
157 -### E. 生成 REQ 卡片并等用户审阅  
158 -  
159 -先用 `Grep` 在 `docs/01-需求清单/README.md` 搜索 `【人工填写:`,命中 → 提示残留行,回到步骤 D。通过后:  
160 -  
161 -1. 用 `Read` 读取 `docs/01-需求清单/README.md`,解析模块索引表(每行:模块代码 / 模块名 / 核心功能点)。  
162 -2. 用 `Read` 读取两份模板:  
163 - - `${CLAUDE_SKILL_DIR}/templates/req-card-template.md`  
164 - - `${CLAUDE_SKILL_DIR}/templates/docs-01-module-template.md`  
165 -3. 对每个模块:  
166 - - 基于「核心功能点」关键词,LLM 扩展为若干 REQ-XXX-NNN 卡片(编号按模块递增)  
167 - - 每张卡片填充字段:  
168 - - `goal` / `input` / `output` / `rules` / `constraints` / `acceptance` —— LLM 基于功能点推断  
169 - - `schema_refs` —— 填 `TBD(A4 自动补)`(A4 `erp-db-design-gen` 回填依赖表)  
170 - - `api_refs` —— 填 `TBD(A5 自动补)`(A5 `erp-downstream-gen` 回填依赖接口)  
171 - - 用 module 模板包装卡片列表  
172 - - 用 `Write` 写入 `docs/01-需求清单/<module_code>-<module_name>.md`  
173 -4. 向用户输出(只打印,**不弹出 QA**,不等待):  
174 -  
175 -```  
176 -━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━  
177 - [erp-scope-lock] REQ 卡片已生成  
178 -  
179 - 📄 文件位置: ./docs/01-需求清单/<module>-*.md  
180 - ⚠️ 依赖表 = TBD(A4 自动补)(A4 阶段回填) / 依赖接口 = TBD(A5 自动补)(A5 阶段回填)  
181 -  
182 - 请人工审阅每张 REQ 卡片的功能字段:  
183 - - 目标 / 输入 / 输出  
184 - - 业务规则 / 边界  
185 - - 验收标准  
186 -  
187 - 审阅是 Plan 阶段的关键人工关口,请认真逐张过一遍。  
188 -━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━  
189 -```  
190 -  
191 -5. 立即进入步骤 F(不等待用户任何输入)。  
192 -  
193 -### F. 勾选 docs/08 进度 + 停下等人工审阅  
194 -  
195 -1. 用 `Edit` 在 `docs/08-模块任务管理.md` 勾选 5 个 checkbox(A1 的 4 个子项 + A1 父项):  
196 - - ` - [ ] 项目概述已填写(CLAUDE.md § 🎯 项目概述)` → `[x]`  
197 - - ` - [ ] 技术栈已确认(docs/04 § 零)` → `[x]`  
198 - - ` - [ ] 需求清单索引已填写(docs/01-需求清单/README.md)` → `[x]`  
199 - - ` - [ ] REQ 卡片已生成(docs/01-需求清单/*.md,schema/api 字段标记为 TBD)` → `[x]`  
200 - - `- [ ] A1 范围锁定 — erp-scope-lock` → `[x]`  
201 -  
202 -2. 输出 `scope-lock: 完成(4 项产出已勾选)`。  
203 -  
204 -3. 打印停下横幅并**停下**(**不调** `Skill(erp-skeleton-gen)`,A2 由用户手动恢复):  
205 -  
206 - ```  
207 - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━  
208 - [erp-scope-lock] ✅ A1 范围锁定完成  
209 -  
210 - 产出:  
211 - ✓ CLAUDE.md § 🎯 项目概述  
212 - ✓ docs/04 § 零 技术栈  
213 - ✓ docs/01-需求清单/README.md 模块索引  
214 - ✓ docs/01-需求清单/<module>-*.md REQ 卡片  
215 -  
216 - ⏸ 现在请你审阅 REQ 卡片(路径:`docs/01-需求清单/<module_code>-<module_name>.md`)。  
217 -  
218 - 审阅完成后,运行以下命令继续进入 A2:  
219 - /erp-workflow:erp-plan-start  
220 -  
221 - (入口会读取 docs/08 进度,自动派发到 A2 erp-skeleton-gen)  
222 - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━  
223 - ```  
224 -  
225 - **停止**,不调用任何下游 skill。  
226 -  
227 -## 参考  
228 -  
229 -- `CLAUDE.md` § 🎯 项目概述(写入目标)  
230 -- `docs/04-技术规范.md`(技术栈输出,供 erp-skeleton-gen 读取使用)  
231 -- `docs/01-需求清单/README.md`(模块索引输入)  
232 -- `docs/01-需求清单/<module>-*.md`(REQ 卡片输出,A4 erp-db-design-gen 会回填 TBD 字段)  
233 -- `${CLAUDE_SKILL_DIR}/templates/req-card-template.md`  
234 -- `${CLAUDE_SKILL_DIR}/templates/docs-01-module-template.md`  
skills/plan/erp-scope-lock/templates/req-card-template.md deleted
1 -### {{req_id}} {{title}}  
2 -  
3 -- **目标**: {{goal}}  
4 -- **输入**: {{input}}  
5 -- **输出**: {{output}}  
6 -- **业务规则**: {{rules}}  
7 -- **边界**: {{constraints}}  
8 -- **依赖表**: {{schema_refs}}  
9 -- **依赖接口**: {{api_refs}}  
10 -- **验收**: {{acceptance}}  
skills/plan/erp-skeleton-gen/SKILL.md deleted
1 ----  
2 -name: erp-skeleton-gen  
3 -description: A2 骨架生成——基于 docs/04 § 零 技术栈 + docs/01-需求清单/README.md 模块索引,生成项目专属的架构文档(docs/04 § 一+、docs/06、docs/07、docs/09)和工具脚本。固定工具文件走 cp,架构文档由 LLM 按大纲生成。  
4 -user-invocable: false  
5 -allowed-tools: Read Write Edit Skill Grep Glob AskUserQuestion Bash(mkdir *) Bash(cp *) Bash(touch *) Bash(chmod *) Bash(git config *) Bash(cat *) Bash(bash *)  
6 ----  
7 -  
8 -**所有输出必须使用中文。**  
9 -  
10 -# erp-skeleton-gen  
11 -  
12 -## 前置条件  
13 -  
14 -本 skill 从 docs/08 进度推进而来。  
15 -  
16 -**输入文件**:  
17 -- `docs/04-技术规范.md § 零`:erp-scope-lock 写入的技术栈表。本 skill 基于它推导 § 一+ 编码规范、docs/07 依赖清单、docs/09 目录结构、scripts/test.sh 的构建/测试命令。  
18 -- `docs/01-需求清单/`:A1 已产出 README.md(模块索引表)+ 每模块一份 REQ 卡片(`<code>-<name>.md`,用户已审阅确认)。A2 只用其中的**模块 ID 列表**生成 docs/09 的后端/前端模块目录树(`module/user/` / `module/order/` 等),REQ 卡片详情不在本 skill 使用(留给 A4 回填 schema、A5 生成 API/验收清单)。  
19 -- `docs/08-模块任务管理.md`:末尾 Edit 勾选 A2 checkbox。  
20 -  
21 -**产出覆盖提醒**:  
22 -- 本 skill 会 `Write` 覆盖以下文件:docs/04(拼接 § 零 + § 一+)、docs/06、docs/07、docs/09、scripts/test.sh、scripts/setup-test-db.sh、.githooks/pre-push、.env.local。  
23 -- 如果之前运行过本 skill 且用户手动改过这些文件,**重新运行会覆盖修改**。  
24 -  
25 -## 执行步骤  
26 -  
27 -### 步骤 0:打印当前位置流程图  
28 -  
29 -向用户展示当前在 A 阶段流程中的位置(A-only,`▶` 标在 A2):  
30 -  
31 -```  
32 -┌──────────────────────────────────────────────────────┐  
33 -│ 📋 阶段 A:规划(一次性) │  
34 -│ │  
35 -│ A0 初始化项目 → A1 锁范围(REQ 卡片) │  
36 -│ ↓ │  
37 -│ ⏸ 等你审阅 REQ,重新运行 /erp-plan-start 继续 │  
38 -│ ↓ │  
39 -│ ▶ A2 生成骨架 → A3 初始化 DB → A4 生成 DB 设计 → A5 生成下游文档│  
40 -│ ↓ │  
41 -│ 规划阶段到此结束 │  
42 -└──────────────────────────────────────────────────────┘  
43 -```  
44 -  
45 -### A. 读取锁定的输入  
46 -  
47 -用 `Read` 读取:  
48 -- `docs/04-技术规范.md` § 零 技术栈表  
49 -- `docs/01-需求清单/README.md` 模块索引  
50 -  
51 -这两份是本次生成的**唯一权威输入**,后续所有内容都基于它们推导。  
52 -  
53 -### B.1 生成 3 个全新架构文档(docs/06 / 07 / 09)  
54 -  
55 -对下表每个目标文件:  
56 -1. 用 `Read` 读取对应的大纲模板(只含 section 标题 + HTML 注释形式的填写提示)  
57 -2. 基于步骤 A 的输入,按大纲生成项目专属内容  
58 -3. **剥掉所有 `<!-- -->` 注释**(注释是给 LLM 的提示,不应出现在最终文档里)  
59 -4. 用 `Write` 写入目标路径  
60 -  
61 -| 目标文件 | 大纲模板 |  
62 -|---|---|  
63 -| `docs/06-UI交互规范.md`(写 § 一 ~ 四,§ 五 占位) | `${CLAUDE_SKILL_DIR}/templates/docs-06-static-template.md` |  
64 -| `docs/07-环境配置.md` | `${CLAUDE_SKILL_DIR}/templates/docs-07-env-template.md` |  
65 -| `docs/09-项目目录结构.md` | `${CLAUDE_SKILL_DIR}/templates/docs-09-structure-template.md` |  
66 -  
67 -项目专属标识(根包名 / 命名空间)保留 `【人工填写:<说明>】` 占位,等人工在 docs/09 顶部补填一次后,其他文件复用。  
68 -  
69 -### B.2 追加 docs/04 § 一+(保留 § 零 不覆盖)  
70 -  
71 -docs/04 已由 erp-scope-lock 写入 § 零。本步骤追加 § 一 ~ 三。  
72 -  
73 -1. 用 `Read` 读取 `docs/04-技术规范.md`(拿现有 § 零 完整内容)。  
74 -2. 用 `Read` 读取 `${CLAUDE_SKILL_DIR}/templates/docs-04-skeleton-template.md`(§ 一+ 大纲)。  
75 -3. 基于步骤 A 技术栈,按大纲生成 § 一 ~ 三 的项目专属内容,剥掉 HTML 注释。  
76 -4. 拼接 `<§ 零 原文>\n\n<新生成的 § 一+>` → 用 `Write` 写回 `docs/04-技术规范.md`。  
77 -  
78 -### C. 生成工具脚本  
79 -  
80 -#### C.1 零槽位文件:纯 `cp`  
81 -  
82 -```bash  
83 -mkdir -p scripts .githooks sql/migrations  
84 -touch sql/migrations/.gitkeep  
85 -cp "${CLAUDE_SKILL_DIR}/templates/env-local-template" .env.local  
86 -cp "${CLAUDE_SKILL_DIR}/templates/githooks-pre-push-template.sh" .githooks/pre-push  
87 -cp "${CLAUDE_SKILL_DIR}/templates/scripts-setup-test-db-template.sh" scripts/setup-test-db.sh  
88 -```  
89 -  
90 -说明:  
91 -- `sql/migrations/` 是 Flyway migration 目录。A3 `erp-db-init` 会在此生成 `V1__initial_schema.sql`,后续 B 阶段每个 REQ 的业务 DDL 也写在这(`V2__xxx.sql` / `V3__xxx.sql` ...)  
92 -- `setup-test-db.sh` 只做 **drop + create 空库**,schema 由 **Flyway 在 Spring Boot 启动时自动应用**  
93 -- **硬依赖**:项目 `pom.xml` 必须包含 `flyway-core` + `flyway-mysql` 依赖(已列入 docs/04 § 零 技术栈);否则 Spring 启动不会 apply migration,测试会因表不存在而失败  
94 -- seed 数据(`sql/seed-data.sql`)由 A3 `erp-db-init` 从本地 MySQL 导出,开发者选一种装载方式(Spring `@Sql` / Flyway `R__seed.sql` / `data.sql`);setup-test-db.sh 只负责清空库  
95 -  
96 -#### C.2 `scripts/test.sh` —— 直接 Write  
97 -  
98 -基于步骤 A 的技术栈推断 build / lint / unit+integration / e2e 四条命令,直接 `Write` 完整 `scripts/test.sh`。  
99 -  
100 -骨架如下(CC 把 4 个 `<推断的 ... 命令>` 替换成实际值后 Write):  
101 -  
102 -```bash  
103 -#!/usr/bin/env bash  
104 -# scripts/test.sh —— 合并到默认分支(main / master)前的唯一硬闸门。  
105 -# 顺序:setup-db → build → lint → unit+integration → e2e → reset-db  
106 -# 由 .githooks/pre-push 和 erp-local-test-gate skill(通过子会话)调用。  
107 -  
108 -set -euo pipefail  
109 -  
110 -PROJECT_ROOT="$(cd "$(dirname "$0")/.." && pwd)"  
111 -cd "$PROJECT_ROOT"  
112 -  
113 -echo "[test.sh] 1/6 setup test db"  
114 -./scripts/setup-test-db.sh  
115 -  
116 -echo "[test.sh] 2/6 build"  
117 -<推断的 build 命令,如:(cd backend && mvn -DskipTests clean package) && (cd frontend && pnpm build)>  
118 -  
119 -echo "[test.sh] 3/6 lint"  
120 -<推断的 lint 命令>  
121 -  
122 -echo "[test.sh] 4/6 unit + integration"  
123 -<推断的 unit+integration 命令>  
124 -  
125 -echo "[test.sh] 5/6 E2E"  
126 -<推断的 e2e 命令>  
127 -  
128 -echo "[test.sh] 6/6 reset test db"  
129 -./scripts/setup-test-db.sh  
130 -  
131 -echo "[test.sh] GREEN"  
132 -```  
133 -  
134 -#### C.3 赋权 + 配置 git hooks  
135 -  
136 -```bash  
137 -chmod +x scripts/*.sh .githooks/pre-push  
138 -git config core.hooksPath .githooks  
139 -```  
140 -  
141 -### D. 追加 .gitignore 忽略项  
142 -  
143 -调用脚本完成合并:  
144 -  
145 -```bash  
146 -bash "${CLAUDE_SKILL_DIR}/scripts/merge-gitignore.sh" "${CLAUDE_SKILL_DIR}/templates/gitignore-append-template"  
147 -```  
148 -  
149 -脚本行为:  
150 -- 若项目根无 `.gitignore` → 直接 `cp` 整份模板  
151 -- 若已有 → 读模板每一行,跳过注释/空行,用 `grep -xF` 整行精确匹配判重(避免 `.env` 误匹配 `.env.local`、通配符 `*.iml` 被当正则),只追加缺失的规则  
152 -  
153 -### E. 占位符智能填充 + `.env.local` 独立提示 + QA 循环验证  
154 -  
155 -目标:减少用户重复编辑。同一"逻辑占位"(如根包名出现多处)只问用户一次,CC 批量填;派生占位(如 Java 路径从根包名派生)由 CC 自己推断。敏感占位(`.env.local` 凭据 / 密钥)不进会话上下文,让用户自己去文件里填。  
156 -  
157 -循环执行直到**两个条件同时满足**:  
158 -(a) 所有占位符已填(重新扫描命中数 N = 0)  
159 -(b) 用户选「继续」  
160 -  
161 -#### E.1 扫描 + 分组  
162 -  
163 -用 `Grep` 在以下 8 个路径下扫描 `【人工填写:`,记录每处命中(文件 + 行号 + 说明文字):  
164 -- `docs/04-技术规范.md`  
165 -- `docs/06-UI交互规范.md`  
166 -- `docs/07-环境配置.md`  
167 -- `docs/09-项目目录结构.md`  
168 -- `scripts/*.sh`  
169 -- `.githooks/pre-push`  
170 -- `.gitignore`  
171 -- `.env.local`  
172 -  
173 -对每个命中提取 `【人工填写:<说明>】` 的 `<说明>`,**分两组**:  
174 -  
175 -- **敏感组**:`.env.local` 路径下的全部命中(密码 / 密钥 / 账号等)。**不**通过 `AskUserQuestion` 问——留给 E.4 提示用户手动编辑。  
176 -- **非敏感组**:其他文件的命中。按语义聚合成"逻辑占位":  
177 - - **说明文字完全相同** → 同一个根占位(多处共用同一值),如"根包名"出现 3 次  
178 - - **说明表达派生关系** → 派生占位,派生自某根占位(如"后端 java 根包路径"派生自"根包名")  
179 - - **无法归类** → 视作独立根占位单独问  
180 -  
181 -若总 N=0(无任何占位)→ 直接跳 E.5 验证。  
182 -  
183 -#### E.2 向用户询问非敏感"根占位"  
184 -  
185 -对每个非派生根占位用 `AskUserQuestion` 询问:  
186 -  
187 -- **question**: `请输入 <说明>(将填充到 <N> 处)`  
188 -- **options**(给**默认值候选 + 自由输入**,供用户快速选择;"Other" 由 CC 运行时自动提供,无需显式列):  
189 - - `{"label": "<合理默认值>", "description": "示例默认值"}`  
190 - - (可选)`{"label": "<第二个常见默认>", "description": "..."}`  
191 -  
192 -示例(根包名):  
193 -```  
194 -question: "请输入 Java 根包名(将填充到 3 处)"  
195 -options:  
196 - - {"label": "com.example.erp", "description": "示例默认"}  
197 -```  
198 -  
199 -- 用户选默认值 → 取该值  
200 -- 用户选 Other → 用户输入的字符串为该值  
201 -  
202 -**派生占位不问用户**——由 CC 在 E.3 自行推断。  
203 -  
204 -#### E.3 CC 批量 Edit 填充  
205 -  
206 -1. 对每个根占位:遍历所有命中位置,用 `Edit` 把 `【人工填写:<说明>】` 替换为 E.2 用户输入的值。  
207 -  
208 -2. 对每个派生占位:CC 基于说明文字 + 根占位值**自行推断**派生值,用 `Edit` 填入。例如:  
209 - - 根 `根包名 = com.xly.erp` → 派生 `后端 java 根包路径 = backend/src/main/java/com/xly/erp/`  
210 - - 根 `根包名 = com.xly.erp` → 派生 `测试 java 根包路径 = backend/src/test/java/com/xly/erp/`  
211 -  
212 -3. 若 CC 对某派生占位无法可靠推断(说明不清 / 上下文不足),**回退**:把该占位当作独立根占位,弹 `AskUserQuestion` 问用户。  
213 -  
214 -#### E.4 `.env.local` 敏感占位提示(不弹出 QA)  
215 -  
216 -若敏感组非空,打印提示横幅(只打印,不问):  
217 -  
218 -```  
219 -━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━  
220 - [erp-skeleton-gen] ⚠️ 敏感占位需你亲自填  
221 -  
222 - 📄 文件: ./.env.local  
223 - 待填字段(<N> 个):  
224 - <列出实际命中的字段名,如 DB_HOST / DB_PORT / DB_USER / DB_PASSWORD / DB_SCHEMA / JWT_SECRET>  
225 -  
226 - 这些是凭据 / 密钥,CC 不通过会话询问(避免写入聊天记录)。  
227 - 请直接编辑 .env.local 填入实际值。  
228 -━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━  
229 -```  
230 -  
231 -#### E.5 验证 + QA 循环  
232 -  
233 -1. 用 `Grep` **重新扫** `【人工填写:` 于所有 8 个路径,得新命中数 N 和残留清单。  
234 -  
235 -2. 打印汇总横幅:  
236 -  
237 - ```  
238 - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━  
239 - [erp-skeleton-gen] 骨架生成完成,请审阅  
240 -  
241 - 📄 架构文档:  
242 - ✓ docs/04-技术规范.md (§ 一 ~ 三)  
243 - ✓ docs/06-UI交互规范.md (§ 一 ~ 四)  
244 - ✓ docs/07-环境配置.md  
245 - ✓ docs/09-项目目录结构.md  
246 -  
247 - 📄 工具文件:  
248 - ✓ scripts/test.sh  
249 - ✓ scripts/setup-test-db.sh  
250 - ✓ .githooks/pre-push  
251 - ✓ .env.local  
252 - ✓ .gitignore(新建 / 追加 / 跳过)  
253 - ✓ sql/migrations/.gitkeep  
254 -  
255 - 占位符状态:  
256 - <N=0 时打印:✅ 全部填完>  
257 - <N>0 时打印:⚠️ 还有 N 处待填:  
258 - <文件:行号> — <行内容摘要>  
259 - ...>  
260 -  
261 - 需要调整 → 直接编辑对应文件(尤其 .env.local 敏感字段)  
262 - 填完后 → 选「继续」放行 A3  
263 - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━  
264 - ```  
265 -  
266 -3. 用 `AskUserQuestion` 询问:  
267 - - **question**: `架构文档审阅 & 占位符补填完毕?`  
268 - - **options**:  
269 - - `{"label": "继续", "description": "进入 A3 数据库配置"}`  
270 - - `{"label": "有疑问想先沟通", "description": "需要讨论或修改"}`  
271 -  
272 -4. 路由:  
273 - - 选「有疑问想先沟通」→ 回答用户问题后**回 E.5.1 重新扫描**  
274 - - 选「继续」→ **回 E.5.1 重新扫描验证**:  
275 - - 新 N = 0 → 进入步骤 F(放行 A3)  
276 - - 新 N > 0 → 用户以为填完其实还有残留,回 E.5.2 打印新横幅并再次弹出 QA  
277 -  
278 -关键点:**每次弹出 QA 前都重新扫描一次**,用户看到的 N 始终是最新的;只有 N = 0 且选「继续」才放行。  
279 -  
280 -### F. 勾选 docs/08 进度 + 进入 A3  
281 -  
282 -1. 用 `Edit` 在 `docs/08-模块任务管理.md` 勾选 4 个 checkbox(A2 的 3 个子项 + A2 父项):  
283 - - ` - [ ] 架构文档已生成(docs/04 § 一+、docs/06、docs/07、docs/09)` → `[x]`  
284 - - ` - [ ] 工具脚本已生成(scripts/*.sh、.githooks/pre-push、.env.local)` → `[x]`  
285 - - ` - [ ] .gitignore 已配置` → `[x]`  
286 - - `- [ ] A2 骨架生成 — erp-skeleton-gen` → `[x]`  
287 -  
288 -2. 输出 `skeleton-gen: 完成(docs/04 § 一+ / docs/06 / docs/07 / docs/09 + scripts/*.sh + .githooks/pre-push + .env.local + .gitignore)`。  
289 -  
290 -3. 立即调用 `Skill(erp-db-init)` 进入 A3,不等用户手动输入。  
291 -  
292 -## 参考  
293 -  
294 -- `docs/04-技术规范.md` § 零(技术栈输入)  
295 -- `docs/01-需求清单/README.md`(模块索引输入)  
296 -- `${CLAUDE_SKILL_DIR}/templates/docs-04-skeleton-template.md`(大纲)  
297 -- `${CLAUDE_SKILL_DIR}/templates/docs-06-static-template.md`(大纲)  
298 -- `${CLAUDE_SKILL_DIR}/templates/docs-07-env-template.md`(大纲)  
299 -- `${CLAUDE_SKILL_DIR}/templates/docs-09-structure-template.md`(大纲)  
300 -- `${CLAUDE_SKILL_DIR}/templates/scripts-setup-test-db-template.sh`(0 槽位)  
301 -- `${CLAUDE_SKILL_DIR}/templates/githooks-pre-push-template.sh`(0 槽位)  
302 -- `${CLAUDE_SKILL_DIR}/templates/env-local-template`(0 槽位)  
303 -- `${CLAUDE_SKILL_DIR}/templates/gitignore-append-template`(0 槽位)  
304 -- `${CLAUDE_SKILL_DIR}/scripts/merge-gitignore.sh`(.gitignore 逐行判重合并脚本)  
skills/plan/erp-project-init/SKILL.md renamed to skills/plan/project-init/SKILL.md
1 --- 1 ---
2 -name: erp-project-init  
3 -description: A0 项目初始化——从插件模板幂等地复制 CLAUDE.md / docs/01-需求清单/README.md / docs/08-模块任务管理.md(已存在则跳过),并初始化 Git(如未初始化)。session-start 在 docs/08 缺失时派发本 skill。 2 +name: project-init
  3 +description: A0 项目初始化——从插件模板幂等地复制 CLAUDE.md / docs/01-需求清单/index.md / docs/04-技术规范.md / docs/08-模块任务管理.md(已存在则跳过),并初始化 Git(如未初始化)。session-start 在 docs/08 缺失时派发本 skill。
4 user-invocable: false 4 user-invocable: false
5 -allowed-tools: Glob Edit Skill Bash(mkdir *) Bash(cp -n *) Bash(git init) Bash(command -v *) Bash(uname *) Bash(brew *) Bash(export PATH=*) Bash(echo *) 5 +allowed-tools: Glob Edit Skill Bash(mkdir *) Bash(cp -n *) Bash(git init) Bash(command -v *) Bash(uname *) Bash(brew *) Bash(apt *) Bash(apt-get *) Bash(yum *) Bash(apk *) Bash(export PATH=*) Bash(echo *)
6 --- 6 ---
7 7
8 **所有输出必须使用中文。** 8 **所有输出必须使用中文。**
9 9
10 -你负责在空/半空项目目录中创建初始文件结构。**本 skill 幂等**——已存在的文件不覆盖。 10 +你负责在项目目录中创建初始文件结构,已存在的文件不覆盖。
11 11
12 ## 执行步骤 12 ## 执行步骤
13 13
14 ### 步骤 0:打印当前位置流程图 14 ### 步骤 0:打印当前位置流程图
15 15
16 -向用户展示当前在 A 阶段流程中的位置(A-only,`▶` 标在 A0) 16 +向用户展示当前在 A 阶段流程中的位置
17 17
18 ``` 18 ```
19 ┌──────────────────────────────────────────────────────┐ 19 ┌──────────────────────────────────────────────────────┐
@@ -21,45 +21,43 @@ allowed-tools: Glob Edit Skill Bash(mkdir *) Bash(cp -n *) Bash(git init) Bash(c @@ -21,45 +21,43 @@ allowed-tools: Glob Edit Skill Bash(mkdir *) Bash(cp -n *) Bash(git init) Bash(c
21 │ │ 21 │ │
22 │ ▶ A0 初始化项目 → A1 锁范围(REQ 卡片) │ 22 │ ▶ A0 初始化项目 → A1 锁范围(REQ 卡片) │
23 │ ↓ │ 23 │ ↓ │
24 -│ ⏸ 等你审阅 REQ,重新运行 /erp-plan-start 继续 24 +│ 等你审阅 REQ,重新运行 /plan-start 继续
25 │ ↓ │ 25 │ ↓ │
26 -│ A2 生成骨架 → A3 初始化 DB → A4 生成 DB 设计 → A5 生成下游文档│ 26 +│ A2 生成骨架 → A3 生成 DB 设计 → A4 初始化 DB → A5 生成下游文档│
27 │ ↓ │ 27 │ ↓ │
28 │ 规划阶段到此结束 │ 28 │ 规划阶段到此结束 │
29 └──────────────────────────────────────────────────────┘ 29 └──────────────────────────────────────────────────────┘
30 ``` 30 ```
31 31
32 -### A. 依赖检查 + 自动安装(命令行工具) 32 +### A. 幂等复制模板文件
33 33
34 -用 `Bash` 检查 `mysql` / `mysqldump` 是否在 PATH 中 34 +用 `Bash` 一次性完成。`cp -n` 表示"不覆盖已存在的文件"
35 35
36 ```bash 36 ```bash
37 -for cmd in mysql mysqldump; do  
38 - command -v "$cmd" >/dev/null 2>&1 || echo "MISSING: $cmd"  
39 -done 37 +mkdir -p docs/01-需求清单
  38 +cp -n "${CLAUDE_SKILL_DIR}/templates/CLAUDE-template.md" CLAUDE.md
  39 +cp -n "${CLAUDE_SKILL_DIR}/templates/docs-01-index-template.md" docs/01-需求清单/index.md
  40 +cp -n "${CLAUDE_SKILL_DIR}/templates/docs-04-stack-template.md" docs/04-技术规范.md
  41 +cp -n "${CLAUDE_SKILL_DIR}/templates/docs-08-initial-template.md" docs/08-模块任务管理.md
40 ``` 42 ```
41 43
42 -**全部在 PATH** → 进入 B。 44 +完成后,用 `Edit` 在 `docs/08-模块任务管理.md` 中勾选:
  45 +- ` - [ ] 项目文件骨架已创建(CLAUDE.md + docs/01-需求清单/index.md + docs/04-技术规范.md)`
43 46
44 -**有缺失** → 尝试自动安装:  
45 -1. 用 `Bash` 探测环境(`uname -s`、是否有 `brew` / `apt` / `yum` / `apk` 等)  
46 -2. 根据当前系统选最合适的包管理器安装 mysql 客户端;若需要 sudo 但 CC 没有权限,打印手动安装命令让用户执行  
47 -3. 装完后,把必要的 bin 路径加入本次会话 PATH(如 macOS 的 keg-only 路径)  
48 -4. 向用户提示如何把路径永久写入 shell 启动脚本  
49 -5. 重新执行开头的 `command -v` 循环验证;仍缺失 → 打印错误并停下,等用户手动解决后重新运行入口 47 +### B. 依赖检查 + 自动安装(命令行工具)
50 48
51 -### B. 幂等复制模板文件 49 +对 **git、mysql** 两个工具依次执行以下流程。
  50 + 1. 如果缺失,尝试自动安装。
  51 + 2. 如果检测到不在 PATH,尝试添加进 PATH,并加载。
52 52
53 -用 `Bash` 一次性完成。`cp -n` 表示"不覆盖已存在的文件" 53 +全部通过后打印单行汇总再进入步骤 C
54 54
55 -```bash  
56 -mkdir -p docs/01-需求清单  
57 -cp -n "${CLAUDE_SKILL_DIR}/templates/CLAUDE-template.md" CLAUDE.md  
58 -cp -n "${CLAUDE_SKILL_DIR}/templates/docs-01-readme-template.md" docs/01-需求清单/README.md  
59 -cp -n "${CLAUDE_SKILL_DIR}/templates/docs-08-initial-template.md" docs/08-模块任务管理.md 55 +```
  56 +[project-init] 依赖检查: git ✓ mysql ✓
60 ``` 57 ```
61 58
62 -故障恢复场景:如果用户上一次初始化中途中断(CLAUDE.md 已存在但 docs/08 缺失),`cp -n` 会保留 CLAUDE.md 原样,只补齐 docs/08。 59 +完成后,用 `Edit` 在 `docs/08-模块任务管理.md` 中勾选:
  60 +- ` - [ ] 依赖检查通过`
63 61
64 ### C. 初始化 Git(如尚未初始化) 62 ### C. 初始化 Git(如尚未初始化)
65 63
@@ -67,28 +65,27 @@ cp -n &quot;${CLAUDE_SKILL_DIR}/templates/docs-08-initial-template.md&quot; docs/08-模块 @@ -67,28 +65,27 @@ cp -n &quot;${CLAUDE_SKILL_DIR}/templates/docs-08-initial-template.md&quot; docs/08-模块
67 - 不存在 → 用 `Bash` 执行 `git init`。 65 - 不存在 → 用 `Bash` 执行 `git init`。
68 - 已存在 → 跳过。 66 - 已存在 → 跳过。
69 67
70 -### D. 勾选 docs/08 的 A0 进度  
71 -  
72 -用 `Edit` 在 `docs/08-模块任务管理.md` 中勾选这两行:  
73 -- ` - [ ] 项目文件骨架已创建(CLAUDE.md + docs/01-需求清单/README.md)` → ` - [x] 项目文件骨架已创建(CLAUDE.md + docs/01-需求清单/README.md)`  
74 -- `- [ ] A0 项目初始化 — erp-project-init` → `- [x] A0 项目初始化 — erp-project-init` 68 +完成后,用 `Edit` 在 `docs/08-模块任务管理.md` 中勾选(A0 子项 + A0 顶层):
  69 +- ` - [ ] Git 已初始化`
  70 +- `- [ ] A0 项目初始化 — project-init`
75 71
76 -### E. 打印完成横幅并进入 A1 72 +### D. 打印完成横幅并进入 A1
77 73
78 向用户输出: 74 向用户输出:
79 75
80 ``` 76 ```
81 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 77 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
82 - [erp-project-init] 项目初始化完成 78 + [project-init] 项目初始化完成
83 79
84 已创建: 80 已创建:
85 ✓ CLAUDE.md(从插件模板复制) 81 ✓ CLAUDE.md(从插件模板复制)
86 - ✓ docs/01-需求清单/README.md(待人工填写模块索引) 82 + ✓ docs/01-需求清单/index.md(待人工填写模块索引)
  83 + ✓ docs/04-技术规范.md(默认技术栈,A1 让用户确认)
87 ✓ docs/08-模块任务管理.md(全流程进度跟踪) 84 ✓ docs/08-模块任务管理.md(全流程进度跟踪)
88 已勾选:A0 项目初始化 85 已勾选:A0 项目初始化
89 86
90 - 下一步:A1 erp-scope-lock(填写项目概述 + 技术栈 + 需求索引 + REQ 卡片) 87 + 下一步:A1 scope-lock(填写项目概述 + 技术栈 + 需求索引 + REQ 卡片)
91 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 88 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
92 ``` 89 ```
93 90
94 -立即调用 `Skill(erp-scope-lock)` 进入 A1,不等用户手动输入。 91 +立即调用 `Skill(scope-lock)` 进入 A1,不等用户手动输入。
skills/plan/project-init/templates/CLAUDE-template.md 0 → 100644
  1 +# CLAUDE.md — ERP项目 Claude Code 主指令文件
  2 +
  3 +> 本文件是 Claude Code 的"操作手册"。Claude Code 启动时会自动读取此文件。
  4 +
  5 +---
  6 +
  7 +## 🎯 项目概述
  8 +
  9 +- **项目名称**: 【人工填写:公司 + 项目名,例如"XX 公司 ERP 管理系统"】
  10 +- **项目简述**: 【人工填写:一句话描述项目目标,例如"面向中小制造企业的全流程 ERP,涵盖采购/库存/生产/销售/财务"】
  11 +- **目标用户**: 【人工填写:谁会用,例如"企业内部管理人员(采购员、仓管员、生产主管、销售员、财务人员、管理层)"】
  12 +- **部署方式**: 【人工填写:私有化部署 / 云部署 / Docker 容器化 等】
  13 +
  14 +---
  15 +
  16 +## 🔄 B 阶段开发流程(模块循环 + 功能循环)
  17 +
  18 +两层嵌套循环**全部固化到 skills**。入口:`/erp-workflow:coding-start`。
  19 +
  20 +- **模块循环(外)**:`module-start` → `test-gate` → `module-report` → `mr-create` → 人工 Approve MR → 下一模块
  21 +- **功能循环(内,每 REQ-XXX-NNN 一遍)**:`feature-brainstorm` → `feature-plan` → `feature-tdd` → `feature-verify` → `feature-review`
  22 +
  23 +MR 前测试闸门:
  24 + - `test-gate`(子会话跑 `scripts/test.sh` 全量——本模块所有 REQ + 已完成模块回归);
  25 + - `.githooks/pre-push` 兜底
  26 + - `git push --no-verify` 被 `deny-no-verify.sh` 硬拦。
  27 +
  28 +---
  29 +
  30 +## ✅ 模块完成判定规则
  31 +
  32 +`docs/08-模块任务管理.md § 二` 是**模块元数据表**——每个模块记录依赖 / 路径 / MR iid / 功能(REQ)子项清单。**模块完成由 `MR:` 字段 + `GitLab API state=merged` 判定**;功能子项勾选只作可视化进度,不参与模块完成判定。
  33 +
  34 +### 规则定义
  35 +
  36 +每个模块在 docs/08 § 二 中长这样:
  37 +
  38 +```markdown
  39 +- module_0 系统管理
  40 + - 依赖: —
  41 + - 路径: backend/module/sys/, frontend/pages/sys/
  42 + - MR: —
  43 + - 功能:
  44 + - [ ] REQ-SYS-001 用户登录
  45 + - [ ] REQ-SYS-002 用户注册
  46 +```
  47 +
  48 +- `MR:` 字段由 `mr-create` 在创建 MR 时从 `—` 改为 `!<iid>`。
  49 +- 每个 `REQ-*` 子项由 `feature-review` 在 `verdict=approve` 时自动勾选为 `[x]`
  50 +- 子项全部勾选不等于模块完成,模块完成判定仍以 `MR:` + GitLab API state 为准。
  51 +
  52 +### 模块状态语义
  53 +
  54 +| `MR:` 字段 | `GitLab API state` | 含义 | 你(Claude Code)的行为 |
  55 +|---|---|---|---|
  56 +| `—` | — | 模块未开始(未创建 MR) | ✅ 开始本模块开发 |
  57 +| `!<iid>` | `opened` / `closed` | 模块开发中 / 打回 | ✅ 继续推进该模块 |
  58 +| `!<iid>` | `merged` | 模块**已完成** | 🟢 进入下一未完成模块 |
  59 +
  60 +### 模块完成报告
  61 +
  62 +由 `module-report` skill 产出,模板位于 由 module-report skill 持有(12 节标准化,含跨模块改动等 CLAUDE.md 软规则映射节)。CC 不手写模块报告,仅填模板。
  63 +
  64 +---
  65 +
  66 +## 🏷️ 占位符统一约定
  67 +
  68 +项目文档里有 **2 种填写占位** + **1 种提示占位**:
  69 +
  70 +| 格式 | 谁填 | 使用阶段 | 说明 |
  71 +|------|-----|---------|------|
  72 +| `【人工填写:<简短说明>】` | 人 | 仅 A 阶段文档 | 密钥 / 账密 / 包名 / 命名约定 / 小版本号等人工才能决定的值;B 阶段 plan/spec 禁止出现,查不到真值时用 `AskUserQuestion` 问用户 |
  73 +| `TBD(<责任人>)` | CC 自动 | A 或 B | 后缀附带责任方(如 `TBD(A3 自动补)` / `TBD(A5 自动补)`);由对应 skill 就地补填,`module-report` § ⑦ 检查 `TBD(CC 补)` 残留 |
  74 +
  75 +**HTML 注释 `<!-- ... -->`**:提示占位,是**插件内部大纲模板**里给 LLM 的**填空提示 / 章节引导**,指引 LLM 按结构填实际内容。skill 生成时会**剥除**这些注释,最终产物里注释不会保留。
  76 +
  77 +---
  78 +
  79 +## 📐 编码行为约束
  80 +
  81 +### 你必须做的 ✅
  82 +
  83 +1. **严格遵循** `docs/04-技术规范.md`——命名 / 编码 / 统一响应 / 异常处理 / 数据访问 / 配置与安全 等项目专属技术规约全部在此
  84 +2. **严格遵循** `docs/09-项目目录结构.md`——文件放对位置
  85 +3. **每个后端接口** 必须先在 `docs/05-API接口契约.md` 定义,再编码实现
  86 +4. **每个功能可追溯到 `REQ-XXX-NNN`**——commit tag + 代码注释(如 `// REQ-SYS-001: 用户登录`)+ plan/spec 文件名均用此 tag
  87 +5. **遇到跨模块改动**(动到非当前模块的代码)——按 § 🟡 软规则 **S2** 执行(允许改,但必须留痕)
  88 +6. **遇到技术栈外组件引入**(`docs/04 § 零` 技术栈表外的框架 / 中间件 / 关键库),按 § 🟡 软规则 **S1** 执行(允许引入,但必须先 AskUserQuestion)
  89 +
  90 +### 你禁止做的 🚫
  91 +
  92 +1. **主会话直接 `mysql -e` 跑业务 DDL**(只读查询 / 临时本地调试除外)——业务 schema 必须走 `sql/migrations/V_n__*.sql`,详见下方 Schema 演化规约
  93 +2. **手动 Edit `docs/08 § 二` 的 `MR:` 字段**,必须要由 `mr-create` 自动回写
  94 +
  95 +### Schema 演化规约(Flyway migration)
  96 +
  97 +1. **文件命名**:`sql/migrations/V<n>__<snake_case_desc>.sql`,例:`V5__add_user_email_unique_index.sql`
  98 +2. **版本号分配**:建文件前 `ls sql/migrations/V*.sql` 查当前最大 n,新文件 `n_max + 1`
  99 +3. **Apply 方式**:Spring Boot 启动 / 测试启动时 Flyway 自动 apply(项目必须在 `pom.xml` 声明 `flyway-core` + `flyway-mysql` 依赖)。`scripts/setup-test-db.sh` 只负责清空库,不做 apply
  100 +4. **已合并的 migration 永不修改**:发现错了写一个补救 migration(如 `V7__fix_V5_index_name.sql`),旧 `V_n.sql`
  101 +5. **临时调试 DDL**:临时在本地试字段/索引可手动 `mysql -e`,但不写 migration;下次 `setup-test-db.sh` 会 drop+create 清掉
  102 +6. **A4 生成的 V1**:`V1__initial_schema.sql` 是 A 阶段由 `db-init` 从 `docs/03-数据库设计文档.md`(A3 正向设计的 schema SSoT)翻译生成的初始版本;后续 V2/V3/... 由 B 阶段每个 REQ 按需写入,**同时**反向同步更新 docs/03 对应表小节以保持 SSoT 一致
  103 +
  104 +---
  105 +
  106 +## 🗂️ Git 提交规范
  107 +
  108 +每次提交必须遵循以下格式:
  109 +
  110 +```
  111 +<type>(<scope>): <subject>
  112 +```
  113 +
  114 +- `scope`: 模块名,如 `user` / `inventory` / `order`
  115 +- `subject`: 简短描述;业务类(feat / fix / test)必须带 `REQ-XXX-NNN` 后缀
  116 +
  117 +`type` 含义:
  118 +
  119 +| type | 看到它意味着 |
  120 +|-----|-------------|
  121 +| `feat` | **新能力上线**——用户多了一个功能、接口、页面或业务规则 |
  122 +| `fix` | **修 bug**——原来行为错了,这次改对 |
  123 +| `refactor` | **重构**——外部行为不变,只改代码结构 / 命名 / 抽象 |
  124 +| `docs` | **文档改动**——只动 Markdown / 代码注释,不动实现 |
  125 +| `style` | **格式调整**——空白 / 缩进 / import 顺序,逻辑 0 变化 |
  126 +| `test` | **只动测试代码**——补用例 / 修 fixture,不碰实现 |
  127 +| `chore` | **流程维护**——构建 / 依赖 / 工具 / 证据档案 / MR 元数据等非业务动作 |
  128 +
  129 +---
  130 +
  131 +## 🚩 中断机制
  132 +
  133 +功能循环(每个功能 REQ-XXX 的 Brainstorm → Plan → TDD → Verify → AI 自审)默认 **静默编程**,但触发以下任何一条必须**立刻停下、记录原因、等人决策**,不得自行绕过:
  134 +
  135 +| # | 中断 | 例子 |
  136 +| - | --- | --- |
  137 +| 1 | **测试反复失败** | 同一测试同一功能内连续 **10 次**修复失败 |
  138 +| 2 | **要改密钥 / 账密 / 包名** | `docs/07-环境配置.md` 里由人工标注必须填的字段 |
  139 +| 3 | **外部接口不可达** | 第三方 API 无法连接、证书失效等环境问题,并无法自行解决 |
  140 +
  141 +> 其余需要人类判断的场景一律走普通 `AskUserQuestion` Q&A,不中断、不写 Blocker 文件。
  142 +
  143 +**触发中断时的固定动作:**
  144 +
  145 +1. 在当前功能的 plan 文件里追加一节 `## 🚩 Blocker`(报告格式由 `interrupt-check` 的 `interrupt-block-template.md` 持有)
  146 +2. 停止后续所有功能的静默执行
  147 +3. 在主会话输出一句话摘要 + 指向 blocker 文件的路径,等人回复
  148 +
  149 +---
  150 +
  151 +## 🟡 软规则(允许继续,但有强制后续动作)
  152 +
  153 +以下情况 **不触发中断**,CC 可自行继续推进,但必须在约定位置留痕,模块完成时统一审计。
  154 +
  155 +| # | 软规则 | 允许动作 | 强制后续 |
  156 +| - | ----- | ------- | ------- |
  157 +| S1 | **技术栈外组件引入** | 用 `AskUserQuestion` 给用户三选一:接受引入 / 换方案 / 拒绝 | ① **接受** → 同会话直接在 `docs/04 § 零` 追加一行 → 继续流程 ② **换方案 / 拒绝** → 视为常规歧义澄清,继续 Q&A 收敛 ③ 不写 Blocker、不中断流程 |
  158 +| S2 | **跨模块改动** | **默认不改**,仅为当前模块实现所必需时允许修改 | ① hook `log-cross-module.sh` 自动落存根 ② `module-report` 一次性调用 `cross-module-log` skill 批量补齐「原因 / 影响评估」+ 「跨模块改动」节完整贴入《模块完成报告》 |
  159 +
  160 +---
  161 +
  162 +## 🧭 通用工作准则(General Principles)
  163 +
  164 +### 1. Think Before Coding
  165 +
  166 +**Don't assume. Don't hide confusion. Surface tradeoffs.**
  167 +
  168 +Before implementing:
  169 +- State your assumptions explicitly. If uncertain, ask.
  170 +- If multiple interpretations exist, present them - don't pick silently.
  171 +- If a simpler approach exists, say so. Push back when warranted.
  172 +- If something is unclear, stop. Name what's confusing. Ask.
  173 +
  174 +### 2. Simplicity First
  175 +
  176 +**Minimum code that solves the problem. Nothing speculative.**
  177 +
  178 +- No features beyond what was asked.
  179 +- No abstractions for single-use code.
  180 +- No "flexibility" or "configurability" that wasn't requested.
  181 +- No error handling for impossible scenarios.
  182 +- If you write 200 lines and it could be 50, rewrite it.
  183 +
  184 +Ask yourself: "Would a senior engineer say this is overcomplicated?" If yes, simplify.
  185 +
  186 +### 3. Surgical Changes
  187 +
  188 +**Touch only what you must. Clean up only your own mess.**
  189 +
  190 +When editing existing code:
  191 +- Don't "improve" adjacent code, comments, or formatting.
  192 +- Don't refactor things that aren't broken.
  193 +- Match existing style, even if you'd do it differently.
  194 +- If you notice unrelated dead code, mention it - don't delete it.
  195 +
  196 +When your changes create orphans:
  197 +- Remove imports/variables/functions that YOUR changes made unused.
  198 +- Don't remove pre-existing dead code unless asked.
  199 +
  200 +The test: Every changed line should trace directly to the user's request.
  201 +
  202 +### 4. Goal-Driven Execution
  203 +
  204 +**Define success criteria. Loop until verified.**
  205 +
  206 +Transform tasks into verifiable goals:
  207 +- "Add validation" → "Write tests for invalid inputs, then make them pass"
  208 +- "Fix the bug" → "Write a test that reproduces it, then make it pass"
  209 +- "Refactor X" → "Ensure tests pass before and after"
  210 +
  211 +For multi-step tasks, state a brief plan:
  212 +```
  213 +1. [Step] → verify: [check]
  214 +2. [Step] → verify: [check]
  215 +3. [Step] → verify: [check]
  216 +```
  217 +
  218 +Strong success criteria let you loop independently. Weak criteria ("make it work") require constant clarification.
skills/plan/erp-project-init/templates/docs-01-readme-template.md renamed to skills/plan/project-init/templates/docs-01-index-template.md
@@ -6,11 +6,11 @@ @@ -6,11 +6,11 @@
6 6
7 | 模块代码 | 模块名称 | 核心功能点(简要) | 7 | 模块代码 | 模块名称 | 核心功能点(简要) |
8 |----------|----------|--------------------| 8 |----------|----------|--------------------|
9 -| SYS | 系统管理 | 【人工填写:用户/角色/权限/部门/字典 等】 |  
10 | 【人工填写:模块代码】 | 【人工填写:模块名称】 | 【人工填写:核心功能点】 | 9 | 【人工填写:模块代码】 | 【人工填写:模块名称】 | 【人工填写:核心功能点】 |
  10 +| SYS | 系统管理 | 用户/角色/权限/部门/字典 等 |
11 11
12 ## 填写说明 12 ## 填写说明
13 13
14 1. 每个模块占一行,`模块代码` 用大写英文缩写(如 SYS / PUR / INV / SAL / FIN / HR) 14 1. 每个模块占一行,`模块代码` 用大写英文缩写(如 SYS / PUR / INV / SAL / FIN / HR)
15 2. `核心功能点` 只需列关键词,CC 会基于此扩展成完整 REQ 卡片 15 2. `核心功能点` 只需列关键词,CC 会基于此扩展成完整 REQ 卡片
16 -3. 填完后运行 `/erp-workflow:erp-plan-start`,CC 会自动检测并进入需求生成阶段 16 +3. 填完后运行 `/erp-workflow:plan-start`,CC 会自动检测并进入需求生成阶段
skills/plan/project-init/templates/docs-04-stack-template.md 0 → 100644
  1 +# 04-技术规范
  2 +
  3 +## 零、技术栈总览
  4 +
  5 +| 分层模块 | 技术 | 版本要求 | 说明 |
  6 +|---|---|---|---|
  7 +| 前端基础框架 | React | 18.x | 构建前端应用 |
  8 +| 前端 UI 组件 | Ant Design | 5.x | 页面组件与交互控件 |
  9 +| 前端状态管理 | Redux Toolkit | 最新稳定版 | 管理全局状态 |
  10 +| 前端路由管理 | React Router | v6 | 页面路由与导航 |
  11 +| 前端工程化构建 | Vite | 最新稳定版 | 前端开发与打包构建 |
  12 +| 前端接口通信 | Axios | 最新稳定版 | 调用后端 API |
  13 +| 后端基础框架 | Spring Boot | 3.x | 构建后端服务 |
  14 +| 后端数据访问 | MyBatis-Plus | 最新稳定版 | 数据库访问与 ORM 增强 |
  15 +| 工作流引擎 | Activiti | 6.x | 审批流、流程流转 |
  16 +| 缓存服务 | Redis | 最新稳定版 | 缓存、会话、分布式能力 |
  17 +| 报表打印 | JXLS | 2.8.1 | 基于 Excel 模板生成报表 |
  18 +| Excel 导入导出 | EasyExcel | 4.0.3 | Excel 数据导入导出 |
  19 +| 关系型数据库 | MySQL | 8.x | 核心业务数据存储 |
  20 +| 数据库 schema 迁移 | Flyway (`flyway-core` + `flyway-mysql`) | 10.x / 最新稳定版 | `sql/migrations/V_n__*.sql` 顺序 apply;Spring Boot 启动时自动应用 |
  21 +| 接口风格 | RESTful API | 统一规范 | 前后端接口设计规范 |
  22 +| 权限认证 | Spring Security / JWT | 最新稳定版 | 登录认证、权限控制 |
  23 +| API 文档 | OpenAPI / Swagger | 最新稳定版 | 接口文档与调试 |
  24 +| 项目构建管理 | Maven | 3.9.x | Java 项目依赖与构建 |
  25 +| JDK 运行环境 | Java | 17 / 21 | Spring Boot 3 推荐版本 |
  26 +| 部署容器 | Docker | 最新稳定版 | 容器化部署 |
  27 +| Web 服务器 / 反向代理 | Nginx | 最新稳定版 | 前端托管、反向代理、负载分发 |
  28 +| 日志管理 | Logback | 默认集成 / 最新稳定版 | 应用日志输出 |
  29 +| 对象映射工具 | MapStruct | 最新稳定版 | DTO / VO / Entity 转换 |
  30 +| 工具类库 | Hutool / Apache Commons | 最新稳定版 | 常用工具方法支持 |
  31 +
  32 +> 本表由 scope-lock 锁定。后续所有规范基于此表推导。
skills/plan/project-init/templates/docs-08-initial-template.md 0 → 100644
  1 +# 08-工作流进度
  2 +
  3 +> 全流程进度跟踪。CC 每完成一项产出就勾选一项。
  4 +> - **§ 一 Plan(A0~A5)**:`plan-start` 找第一个未勾 A 子项分发到对应 skill
  5 +> - **§ 二 Coding(模块)**:分发以 `docs/02-开发计划.md § 二 开发顺序清单` 为准;`coding-start` 按 docs/02 顺序扫描,对每个 REQ 所属模块查询本 § 二的 `MR:` 字段 + GitLab API `state`,找第一个非 merged 模块分发。本 § 二 行序无语义,仅作模块元数据表
  6 +
  7 +## 一、Plan 阶段(一次性)
  8 +
  9 +- [ ] A0 项目初始化 — project-init
  10 + - [ ] 依赖检查通过
  11 + - [ ] 项目文件骨架已创建(CLAUDE.md + docs/01-需求清单/index.md + docs/04-技术规范.md)
  12 + - [ ] Git 已初始化
  13 +
  14 +- [ ] A1 范围锁定 — scope-lock
  15 + - [ ] 项目概述已填写(CLAUDE.md § 🎯 项目概述)
  16 + - [ ] 技术栈已确认(docs/04 § 零)
  17 + - [ ] 需求清单索引已填写(docs/01-需求清单/index.md)
  18 + - [ ] REQ 卡片已生成(docs/01-需求清单/*.md,schema/api 字段标记为 TBD)
  19 +
  20 +- [ ] A2 骨架生成 — skeleton-gen
  21 + - [ ] 架构文档已生成(docs/04 § 一+、docs/06、docs/07、docs/09)
  22 + - [ ] 工具脚本已生成(scripts/*.sh、.githooks/pre-push、.env.local)
  23 + - [ ] .gitignore 已配置
  24 +
  25 +- [ ] A3 DB 设计 + REQ 回填 — db-design-gen
  26 + - [ ] docs/03-数据库设计文档.md 已生成
  27 + - [ ] docs/01 各 REQ 卡片"涉及数据表"已回填
  28 + - [ ] 用户已审阅 docs/03 表结构
  29 +
  30 +- [ ] A4 DB 初始化 — db-init
  31 + - [ ] sql/migrations/V1__initial_schema.sql 已生成
  32 + - [ ] DDL 与 docs/03 全量一致(5 维度校验通过)
  33 + - [ ] .env.local 凭据已验证(mysql -e "SELECT 1" OK)
  34 + - [ ] setup-test-db.sh 防护通过 + DROP+CREATE + apply V1 已执行
  35 + - [ ] SHOW TABLES 行数 == docs/03 表数量
  36 +
  37 +- [ ] A5 下游文档生成 — downstream-gen
  38 + - [ ] docs/02 开发计划已生成
  39 + - [ ] docs/05 API 契约已生成
  40 + - [ ] docs/06 § 五 页面清单已填入
  41 + - [ ] docs/10 验收清单已生成
  42 + - [ ] 下方模块列表已填入
  43 + - [ ] REQ 卡片依赖接口已回填
  44 +
  45 +## 二、Coding 阶段(按模块循环)
  46 +
  47 +(A5 填入后,每行一个模块。每个模块的 `MR:` 字段在 `—` 和 `!<iid>` 之间变化,完成由 GitLab API `state=merged` 判定。`coding-start` 每次按 docs/02 REQ 序扫每模块的 MR state 决定派发。)
  48 +
  49 +<!-- 模块格式示例(由 A5 downstream-gen 追加;功能子项由 feature-review 在 approve 时勾选):
  50 +- module_0 系统管理
  51 + - 依赖: —
  52 + - 路径: backend/module/sys/, frontend/pages/sys/
  53 + - MR: —
  54 + - 功能:
  55 + - [ ] REQ-SYS-001 用户登录
  56 + - [ ] REQ-SYS-002 用户注册
  57 +-->
skills/plan/scope-lock/SKILL.md 0 → 100644
  1 +---
  2 +name: scope-lock
  3 +description: A1 计划范围锁定——引导用户填写项目概述 + 技术栈 + 需求索引,并自动扩展 REQ 卡片待人工评审(依赖表 / 依赖接口两字段由模板写死 `TBD(...)` 占位,A3/A5 后续回填)。
  4 +user-invocable: false
  5 +allowed-tools: Read Write Edit Grep Skill AskUserQuestion
  6 +---
  7 +
  8 +**所有输出必须使用中文。**
  9 +
  10 +# scope-lock
  11 +
  12 +## 执行步骤
  13 +
  14 +### 步骤 0:打印当前位置流程图
  15 +
  16 +向用户展示当前在 A 阶段流程中的位置:
  17 +
  18 +```
  19 +┌──────────────────────────────────────────────────────┐
  20 +│ 📋 阶段 A:规划(一次性) │
  21 +│ │
  22 +│ A0 初始化项目 → ▶ A1 锁范围(REQ 卡片) │
  23 +│ ↓ │
  24 +│ ⏸ 等你审阅 REQ,重新运行 /plan-start 继续 │
  25 +│ ↓ │
  26 +│ A2 生成骨架 → A3 生成 DB 设计 → A4 初始化 DB → A5 生成下游文档│
  27 +│ ↓ │
  28 +│ 规划阶段到此结束 │
  29 +└──────────────────────────────────────────────────────┘
  30 +```
  31 +
  32 +### A. 提示用户填写项目概述并等待
  33 +
  34 +向用户输出:
  35 +
  36 +```
  37 +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  38 + [scope-lock] 请填写项目概述
  39 +
  40 + 📄 文件位置: ./CLAUDE.md
  41 + 📌 编辑位置: § 🎯 项目概述
  42 +
  43 + 请将以下占位符替换为实际值:
  44 + - 项目名称
  45 + - 项目简述
  46 + - 目标用户
  47 + - 部署方式
  48 + 改完后回来选择「继续」。
  49 +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  50 +```
  51 +
  52 +用 `AskUserQuestion` 询问:
  53 +- **question**: `项目概述填写完毕了吗?`
  54 + - 用户选择「继续」→ 用 `Grep` 在 `CLAUDE.md` 搜索 `【人工填写:`(限定 § 🎯 项目概述 节)。命中 → 打印残留行 + 路径,重新弹出同样的 AskUserQuestion;0 命中 → 勾选并进入步骤 B。
  55 + - 用户选择「有疑问想先沟通」→ 回答用户问题后,再次弹出同样的 QA。
  56 +
  57 +0 命中后,用 `Edit` 在 `docs/08-模块任务管理.md` 中勾选:
  58 +- ` - [ ] 项目概述已填写(CLAUDE.md § 🎯 项目概述)`
  59 +
  60 +### B. 提示用户检查默认技术栈并等待
  61 +
  62 +`docs/04-技术规范.md` 已由 A0 `project-init` 用模板复制(默认技术栈,见 `project-init/templates/docs-04-stack-template.md`)。本步骤让用户检查 / 调整 § 零。
  63 +
  64 +向用户输出:
  65 +
  66 +```
  67 +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  68 + [scope-lock] 技术栈已保存
  69 +
  70 + 📄 文件位置: ./docs/04-技术规范.md(由 A0 模板生成)
  71 + 📌 编辑位置: § 零、技术栈总览
  72 +
  73 + 请检查技术栈表:
  74 + - 不需要的行直接删除(如纯后端项目删前端行)
  75 + - 需要替换的技术直接改
  76 + - 需要新增的条目直接加行
  77 + 改完后回来选择「继续」。
  78 +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  79 +```
  80 +
  81 +用 `AskUserQuestion` 询问:
  82 +- **question**: `技术栈检查完毕了吗?`
  83 + - 用户选择「继续」→ 进入步骤 C。
  84 + - 用户选择「有疑问想先沟通」→ 回答用户问题后,再次弹出同样的 QA。
  85 +
  86 +完成后,用 `Edit` 在 `docs/08-模块任务管理.md` 中勾选:
  87 +- ` - [ ] 技术栈已确认(docs/04 § 零)`
  88 +
  89 +### C. 提示用户填写需求清单并等待
  90 +
  91 +`docs/01-需求清单/index.md` 已由 `project-init` 写入占位符模板,这里让用户补齐模块清单。
  92 +
  93 +向用户输出:
  94 +
  95 +```
  96 +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  97 + [scope-lock] 请填写需求清单模块索引
  98 +
  99 + 📄 文件位置: ./docs/01-需求清单/index.md
  100 + 📌 编辑位置: § 模块索引(表格)
  101 +
  102 + 请按业务列出所有模块:
  103 + - 每行一个模块(如 SYS 系统管理 / PUR 采购 / SAL 销售)
  104 + - 「核心功能点」只需关键词,CC 会扩展为完整 REQ 卡片
  105 + 改完后回来选择「继续」。
  106 +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  107 +```
  108 +
  109 +用 `AskUserQuestion` 询问:
  110 +- **question**: `需求清单模块索引填写完毕了吗?`
  111 + - 用户选择「继续」→ 进入步骤 D。
  112 + - 用户选择「有疑问想先沟通」→ 回答用户问题后,再次弹出同样的 QA。
  113 +
  114 +完成后,用 `Edit` 在 `docs/08-模块任务管理.md` 中勾选:
  115 +- ` - [ ] 需求清单索引已填写(docs/01-需求清单/index.md)`
  116 +
  117 +### D. 生成 REQ 卡片并停下等人工审阅
  118 +
  119 +1. 用 `Grep` 校验 `docs/01-需求清单/index.md` 无 `【人工填写:` 残留;有则回步骤 C。
  120 +2. 用 `Read` 读 `index.md` 解析模块索引。
  121 +3. 对每个模块:
  122 + - 基于「核心功能点」扩展若干 REQ-XXX-NNN 卡片
  123 + - 用 `${CLAUDE_SKILL_DIR}/templates/req-card-template.md` 渲染每张(渲染约定见模板顶部 HTML 注释)。
  124 + - 用 `${CLAUDE_SKILL_DIR}/templates/docs-01-module-template.md` 包装卡片列表,用 `Write` 写入 `docs/01-需求清单/<module_code>-<module_name>.md`。
  125 +4. 用 `Edit` 在 `docs/08-模块任务管理.md` 勾选(A1 子项 + A1 顶层):
  126 + - ` - [ ] REQ 卡片已生成(docs/01-需求清单/*.md,schema/api 字段标记为 TBD)`
  127 + - `- [ ] A1 范围锁定 — scope-lock`
  128 +5. 打印停下横幅并**停止**:
  129 +
  130 +```
  131 +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  132 + [scope-lock] ✅ A1 范围锁定完成
  133 +
  134 + 产出:
  135 + ✓ CLAUDE.md § 🎯 项目概述
  136 + ✓ docs/04 § 零 技术栈
  137 + ✓ docs/01-需求清单/index.md 模块索引
  138 + ✓ docs/01-需求清单/<module>-*.md REQ 卡片
  139 +
  140 + ⏸ 现在请你审阅每张 REQ 卡片(路径:`docs/01-需求清单/<module_code>-<module_name>.md`)
  141 +
  142 + 审阅是 Plan 阶段的关键人工关口,请认真逐张过一遍。
  143 + 审阅完成后,运行以下命令继续进入 A2:
  144 + /erp-workflow:plan-start
  145 +
  146 + (入口会读取 docs/08 进度,自动派发到 A2 skeleton-gen)
  147 +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  148 +```
  149 +
  150 +## 参考
  151 +
  152 +- `CLAUDE.md` § 🎯 项目概述(写入目标)
  153 +- `docs/04-技术规范.md`(技术栈输出,供 skeleton-gen 读取使用)
  154 +- `docs/01-需求清单/index.md`(模块索引输入)
  155 +- `docs/01-需求清单/<module>-*.md`(REQ 卡片输出,A3 db-design-gen 会回填 TBD 字段)
  156 +- `${CLAUDE_SKILL_DIR}/templates/req-card-template.md`
  157 +- `${CLAUDE_SKILL_DIR}/templates/docs-01-module-template.md`
skills/plan/erp-scope-lock/templates/docs-01-module-template.md renamed to skills/plan/scope-lock/templates/docs-01-module-template.md
1 # {{module_code}}-{{module_name}} 1 # {{module_code}}-{{module_name}}
2 2
3 模块简述: {{module_brief}} 3 模块简述: {{module_brief}}
4 -依赖模块: {{depends_on}}  
5 -涉及表: {{tables}} 4 +依赖模块: TBD(A5 自动补)
  5 +涉及表: TBD(A3 自动补)
6 6
7 ## 功能清单 7 ## 功能清单
8 8
skills/plan/scope-lock/templates/req-card-template.md 0 → 100644
  1 +<!--
  2 +req-card-template:单张 REQ 卡片结构(三段式)。
  3 +1) 标题 + 目标引言:`### {{req_id}} {{title}}` + 一行 `**目标**: {{goal}}`
  4 +2) 字段表(7 列 × N 行):UI 字段 / API 参数的结构化清单
  5 + - 是多行块占位,每个字段一行,LLM 根据本 REQ 实际字段数**复制该行 N 次**,每行填实际值
  6 + - `{{field_rules}}` 是**字段级**规则(例:"13 位数字"、"至少 1 个"、"员工名选择后显示");多条用 `;` 分割
  7 + - `{{source}}` 若来自 DB 表用反引号包裹(如 `` `职员表` ``)
  8 + - 若本 REQ 无表单字段(纯后台任务),schema 行填占位:`| — | — | — | — | — | — | 无表单输入 |`
  9 +3) REQ 级元数据(bullet list):
  10 + - `**跨字段规则**: {{rules}}` = **REQ 级** 跨字段 / 业务流程规则,与字段表 `{{field_rules}}` 区分
  11 + - `TBD(A3 自动补)` 由 A3 `db-design-gen` 回填
  12 + - `TBD(A5 自动补)` 由 A5 `downstream-gen` 回填
  13 + - REQ 级槽位由 LLM 基于功能点推断。
  14 +渲染时 scope-lock skill 会**剥掉本 HTML 注释**,最终 REQ 卡片不保留。
  15 +-->
  16 +### {{req_id}} {{title}}
  17 +
  18 +**目标**: {{goal}}
  19 +
  20 +| 字段 | 类型 | 必填 | 输入方式 | 显示来源 | 默认值 | 业务规则 |
  21 +|---|---|---|---|---|---|---|
  22 +| {{field}} | {{type}} | {{required}} | {{input_method}} | {{source}} | {{default}} | {{field_rules}} |
  23 +
  24 +- **输出**: {{output}}
  25 +- **跨字段规则**: {{rules}}
  26 +- **边界**: {{constraints}}
  27 +- **验收**: {{acceptance}}
  28 +- **依赖表**: TBD(A3 自动补)
  29 +- **依赖接口**: TBD(A5 自动补)
skills/plan/skeleton-gen/SKILL.md 0 → 100644
  1 +---
  2 +name: skeleton-gen
  3 +description: A2 骨架生成——基于 docs/04 § 零 技术栈 + docs/01-需求清单/index.md 模块索引,生成项目专属的架构文档(docs/04 § 一+、docs/06、docs/07、docs/09)和工具脚本。固定工具文件走 cp,架构文档由 LLM 按大纲生成。
  4 +user-invocable: false
  5 +allowed-tools: Read Write Edit Skill Grep Glob AskUserQuestion Bash(mkdir *) Bash(cp *) Bash(touch *) Bash(chmod *) Bash(git config *) Bash(cat *) Bash(bash *)
  6 +---
  7 +
  8 +**所有输出必须使用中文。**
  9 +
  10 +# skeleton-gen
  11 +
  12 +## 执行步骤
  13 +
  14 +### 步骤 0:打印当前位置流程图
  15 +
  16 +向用户展示当前在 A 阶段流程中的位置:
  17 +
  18 +```
  19 +┌──────────────────────────────────────────────────────┐
  20 +│ 📋 阶段 A:规划(一次性) │
  21 +│ │
  22 +│ A0 初始化项目 → A1 锁范围(REQ 卡片) │
  23 +│ ↓ │
  24 +│ ⏸ 等你审阅 REQ,重新运行 /plan-start 继续 │
  25 +│ ↓ │
  26 +│ ▶ A2 生成骨架 → A3 生成 DB 设计 → A4 初始化 DB → A5 生成下游文档│
  27 +│ ↓ │
  28 +│ 规划阶段到此结束 │
  29 +└──────────────────────────────────────────────────────┘
  30 +```
  31 +
  32 +### A. 读取锁定的输入
  33 +
  34 +用 `Read` 读取:
  35 +- `docs/04-技术规范.md` § 零 技术栈表
  36 +- `docs/01-需求清单/index.md` 需求索引
  37 +- `docs/01-需求清单/` 需求卡片
  38 +
  39 +后续所有内容都基于它们推导。
  40 +
  41 +### B.1 生成 3 个全新架构文档(docs/06 / 07 / 09)
  42 +
  43 +对下表每个目标文件:
  44 +1. 读取对应的大纲模板
  45 +2. 基于步骤 A 的输入,按大纲生成项目专属内容
  46 +3. 剥掉 HTML 注释(注释是给 LLM 的提示,不应出现在最终文档里)
  47 +4. 写入目标路径
  48 +
  49 +| 目标文件 | 大纲模板 |
  50 +|---|---|
  51 +| `docs/06-UI交互规范.md`(§ 一 ~ 四,§ 五 占位) | `${CLAUDE_SKILL_DIR}/templates/docs-06-static-template.md` |
  52 +| `docs/07-环境配置.md` | `${CLAUDE_SKILL_DIR}/templates/docs-07-env-template.md` |
  53 +| `docs/09-项目目录结构.md` | `${CLAUDE_SKILL_DIR}/templates/docs-09-structure-template.md` |
  54 +
  55 +项目专属标识(根包名 / 命名空间)保留 `【人工填写:<说明>】` 占位,等人工在 docs/09 顶部补填一次后,其他文件复用。
  56 +
  57 +### B.2 追加 docs/04 § 一+(保留 § 零 不覆盖)
  58 +
  59 +docs/04 已由 scope-lock 写入 § 零。本步骤追加 § 一 ~ 三。
  60 +
  61 +1. 读取 `docs/04-技术规范.md`(现有 § 零 完整内容)。
  62 +2. 读取 `${CLAUDE_SKILL_DIR}/templates/docs-04-skeleton-template.md`。
  63 +3. 基于技术栈,按大纲生成 § 一 ~ 三 的项目专属内容,剥掉 HTML 注释。
  64 +4. 拼接原有内容和新生成内容,写回 `docs/04-技术规范.md`。
  65 +
  66 +完成后,用 `Edit` 在 `docs/08-模块任务管理.md` 中勾选:
  67 +- ` - [ ] 架构文档已生成(docs/04 § 一+、docs/06、docs/07、docs/09)`
  68 +
  69 +### C. 生成工具脚本
  70 +
  71 +#### C.1 复制
  72 +
  73 +```bash
  74 +mkdir -p scripts .githooks sql/migrations
  75 +touch sql/migrations/.gitkeep
  76 +cp "${CLAUDE_SKILL_DIR}/templates/env-local-template" .env.local
  77 +cp "${CLAUDE_SKILL_DIR}/templates/githooks-pre-push-template.sh" .githooks/pre-push
  78 +cp "${CLAUDE_SKILL_DIR}/templates/scripts-setup-test-db-template.sh" scripts/setup-test-db.sh
  79 +```
  80 +
  81 +#### C.2 渲染 scripts/test.sh
  82 +
  83 +读取 `${CLAUDE_SKILL_DIR}/templates/scripts-test-template.sh`,基于步骤 A 的技术栈(docs/04)推断命令后写到 `scripts/test.sh`:
  84 +
  85 +- `{{build_cmd}}` 构建
  86 +- `{{lint_cmd}}` lint
  87 +- `{{test_cmd}}` unit + integration
  88 +- `{{e2e_cmd}}` E2E(无 E2E 则填 `echo "[test.sh] e2e 略"`)
  89 +
  90 +> 双端项目(backend + frontend)用 `(cd backend && <cmd>) && (cd frontend && <cmd>)` 串联;单端直接写一条。
  91 +
  92 +#### C.3 赋权 + 配置 git hooks
  93 +
  94 +```bash
  95 +chmod +x scripts/*.sh .githooks/pre-push
  96 +git config core.hooksPath .githooks
  97 +```
  98 +
  99 +完成后,用 `Edit` 在 `docs/08-模块任务管理.md` 中勾选:
  100 +- ` - [ ] 工具脚本已生成(scripts/*.sh、.githooks/pre-push、.env.local)`
  101 +
  102 +### D. 追加 .gitignore 忽略项
  103 +
  104 +调用脚本完成合并:
  105 +
  106 +```bash
  107 +bash "${CLAUDE_SKILL_DIR}/scripts/merge-gitignore.sh" "${CLAUDE_SKILL_DIR}/templates/gitignore-append-template"
  108 +```
  109 +
  110 +完成后,用 `Edit` 在 `docs/08-模块任务管理.md` 中勾选:
  111 +- ` - [ ] .gitignore 已配置`
  112 +
  113 +### E. 占位符补填 + QA 闸门
  114 +
  115 +#### E.1 扫描 + 分组
  116 +
  117 +用 `Grep` 在以下 8 个路径扫 `【人工填写:`,记录命中(文件 / 行号 / 说明):
  118 +- `docs/04-技术规范.md` / `docs/06-UI交互规范.md` / `docs/07-环境配置.md` / `docs/09-项目目录结构.md`
  119 +- `scripts/*.sh` / `.githooks/pre-push` / `.gitignore`
  120 +- `.env.local`
  121 +
  122 +分两组:
  123 +- **敏感组**:`.env.local` 路径命中(凭据 / 密钥)。**不弹 QA**(凭据不进会话),E.3 提示用户自填。
  124 +- **非敏感组**:其余文件。按说明文字聚合为「根占位」(相同说明 = 同一值,多处共用)或「派生占位」(说明表达派生关系,如"后端 java 根包路径"派生自"根包名")。
  125 +
  126 +无命中 → 跳 E.4。
  127 +
  128 +#### E.2 问根占位 + 推派生 + 批量 Edit
  129 +
  130 +- 每个根占位用 `AskUserQuestion` 问(给合理默认值 + 自由输入),用 `Edit` 批量替换所有命中位置
  131 +- 派生占位**不问**,CC 基于根占位值推断后 `Edit`;不能可靠推断则回退当独立根占位问
  132 +
  133 +#### E.3 敏感占位提示(不弹 QA)
  134 +
  135 +若敏感组非空:打印提示横幅,列出 `.env.local` 待填字段名 + 告诉用户"直接编辑文件,凭据不进会话"。
  136 +
  137 +#### E.4 验证 + QA 闸门
  138 +
  139 +循环直到两条件**同时**满足:
  140 +(a) `Grep` 重新扫 8 路径,0 命中
  141 +(b) 用户 `AskUserQuestion` 选「继续」
  142 +
  143 +每次弹 QA 前重扫;有残留则打印残留位置清单(文件:行号 — 说明)+ 再弹 QA。
  144 +
  145 +QA 横幅涵盖:产出文件清单(docs/04 / 06 / 07 / 09 + scripts/*.sh + .githooks/pre-push + .env.local + .gitignore)、占位状态(N=0 或待填清单)、「继续」/「有疑问先沟通」两选项。
  146 +
  147 +通过后(N=0 且用户选「继续」),用 `Edit` 在 `docs/08-模块任务管理.md` 中勾选:
  148 +- `- [ ] A2 骨架生成 — skeleton-gen`
  149 +
  150 +### F. 进入 A3
  151 +
  152 +输出 `skeleton-gen: 完成`,立即调用 `Skill(db-design-gen)`。
  153 +
  154 +## 参考
  155 +
  156 +- `docs/04-技术规范.md` § 零(技术栈输入)
  157 +- `docs/01-需求清单/index.md`(模块索引输入)
  158 +- `${CLAUDE_SKILL_DIR}/templates/docs-04-skeleton-template.md`(大纲)
  159 +- `${CLAUDE_SKILL_DIR}/templates/docs-06-static-template.md`(大纲)
  160 +- `${CLAUDE_SKILL_DIR}/templates/docs-07-env-template.md`(大纲)
  161 +- `${CLAUDE_SKILL_DIR}/templates/docs-09-structure-template.md`(大纲)
  162 +- `${CLAUDE_SKILL_DIR}/templates/scripts-setup-test-db-template.sh`(0 槽位)
  163 +- `${CLAUDE_SKILL_DIR}/templates/githooks-pre-push-template.sh`(0 槽位)
  164 +- `${CLAUDE_SKILL_DIR}/templates/env-local-template`(0 槽位)
  165 +- `${CLAUDE_SKILL_DIR}/templates/gitignore-append-template`(0 槽位)
  166 +- `${CLAUDE_SKILL_DIR}/scripts/merge-gitignore.sh`(.gitignore 逐行判重合并脚本)
skills/plan/erp-skeleton-gen/scripts/merge-gitignore.sh renamed to skills/plan/skeleton-gen/scripts/merge-gitignore.sh
@@ -5,7 +5,7 @@ @@ -5,7 +5,7 @@
5 # - 若已存在 → 逐行判重,只追加模板里缺失的规则行(跳过注释/空行) 5 # - 若已存在 → 逐行判重,只追加模板里缺失的规则行(跳过注释/空行)
6 # 6 #
7 # 用法:merge-gitignore.sh <template_path> [<target_gitignore_path>] 7 # 用法:merge-gitignore.sh <template_path> [<target_gitignore_path>]
8 -# template_path 模板文件绝对路径(由 erp-skeleton-gen skill 传入) 8 +# template_path 模板文件绝对路径(由 skeleton-gen skill 传入)
9 # target_gitignore_path 目标 .gitignore 路径,默认为当前工作目录下的 .gitignore 9 # target_gitignore_path 目标 .gitignore 路径,默认为当前工作目录下的 .gitignore
10 # 10 #
11 # 判重:grep -xF 整行精确匹配 + 字面字符串(非正则),避免 .env 误匹配 .env.local, 11 # 判重:grep -xF 整行精确匹配 + 字面字符串(非正则),避免 .env 误匹配 .env.local,
skills/plan/erp-skeleton-gen/templates/docs-04-skeleton-template.md renamed to skills/plan/skeleton-gen/templates/docs-04-skeleton-template.md
1 <!-- 1 <!--
2 本文件是 docs/04-技术规范.md 的 § 一+ 大纲。 2 本文件是 docs/04-技术规范.md 的 § 一+ 大纲。
3 -skeleton-gen 读取 docs/04 § 零(技术栈表)和 docs/01-需求清单/README.md(模块索引), 3 +skeleton-gen 读取 docs/04 § 零(技术栈表)和 docs/01-需求清单/index.md(模块索引),
4 按下述大纲生成本项目专属的规范内容。LLM 不要原样拷贝提示文字,只保留 section 标题。 4 按下述大纲生成本项目专属的规范内容。LLM 不要原样拷贝提示文字,只保留 section 标题。
5 --> 5 -->
6 6
@@ -16,7 +16,7 @@ skeleton-gen 读取 docs/04 § 零(技术栈表)和 docs/01-需求清单/REA @@ -16,7 +16,7 @@ skeleton-gen 读取 docs/04 § 零(技术栈表)和 docs/01-需求清单/REA
16 <!-- 成功/失败的 JSON 结构,错误码段位划分。 --> 16 <!-- 成功/失败的 JSON 结构,错误码段位划分。 -->
17 17
18 ### 1.4 异常处理 18 ### 1.4 异常处理
19 -<!-- 全局异常处理器的使用方式;哪些异常要 catch,哪些禁止。 --> 19 +<!-- 全局异常处理器的使用方式;哪些异常要 catch,哪些禁止;**接口响应禁止回显后端异常堆栈**(返用户友好错误码 + 文案)。 -->
20 20
21 ### 1.5 事务 21 ### 1.5 事务
22 <!-- 事务边界(通常 service 层);跨服务调用的禁止/替代方案。 --> 22 <!-- 事务边界(通常 service 层);跨服务调用的禁止/替代方案。 -->
@@ -27,7 +27,7 @@ skeleton-gen 读取 docs/04 § 零(技术栈表)和 docs/01-需求清单/REA @@ -27,7 +27,7 @@ skeleton-gen 读取 docs/04 § 零(技术栈表)和 docs/01-需求清单/REA
27 ## 二、前端规范 27 ## 二、前端规范
28 28
29 ### 2.1 目录约定 29 ### 2.1 目录约定
30 -<!-- 基于 § 零 前端框架推导:api/components/pages/store/hooks/utils 的职责。 --> 30 +<!-- 基于 § 零 前端框架推导:api/components/pages/store/hooks/utils 的职责;**前端禁止直接写 SQL / 操作 DB**,所有数据访问走 api/ 层统一封装。 -->
31 31
32 ### 2.2 状态管理 32 ### 2.2 状态管理
33 <!-- 基于 § 零 状态管理技术推导:全局 vs 局部、服务端数据的存放。 --> 33 <!-- 基于 § 零 状态管理技术推导:全局 vs 局部、服务端数据的存放。 -->
@@ -48,3 +48,10 @@ skeleton-gen 读取 docs/04 § 零(技术栈表)和 docs/01-需求清单/REA @@ -48,3 +48,10 @@ skeleton-gen 读取 docs/04 § 零(技术栈表)和 docs/01-需求清单/REA
48 48
49 ### 3.3 日期与金额 49 ### 3.3 日期与金额
50 <!-- 后端类型(如 LocalDateTime / BigDecimal)+ 前端展示工具;金额精度约定。 --> 50 <!-- 后端类型(如 LocalDateTime / BigDecimal)+ 前端展示工具;金额精度约定。 -->
  51 +
  52 +### 3.4 数据访问规约
  53 +<!-- 基于 § 零 数据访问技术(MyBatis-Plus / JPA 等):SELECT 字段显式列举,**禁止 `SELECT *`**;循环中不得执行 DB 查询(**N+1 反模式**),改用批量查 / IN 子句 / JOIN;Mapper XML 里字段与表名用常量或引用,避免拼字符串。 -->
  54 +
  55 +### 3.5 配置与安全
  56 +<!-- 配置:DB 连接 / 端口 / 密钥 / 第三方 URL 等一律放 `application.yml` + `.env.local`,代码里**禁止硬编码**。
  57 + 前端安全:`localStorage` 不存敏感信息(token / 身份 / 个人数据),推荐 HttpOnly Cookie 或 内存 + 刷新 token 模式;接口响应禁止回显后端异常堆栈(与 § 1.4 一致)。 -->
skills/plan/erp-skeleton-gen/templates/docs-06-static-template.md renamed to skills/plan/skeleton-gen/templates/docs-06-static-template.md
1 <!-- 1 <!--
2 -本文件是 docs/06-UI交互规范.md çš„ § 一~å›› 大纲(§ 五由 erp-downstream-gen 追加)。  
3 -skeleton-gen è¯»å– docs/04 § é›¶ å’Œ docs/01 README,按下述大纲生æˆé¡¹ç›®ä¸“属内容。 2 +本文件是 docs/06-UI交互规范.md çš„ § 一~å›› 大纲(§ 五由 downstream-gen 追加)。
  3 +skeleton-gen è¯»å– docs/04 § é›¶ å’Œ docs/01 index,按下述大纲生æˆé¡¹ç›®ä¸“属内容。
4 UI ç»†èŠ‚ï¼ˆå¸ƒå±€å‚æ•°ã€é¢œè‰²ã€ç»„件选型)æ¥è‡ª § é›¶ å‰ç«¯ UI 组件库。 4 UI ç»†èŠ‚ï¼ˆå¸ƒå±€å‚æ•°ã€é¢œè‰²ã€ç»„件选型)æ¥è‡ª § é›¶ å‰ç«¯ UI 组件库。
5 --> 5 -->
6 6
@@ -15,7 +15,7 @@ UI ç»†èŠ‚ï¼ˆå¸ƒå±€å‚æ•°ã€é¢œè‰²ã€ç»„件选型)æ¥è‡ª § é›¶ å‰ç«¯ UI ç»„ä» @@ -15,7 +15,7 @@ UI ç»†èŠ‚ï¼ˆå¸ƒå±€å‚æ•°ã€é¢œè‰²ã€ç»„件选型)æ¥è‡ª § é›¶ å‰ç«¯ UI 组ä»
15 <!-- 表格形å¼ï¼šHeader 高度 / Sidebar 宽度 / å†…è¾¹è· / 最å°åˆ†è¾¨çŽ‡ï¼Œç»™å‡ºé»˜è®¤å€¼ã€‚ --> 15 <!-- 表格形å¼ï¼šHeader 高度 / Sidebar 宽度 / å†…è¾¹è· / 最å°åˆ†è¾¨çŽ‡ï¼Œç»™å‡ºé»˜è®¤å€¼ã€‚ -->
16 16
17 ## äºŒã€æ ‡å‡†é¡µé¢ç±»åž‹ 17 ## äºŒã€æ ‡å‡†é¡µé¢ç±»åž‹
18 -<!-- æ ¹æ® docs/01 README 的模å—索引推断业务å¯èƒ½å‡ºçŽ°çš„é¡µé¢ç±»åž‹ï¼ˆé€šå¸¸åˆ—表/表å•/详情/æ ‘å½¢ 4 类,根æ®é¡¹ç›®è£å‰ªï¼‰ã€‚ --> 18 +<!-- æ ¹æ® docs/01 index 的模å—索引推断业务å¯èƒ½å‡ºçŽ°çš„é¡µé¢ç±»åž‹ï¼ˆé€šå¸¸åˆ—表/表å•/详情/æ ‘å½¢ 4 类,根æ®é¡¹ç›®è£å‰ªï¼‰ã€‚ -->
19 19
20 ### 2.1 列表页 20 ### 2.1 列表页
21 <!-- 顶部æ“作区 + æœç´¢æ  + 表格 + 分页,关键组件选型。 --> 21 <!-- 顶部æ“作区 + æœç´¢æ  + 表格 + 分页,关键组件选型。 -->
@@ -44,4 +44,4 @@ UI ç»†èŠ‚ï¼ˆå¸ƒå±€å‚æ•°ã€é¢œè‰²ã€ç»„件选型)æ¥è‡ª § é›¶ å‰ç«¯ UI ç»„ä» @@ -44,4 +44,4 @@ UI ç»†èŠ‚ï¼ˆå¸ƒå±€å‚æ•°ã€é¢œè‰²ã€ç»„件选型)æ¥è‡ª § é›¶ å‰ç«¯ UI 组ä»
44 <!-- 基于 § é›¶ UI 库的主题 token;主色 / æˆåŠŸ / 警告 / 错误 色值。 --> 44 <!-- 基于 § é›¶ UI 库的主题 token;主色 / æˆåŠŸ / 警告 / 错误 色值。 -->
45 45
46 ## 五ã€é¡µé¢æ¸…å•(CC 生æˆï¼‰ 46 ## 五ã€é¡µé¢æ¸…å•(CC 生æˆï¼‰
47 -(由 `erp-downstream-gen` 按模å—追加段è½ï¼‰ 47 +(由 `downstream-gen` 按模å—追加段è½ï¼‰
skills/plan/erp-skeleton-gen/templates/docs-07-env-template.md renamed to skills/plan/skeleton-gen/templates/docs-07-env-template.md
skills/plan/erp-skeleton-gen/templates/docs-09-structure-template.md renamed to skills/plan/skeleton-gen/templates/docs-09-structure-template.md
@@ -6,7 +6,7 @@ skeleton-gen 基于 docs/04 § 零 技术栈推导目录树: @@ -6,7 +6,7 @@ skeleton-gen 基于 docs/04 § 零 技术栈推导目录树:
6 § 四 docs 目录 → 沿用插件标准 6 § 四 docs 目录 → 沿用插件标准
7 § 五 命名约定 → 按后端语言的包/命名空间习惯 7 § 五 命名约定 → 按后端语言的包/命名空间习惯
8 8
9 -模块划分参考 docs/01-需求清单/README.md 的模块索引,将业务模块落到代码目录。 9 +模块划分参考 docs/01-需求清单/index.md 的模块索引,将业务模块落到代码目录。
10 --> 10 -->
11 11
12 # 09-项目目录结构 12 # 09-项目目录结构
@@ -17,7 +17,7 @@ skeleton-gen 基于 docs/04 § 零 技术栈推导目录树: @@ -17,7 +17,7 @@ skeleton-gen 基于 docs/04 § 零 技术栈推导目录树:
17 17
18 ## 二、后端目录 18 ## 二、后端目录
19 19
20 -<!-- 基于后端框架的目录树;按 docs/01 README 的模块代码把业务模块列出(module/user/、module/order/ 等)。 --> 20 +<!-- 基于后端框架的目录树;按 docs/01 index 的模块代码把业务模块列出(module/user/、module/order/ 等)。 -->
21 21
22 ## 三、前端目录 22 ## 三、前端目录
23 23
skills/plan/erp-skeleton-gen/templates/env-local-template renamed to skills/plan/skeleton-gen/templates/env-local-template
@@ -24,8 +24,8 @@ JWT_SECRET=【人工填写:JWT 签名密钥,256+ bit 随机串】 @@ -24,8 +24,8 @@ JWT_SECRET=【人工填写:JWT 签名密钥,256+ bit 随机串】
24 # (防护 2 还会检查 schema 名须含 test/_dev/_local/_ci,独立兜底。) 24 # (防护 2 还会检查 schema 名须含 test/_dev/_local/_ci,独立兜底。)
25 TEST_DB_ALLOWED_HOSTS= 25 TEST_DB_ALLOWED_HOSTS=
26 26
27 -# GitLab REST API 接入(erp-mr-create / erp-coding-start / erp-module-start 用 curl 调用,无需 glab CLI):  
28 -# - GITLAB_API_URL:GitLab API base。本项目服务器用 v3。A5 `erp-downstream-gen` 从 `git remote get-url origin` 27 +# GitLab REST API 接入(mr-create / coding-start / module-start 用 curl 调用,无需 glab CLI):
  28 +# - GITLAB_API_URL:GitLab API base。本项目服务器用 v3。A5 `downstream-gen` 从 `git remote get-url origin`
29 # 自动派生为 `<scheme>://<host>/api/v3`;如派生的 scheme 错(例如远程是 ssh 但实际 web 走 https),手动改掉即可 29 # 自动派生为 `<scheme>://<host>/api/v3`;如派生的 scheme 错(例如远程是 ssh 但实际 web 走 https),手动改掉即可
30 # - GITLAB_TOKEN:GitLab v3 的 **Private Token**(用户 Profile → Account → Private token 生成;HTTP 调用仍用 30 # - GITLAB_TOKEN:GitLab v3 的 **Private Token**(用户 Profile → Account → Private token 生成;HTTP 调用仍用
31 # `PRIVATE-TOKEN` 头。v3 token 是全权限、无细粒度 scope)。**无法派生,必须人工填** 31 # `PRIVATE-TOKEN` 头。v3 token 是全权限、无细粒度 scope)。**无法派生,必须人工填**
skills/plan/erp-skeleton-gen/templates/githooks-pre-push-template.sh renamed to skills/plan/skeleton-gen/templates/githooks-pre-push-template.sh
skills/plan/erp-skeleton-gen/templates/gitignore-append-template renamed to skills/plan/skeleton-gen/templates/gitignore-append-template
1 -# ==== ERP 插件推荐忽略项(erp-skeleton-gen 追加) ==== 1 +# ==== ERP 插件推荐忽略项(skeleton-gen 追加) ====
2 # 本地运行时配置(含真实凭据,严禁入库) 2 # 本地运行时配置(含真实凭据,严禁入库)
3 .env.local 3 .env.local
4 .env.*.local 4 .env.*.local
skills/plan/erp-skeleton-gen/templates/scripts-setup-test-db-template.sh renamed to skills/plan/skeleton-gen/templates/scripts-setup-test-db-template.sh
skills/plan/skeleton-gen/templates/scripts-test-template.sh 0 → 100644
  1 +#!/usr/bin/env bash
  2 +# scripts/test.sh —— 合并到默认分支(main / master)前的测试闸门。
  3 +# 顺序:setup-db → build → lint → unit+integration → e2e → reset-db
  4 +# 由 .githooks/pre-push 和 test-gate skill(通过子会话)调用。
  5 +
  6 +set -euo pipefail
  7 +
  8 +PROJECT_ROOT="$(cd "$(dirname "$0")/.." && pwd)"
  9 +cd "$PROJECT_ROOT"
  10 +
  11 +echo "[test.sh] 1/6 setup test db"
  12 +./scripts/setup-test-db.sh
  13 +
  14 +echo "[test.sh] 2/6 build"
  15 +{{build_cmd}}
  16 +
  17 +echo "[test.sh] 3/6 lint"
  18 +{{lint_cmd}}
  19 +
  20 +echo "[test.sh] 4/6 unit + integration"
  21 +{{test_cmd}}
  22 +
  23 +echo "[test.sh] 5/6 E2E"
  24 +{{e2e_cmd}}
  25 +
  26 +echo "[test.sh] 6/6 reset test db"
  27 +./scripts/setup-test-db.sh
  28 +
  29 +echo "[test.sh] GREEN"