@house365/comate 0.5.0 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (30) hide show
  1. package/README.md +27 -9
  2. package/bin/cli.mjs +6 -0
  3. package/bin/doctor.mjs +86 -2
  4. package/bin/init-run.mjs +1 -1
  5. package/bin/init.mjs +2 -2
  6. package/bin/usage.mjs +252 -0
  7. package/docs/COMATE_MANUAL.md +710 -669
  8. package/package.json +3 -2
  9. package/skills/comate/SKILL.md +17 -20
  10. package/skills/comate/reference/decision-points.md +3 -3
  11. package/skills/comate/reference/prerequisites.md +1 -2
  12. package/skills/comate/scripts/comate-lib.sh +29 -12
  13. package/skills/comate/scripts/comate.sh +10 -10
  14. package/skills/comate/tests/comate.bats +31 -26
  15. package/skills/comate-build/SKILL.md +3 -3
  16. package/skills/comate-fix/SKILL.md +153 -0
  17. package/skills/{comate-intake → comate-gate}/SKILL.md +26 -6
  18. package/skills/{comate-intake → comate-gate}/scaffold/docs/README.md +2 -2
  19. package/skills/{comate-intake → comate-gate}/scaffold/docs/architecture/README.md +2 -2
  20. package/skills/{comate-intake → comate-gate}/scaffold/docs/knowledge-base/README.md +8 -8
  21. package/skills/comate-gate/scaffold/docs/knowledge-base/integrations/README.md +31 -0
  22. package/skills/{comate-intake → comate-gate}/scaffold/docs/knowledge-base/requirements/_templates/PRD.md +2 -2
  23. package/skills/comate-grill/SKILL.md +6 -6
  24. package/skills/comate-kb-integration/SKILL.md +128 -0
  25. package/skills/comate-kb-integration/scripts/fetch_rendered_doc.py +84 -0
  26. package/skills/comate-open/SKILL.md +5 -5
  27. package/skills/comate-hotfix/SKILL.md +0 -115
  28. package/skills/comate-tweak/SKILL.md +0 -109
  29. /package/skills/{comate-intake → comate-gate}/scaffold/docs/knowledge-base/integrations/_TEMPLATE/README.md +0 -0
  30. /package/skills/{comate-intake → comate-gate}/scaffold/docs/knowledge-base/integrations/_TEMPLATE/api-snapshot.md +0 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@house365/comate",
3
- "version": "0.5.0",
3
+ "version": "0.7.0",
4
4
  "description": "comate —— OpenSpec + Superpowers 规约驱动的 AI 开发编排器(Agent Skills)",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -41,11 +41,12 @@
41
41
  "node": ">=20"
42
42
  },
43
43
  "dependencies": {
44
+ "ccusage": "^20.0.19",
44
45
  "skills": "^1.5.21"
45
46
  },
46
47
  "scripts": {
47
48
  "postinstall": "node bin/postinstall.mjs",
48
- "test": "node bin/init.test.mjs && bash skills/comate/tests/run.sh",
49
+ "test": "node bin/init.test.mjs && node bin/usage.test.mjs && bash skills/comate/tests/run.sh",
49
50
  "doctor": "cd skills && bash comate/scripts/comate.sh doctor",
50
51
  "prepublish-check": "node scripts/prepublish-check.mjs",
51
52
  "pack-check": "node scripts/pack-check.mjs",
@@ -6,7 +6,7 @@ description: "comate —— OpenSpec + Superpowers 规格驱动开发编排器
6
6
  # comate —— OpenSpec + Superpowers 规格驱动开发流
7
7
 
8
8
 
9
- **核心原则:brainstorming 不可跳过。每个变更都必须经过深度设计(hotfix 和 tweak 预设除外)。**
9
+ **核心原则:brainstorming 不可跳过。每个变更都必须经过深度设计(fix 预设除外)。**
10
10
 
11
11
  ---
12
12
 
@@ -18,18 +18,17 @@ agent 做决策只需读本节,其余参见末尾「参考附录」。决策
18
18
 
19
19
  **Step 0:活跃 change 发现 + 意图探测**
20
20
 
21
- 1. 先探测预设;命中 hotfix/tweak 条件则直接调用对应预设 skill,不进入普通 open 分支。
21
+ 1. 先探测预设;命中 fix 条件则直接调用 `/comate-fix`,不进入普通 open 分支。
22
22
  2. 无预设命中时,运行 `openspec list --json` 获取所有活跃 change。
23
23
 
24
24
  **预设探测优先级最高**:
25
- - 用户明确描述 bug 修复/热修 + 满足 hotfix 条件 → 直接调用 `/comate-hotfix`
26
- - 用户明确描述文案/配置/文档/prompt 小调整 + 满足 tweak 条件 → 直接调用 `/comate-tweak`
27
- - **用户输入指向一份原始 PRD**(给了 PRD 路径/编号,或明确说「这是 PRD / 从这份需求文档开始」,典型路径 `docs/knowledge-base/**/PRD-*.md`)**且无对应活跃 change** → 直接调用 `/comate-intake`(阶段 0:先过门禁,再拆分建 change)。不要直接调 `/comate-open`——PRD 必须先过质量门禁。
25
+ - 用户明确描述 bug 修复或文案/配置/文档/prompt 小调整 + 满足 fix 条件 → 直接调用 `/comate-fix`
26
+ - **用户输入指向一份原始 PRD**(给了 PRD 路径/编号,或明确说「这是 PRD / 从这份需求文档开始」,典型路径 `docs/knowledge-base/**/PRD-*.md`)**且无对应活跃 change** → 直接调用 `/comate-gate`(阶段 0:先过门禁,再拆分建 change)。不要直接调 `/comate-open`——PRD 必须先过质量门禁。
28
27
  - 无预设命中 → 按下表处理
29
28
 
30
29
  | 活跃 change | 用户输入 | 行为 |
31
30
  |-------------|----------|------|
32
- | 无 | 指向原始 PRD | → 调用 `/comate-intake` |
31
+ | 无 | 指向原始 PRD | → 调用 `/comate-gate` |
33
32
  | 无 | 非预设输入 | → 调用 `/comate-open` |
34
33
  | 恰好 1 个 | `/comate <描述>` | → **询问**:继续该 change 还是新建 |
35
34
  | 多个 | `/comate <描述>` | → **询问**:继续已有还是新建;继续则列出供选择 |
@@ -60,7 +59,7 @@ agent 做决策只需读本节,其余参见末尾「参考附录」。决策
60
59
  2. `verify_result: pass` 且 `archived` 非 `true` → 调用 `/comate-archive`
61
60
  3. `verify_result: fail` → 验证失败决策阻塞点(决策点 4)
62
61
  4. `phase: verify` 或 tasks.md 全勾 → 调用 `/comate-verify`
63
- 5. `phase: build` 或有 Design Doc 但 plan/执行未完成 → 按 workflow 路由:`hotfix`→`/comate-hotfix`,`tweak`→`/comate-tweak`,`full`→`/comate-build`
62
+ 5. `phase: build` 或有 Design Doc 但 plan/执行未完成 → 按 workflow 路由:`fix`→`/comate-fix`,`full`→`/comate-build`
64
63
  6. `phase: design` 或有 change 但无 Design Doc → 调用 `/comate-design`
65
64
  7. `phase: open` 或有活跃 change 但 `.comate.yaml` 缺失 → 调用 `/comate-open`
66
65
  8. 无活跃 change → 调用 `/comate-open`
@@ -69,9 +68,7 @@ agent 做决策只需读本节,其余参见末尾「参考附录」。决策
69
68
 
70
69
  ### 预设升级判定
71
70
 
72
- **hotfix → full**(任一满足即升级):改动 ≥ 3 文件 / 架构变更(新模块、新接口、新依赖)/ 数据库 schema 变更 / 引入新 public API / 范围超出单一函数模块。
73
-
74
- **tweak → full**(任一满足即升级):改动 ≥ 5 文件 / 跨模块协调 / 需新增 ≥ 5 测试用例 / 配置项增删(非值修改)。
71
+ **fix → full**:见 `/comate-fix` 的两种模式升级条件(bug 模式 3+ 文件 / 架构变更 / schema 变更 / 新 API / 跨模块;调整模式 5+ 文件 / 多模块协调 / 5+ 测试 / 配置项增删 / 新 capability / delta spec)。
75
72
 
76
73
  ### 错误处理速查
77
74
 
@@ -101,17 +98,17 @@ agent 做决策只需读本节,其余参见末尾「参考附录」。决策
101
98
 
102
99
  | 命令 | 阶段 | Owner | 产物 |
103
100
  |------|------|-------|------|
104
- | `/comate-intake` | 0. PRD 门禁与拆分 | Claude | `<PRD>.gate.yaml`, 评审报告, N 个 change |
101
+ | `/comate-gate` | 0. PRD 门禁与拆分 | Claude | `<PRD>.gate.yaml`, 评审报告, N 个 change |
105
102
  | `/comate-open` | 1. 开题 | OpenSpec | proposal.md, design.md, tasks.md |
106
103
  | `/comate-design` | 2. 深度设计 | Superpowers | Design Doc, delta spec |
107
104
  | `/comate-build` | 3. 计划与构建 | Superpowers | 实施计划, 代码提交 |
108
105
  | `/comate-verify` | 4. 验证收尾 | 双方 | 验证报告, 分支处理 |
109
106
  | `/comate-archive` | 5. 归档 | OpenSpec | delta→main spec 同步, design doc 标注, 归档 |
110
- | `/comate-hotfix` | 预设 | 双方 | 快速修复(跳过 brainstorming) |
111
- | `/comate-tweak` | 预设 | 双方 | 小调整(跳过 brainstorming + 完整 plan) |
107
+ | `/comate-fix` | 预设 | 双方 | 快速小改动(bug 修复 + 非 bug 调整,跳过 brainstorming) |
108
+ | `/comate-kb-integration` | 工具 | Claude | 第三方对接档案(从官方文档 URL 生成 integrations 目录档案) |
112
109
 
113
110
  ```
114
- [原始 PRD] ──→ /comate-intake ──┐ (门禁+拆分,扇出 N 个 change)
111
+ [原始 PRD] ──→ /comate-gate ──┐ (门禁+拆分,扇出 N 个 change)
115
112
  (Claude) │
116
113
  /comate ▼
117
114
  ↓ 自动探测
@@ -119,7 +116,7 @@ agent 做决策只需读本节,其余参见末尾「参考附录」。决策
119
116
  (OpenSpec) (Superpowers) (Superpowers) (双方) (OpenSpec)
120
117
  ```
121
118
 
122
- 需求来自对话时从 `/comate-open` 起步;来自原始 PRD 时先过 `/comate-intake` 门禁再拆分。
119
+ 需求来自对话时从 `/comate-open` 起步;来自原始 PRD 时先过 `/comate-gate` 门禁再拆分。
123
120
 
124
121
  ---
125
122
 
@@ -142,7 +139,7 @@ fi
142
139
  之后全程复用 `$COMATE`:
143
140
 
144
141
  ```bash
145
- bash "$COMATE" state <name> init <full|hotfix|tweak>
142
+ bash "$COMATE" state <name> init <full|fix>
146
143
  bash "$COMATE" state <name> transition <event>
147
144
  bash "$COMATE" state <name> check <phase> [--json]
148
145
  bash "$COMATE" state <name> recover <phase>
@@ -167,10 +164,10 @@ bash "$COMATE" doctor
167
164
  | 字段 | 含义 |
168
165
  |------|------|
169
166
  | `schema_version` | 状态文件格式版本(当前 1) |
170
- | `workflow` | `full` / `hotfix` / `tweak` |
167
+ | `workflow` | `full` / `fix` |
171
168
  | `phase` | `open` / `design` / `build` / `verify` / `archive` |
172
169
  | `build_mode` | `subagent-driven-development` / `executing-plans` / `direct` |
173
- | `tdd_mode` | `tdd` / `direct`(build→verify 前必须已选;hotfix/tweak 默认 `direct`) |
170
+ | `tdd_mode` | `tdd` / `direct`(build→verify 前必须已选;fix 默认 `direct`) |
174
171
  | `isolation` | `branch` / `worktree`(build→verify 前必须已选) |
175
172
  | `verify_mode` | `light` / `full`(由 scale 评估写入) |
176
173
  | `verify_result` | `pending` / `pass` / `fail` |
@@ -187,7 +184,7 @@ bash "$COMATE" doctor
187
184
  - `build → verify` 前 `isolation` 必须为 `branch` 或 `worktree`
188
185
  - `build → verify` 前 `build_mode` 必须已选
189
186
  - `build → verify` 前 `tdd_mode` 必须为 `tdd` 或 `direct`
190
- - `build_mode: direct` 默认仅 hotfix/tweak;full 流程需 `direct_override: true`
187
+ - `build_mode: direct` 默认仅 fix;full 流程需 `direct_override: true`
191
188
  - `verify → archive` 前 `verification_report` 指向真实文件、`branch_status: handled`、`impl_hash` 与当前 plan+tasks 一致
192
189
 
193
190
  ### 文件结构
@@ -212,7 +209,7 @@ docs/superpowers/ # Superpowers —— HOW
212
209
 
213
210
  ### 最佳实践
214
211
 
215
- 1. brainstorming 不可跳过(hotfix/tweak 除外)
212
+ 1. brainstorming 不可跳过(fix 除外)
216
213
  2. delta spec 是活文档,build 阶段随时改,归档时同步
217
214
  3. 交接包由脚本生成(`handoff`),guard 校验 source/hash/mode
218
215
  4. tasks.md 实时同步,每完成一个任务勾选并提交
@@ -55,9 +55,9 @@
55
55
  暂停请用户选择:本地合并 / 推送建 PR / 保持分支 / 丢弃工作。仅在用户选择且对应操作完成后,才写 `branch_status: handled`。
56
56
  引用:`comate-verify` Step 3。
57
57
 
58
- 6. **预设升级确认**(hotfix / tweak → full)
59
- 命中升级条件(见各 preset SKILL 的「升级条件」表)时,暂停请用户确认升级为完整 `/comate`。不得直接进入 `/comate-design`,不得自动补 Design Doc。用户确认后先 `state set <name> workflow full` 再进入完整流程。
60
- 引用:`comate-hotfix` / `comate-tweak`「升级条件」。
58
+ 6. **预设升级确认**(fix → full)
59
+ 命中升级条件(见 `comate-fix` SKILL 的「升级条件」,bug 模式与调整模式各有阈值)时,暂停请用户确认升级为完整 `/comate`。不得直接进入 `/comate-design`,不得自动补 Design Doc。用户确认后先 `state set <name> workflow full` 再进入完整流程。
60
+ 引用:`comate-fix`「升级条件」。
61
61
 
62
62
  7. **构建期范围扩张**(build)
63
63
  实施中发现需要重新设计或拆分新 change 时暂停。判定基准:以 tasks.md 初始任务总数为准,新增任务超过总数一半(50% 阈值)即视为超范围,请用户决定是否拆分。中等规模(接口变更、新增组件)确认后加载 `superpowers:brainstorming` 更新设计;大规模(全新 capability)确认后用 `/comate-open` 拆独立 change。
@@ -81,8 +81,7 @@ skills/
81
81
  ├── comate-build/SKILL.md # 阶段 3
82
82
  ├── comate-verify/SKILL.md # 阶段 4
83
83
  ├── comate-archive/SKILL.md # 阶段 5
84
- ├── comate-hotfix/SKILL.md # 预设
85
- └── comate-tweak/SKILL.md # 预设
84
+ ├── comate-fix/SKILL.md # 预设(bug + 调整)
86
85
  ```
87
86
 
88
87
  各 phase skill 通过 `*/comate/scripts/comate.sh` glob 定位脚本,共享 `comate/reference/*` 和 `comate/scripts/*`。若目标平台支持嵌套 skill 发现,也可改回 `comate/<phase>/SKILL.md` 子目录布局,纯命名调整,不影响脚本。
@@ -4,7 +4,7 @@
4
4
  # Single source of truth for: YAML flat read/write, field-order template + enums,
5
5
  # hashing, logging, exit-code contract. Other scripts `source` this file.
6
6
  #
7
- # - all YAML logic lives here (Comet duplicated it across 4 scripts).
7
+ # - all YAML logic lives here
8
8
  # - .comate.yaml is a declared flat `key: value` subset; validate_flat_yaml enforces it.
9
9
  # - yaml_set does full-rewrite + atomic mv + write-back verification.
10
10
  # - stable exit codes — 0 OK | 1 BLOCK | 2 USAGE | 3 ENV | 4 CORRUPT.
@@ -81,7 +81,7 @@ readonly COMATE_SCHEMA_VERSION=1
81
81
  # --- Enum table: key -> space-separated legal values ---
82
82
  declare -A ENUMS=(
83
83
  [schema_version]="1"
84
- [workflow]="full hotfix tweak"
84
+ [workflow]="full fix"
85
85
  [phase]="open design build verify archive"
86
86
  [build_mode]="subagent-driven-development executing-plans direct"
87
87
  [tdd_mode]="tdd direct"
@@ -460,23 +460,40 @@ declare -A GATE_ENUMS=(
460
460
  [gate_status]="reviewing blocked passed passed-with-tbd stale"
461
461
  )
462
462
 
463
+ # gate_stem_for <prd> — derive the short stem used to name a PRD's gate.yaml
464
+ # and review report. A conforming PRD file is `PRD-<NNN>-<title>.md`, whose
465
+ # gate/report drop the title and key off `PRD-<NNN>` (so one dir with
466
+ # PRD-001/PRD-002 gets PRD-001.gate.yaml / PRD-002.gate.yaml). Non-conforming
467
+ # names (no PRD-NNN prefix) fall back to the full basename so callers still get
468
+ # a stable, collision-free stem instead of an error.
469
+ gate_stem_for() {
470
+ local base
471
+ base=$(basename "$1")
472
+ base="${base%.markdown}"
473
+ base="${base%.md}"
474
+ if [[ "$base" =~ ^([Pp][Rr][Dd]-[0-9]+) ]]; then
475
+ echo "${BASH_REMATCH[1]}"
476
+ else
477
+ echo "$base"
478
+ fi
479
+ }
480
+
463
481
  # gate_path_for <prd> — echo the gate.yaml path adjacent to the PRD.
464
- # Strips a trailing .md/.markdown and appends .gate.yaml.
482
+ # Named `<stem>.gate.yaml` where stem is PRD-<NNN> (see gate_stem_for).
465
483
  gate_path_for() {
466
- local prd="$1" base
467
- base="${prd%.markdown}"
468
- base="${base%.md}"
469
- echo "${base}.gate.yaml"
484
+ local prd="$1" dir stem
485
+ dir=$(dirname "$prd")
486
+ stem=$(gate_stem_for "$prd")
487
+ echo "${dir}/${stem}.gate.yaml"
470
488
  }
471
489
 
472
490
  # gate_report_for <prd> — echo the review report path (PRD same dir).
491
+ # Named `<stem>-REVIEW.md` where stem is PRD-<NNN> (see gate_stem_for).
473
492
  gate_report_for() {
474
- local prd="$1" dir base
493
+ local prd="$1" dir stem
475
494
  dir=$(dirname "$prd")
476
- base=$(basename "$prd")
477
- base="${base%.markdown}"
478
- base="${base%.md}"
479
- echo "${dir}/PRD-REVIEW-${base}.md"
495
+ stem=$(gate_stem_for "$prd")
496
+ echo "${dir}/${stem}-REVIEW.md"
480
497
  }
481
498
 
482
499
  # gate_yaml_set <file> <key> <value> — gate-file analogue of yaml_set: validate
@@ -57,7 +57,7 @@ usage_top() {
57
57
  cat >&2 <<'EOF'
58
58
  Usage: comate.sh <command> ...
59
59
 
60
- state <name> init <workflow> full | hotfix | tweak
60
+ state <name> init <workflow> full | fix
61
61
  state <name> get <field>
62
62
  state <name> set <field> <value>
63
63
  state <name> transition <event> open-complete|design-complete|build-complete|verify-pass|verify-fail|archived
@@ -102,7 +102,7 @@ state_init() {
102
102
  local name="$1" workflow="${2:-}"
103
103
  validate_change_name "$name"
104
104
  validate_enum workflow "$workflow"
105
- [ -n "$workflow" ] || die "$COMATE_USAGE" "Usage: comate.sh state <name> init <full|hotfix|tweak>"
105
+ [ -n "$workflow" ] || die "$COMATE_USAGE" "Usage: comate.sh state <name> init <full|fix>"
106
106
 
107
107
  local dir yaml
108
108
  dir=$(comate_change_dir "$name")
@@ -128,7 +128,7 @@ state_init() {
128
128
  # Workflow defaults: full leaves decisions null; presets prefill.
129
129
  local build_mode="null" tdd_mode="null" isolation="null" verify_mode="null"
130
130
  case "$workflow" in
131
- hotfix|tweak)
131
+ fix)
132
132
  build_mode="direct"; tdd_mode="direct"; isolation="branch"; verify_mode="light" ;;
133
133
  esac
134
134
 
@@ -212,8 +212,8 @@ _require_build_decisions() {
212
212
  subagent-driven-development|executing-plans|direct) ;;
213
213
  *) die "$COMATE_BLOCK" "ERROR: build_mode must be selected, got '${build_mode:-null}'" ;;
214
214
  esac
215
- if [ "$build_mode" = "direct" ] && [ "$workflow" != "hotfix" ] && [ "$workflow" != "tweak" ] && [ "$direct_override" != "true" ]; then
216
- die "$COMATE_BLOCK" "ERROR: build_mode=direct is only allowed for hotfix/tweak unless direct_override=true"
215
+ if [ "$build_mode" = "direct" ] && [ "$workflow" != "fix" ] && [ "$direct_override" != "true" ]; then
216
+ die "$COMATE_BLOCK" "ERROR: build_mode=direct is only allowed for fix unless direct_override=true"
217
217
  fi
218
218
  case "$tdd_mode" in
219
219
  tdd|direct) ;;
@@ -561,7 +561,7 @@ state_recover() {
561
561
  _field_status "isolation" "$isolation"
562
562
  _field_status "build_mode" "$build_mode"
563
563
  _field_status "tdd_mode" "$tdd_mode"
564
- if [ "$build_mode" = "direct" ] && [ "$workflow" != "hotfix" ] && [ "$workflow" != "tweak" ]; then
564
+ if [ "$build_mode" = "direct" ] && [ "$workflow" != "fix" ]; then
565
565
  _field_status "direct_override" "$direct_override"
566
566
  fi
567
567
  echo ""
@@ -790,9 +790,9 @@ _g_build_mode_allowed() {
790
790
  build_mode=$(yaml_get "$G_YAML" build_mode)
791
791
  direct_override=$(yaml_get "$G_YAML" direct_override)
792
792
  [ "$build_mode" != "direct" ] && return 0
793
- case "$workflow" in hotfix|tweak) return 0 ;; esac
793
+ case "$workflow" in fix) return 0 ;; esac
794
794
  [ "$direct_override" = "true" ] && return 0
795
- echo "build_mode=direct only allowed for hotfix/tweak unless direct_override=true"
795
+ echo "build_mode=direct only allowed for fix unless direct_override=true"
796
796
  return 1
797
797
  }
798
798
  _g_tdd_mode_selected() {
@@ -1508,7 +1508,7 @@ gate_check() {
1508
1508
  local prd; prd=$(require_prd "$1")
1509
1509
  local gate; gate=$(gate_path_for "$prd")
1510
1510
  if [ ! -f "$gate" ]; then
1511
- die "$COMATE_BLOCK" "BLOCK: no gate for $prd — run /comate-intake to review the PRD before creating a change"
1511
+ die "$COMATE_BLOCK" "BLOCK: no gate for $prd — run /comate-gate to review the PRD before creating a change"
1512
1512
  fi
1513
1513
  local st; st=$(yaml_get "$gate" gate_status)
1514
1514
  case "$st" in
@@ -1516,7 +1516,7 @@ gate_check() {
1516
1516
  *) die "$COMATE_BLOCK" "BLOCK: gate_status='$st' (not passed) — a change cannot be spawned until the PRD gate passes" ;;
1517
1517
  esac
1518
1518
  if _gate_is_stale "$gate" "$prd"; then
1519
- die "$COMATE_BLOCK" "BLOCK: PRD changed since it passed the gate (hash mismatch) — re-run /comate-intake to re-gate before spawning a change"
1519
+ die "$COMATE_BLOCK" "BLOCK: PRD changed since it passed the gate (hash mismatch) — re-run /comate-gate to re-gate before spawning a change"
1520
1520
  fi
1521
1521
  log_pass "[GATE] check PASS ($st) — $prd"
1522
1522
  return "$COMATE_OK"
@@ -50,21 +50,14 @@ seed_open() {
50
50
  [ "$(comate state demo get isolation)" = "null" ]
51
51
  }
52
52
 
53
- @test "init hotfix prefills preset defaults" {
54
- comate state demo init hotfix
53
+ @test "init fix prefills preset defaults" {
54
+ comate state demo init fix
55
55
  [ "$(comate state demo get build_mode)" = "direct" ]
56
56
  [ "$(comate state demo get tdd_mode)" = "direct" ]
57
57
  [ "$(comate state demo get isolation)" = "branch" ]
58
58
  [ "$(comate state demo get verify_mode)" = "light" ]
59
59
  }
60
60
 
61
- @test "init tweak prefills tdd direct" {
62
- comate state demo init tweak
63
- [ "$(comate state demo get build_mode)" = "direct" ]
64
- [ "$(comate state demo get tdd_mode)" = "direct" ]
65
- [ "$(comate state demo get isolation)" = "branch" ]
66
- }
67
-
68
61
  @test "init records base_ref and base_branch" {
69
62
  comate state demo init full
70
63
  run comate state demo get base_ref
@@ -155,14 +148,14 @@ seed_open() {
155
148
  [ "$(comate state demo get phase)" = "design" ]
156
149
  }
157
150
 
158
- @test "open-complete routes hotfix to build" {
159
- comate state demo init hotfix
151
+ @test "open-complete routes fix to build" {
152
+ comate state demo init fix
160
153
  comate state demo transition open-complete
161
154
  [ "$(comate state demo get phase)" = "build" ]
162
155
  }
163
156
 
164
157
  @test "build-complete blocked without isolation" {
165
- comate state demo init hotfix
158
+ comate state demo init fix
166
159
  comate state demo transition open-complete
167
160
  comate state demo set isolation null >/dev/null
168
161
  run comate state demo transition build-complete
@@ -248,7 +241,7 @@ seed_open() {
248
241
  # --- build->verify drift ---
249
242
 
250
243
  @test "verify guard blocks when tasks change after build handoff" {
251
- comate state demo init hotfix
244
+ comate state demo init fix
252
245
  local d="openspec/changes/demo"
253
246
  printf '# p\n' > "$d/proposal.md"; printf '# d\n' > "$d/design.md"; printf -- '- [x] t1\n' > "$d/tasks.md"
254
247
  comate guard demo open --apply >/dev/null 2>&1
@@ -422,7 +415,7 @@ SH
422
415
  }
423
416
 
424
417
  @test "build guard blocks when tracked source drifts" {
425
- comate state demo init hotfix
418
+ comate state demo init fix
426
419
  local d="openspec/changes/demo"
427
420
  printf '# p\n' > "$d/proposal.md"; printf '# d\n' > "$d/design.md"; printf -- '- [x] t1\n' > "$d/tasks.md"
428
421
  mkdir -p docs/knowledge-base/cb
@@ -461,13 +454,25 @@ seed_prd() {
461
454
  local prd; prd=$(seed_prd)
462
455
  run comate gate "$prd" review
463
456
  [ "$status" -eq 0 ]
464
- [ -f "docs/knowledge-base/requirements/test/PRD-001-demo.gate.yaml" ]
457
+ [ -f "docs/knowledge-base/requirements/test/PRD-001.gate.yaml" ]
458
+ }
459
+
460
+ @test "gate names key off PRD-NNN stem, dropping title" {
461
+ local prd; prd=$(seed_prd)
462
+ run comate gate "$prd" review
463
+ [ "$status" -eq 0 ]
464
+ # gate.yaml and review report drop the -demo title, key off PRD-001
465
+ [ -f "docs/knowledge-base/requirements/test/PRD-001.gate.yaml" ]
466
+ [ ! -f "docs/knowledge-base/requirements/test/PRD-001-demo.gate.yaml" ]
467
+ [[ "$output" == *"PRD-001-REVIEW.md"* ]]
468
+ grep -q "review_report: docs/knowledge-base/requirements/test/PRD-001-REVIEW.md" \
469
+ "docs/knowledge-base/requirements/test/PRD-001.gate.yaml"
465
470
  }
466
471
 
467
472
  @test "gate review writes reviewing status and pins prd_hash" {
468
473
  local prd; prd=$(seed_prd)
469
474
  comate gate "$prd" review >/dev/null
470
- local gate="docs/knowledge-base/requirements/test/PRD-001-demo.gate.yaml"
475
+ local gate="docs/knowledge-base/requirements/test/PRD-001.gate.yaml"
471
476
  run comate gate "$prd" status
472
477
  [ "$status" -eq 0 ]
473
478
  [[ "$output" == *"reviewing"* ]]
@@ -509,7 +514,7 @@ seed_prd() {
509
514
  comate gate "$prd" set score 90 >/dev/null
510
515
  comate gate "$prd" set blocking_open 0 >/dev/null
511
516
  printf '# 评审报告\n' > \
512
- "docs/knowledge-base/requirements/test/PRD-REVIEW-PRD-001-demo.md"
517
+ "docs/knowledge-base/requirements/test/PRD-001-REVIEW.md"
513
518
  run comate gate "$prd" pass
514
519
  [ "$status" -eq 0 ]
515
520
  run comate gate "$prd" check
@@ -522,7 +527,7 @@ seed_prd() {
522
527
  comate gate "$prd" set score 65 >/dev/null
523
528
  comate gate "$prd" set blocking_open 0 >/dev/null
524
529
  printf '# 评审报告\n' > \
525
- "docs/knowledge-base/requirements/test/PRD-REVIEW-PRD-001-demo.md"
530
+ "docs/knowledge-base/requirements/test/PRD-001-REVIEW.md"
526
531
  run comate gate "$prd" pass --tbd
527
532
  [ "$status" -eq 0 ]
528
533
  run comate gate "$prd" status
@@ -535,7 +540,7 @@ seed_prd() {
535
540
  comate gate "$prd" set score 90 >/dev/null
536
541
  comate gate "$prd" set blocking_open 0 >/dev/null
537
542
  printf '# 评审报告\n' > \
538
- "docs/knowledge-base/requirements/test/PRD-REVIEW-PRD-001-demo.md"
543
+ "docs/knowledge-base/requirements/test/PRD-001-REVIEW.md"
539
544
  comate gate "$prd" pass >/dev/null
540
545
  # mutate PRD after passing
541
546
  printf '\n额外内容\n' >> "$prd"
@@ -550,14 +555,14 @@ seed_prd() {
550
555
  comate gate "$prd" set score 90 >/dev/null
551
556
  comate gate "$prd" set blocking_open 0 >/dev/null
552
557
  printf '# 评审报告\n' > \
553
- "docs/knowledge-base/requirements/test/PRD-REVIEW-PRD-001-demo.md"
558
+ "docs/knowledge-base/requirements/test/PRD-001-REVIEW.md"
554
559
  comate gate "$prd" pass >/dev/null
555
560
  printf '\n改动\n' >> "$prd"
556
561
  run comate gate "$prd" status
557
562
  [ "$status" -eq 0 ]
558
563
  [[ "$output" == *"stale"* ]]
559
564
  # gate.yaml should still say passed (status is computed, not written by status cmd)
560
- local gate="docs/knowledge-base/requirements/test/PRD-001-demo.gate.yaml"
565
+ local gate="docs/knowledge-base/requirements/test/PRD-001.gate.yaml"
561
566
  local stored; stored=$(grep '^gate_status:' "$gate" | awk '{print $2}')
562
567
  [ "$stored" = "passed" ]
563
568
  }
@@ -568,11 +573,11 @@ seed_prd() {
568
573
  comate gate "$prd" set score 90 >/dev/null
569
574
  comate gate "$prd" set blocking_open 0 >/dev/null
570
575
  printf '# 报告\n' > \
571
- "docs/knowledge-base/requirements/test/PRD-REVIEW-PRD-001-demo.md"
576
+ "docs/knowledge-base/requirements/test/PRD-001-REVIEW.md"
572
577
  comate gate "$prd" pass >/dev/null
573
578
  run comate gate "$prd" spawned login-flow
574
579
  [ "$status" -eq 0 ]
575
- local gate="docs/knowledge-base/requirements/test/PRD-001-demo.gate.yaml"
580
+ local gate="docs/knowledge-base/requirements/test/PRD-001.gate.yaml"
576
581
  local sc; sc=$(grep '^spawned_changes:' "$gate" | sed 's/spawned_changes: //')
577
582
  [[ "$sc" == *"login-flow"* ]]
578
583
  }
@@ -583,11 +588,11 @@ seed_prd() {
583
588
  comate gate "$prd" set score 90 >/dev/null
584
589
  comate gate "$prd" set blocking_open 0 >/dev/null
585
590
  printf '# 报告\n' > \
586
- "docs/knowledge-base/requirements/test/PRD-REVIEW-PRD-001-demo.md"
591
+ "docs/knowledge-base/requirements/test/PRD-001-REVIEW.md"
587
592
  comate gate "$prd" pass >/dev/null
588
593
  comate gate "$prd" spawned login-flow >/dev/null
589
594
  comate gate "$prd" spawned logout-flow >/dev/null
590
- local gate="docs/knowledge-base/requirements/test/PRD-001-demo.gate.yaml"
595
+ local gate="docs/knowledge-base/requirements/test/PRD-001.gate.yaml"
591
596
  local sc; sc=$(grep '^spawned_changes:' "$gate" | sed 's/spawned_changes: //')
592
597
  [[ "$sc" == *"login-flow"* ]]
593
598
  [[ "$sc" == *"logout-flow"* ]]
@@ -612,7 +617,7 @@ seed_prd() {
612
617
  comate gate "$prd" set score 90 >/dev/null
613
618
  comate gate "$prd" set blocking_open 0 >/dev/null
614
619
  printf '# 报告\n' > \
615
- "docs/knowledge-base/requirements/test/PRD-REVIEW-PRD-001-demo.md"
620
+ "docs/knowledge-base/requirements/test/PRD-001-REVIEW.md"
616
621
  comate gate "$prd" pass >/dev/null
617
622
  printf '\n改动\n' >> "$prd"
618
623
  # re-run review after PRD change — should reset to reviewing
@@ -82,7 +82,7 @@ bash "$COMATE" state <name> set plan docs/superpowers/plans/YYYY-MM-DD-feature.m
82
82
  对仍有多个有效选项的维度,**一次 AskUserQuestion 问清全部**,选 `branch` 时**分支名也在同一次确认**,不得先问是否继续再二次追问配置或命名。已在 3b 自动写入的维度不再列入问题。每个选项附推荐理由(推荐只说明倾向,不代替用户拍板):
83
83
 
84
84
  - **工作区隔离**:`branch` 新建分支(简单快速,≤3 文件推荐)/ `worktree` 独立工作区(需并行或当前分支有未提交工作时推荐)。
85
- - **执行方式**:`subagent-driven-development`(任务 ≥3、独立、需双阶段审查)/ `executing-plans`(任务 ≤2 且无跨模块依赖,或来自 hotfix)。
85
+ - **执行方式**:`subagent-driven-development`(任务 ≥3、独立、需双阶段审查)/ `executing-plans`(任务 ≤2 且无跨模块依赖,或来自 fix 预设)。
86
86
  - **TDD 模式**:`tdd`(涉及业务逻辑/新功能/API,推荐)/ `direct`(无需测试覆盖或用户明确跳过)。
87
87
 
88
88
  用户选择后(连同 3b 已自动应用的维度)写入:
@@ -95,7 +95,7 @@ bash "$COMATE" state <name> set tdd_mode <tdd|direct>
95
95
 
96
96
  `isolation` 是脚本级硬约束,保持 `null` 时 `build → verify` 的 guard 和 `state transition build-complete` 都会失败。
97
97
 
98
- `build_mode: direct` 默认仅 hotfix/tweak 预设使用。full 流程只有用户明确要求跳过计划执行技能、且已记录显式 override 时才允许:
98
+ `build_mode: direct` 默认仅 fix 预设使用。full 流程只有用户明确要求跳过计划执行技能、且已记录显式 override 时才允许:
99
99
 
100
100
  ```bash
101
101
  bash "$COMATE" state <name> set direct_override true
@@ -109,7 +109,7 @@ bash "$COMATE" state <name> set build_mode direct
109
109
  | 选项 | 含义 | 适用场景 |
110
110
  |------|------|---------|
111
111
  | `tdd` | 每个任务先写失败测试再实现 | 推荐。涉及业务逻辑、新功能、API 的改动 |
112
- | `direct` | 直接实现,不强制 TDD 流程 | 不需要测试覆盖的改动,或用户选择跳过测试直接写代码。hotfix/tweak 预设默认 `direct` |
112
+ | `direct` | 直接实现,不强制 TDD 流程 | 不需要测试覆盖的改动,或用户选择跳过测试直接写代码。fix 预设默认 `direct` |
113
113
 
114
114
  `tdd_mode` 是脚本级硬约束,full 流程在离开 build 阶段前必须选择 `tdd` 或 `direct`,否则 guard 和 `state transition build-complete` 都会失败。
115
115