Commit d61c07b15790812ceb77f6dcfdbc0068ef5188a9

Authored by zichun
1 parent f7306acf

skill(plan A3-A6): trim banners, drop redundant verification loops, defer plan-start narration

skills/plan/db-design-gen/SKILL.md
1 --- 1 ---
2 name: db-design-gen 2 name: db-design-gen
3 -description: A3 DB 设计 + REQ 回填——基于 docs/01-需求清单/<module>/REQ-*.md 正向设计 docs/03-数据库设计文档.md(业务实体 → 表 + 字段 + 索引 + 外键 + 业务注记),并把回填值写入 REQ 卡片的「依赖表: TBD(A3 自动补)」与模块头的「涉及表: TBD(A3 自动补)」占位。生成完毕停下等人工审阅。 3 +description: A3 DB 设计 + REQ 回填——A0 确认 schema 约定写入 docs/04 + CLAUDE.md;基于 docs/01 REQ 卡片正向设计 docs/03(表/字段/索引/外键/业务注记),并回填 REQ 卡片「依赖表」与模块头「涉及表」的 `TBD(A3 自动补)`。停下等人工审阅。
4 user-invocable: false 4 user-invocable: false
5 allowed-tools: Read Write Edit Grep Glob AskUserQuestion 5 allowed-tools: Read Write Edit Grep Glob AskUserQuestion
6 --- 6 ---
@@ -18,30 +18,15 @@ allowed-tools: Read Write Edit Grep Glob AskUserQuestion @@ -18,30 +18,15 @@ allowed-tools: Read Write Edit Grep Glob AskUserQuestion
18 18
19 ### 步骤 A0:确认 ERP schema 约定(一次性) 19 ### 步骤 A0:确认 ERP schema 约定(一次性)
20 20
21 -在正向设计 schema 之前,**先确认本项目的 3 项数据库约定**。默认值即现 ERP 约定,用户可逐项覆盖。结果写入 `docs/04` + `CLAUDE.md`,本 skill 后续步骤(B/C)严格引用确认后的值,不再字面写死。 21 +先 `Grep` `docs/04-技术规范.md § 四 数据库 schema 约定`。已存在则读取后直接进入步骤 A;缺失则按下表默认值,逐项问用户是否覆盖:
22 22
23 -> 先用 `Grep` 检查 `docs/04-技术规范.md` 是否已含 `## 四、数据库 schema 约定` 节。**已存在则视为本约定已确认**,跳过本步骤直接读取该节作为 `PK_CONVENTION` / `TENANT_COLS` / `COL_PREFIX_RULE` 的值,进入步骤 A。 23 +| 键 | 默认值(ERP 沿用) |
  24 +|---|---|
  25 +| `PK_CONVENTION` | `iIncrement` int 主键 + `sId` varchar(100) 业务 ID |
  26 +| `TENANT_COLS` | `sBrandsId` varchar(100) + `sSubsidiaryId` varchar(100),默认值 `1111111111`(无多租户则填「无」) |
  27 +| `COL_PREFIX_RULE` | 匈牙利前缀 `i`=int / `s`=varchar / `t`=datetime(无前缀则填「无前缀」) |
24 28
25 -用 `AskUserQuestion` 一次性提出以下 3 个问题(每题给「沿用默认」与「自定义」两类选项;选自定义时追问具体值):  
26 -  
27 -1. **主键约定(PK_CONVENTION)**  
28 - - 默认(沿用 ERP):`iIncrement` int 整数主键(自增方式由实现决定:DB `AUTO_INCREMENT` 或应用/触发器分配),另设 `sId` varchar(100) 业务 ID 对外暴露。  
29 - - 自定义:用户给出主键列名 / 类型 / 生成策略(如复合主键 / UUID / 业务主键)。  
30 -  
31 -2. **租户隔离列(TENANT_COLS)**  
32 - - 默认(沿用 ERP):`sBrandsId` varchar(100)(品牌 ID,多租户隔离)+ `sSubsidiaryId` varchar(100)(子公司 ID,组织层级隔离),默认值均为 `1111111111`。  
33 - - 自定义:用户给出租户列名 / 类型 / 默认值,或声明本项目不做多租户隔离(此时 TENANT_COLS = 「无」)。  
34 -  
35 -3. **列命名前缀规则(COL_PREFIX_RULE)**  
36 - - 默认(沿用 ERP):匈牙利前缀——`i` = int、`s` = varchar、`t` = datetime。  
37 - - 自定义:用户给出自己的前缀/命名规则,或声明不使用前缀(此时 COL_PREFIX_RULE = 「无前缀,列名直接用业务语义」)。  
38 -  
39 -得到三项确认值后:  
40 -  
41 -- **写入 `docs/04-技术规范.md`**:用 `Grep` 确认无 `## 四、数据库 schema 约定` 节后,用 `Edit` 在文末追加该节,列出 `PK_CONVENTION` / `TENANT_COLS` / `COL_PREFIX_RULE` 三项的确认值(每项含列名/类型/默认值/生成策略的完整描述)。  
42 -- **写入 `CLAUDE.md`**:用 `Edit` 在「Schema 演化规约」节末尾追加一条「数据库 schema 约定(A3 确认)」小节,简述三项约定,并注明「详见 `docs/04 § 四`」。  
43 -  
44 -后续步骤 B/C 用到 `{{PK_CONVENTION}}` / `{{TENANT_COLS}}` / `{{COL_PREFIX_RULE}}` 处,一律引用此处确认后的值。 29 +如 `docs/04 § 四` 缺失,用 `AskUserQuestion` 一次性收三项覆盖(默认即沿用上表),然后 `Edit` 追加 `docs/04 § 四` + 在 `CLAUDE.md`「Schema 演化规约」末尾追加「数据库 schema 约定(A3 确认)」一段引用 `docs/04 § 四`。后续 B/C 步骤一律引用确认后的值。
45 30
46 ### A. 读取设计输入 31 ### A. 读取设计输入
47 32
@@ -86,32 +71,15 @@ allowed-tools: Read Write Edit Grep Glob AskUserQuestion @@ -86,32 +71,15 @@ allowed-tools: Read Write Edit Grep Glob AskUserQuestion
86 1. 完成后,用 `Edit` 在 `docs/08-模块任务管理.md` 中勾选 A3 顶层(A3 两个子项已在 C / D 步骤分别勾选): 71 1. 完成后,用 `Edit` 在 `docs/08-模块任务管理.md` 中勾选 A3 顶层(A3 两个子项已在 C / D 步骤分别勾选):
87 - `- [ ] A3 DB 设计 + REQ 回填 — db-design-gen` 72 - `- [ ] A3 DB 设计 + REQ 回填 — db-design-gen`
88 73
89 -2. 打印停下横幅并**停下** 74 +2. 打印停下横幅并**停下**,不调用任何下游 skill
90 75
91 ``` 76 ```
92 - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━  
93 - [db-design-gen] ✅ A3 DB 设计完成  
94 -  
95 - 产出:  
96 - ✓ docs/03-数据库设计文档.md  
97 - ✓ docs/01-需求清单/<module>/REQ-*.md 依赖表已回填 + _module.md 涉及表已回填  
98 -  
99 - ⏸ 现在请你审阅 docs/03。  
100 - 重点关注:  
101 - - 业务实体覆盖是否完整  
102 - - 字段类型 / 长度 / 是否可空 / 默认值是否合理  
103 - - 索引是否覆盖主要查询模式  
104 - - 外键 ON DELETE / ON UPDATE 策略是否符合业务  
105 - - 字段「业务含义」列含 `【人工填写:需用户审阅】` 标注的位置需逐一确认  
106 -  
107 - 审阅完成后,再运行:  
108 - /erp-workflow:plan-start  
109 -  
110 - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 77 + [db-design-gen] ✅ A3 DB 设计完成
  78 + 产出:docs/03-数据库设计文档.md + REQ 卡片依赖表/模块头涉及表已回填
  79 + ⏸ 请审阅 docs/03(业务实体覆盖、字段类型/默认值、索引、外键策略、`【人工填写:需用户审阅】` 标注)。
  80 + 审阅完成后运行:/erp-workflow:plan-start
111 ``` 81 ```
112 82
113 - **停止**,不调用任何下游 skill。  
114 -  
115 ## 参考 83 ## 参考
116 84
117 - `${CLAUDE_SKILL_DIR}/templates/docs-03-header-template.md` 85 - `${CLAUDE_SKILL_DIR}/templates/docs-03-header-template.md`
skills/plan/db-init/SKILL.md
@@ -15,31 +15,20 @@ allowed-tools: Read Write Edit Glob Skill Bash(node *) Bash(mysql *) @@ -15,31 +15,20 @@ allowed-tools: Read Write Edit Glob Skill Bash(node *) Bash(mysql *)
15 15
16 #### A.1 读 docs/03 并翻译为 DDL 16 #### A.1 读 docs/03 并翻译为 DDL
17 17
18 -读取 `docs/03-数据库设计文档.md`,按字段 / 索引 / 外键 / 业务注记**严格翻译**为:  
19 -  
20 -- 每张表一段 `CREATE TABLE`  
21 -- 字段顺序与 docs/03 表格行序一致;`Nullable` 列直接映射 `NOT NULL` / `NULL`;`默认` 列映射 `DEFAULT <value>`;列尾用 `COMMENT '<业务含义>'` 写注释  
22 -- 索引  
23 -- 外键:在所有表创建完成后**统一追加**  
24 -  
25 -要求:  
26 -- **严禁臆造** docs/03 中没有的表 / 字段 / 索引 / 外键  
27 -- **严禁省略** docs/03 中已有的列、注释或约束  
28 -- 字符集统一 `utf8mb4` + `utf8mb4_unicode_ci`,引擎统一 `InnoDB`,除非 docs/03 业务注记明确要求其他设置 18 +读取 `docs/03-数据库设计文档.md`,对每张表生成一段 `CREATE TABLE`(字段顺序/可空/默认/列注释严格对齐 docs/03 行序),随后按顺序追加 `CREATE INDEX` 与统一追加的 `ALTER TABLE ... ADD CONSTRAINT ... FOREIGN KEY`。**严禁臆造或省略** docs/03 中的任何表/字段/索引/外键/约束。字符集 `utf8mb4` + `utf8mb4_unicode_ci`、引擎 `InnoDB`,除非 docs/03 业务注记另有说明。
29 19
30 #### A.2 落盘 V1 文件 20 #### A.2 落盘 V1 文件
31 21
32 -用 `Write` 写 `sql/migrations/V1__initial_schema.sql`(`Write` 会自动创建缺失的父目录 `sql/migrations/`),内容 = 头部注释 + DDL 主体:  
33 -  
34 -1. **头部注释**(6 行 SQL 注释):  
35 - - `-- Flyway migration V1 — initial schema for <project_name>`(从 `CLAUDE.md § 🎯 项目概述` 读)  
36 - - `-- Generated: <YYYY-MM-DDTHH:MM:SSZ>`(UTC ISO 8601 时间戳)  
37 - - `-- Source: 由 A4 db-init 从 docs/03-数据库设计文档.md 翻译生成(schema SSoT 是 docs/03)`  
38 - - `-- This is the FIRST migration; subsequent schema changes must be written as new files sql/migrations/V2__<desc>.sql, V3__... etc.`  
39 - - `-- Apply: Flyway runs this automatically at Spring Boot startup.`  
40 - - `-- Do not hand-edit this file after it is committed; write a new migration instead.` 22 +用 `Write` 写 `sql/migrations/V1__initial_schema.sql`(`Write` 自动创建父目录)。文件开头是以下 6 行注释,其后接 A.1 的 DDL 主体(`CREATE TABLE` → `CREATE INDEX` → `ALTER TABLE ... ADD FOREIGN KEY`):
41 23
42 -2. **DDL 主体**:A.1 推导出的所有 `CREATE TABLE` → `CREATE INDEX` → `ALTER TABLE ... ADD CONSTRAINT ... FOREIGN KEY`,按此顺序拼接。 24 +```sql
  25 +-- Flyway migration V1 — initial schema for <project_name> -- 从 CLAUDE.md § 🎯 项目概述 读
  26 +-- Generated: <YYYY-MM-DDTHH:MM:SSZ> -- UTC ISO 8601
  27 +-- Source: 由 A4 db-init 从 docs/03-数据库设计文档.md 翻译生成(schema SSoT 是 docs/03)
  28 +-- This is the FIRST migration; subsequent schema changes must be written as new files sql/migrations/V2__<desc>.sql, V3__... etc.
  29 +-- Apply: Flyway runs this automatically at Spring Boot startup.
  30 +-- Do not hand-edit this file after it is committed; write a new migration instead.
  31 +```
43 32
44 #### A.3 校验 V1 ↔ docs/03 5 维一致性 + 自主修正 33 #### A.3 校验 V1 ↔ docs/03 5 维一致性 + 自主修正
45 34
@@ -65,24 +54,15 @@ node &quot;${CLAUDE_PLUGIN_ROOT}/lib/validate-ddl.mjs&quot; \ @@ -65,24 +54,15 @@ node &quot;${CLAUDE_PLUGIN_ROOT}/lib/validate-ddl.mjs&quot; \
65 54
66 ### B. 数据库环境检查 55 ### B. 数据库环境检查
67 56
68 -#### B.1 检查 .env.local 凭据  
69 -  
70 -用 `Glob` 检查 `.env.local` 是否存在;不存在 → 提示用户重新运行 A2 `skeleton-gen` 重建并停下。 57 +用 `Glob` 确认 `.env.local` 存在(不存在 → 提示重跑 A2 `skeleton-gen` 并停下)。用 `Read` 逐行解析 `KEY=VALUE`(跳过空行 / `#` 注释,**不做 shell-source / 变量展开**),校验 `DB_HOST` / `DB_PORT` / `DB_USER` / `DB_PASSWORD` / `DB_SCHEMA` 5 项均非空——任一缺失 → 打印缺失字段并停下。
71 58
72 -用 `Read` 读取 `.env.local`,逐行解析 `KEY=VALUE`(跳过空行 / `#` 注释,**不做** shell-source / 变量展开),校验 5 个必填字段 `DB_HOST`、`DB_PORT`、`DB_USER`、`DB_PASSWORD`、`DB_SCHEMA` 均存在且非空。  
73 -  
74 -任一缺失 → 打印缺失字段名并停下,提示用户编辑 `.env.local` 后重跑。  
75 -  
76 -#### B.2 验证 MySQL 连接  
77 -  
78 -用 B.1 解析出的字段值(**不要** shell-source `.env.local`)拼出 `mysql` 客户端调用,做一次连通性自检。把 `<DB_HOST>` 等占位替换为读到的实际值: 59 +用解析出的值跑连通性自检:
79 60
80 ```bash 61 ```bash
81 mysql -h<DB_HOST> -P<DB_PORT> -u<DB_USER> -p<DB_PASSWORD> -e "SELECT 1;" 62 mysql -h<DB_HOST> -P<DB_PORT> -u<DB_USER> -p<DB_PASSWORD> -e "SELECT 1;"
82 ``` 63 ```
83 64
84 -- **成功** → 进入步骤 C  
85 -- **失败** → 打印具体错误(认证 / 主机不可达 / 端口拒接等),提示检查 `.env.local`,**停下**。 65 +成功 → 进入步骤 C;失败 → 打印具体错误(认证 / 主机不可达 / 端口拒接)并停下。
86 66
87 完成后,用 `Edit` 在 `docs/08-模块任务管理.md` 中勾选: 67 完成后,用 `Edit` 在 `docs/08-模块任务管理.md` 中勾选:
88 - ` - [ ] .env.local 凭据已验证(mysql -e "SELECT 1" OK)` 68 - ` - [ ] .env.local 凭据已验证(mysql -e "SELECT 1" OK)`
@@ -104,29 +84,16 @@ node &quot;${CLAUDE_PLUGIN_ROOT}/lib/apply-ddl.mjs&quot; .env.local sql/migrations/V1__ini @@ -104,29 +84,16 @@ node &quot;${CLAUDE_PLUGIN_ROOT}/lib/apply-ddl.mjs&quot; .env.local sql/migrations/V1__ini
104 ``` 84 ```
105 85
106 退出码与处理: 86 退出码与处理:
107 -- `0` → 成功,进入 C.3  
108 -- `1` → 失败:若错误提示 `mysql2 not found`,先在目标项目执行 `npm i mysql2` 再重跑;其余错误打印 stderr 并停下 87 +- `0` → 成功,进入步骤 D
  88 +- `1` → 失败:打印 stderr 并停下
109 - `2` → 用法错(路径找不到),打印路径并停下 89 - `2` → 用法错(路径找不到),打印路径并停下
110 90
111 完成后,用 `Edit` 在 `docs/08-模块任务管理.md` 中勾选: 91 完成后,用 `Edit` 在 `docs/08-模块任务管理.md` 中勾选:
112 - ` - [ ] setup-test-db.mjs 防护通过 + DROP+CREATE + apply V1 已执行` 92 - ` - [ ] setup-test-db.mjs 防护通过 + DROP+CREATE + apply V1 已执行`
113 93
114 -#### C.3 自检:docs/03 ↔ V1 表集合一致  
115 -  
116 -再跑一次 `validate-ddl.mjs`,确认刚 apply 的 `V1__initial_schema.sql` 与 docs/03 的表/列/类型/索引/外键 5 维仍然一致(参数顺序:docs/03 在前,V1.sql 在后):  
117 -  
118 -```bash  
119 -node "${CLAUDE_PLUGIN_ROOT}/lib/validate-ddl.mjs" \  
120 - docs/03-数据库设计文档.md \  
121 - sql/migrations/V1__initial_schema.sql  
122 -```  
123 -  
124 -退出码 `0` → 进入步骤 D;`1` → 打印 stderr 5 维 diff 并停下;`2` → 路径错,打印路径并停下。  
125 -  
126 ### D. 勾选 docs/08 进度 + 进入 A5 94 ### D. 勾选 docs/08 进度 + 进入 A5
127 95
128 -  
129 -1. 完成后,用 `Edit` 在 `docs/08-模块任务管理.md` 中勾选(A4 子项 + A4 顶层): 96 +1. 完成后,用 `Edit` 在 `docs/08-模块任务管理.md` 中勾选(A4 子项 + A4 顶层;DDL ↔ docs/03 5 维一致已由 A.3 校验过,V1 文件自此未变):
130 - ` - [ ] DDL ↔ docs/03 apply 后 5 维一致(validate-ddl.mjs)` 97 - ` - [ ] DDL ↔ docs/03 apply 后 5 维一致(validate-ddl.mjs)`
131 - `- [ ] A4 DB 初始化 — db-init` 98 - `- [ ] A4 DB 初始化 — db-init`
132 99
@@ -134,7 +101,7 @@ node &quot;${CLAUDE_PLUGIN_ROOT}/lib/validate-ddl.mjs&quot; \ @@ -134,7 +101,7 @@ node &quot;${CLAUDE_PLUGIN_ROOT}/lib/validate-ddl.mjs&quot; \
134 101
135 ## 参考 102 ## 参考
136 103
137 -- `${CLAUDE_PLUGIN_ROOT}/lib/validate-ddl.mjs`(A.3 / C.3 docs/03 ↔ V1.sql 5 维一致性校验,跨平台纯 Node) 104 +- `${CLAUDE_PLUGIN_ROOT}/lib/validate-ddl.mjs`(A.3 docs/03 ↔ V1.sql 5 维一致性校验,跨平台纯 Node)
138 - `${CLAUDE_PLUGIN_ROOT}/lib/apply-ddl.mjs`(C.2 安全解析 .env.local + mysql2 灌入 DDL,不 shell-source) 105 - `${CLAUDE_PLUGIN_ROOT}/lib/apply-ddl.mjs`(C.2 安全解析 .env.local + mysql2 灌入 DDL,不 shell-source)
139 - `docs/03-数据库设计文档.md`(DDL 翻译输入,SSoT) 106 - `docs/03-数据库设计文档.md`(DDL 翻译输入,SSoT)
140 - `.env.local`(DB 凭据) 107 - `.env.local`(DB 凭据)
skills/plan/downstream-gen/SKILL.md
@@ -15,21 +15,9 @@ allowed-tools: Read Write Edit Glob Grep Skill AskUserQuestion @@ -15,21 +15,9 @@ allowed-tools: Read Write Edit Glob Grep Skill AskUserQuestion
15 15
16 **清单颗粒度**:一行一个 REQ,同一模块的 REQ 必须**连续排列**。 16 **清单颗粒度**:一行一个 REQ,同一模块的 REQ 必须**连续排列**。
17 17
18 -1. 构建**模块依赖 DAG**。  
19 -2. 对**每个模块内部**构建 REQ 间依赖,得到模块内 REQ 顺序。  
20 -3. 合成 `req_order[]`:按 `module_topo_order[]` 依次铺开每个模块内的 REQ 序列(**同模块 REQ 连续**)。  
21 -4. **环依赖打破**:  
22 - - **模块级**:若模块 DAG 存在环(module_A ↔ module_B),按启发式(字母序 / 被依赖次数多者先)破环排出 `module_topo_order`,并在**参与环的模块里第一个 REQ** 的 `note` 字段填入原因(如 "A↔B 互依赖:先做 A 的骨架")。  
23 - - **REQ 级(同模块内)**:若模块内 REQ 互依赖,同样破环,`note` 填原因。  
24 - - 非环 REQ `note` 留 `—`。  
25 -5. 为 `req_order[]` 每项生成字段:  
26 - - `index`:行号(从 1 开始)  
27 - - `req_id`:如 `REQ-SYS-001`  
28 - - `module_id`:该 REQ 所属模块,如 `module_sys`  
29 - - `rationale`(**选中理由**):依赖驱动的简短描述,如 `所属模块无依赖,基础模块` / `依赖 REQ-SYS-001 已在前` / `所属模块依赖 module_sys 已在前`  
30 - - `note`(**备注**):默认 `—`;仅环依赖打破场景填原因  
31 -6. 读取并填充 `${CLAUDE_SKILL_DIR}/templates/docs-02-template.md`。  
32 -7. 写入 `docs/02-开发计划.md`。 18 +1. 拓扑排模块得 `module_topo_order[]`,对每个模块内部拓扑排 REQ;按模块顺序依次铺开生成 `req_order[]`(同模块 REQ 连续)。出现环(模块级或模块内 REQ 级)用启发式(字母序 / 被依赖次数多者先)破环,并把原因填入参与环的首个 REQ 的 `note`;非环 REQ `note` 留 `—`。
  19 +2. 为每项生成 `index`(从 1)/ `req_id` / `module_id` / `rationale`(依赖驱动短描述)/ `note`。
  20 +3. 读取并填充 `${CLAUDE_SKILL_DIR}/templates/docs-02-template.md`,写入 `docs/02-开发计划.md`。
33 21
34 完成后,用 `Edit` 在 `docs/08-模块任务管理.md` 中勾选: 22 完成后,用 `Edit` 在 `docs/08-模块任务管理.md` 中勾选:
35 - ` - [ ] docs/02 开发计划已生成` 23 - ` - [ ] docs/02 开发计划已生成`
@@ -73,67 +61,25 @@ allowed-tools: Read Write Edit Glob Grep Skill AskUserQuestion @@ -73,67 +61,25 @@ allowed-tools: Read Write Edit Glob Grep Skill AskUserQuestion
73 61
74 ### F. 验证 + 勾选 docs/08 进度 + 结束 Plan 62 ### F. 验证 + 勾选 docs/08 进度 + 结束 Plan
75 63
76 -1. 一致性检查 + 自主修复循环(最多 3 轮,docs/01 是 REQ SSoT 不动) 64 +1. **合并扫描三类问题**(最多 3 轮自主修复,docs/01 是 REQ SSoT 不动)——一次性扫一致性 + `TBD(A3/A5 自动补)` + 结构性残留
77 65
78 - **检查项**:  
79 - - 每个 docs/01 REQ 都出现在 docs/05(作为接口,如适用)  
80 - - `docs/02 § 二` 的 `module_id` 集合 = `docs/08 § 二` 的 `module_id` 集合 66 + - **一致性**:docs/01 REQ 全部出现在 docs/05;`docs/02 § 二` `module_id` 集合 = `docs/08 § 二` `module_id` 集合。
  67 + - **TBD 残留**:`TBD(A3 自动补)` → 查 docs/03 填依赖表;`TBD(A5 自动补)` → 查 docs/05 按 REQ-ID 填依赖接口。
  68 + - **结构性**:docs/05 每个 `### REQ-` 端点段含非空 `- **请求**:` / `- **响应**:`(非 `TBD`/`—`/`【人工填写:…】`);docs/01 全部 REQ-ID 都出现在 `docs/02 § 二` 顺序清单。
81 69
82 - **不一致 → 按差异类型自主修复**:  
83 - - **REQ 缺 docs/05 endpoint** → 按步骤 B 规则为该 REQ 推测,并追加到 docs/05  
84 - - **module_id 缺 docs/08 § 二** → 按步骤 D 规则渲染该模块 bullet(含 REQ 子项),按 `module_id` 字母序插入正确位置  
85 - - **module_id 缺 docs/02 § 二** → 重算该模块的 `req_order` 段(步骤 A 子流程),按拓扑序插入 docs/02 § 二 70 + 命中即按对应步骤规则就地补填(缺端点 → 按 B 推测;缺 module 行 → 按 D 渲染;缺 REQ 顺序行 → 按 A 子流程拓扑插入)。3 轮后仍残留 `【人工填写:】` 或结构缺口 → 打印清单 + 用 `AskUserQuestion` 弹「继续」/「有疑问想先沟通」二选一;每次弹问前重扫一次,避免脏读放行。
86 71
87 - 修复后重跑检查;通过 → 进入 2;3 轮仍失败 → 停下,打印最终残留差异 + 已尝试的 3 轮修复摘要让用户介入 72 +2. **docs/05 + docs/02 人工评审闸**(未确认不得勾选 A5):摘要展示 docs/05 全部端点(`METHOD PATH — REQ-ID`,标注「由 A5 自动推断」的项)+ docs/02 `req_order[]`(特别标 `note ≠ —` 的环依赖打破项)。`AskUserQuestion` 多问题表单同时问两项:「docs/05 端点/字段无误」+「docs/02 构建顺序可接受」,各二选一 `确认` / `需要修改`。任一需修改 → 收集修改点就地修订并重跑本闸,直到两项均 `确认`;否则禁止勾选 A5、禁止打印横幅
88 73
89 -2. **最终占位符扫描 + 结构性残留检查**(覆盖 Plan 阶段全部产出):  
90 -  
91 - a. **`TBD` → 自动补齐**:Grep 搜索 `TBD(A3 自动补)` 和 `TBD(A5 自动补)`。有命中则就地补填(A3 残留 → 查 docs/03 填 `依赖表`;A5 残留 → 查 docs/05 按 REQ-ID 填 `依赖接口`),再 Grep 确认 0 命中;仍残留报错停下。  
92 -  
93 - b. **结构性残留检查(不只看字面占位符,校验 SSoT 完整性)**:  
94 -  
95 - - **docs/05 每个端点都有请求/响应 schema**:逐个解析 docs/05 的每个 endpoint 段(以 `### REQ-` 开头的小节)。每段必须同时含非空的 `- **请求**:` 与 `- **响应**:` 行——值不得为空、`TBD`、`—` 或 `【人工填写:…】`。缺失/留空 → 按步骤 B 规则就地为该端点推测补全请求/响应 schema,再复核;3 轮仍补不全则计入残留清单(见下方 c),交由 QA 循环让用户介入。  
96 - - **docs/02 DAG 覆盖每个 REQ**:收集 docs/01 全部 REQ-ID 集合,与 `docs/02 § 二、开发顺序清单` 表中出现的 `req_id` 集合比对。任一 docs/01 REQ 未出现在 docs/02 顺序清单 → 按步骤 A 子流程把该 REQ 插入其所属模块段的正确拓扑位置(保持同模块 REQ 连续),再复核;3 轮仍无法补齐则计入残留清单交由 QA 循环。  
97 -  
98 - c. **`【人工填写:...】` + 结构性残留 → QA 循环等用户补**:  
99 -  
100 - 循环执行直到(搜索不到 `【人工填写:`)**且**(步骤 b 两项结构检查均通过)且用户选「继续」:  
101 - - 0 残留 → 直接放行进入步骤 3  
102 - - 有残留 → 打印残留清单(含字面占位符 `<文件:行号> — <内容摘要>`,以及结构性缺口 `docs/05 端点 <REQ-ID> 缺请求/响应 schema` / `docs/02 顺序清单缺 REQ <REQ-ID>`),用 `AskUserQuestion` 弹「继续」/「有疑问想先沟通」二选一;用户回答后重扫 + 重跑结构检查再决定放行 / 继续循环  
103 -  
104 - **每次弹 QA 前都重扫一次**(含两项结构检查)——保证用户看到的 N 是最新的,避免「用户以为填完但实际还有残留」直接放行。  
105 -  
106 -3. **docs/05 + docs/02 人工评审闸(强制,未确认不得勾选 A5)**:  
107 -  
108 - 向用户摘要展示两份 SSoT 的关键内容,请其确认无误:  
109 - - **docs/05 API 契约**:列出全部端点(`METHOD PATH — REQ-ID`),并标注任何「由 A5 自动推断」的端点/字段供重点核对。  
110 - - **docs/02 构建顺序**:展示 `req_order[]` 顺序,**特别标出所有 `note ≠ —` 的环依赖打破项**(启发式选定的顺序 + 原因),供用户判断该顺序是否可接受。  
111 -  
112 - 用 `AskUserQuestion` 同时问两项确认(多问题表单),每项二选一:  
113 - - 「docs/05 端点/字段确认无误」:`确认` / `需要修改`  
114 - - 「docs/02 构建顺序可接受(含 cycle-breaking 选定的顺序)」:`确认` / `需要修改`  
115 -  
116 - 裁决:  
117 - - 两项均 `确认` → 进入步骤 4 勾选 A5。  
118 - - 任一为 `需要修改` → 用 `AskUserQuestion` 收集具体修改点,就地修订对应文档(docs/05 端点/字段或 docs/02 顺序/备注),改完重新展示摘要并重跑本评审闸,直到两项均 `确认`。**未两项确认前禁止勾选 A5、禁止打印终止横幅。**  
119 -  
120 -4. 完成后,用 `Edit` 在 `docs/08-模块任务管理.md` 勾选 A5 父项: 74 +3. 用 `Edit` 在 `docs/08-模块任务管理.md` 勾选 A5 父项:
121 - `- [ ] A5 下游文档生成 — downstream-gen` 75 - `- [ ] A5 下游文档生成 — downstream-gen`
122 76
123 -5. 打印 A5 完成横幅并**停下**(A6 仍未跑——A5 之后由 plan-start 派发 A6 frontend-scope-lock,A6 完成后再由 plan-start 跑 5 项终结闸;只有终结闸全过才会提示运行 coding-start) 77 +4. 打印 A5 完成横幅并**停下**
124 78
125 ``` 79 ```
126 - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━  
127 - [downstream-gen] ✅ A5 下游文档生成完成(A0~A5)  
128 -  
129 - docs/02 / docs/05 / docs/06 § 三 / docs/08 § 二 / docs/10 已就绪;  
130 - docs/05 + docs/02 评审闸已通过;docs/08 § 一 A0~A5 已全勾。  
131 -  
132 - ⏭️ 下一步:运行 /erp-workflow:plan-start  
133 - plan-start 会派发到 A6 frontend-scope-lock 锁定前端 scope,  
134 - A6 完成后再由 plan-start 跑 5 项终结闸校验;  
135 - 全过才会提示运行 /erp-workflow:coding-start 进入 B 阶段。  
136 - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 80 + [downstream-gen] ✅ A5 下游文档生成完成(A0~A5)
  81 + 产出:docs/02 / docs/05 / docs/06 § 三 / docs/08 § 二 / docs/10;docs/08 § 一 A0~A5 已全勾。
  82 + ⏭️ 下一步:运行 /erp-workflow:plan-start
137 ``` 83 ```
138 84
139 ## 参考 85 ## 参考
skills/plan/frontend-scope-lock/SKILL.md
@@ -9,32 +9,10 @@ allowed-tools: Read Write Edit Glob Grep Skill AskUserQuestion @@ -9,32 +9,10 @@ allowed-tools: Read Write Edit Glob Grep Skill AskUserQuestion
9 9
10 # frontend-scope-lock 10 # frontend-scope-lock
11 11
12 -A6 是 **Plan 阶段最后一个前端守门 skill**,由 `plan-start` 在 A5(downstream-gen)完成后派发。  
13 -  
14 -**定位**:把原 Coding 阶段晚到的前端闸(`frontend-start` 的 prototype 检查 + `fe-feature-brainstorm` / `fe-feature-plan` 的交互式 Q&A)整体**前移到 Plan 期**。Plan 期允许 `AskUserQuestion` 问人;问清后写入 SSoT(docs/06 + docs/04),Coding 阶段的前端循环只读不问。  
15 -  
16 -## 阶段范围  
17 -  
18 -锁定**项目级**前端契约:UI 约定 / Design Tokens / 组件库选型 + 每个 FE-NN 的设计决策。**不涉及** SQL / migration / controller / service / DTO(后端范畴),也**不在此实现**任何页面代码(Coding 阶段做)。  
19 -  
20 ## 执行步骤 12 ## 执行步骤
21 13
22 > **关于 AskUserQuestion**:下文只描述「问什么、给哪些选项、各选项导向什么后续」。`header` / 各选项的 `description` / `multiSelect` 等具体参数由你按工具 schema 自行填全合法值——不要把下文的选项文字当成完整调用照抄。 14 > **关于 AskUserQuestion**:下文只描述「问什么、给哪些选项、各选项导向什么后续」。`header` / 各选项的 `description` / `multiSelect` 等具体参数由你按工具 schema 自行填全合法值——不要把下文的选项文字当成完整调用照抄。
23 15
24 -### 步骤 0:打印当前位置流程图  
25 -  
26 -向用户**直接输出**(模型自己打印,不调 bash / cat)当前位置:  
27 -  
28 -```  
29 -┌────────────────────────────────────────────────────────┐  
30 -│ 📋 阶段 A:规划(一次性) │  
31 -│ A0 初始化 → A1 锁范围 → A2 骨架 → A3 DB 设计 │  
32 -│ → A4 DB 初始化 → A5 下游文档 │  
33 -│ ▶ A6 前端范围锁定(prototype + tokens + 约定) │  
34 -│ 规划阶段到此结束 │  
35 -└────────────────────────────────────────────────────────┘  
36 -```  
37 -  
38 ### 步骤 1:检查 prototype(缺失则在此问) 16 ### 步骤 1:检查 prototype(缺失则在此问)
39 17
40 用 `Glob` 检查项目根 `prototype/**/*.html`: 18 用 `Glob` 检查项目根 `prototype/**/*.html`:
@@ -42,11 +20,10 @@ A6 是 **Plan 阶段最后一个前端守门 skill**,由 `plan-start` 在 A5 @@ -42,11 +20,10 @@ A6 是 **Plan 阶段最后一个前端守门 skill**,由 `plan-start` 在 A5
42 - **至少 1 个 `.html`** → 通过,记下文件清单,进入步骤 2。 20 - **至少 1 个 `.html`** → 通过,记下文件清单,进入步骤 2。
43 - **0 个** → 这是 Plan 期,**可以问**。用 `AskUserQuestion` 告知用户「未在 prototype/ 找到任何 .html 原型,前端范围锁定依赖原型作为页面骨架权威」,给「我已补齐原型,请重新检查」和「本项目无前端,跳过 A6」两个选项。 21 - **0 个** → 这是 Plan 期,**可以问**。用 `AskUserQuestion` 告知用户「未在 prototype/ 找到任何 .html 原型,前端范围锁定依赖原型作为页面骨架权威」,给「我已补齐原型,请重新检查」和「本项目无前端,跳过 A6」两个选项。
44 - 选「已补齐」→ 重新 `Glob`:命中则进入步骤 2,仍为 0 则重复本问。 22 - 选「已补齐」→ 重新 `Glob`:命中则进入步骤 2,仍为 0 则重复本问。
45 - - 选「无前端」→ 在 docs/08 § 一 把 A6 的**父项 + 全部 3 个子项**一并勾选并在父项行尾注明「(无前端,A6 跳过)」,打印步骤 6 的终止横幅(产出标注「跳过」),**停止**,不写 docs/06 / docs/04。  
46 - > 必须同时勾子项:`plan-start` 的分发依据是「§ 一 第一个未勾 [ ] 子项」,若只勾父项会让下一次 plan-start 重复派发回本 skill,无前端项目无法满足 Plan 终结闸。具体要勾的子项:  
47 - > - ` - [x] docs/06 项目级 UI 约定 + Design Tokens + 组件库已锁定(无前端跳过)`  
48 - > - ` - [x] docs/04 § 二 前端栈已锁定(引用 docs/06)(无前端跳过)`  
49 - > - ` - [x] 各 FE-NN 设计决策表已生成(docs/06 § 三之后 / docs/08 § 三)(无前端跳过)` 23 + - 选「无前端」→ 在 docs/08 § 一 同时勾父项 + 3 子项(否则下次 plan-start 会重派),父项行尾注「(无前端,A6 跳过)」,打印步骤 6 横幅(产出标注「跳过」)并**停止**,不写 docs/06 / docs/04。3 子项:
  24 + - ` - [x] docs/06 项目级 UI 约定 + Design Tokens + 组件库已锁定(无前端跳过)`
  25 + - ` - [x] docs/04 § 二 前端栈已锁定(引用 docs/06)(无前端跳过)`
  26 + - ` - [x] 各 FE-NN 设计决策表已生成(docs/06 § 三之后 / docs/08 § 三)(无前端跳过)`
50 27
51 ### 步骤 2:收集证据(只读,不问) 28 ### 步骤 2:收集证据(只读,不问)
52 29
@@ -98,23 +75,12 @@ A6 是 **Plan 阶段最后一个前端守门 skill**,由 `plan-start` 在 A5 @@ -98,23 +75,12 @@ A6 是 **Plan 阶段最后一个前端守门 skill**,由 `plan-start` 在 A5
98 - ` - [ ] docs/04 § 二 前端栈已锁定(引用 docs/06)` 75 - ` - [ ] docs/04 § 二 前端栈已锁定(引用 docs/06)`
99 - ` - [ ] 各 FE-NN 设计决策表已生成(docs/06 § 三之后 / docs/08 § 三)` 76 - ` - [ ] 各 FE-NN 设计决策表已生成(docs/06 § 三之后 / docs/08 § 三)`
100 - `- [ ] A6 前端范围锁定 — frontend-scope-lock` 77 - `- [ ] A6 前端范围锁定 — frontend-scope-lock`
101 -2. 向用户**直接输出**终止横幅并**停止**(不自动进入 B 阶段,回交给 plan-start 的终结闸判定) 78 +2. 向用户**直接输出**终止横幅并**停止**
102 79
103 ``` 80 ```
104 -━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━  
105 - [frontend-scope-lock] ✅ A6 前端范围锁定完成  
106 -  
107 - 产出:  
108 - ✓ docs/06 § 一 项目级 UI 约定(通用交互规则)  
109 - ✓ docs/06 § 二 Design Tokens(全局调色板 + 组件级状态色)  
110 - ✓ docs/06 § 三之后 各 FE-NN 设计决策表  
111 - ✓ docs/04 § 二 前端栈 + 组件库选型(引用 docs/06)  
112 -  
113 - 前端契约已全部锁定,Coding 阶段前端循环将只读不问。  
114 -  
115 - Plan 阶段(A0~A6)到此结束。请运行 /erp-workflow:plan-start  
116 - 让终结闸校验全部前移闸门是否通过,再进入 B 阶段。  
117 -━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 81 +[frontend-scope-lock] ✅ A6 前端范围锁定完成
  82 +产出:docs/06 § 一/二 + § 三之后各 FE-NN 决策表;docs/04 § 二 前端栈(引用 docs/06)。
  83 +Plan 阶段(A0~A6)到此结束。请运行 /erp-workflow:plan-start 进入终结闸。
118 ``` 84 ```
119 85
120 ## 参考 86 ## 参考