SKILL.md 14.9 KB

name: scope-lock description: A1 计划范围锁定——引导用户填写项目概述 + 技术栈 + 需求索引,并按模块子目录生成 REQ 卡片骨架(CC 推断 req_id/title/goal/rules/constraints/acceptance;输入/输出 字段表为结构化 6 列表单由人工逐行填真实数据);末尾执行 A1 终结校验:每张 REQ 卡片字段含真实数据、配置字段名锁进 config-vars.yaml(非敏感填值 + secrets_ref 键名引用 .env.local)、build/lint/unit/e2e 命令锁进 docs/04 §零,缺则当场 AskUserQuestion 问清。 user-invocable: false

allowed-tools: Read Write Edit Grep Glob Skill AskUserQuestion Bash(mkdir *) Bash(node *) Bash(rm *)

所有输出必须使用中文。

scope-lock

关于 AskUserQuestion:下文只描述「问什么、给哪些选项、各选项导向什么后续」。header / 各选项的 description / multiSelect 等具体参数由你按工具 schema 自行填全合法值——不要把下文的选项文字当成完整调用照抄。

执行步骤

A. 提示用户填写项目概述并等待

向用户输出:

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
 [scope-lock] 请填写项目概述

 📄 文件位置: ./CLAUDE.md
 📌 编辑位置: § 🎯 项目概述

 请将以下占位符替换为实际值:
   - 项目名称
   - 项目简述
   - 目标用户
   - 部署方式
 改完后回来选择「继续」。
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

AskUserQuestion 确认「项目概述填写完毕了吗?」,给「继续」和「有疑问想先沟通」两个选项。

  • 选「继续」→ 用 GrepCLAUDE.md 搜索 【人工填写:(限定 § 🎯 项目概述 节)。命中 → 打印残留行 + 路径,重新确认一次;0 命中 → 勾选并进入步骤 B。
  • 选「有疑问想先沟通」→ 回答用户问题后,再确认一次。

0 命中后,用 Editdocs/08-模块任务管理.md 中勾选:

  • - [ ] 项目概述已填写(CLAUDE.md § 🎯 项目概述)

B. 提示用户检查默认技术栈并等待

docs/04-技术规范.md 已由 A0 project-init 用模板复制(默认技术栈,见 project-init/templates/docs-04-stack-template.md)。本步骤让用户检查 / 调整 § 零。

向用户输出:

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
 [scope-lock] 技术栈已保存

 📄 文件位置: ./docs/04-技术规范.md(由 A0 模板生成)
 📌 编辑位置: § 零、技术栈总览

 请检查技术栈表:
   - 不需要的行直接删除(如纯后端项目删前端行)
   - 需要替换的技术直接改
   - 需要新增的条目直接加行
 改完后回来选择「继续」。
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

AskUserQuestion 确认「技术栈检查完毕了吗?」,给「继续」和「有疑问想先沟通」两个选项。

  • 选「继续」→ 进入步骤 C。
  • 选「有疑问想先沟通」→ 回答用户问题后,再确认一次。

完成后,用 Editdocs/08-模块任务管理.md 中勾选:

  • - [ ] 技术栈已确认(docs/04 § 零)

C. 提示用户填写需求清单并等待

docs/01-需求清单/index.md 已由 project-init 写入占位符模板,这里让用户补齐模块清单。

向用户输出:

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
 [scope-lock] 请填写需求清单模块索引

 📄 文件位置: ./docs/01-需求清单/index.md
 📌 编辑位置: § 模块索引(表格)

 请按业务列出所有模块:
   - 每行一个模块(如 SYS 系统管理 / PUR 采购 / SAL 销售)
   - 「核心功能点」只需关键词,CC 会拆分为 REQ 卡片
 改完后回来选择「继续」。
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

AskUserQuestion 确认「需求清单模块索引填写完毕了吗?」,给「继续」和「有疑问想先沟通」两个选项。

  • 选「继续」→ 进入步骤 D。
  • 选「有疑问想先沟通」→ 回答用户问题后,再确认一次。

完成后,用 Editdocs/08-模块任务管理.md 中勾选:

  • - [ ] 需求清单索引已填写(docs/01-需求清单/index.md)

D. 生成 REQ 卡片骨架并停下等人工审阅

  1. Grep 校验 docs/01-需求清单/index.md【人工填写: 残留;有则回步骤 C。
  2. Readindex.md 解析模块索引。
  3. 逐文件渲染落盘(用 Node 渲染助手,跨平台、字面量安全):
  • 每模块推断:三元组 {module_code, module_name, module_brief} + N 个 REQ 的六元组 {req_id, title, goal, rules, constraints, acceptance}req_id/title 从核心功能点拆分;goal 展开 titlerules/constraints/acceptance 起草业务语义。不推断输入 / 输出字段(模板的结构化字段表保留示例行,留待人工逐行填真实数据)。
  • 渲染助手 lib/render.mjs 的 CLI 形态为 node <render.mjs> <模板路径> <vars.json 路径> <输出路径>:读模板 + 读 JSON 变量 + 占位符字面替换 + 自动剥离 HTML 注释,写到输出路径。值含 ${}}} 均按字面插入,无需兜底。
  • 每个文件三步:(a) 用 Write 写一个临时 vars JSON(仅含该文件用到的占位符键值);(b) mkdir -p 模块目录;(c) node 调 render.mjs 渲染。<MOD> / <模块名> / <REQ-MOD-NNN> 等尖括号位置 CC 按 index.md 实际值替换。调用形态:

     # 模块头:先 Write docs/01-需求清单/<MOD>-<模块名>/_module.vars.json,内容形如
     #   {"module_code":"<MOD>","module_name":"<模块名>","module_brief":"<module_brief>"}
     mkdir -p "docs/01-需求清单/<MOD>-<模块名>"
     node "${CLAUDE_PLUGIN_ROOT}/lib/render.mjs" \
       "${CLAUDE_SKILL_DIR}/templates/_module-template.md" \
       "docs/01-需求清单/<MOD>-<模块名>/_module.vars.json" \
       "docs/01-需求清单/<MOD>-<模块名>/_module.md"
    
     # 每个 REQ:先 Write 该 REQ 的 vars JSON,内容形如
     #   {"req_id":"<REQ-MOD-NNN>","title":"<title>","goal":"<goal>","rules":"<rules>","constraints":"<constraints>","acceptance":"<acceptance>"}
     node "${CLAUDE_PLUGIN_ROOT}/lib/render.mjs" \
       "${CLAUDE_SKILL_DIR}/templates/req-card-template.md" \
       "docs/01-需求清单/<MOD>-<模块名>/<REQ-MOD-NNN>.vars.json" \
       "docs/01-需求清单/<MOD>-<模块名>/<REQ-MOD-NNN>.md"
    
  • 渲染完成后删除临时 *.vars.jsonrm 或不留亦可,不进入交付物)。

    1. Editdocs/08-模块任务管理.md 勾选(A1 子项):
  • - [ ] REQ 卡片骨架已生成(docs/01-需求清单/<module>/REQ-*.md,业务内容留待人工填写)

注意:此处先勾选 - [ ] A1 范围锁定 — scope-lock 顶层项;A1 顶层项必须在步骤 E(A1 终结校验)全部通过后才勾选。

  1. 打印「请人工填写 REQ 卡片」横幅并提示用户填完后回来继续(不停止,下一步是 A1 终结校验):
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
 [scope-lock] REQ 卡片骨架已生成

 产出:
   ✓ docs/01-需求清单/<module>/_module.md 模块头
   ✓ docs/01-需求清单/<module>/REQ-*.md REQ 卡片骨架

 ⏸ 现在请你逐张打开 REQ 卡片,把结构化字段表填成真实数据:
   - **必改**:`输入字段` / `输出字段` 两张表
     · 删掉「【示例行,替换为真实字段】」示例行,按本 REQ 业务逐行填真实字段
     · 6 列全部填:字段名 / 类型 / 必填 / 校验规则 / 业务规则 / 示例值
     · **「示例值」列必须是真实约束下的合法取值**——留 `<示例值>` 或示例行会被 A1 终结校验阻断
   - **审阅**:目标 / 跨字段规则 / 边界 / 验收(已起草,对照业务校正)
   - **保留**:`TBD` 不要改,由之后流程自动回填

 填完后回来选择「继续」,进入 A1 终结校验。
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

AskUserQuestion 确认「所有 REQ 卡片的结构化字段都填成真实数据了吗?」,给「继续」和「有疑问想先沟通」两个选项。

  • 选「继续」→ 进入步骤 E(A1 终结校验)。
  • 选「有疑问想先沟通」→ 回答用户问题后,再确认一次。

E. A1 终结校验(硬闸:全部通过才勾选 A1 顶层)

本步骤把原本会在编码期(coding.mjs 的 spec / plan stage)弹出的需求澄清 / config Q&A 全部前移到此处。任一检查不满足,用 AskUserQuestion此处(Plan 期)问清并修订,禁止留待编码期。三项检查全过后才在 docs/08 勾选 - [ ] A1 范围锁定 — scope-lock

E.1 真实数据校验(每张 REQ 卡片)

  1. Glob 列出所有 docs/01-需求清单/<module>/REQ-*.md
  2. 对每张卡片用 Read + Grep 校验:
    • 无模板默认占位:卡片内不得出现 【示例行,替换为真实字段】<示例值>(用 Grep 搜这两个字面量,命中即视为未完成)。
    • 结构化字段非空输入字段 / 输出字段 两张表每行 6 列均非空,且不是模板示例行内容;至少各有 1 行真实字段(除非该 REQ 确实无输入/输出,需在卡片显式标注)。
    • 示例值 列已填真实取值:每行示例值列为真实约束下的合法取值,非占位。
    • {{...}} 残留:不得残留任何 {{ 占位(说明渲染未替换)。
  3. 任一卡片不通过:打印不通过的卡片路径 + 具体缺口行,用 AskUserQuestion 引导用户当场补齐(可针对具体字段含义/校验规则发问),修订后重跑 E.1,直到全部通过。

E.2 配置字段名锁进 config-vars.yaml(敏感键名引用 .env.local)

  1. Readdocs/04-技术规范.md § 零技术栈,结合 REQ 卡片,盘点本项目需人工提供 / 确认的配置字段,分两类:
    • 非敏感、项目级:后端根包名 / 命名空间(Java package / C# namespace / Python 顶层包 / Go module path 等)、应用端口、前端包名 / scope、前端 dev 端口、管理员初始账号等。
    • 敏感凭据:数据库密码、JWT / 签名密钥、Redis 密码、第三方 API key/secret、OSS / 对象存储凭证、短信 / 邮件服务凭证、管理员初始密码等。
  2. Read 读模板 ${CLAUDE_SKILL_DIR}/templates/config-vars-template.yaml,用 Write 落盘到仓库根 config-vars.yaml
    • 非敏感字段:按技术栈推断默认值直接填入(如 http_port: 8080base_package: com.<org>.<app>);无对应技术栈的整节删除(如纯后端项目删 frontend:);无法可靠推断的留 【人工填写:…】(A2 skeleton-gen 补填)。
    • 敏感字段:只把「键名 + 含义」登记进 secrets_ref 列表,绝不写真实值(真实值由 A2 写进 .env.local,A2 据 secrets_ref 核对齐全)。
  3. 在此创建 / 填写 docs/07-环境配置.md——它由 A2 skeleton-gen 生成,只记规则不记具体值。
  4. AskUserQuestion 向用户确认:「以下配置 / 凭据字段已登记进 config-vars.yaml,是否齐全?还有遗漏的吗?」展示非敏感字段 + secrets_ref 键名清单。用户补充则继续登记,直到确认齐全。

E.3 build / lint / unit / e2e 命令锁进 docs/04 § 零

  1. Readdocs/04-技术规范.md § 零技术栈表,确定本项目涉及的每个 stack(如后端、前端,可能多个)。
  2. 每个 stack,用 AskUserQuestion(如默认值可推断则展示默认值让用户确认/覆盖)收集四类命令:
    • build(构建命令,如 mvn package / npm run build
    • lint(静态检查命令,如 npm run lint
    • unit(单元测试命令,如 mvn test / npm run test:unit
    • e2e(端到端测试命令,如 npm run test:e2e;无则显式记
  3. 把确认后的命令写入 docs/04-技术规范.md § 零(若 § 零无「命令」小节则用 Edit 新增一个「命令清单」小节,按 stack 分组列出 build/lint/unit/e2e 四行)。这些命令是 Coding 阶段 coding.mjs 的 tdd / test-gate 读取来源,必须在此锁全。

E.4 全部通过后勾选 A1 顶层并停止

三项检查(E.1 / E.2 / E.3)全部通过后:

  1. Editdocs/08-模块任务管理.md 勾选 - [ ] A1 范围锁定 — scope-lock 顶层项。
  2. 打印 A1 完成横幅并停止
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
 [scope-lock] ✅ A1 范围锁定完成(终结校验通过)

 产出 & 锁定:
   ✓ CLAUDE.md § 🎯 项目概述
   ✓ docs/04 § 零 技术栈 + build/lint/unit/e2e 命令
   ✓ docs/01-需求清单/index.md 模块索引
   ✓ docs/01-需求清单/<module>/_module.md 模块头
   ✓ docs/01-需求清单/<module>/REQ-*.md 字段表已填真实数据
   ✓ config-vars.yaml 配置字段 + secrets_ref 键名已锁(敏感真实值留待 A2 .env.local)

 运行以下命令继续进入 A2:
   /erp-workflow:plan-start

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

参考

  • CLAUDE.md § 🎯 项目概述(写入目标)
  • docs/04-技术规范.md(技术栈输出,供 skeleton-gen 读取使用)
  • docs/01-需求清单/index.md(模块索引输入)
  • docs/01-需求清单/<module>/_module.md(模块头输出)
  • docs/01-需求清单/<module>/REQ-*.md(REQ 卡片骨架输出,A3 db-design-gen / A5 downstream-gen 会回填 TBD 字段)
  • config-vars.yaml(A1 终结校验 E.2 输出:非敏感配置字段填值 + secrets_ref 键名锁定;仓库根)
  • ${CLAUDE_SKILL_DIR}/templates/config-vars-template.yaml(E.2 渲染来源;跨栈中立,YAML 注释引导)
  • ${CLAUDE_SKILL_DIR}/templates/req-card-template.md(结构化 6 列字段表)
  • ${CLAUDE_SKILL_DIR}/templates/_module-template.md
  • ${CLAUDE_PLUGIN_ROOT}/lib/render.mjs(步骤 D 渲染助手;CLI 形态 node render.mjs <模板> <vars.json> <输出>,字面量安全 + 自动剥 HTML 注释)