@rpamis/comet 0.3.7 → 0.3.9

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 (100) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +557 -539
  3. package/assets/manifest.json +41 -34
  4. package/assets/skills/comet/SKILL.md +282 -329
  5. package/assets/skills/comet/reference/auto-transition.md +27 -0
  6. package/assets/skills/comet/reference/comet-yaml-fields.md +68 -0
  7. package/assets/skills/comet/reference/context-recovery.md +35 -0
  8. package/assets/skills/comet/reference/debug-gate.md +17 -0
  9. package/assets/skills/comet/reference/decision-point.md +20 -0
  10. package/assets/skills/comet/reference/dirty-worktree.md +59 -59
  11. package/assets/skills/comet/reference/file-structure.md +28 -0
  12. package/assets/skills/comet/reference/subagent-dispatch.md +113 -0
  13. package/assets/skills/comet/rules/comet-phase-guard.en.md +123 -0
  14. package/assets/skills/comet/rules/comet-phase-guard.md +125 -90
  15. package/assets/skills/comet/scripts/comet-guard.sh +27 -1
  16. package/assets/skills/comet/scripts/comet-hook-guard.sh +121 -45
  17. package/assets/skills/comet/scripts/comet-state.sh +162 -7
  18. package/assets/skills/comet/scripts/comet-yaml-validate.sh +3 -1
  19. package/assets/skills/comet-archive/SKILL.md +100 -106
  20. package/assets/skills/comet-build/SKILL.md +304 -316
  21. package/assets/skills/comet-design/SKILL.md +263 -272
  22. package/assets/skills/comet-hotfix/SKILL.md +204 -211
  23. package/assets/skills/comet-open/SKILL.md +220 -186
  24. package/assets/skills/comet-tweak/SKILL.md +180 -179
  25. package/assets/skills/comet-verify/SKILL.md +234 -240
  26. package/assets/skills-zh/comet/SKILL.md +269 -332
  27. package/assets/skills-zh/comet/reference/auto-transition.md +27 -0
  28. package/assets/skills-zh/comet/reference/comet-yaml-fields.md +71 -0
  29. package/assets/skills-zh/comet/reference/context-recovery.md +35 -0
  30. package/assets/skills-zh/comet/reference/debug-gate.md +17 -0
  31. package/assets/skills-zh/comet/reference/decision-point.md +20 -0
  32. package/assets/skills-zh/comet/reference/dirty-worktree.md +59 -59
  33. package/assets/skills-zh/comet/reference/file-structure.md +28 -0
  34. package/assets/skills-zh/comet/reference/subagent-dispatch.md +120 -0
  35. package/assets/skills-zh/comet-archive/SKILL.md +100 -106
  36. package/assets/skills-zh/comet-build/SKILL.md +317 -316
  37. package/assets/skills-zh/comet-design/SKILL.md +264 -273
  38. package/assets/skills-zh/comet-hotfix/SKILL.md +200 -207
  39. package/assets/skills-zh/comet-open/SKILL.md +220 -186
  40. package/assets/skills-zh/comet-tweak/SKILL.md +176 -175
  41. package/assets/skills-zh/comet-verify/SKILL.md +232 -238
  42. package/bin/comet.js +3 -3
  43. package/dist/cli/index.js +21 -1
  44. package/dist/cli/index.js.map +1 -1
  45. package/dist/commands/doctor.d.ts.map +1 -1
  46. package/dist/commands/doctor.js +5 -1
  47. package/dist/commands/doctor.js.map +1 -1
  48. package/dist/commands/i18n.d.ts +4 -0
  49. package/dist/commands/i18n.d.ts.map +1 -0
  50. package/dist/commands/i18n.js +154 -0
  51. package/dist/commands/i18n.js.map +1 -0
  52. package/dist/commands/init.d.ts +3 -0
  53. package/dist/commands/init.d.ts.map +1 -1
  54. package/dist/commands/init.js +127 -75
  55. package/dist/commands/init.js.map +1 -1
  56. package/dist/commands/uninstall.d.ts +9 -0
  57. package/dist/commands/uninstall.d.ts.map +1 -0
  58. package/dist/commands/uninstall.js +132 -0
  59. package/dist/commands/uninstall.js.map +1 -0
  60. package/dist/commands/update.d.ts +3 -2
  61. package/dist/commands/update.d.ts.map +1 -1
  62. package/dist/commands/update.js +105 -68
  63. package/dist/commands/update.js.map +1 -1
  64. package/dist/core/codegraph.d.ts +4 -7
  65. package/dist/core/codegraph.d.ts.map +1 -1
  66. package/dist/core/codegraph.js +63 -41
  67. package/dist/core/codegraph.js.map +1 -1
  68. package/dist/core/detect.d.ts +13 -1
  69. package/dist/core/detect.d.ts.map +1 -1
  70. package/dist/core/detect.js +68 -12
  71. package/dist/core/detect.js.map +1 -1
  72. package/dist/core/openspec.d.ts +2 -2
  73. package/dist/core/openspec.d.ts.map +1 -1
  74. package/dist/core/openspec.js +51 -22
  75. package/dist/core/openspec.js.map +1 -1
  76. package/dist/core/platforms.d.ts.map +1 -1
  77. package/dist/core/platforms.js +14 -1
  78. package/dist/core/platforms.js.map +1 -1
  79. package/dist/core/skills.d.ts +3 -1
  80. package/dist/core/skills.d.ts.map +1 -1
  81. package/dist/core/skills.js +151 -66
  82. package/dist/core/skills.js.map +1 -1
  83. package/dist/core/superpowers.d.ts +1 -1
  84. package/dist/core/superpowers.d.ts.map +1 -1
  85. package/dist/core/superpowers.js +5 -1
  86. package/dist/core/superpowers.js.map +1 -1
  87. package/dist/core/uninstall.d.ts +28 -0
  88. package/dist/core/uninstall.d.ts.map +1 -0
  89. package/dist/core/uninstall.js +421 -0
  90. package/dist/core/uninstall.js.map +1 -0
  91. package/dist/core/version.d.ts +31 -0
  92. package/dist/core/version.d.ts.map +1 -0
  93. package/dist/core/version.js +111 -0
  94. package/dist/core/version.js.map +1 -0
  95. package/dist/utils/file-system.d.ts +23 -0
  96. package/dist/utils/file-system.d.ts.map +1 -1
  97. package/dist/utils/file-system.js +100 -5
  98. package/dist/utils/file-system.js.map +1 -1
  99. package/package.json +69 -64
  100. package/scripts/postinstall.js +44 -44
@@ -1,90 +1,125 @@
1
- # Comet 阶段感知(防漂移规则)
2
-
3
- > 此规则每轮注入,防止长上下文时遗忘 Comet 流程状态。
4
- > Hook 平台额外执行 `comet-hook-guard.sh` 进行硬性拦截;
5
- > 此 Rule 是所有平台通用的软性防线。
6
-
7
- ## 全局规则
8
-
9
- ### 阶段感知(最高优先级)
10
-
11
- 有活跃 comet change 时(`openspec/changes/<name>/.comet.yaml` 存在),**每次开始执行操作前**必须读取 `phase` 字段确认当前阶段。
12
-
13
- **阶段与允许操作:**
14
-
15
- | 阶段 | 允许 | 禁止 |
16
- |------|------|------|
17
- | `open` | 创建 proposal/design/tasks, 运行 guard | 写源代码 |
18
- | `design` | brainstorming, 创建 Design Doc, 运行 guard | 写源代码 |
19
- | `build` | 写源代码、测试、执行计划 | 跳过用户确认点 |
20
- | `verify` | 验证、branch handling | 跳过失败处理 |
21
- | `archive` | 确认归档、运行归档脚本 | 写源代码 |
22
-
23
- ### Skill 调用(不可用普通对话替代)
24
-
25
- 以下操作必须通过 Skill 工具加载,Skill 不可用时应停止流程并提示安装:
26
-
27
- - **brainstorming** design 阶段、build 阶段中等规模 spec 变更
28
- - **writing-plans** — build 阶段创建实现计划
29
- - **executing-plans** / **subagent-driven-development** build 阶段执行
30
- - **test-driven-development** build 阶段 `tdd_mode: tdd` 时,第一个 task 前
31
- - **systematic-debugging** 遇到崩溃/测试失败/构建失败时
32
- - **verification-before-completion** — verify 阶段
33
- - **using-git-worktrees** build 阶段选择 worktree 隔离时
34
-
35
- ### 脚本执行(不可跳过)
36
-
37
- - **阶段退出**: `comet-guard <name> <phase> --apply`(必须看到 ALL CHECKS PASSED)
38
- - **压缩恢复**: `comet-state check <name> <phase> --recover`
39
- - **状态更新**: 关键操作后通过 `comet-state set` 更新字段,禁止手工编辑 .comet.yaml
40
- - **handoff 生成**: `comet-handoff <name> design --write`(禁止手写摘要)
41
-
42
- ### 用户确认(不可自动跳过)
43
-
44
- 以下决策点必须暂停等待用户明确选择,不得根据推荐规则自动填写:
45
-
46
- - **open**: 需求澄清完成确认、artifact 评审确认
47
- - **design**: brainstorming 方案确认(确认前不得创建 Design Doc)
48
- - **build**: plan-ready 暂停、isolation/build_mode/tdd_mode 选择、spec 大规模变更确认
49
- - **verify**: 验证失败处理策略、branch handling 选择
50
- - **archive**: 归档前最终确认
51
-
52
- ## Design 阶段专项
53
-
54
- 1. 第一个脚本操作 = `comet-handoff <name> design --write`(未生成 handoff 禁止加载 brainstorming)
55
- 2. brainstorming in progress: incrementally update brainstorm-summary.md(每轮澄清或方案迭代后增量更新恢复检查点,未确认内容标注为待确认/候选)
56
- 3. brainstorming 完成后下一步 = brainstorm-summary.md 定稿 → Design Doc → guard
57
- 4. active compaction gate: brainstorm-summary.md 定稿后、创建 Design Doc 前,优先触发宿主平台原生上下文压缩;无法程序化触发时暂停提示用户手动压缩或确认继续
58
- 5. **绝对不能直接开始写实现代码** — 必须先创建 Design Doc 并通过 guard
59
-
60
- ## Build 阶段专项
61
-
62
- 1. plan 创建后必须询问用户选择继续或暂停(`build_pause` 机制)
63
- 2. 每个 task 完成后必须: tasks.md 打勾 → git commit(不得积攒)
64
- 3. 遇到失败必须加载 **systematic-debugging** skill,根因未定位前不得提出源码修复
65
- 4. spec 变更分级: 小改直接编辑 | 中改加载 brainstorming | 大改暂停等用户确认拆分
66
-
67
- ## Verify 阶段专项
68
-
69
- 1. 第一步运行 `comet-state scale <name>` 确定验证级别
70
- 2. 验证失败后列出失败项等用户选择,CRITICAL 必须修
71
- 3. 连续 3 次失败后必须让用户选择接受偏差或继续修
72
-
73
- ## 上下文压缩恢复
74
-
75
- 如果怀疑发生上下文压缩(之前对话被摘要、找不到之前讨论的内容),立即运行:
76
-
77
- ```bash
78
- "$COMET_BASH" "$COMET_STATE" check <name> <phase> --recover
79
- ```
80
-
81
- 按脚本输出的 **Recovery action** 决定下一步。
82
-
83
- ## 阶段退出后自动过渡
84
-
85
- guard `--apply` 成功后,必须调用下一阶段的 skill:
86
-
87
- - open → `comet-design`(full)/ `comet-build`(hotfix/tweak)
88
- - design → `comet-build`
89
- - build → `comet-verify`
90
- - verify → `comet-archive`
1
+ # Comet 阶段感知(防漂移规则)
2
+
3
+ > 此规则每轮注入,防止长上下文时遗忘 Comet 流程状态。
4
+ > Hook 平台额外执行 `comet-hook-guard.sh` 进行硬性拦截;
5
+ > 此 Rule 是所有平台通用的软性防线。
6
+
7
+ ## 全局规则
8
+
9
+ ### 阶段感知(最高优先级)
10
+
11
+ 有活跃 comet change 时(`openspec/changes/<name>/.comet.yaml` 存在),**每次开始执行操作前**必须读取 `phase` 字段确认当前阶段。
12
+
13
+ **阶段与允许操作:**
14
+
15
+ | 阶段 | 允许 | 禁止 |
16
+ |------|------|------|
17
+ | `open` | 创建 proposal/design/tasks, 运行 guard | 写源代码 |
18
+ | `design` | brainstorming, 创建 Design Doc, 运行 guard | 写源代码 |
19
+ | `build` | 写源代码、测试、执行计划 | 跳过用户确认点 |
20
+ | `verify` | 验证、branch handling | 跳过失败处理 |
21
+ | `archive` | 确认归档、运行归档脚本 | 写源代码 |
22
+
23
+ ### 阶段进入自洽性校验(写源代码前必查)
24
+
25
+ 仅看 `phase` 字段不够——还必须确认"是如何到达这个阶段的"。每次准备写源代码前,先用下表自检 `.comet.yaml` 是否处于**非法空跳**状态(绕过了前置阶段)。命中任一行,立即停止写源代码,按动作回到对应阶段补齐产物,不得信任 `phase` 字段直接续跑。
26
+
27
+ | 检测到 | 判定 | 动作 |
28
+ |--------|------|------|
29
+ | `phase: build` + `workflow: full` + `design_doc` 为空/null | 绕过 design 空跳 | 停止写源代码,运行 `/comet-design` Design Doc 并过 guard |
30
+ | `phase: build/verify` + proposal/design/tasks 任一缺失或为空 | 绕过 open 空跳 | 回 `/comet-open` 补齐三件套 |
31
+ | `phase: archive` + `verify_result` ≠ `pass` | 绕过 verify 空跳 | 回 `/comet-verify` 完成验证 |
32
+
33
+ 预设例外:`workflow: hotfix/tweak` 本就跳过 design,`design_doc` 为空属正常,不算非法。
34
+
35
+ ### Skill 调用(不可用普通对话替代)
36
+
37
+ 以下操作必须通过 Skill 工具加载,Skill 不可用时应停止流程并提示安装:
38
+
39
+ - **brainstorming** design 阶段、build 阶段中等规模 spec 变更
40
+ - **writing-plans** build 阶段创建实现计划
41
+ - **executing-plans** / **subagent-driven-development** — build 阶段执行
42
+ - **test-driven-development** — `executing-plans` 由主会话在第一个 task 前加载;`subagent-driven-development` 由每个后台 implementer 和修复 agent 加载
43
+ - **systematic-debugging** — 遇到崩溃/测试失败/构建失败时
44
+ - **verification-before-completion** — verify 阶段
45
+ - **using-git-worktrees** — build 阶段选择 worktree 隔离时
46
+
47
+ ### 脚本执行(不可跳过)
48
+
49
+ - **阶段退出**: `comet-guard <name> <phase> --apply`(必须看到 ALL CHECKS PASSED)
50
+ - **压缩恢复**: `comet-state check <name> <phase> --recover`
51
+ - **状态更新**: 关键操作后通过 `comet-state set` 更新字段,禁止手工编辑 .comet.yaml
52
+ - **阶段推进只能经 guard/transition**: 禁止用 `comet-state set <name> phase <值>` 手动跳阶段(会绕过证据校验,脚本已硬拦截);确需修复畸形状态时才用 `COMET_FORCE_PHASE=1` 逃生阀
53
+ - **handoff 生成**: `comet-handoff <name> design --write`(禁止手写摘要)
54
+
55
+ ### 用户确认(不可自动跳过)
56
+
57
+ 以下决策点必须暂停等待用户明确选择,不得根据推荐规则自动填写:
58
+
59
+ - **open**: 需求澄清完成确认、artifact 评审确认
60
+ - **design**: brainstorming 方案确认(确认前不得创建 Design Doc)
61
+ - **build**: plan-ready 暂停、isolation/build_mode/tdd_mode 选择、spec 大规模变更确认
62
+ - **verify**: 验证失败处理策略、branch handling 选择
63
+ - **archive**: 归档前最终确认
64
+
65
+ ## Design 阶段专项
66
+
67
+ 1. 第一个脚本操作 = `comet-handoff <name> design --write`(未生成 handoff 禁止加载 brainstorming)
68
+ 2. brainstorming in progress: incrementally update brainstorm-summary.md(每轮澄清或方案迭代后增量更新恢复检查点,未确认内容标注为待确认/候选)
69
+ 3. brainstorming 完成后下一步 = brainstorm-summary.md 定稿 Design Doc → guard
70
+ 4. active compaction gate: brainstorm-summary.md 定稿后、创建 Design Doc 前,优先触发宿主平台原生上下文压缩;无法程序化触发时暂停提示用户手动压缩或确认继续
71
+ 5. **绝对不能直接开始写实现代码** 必须先创建 Design Doc 并通过 guard
72
+
73
+ ## Build 阶段专项
74
+
75
+ 1. plan 创建后必须询问用户选择继续或暂停(`build_pause` 机制)
76
+ 2. 每个 task 验收后必须: tasks.md 打勾 → git commit(不得积攒)。`subagent-driven-development` 必须等 spec compliance 与 code quality 两个审查都通过,再由协调者按任务唯一文本定向勾选和验证;不得用未完成任务总表代替当前任务验证
77
+ 3. 遇到失败必须加载 **systematic-debugging** skill,根因未定位前不得提出源码修复
78
+ 4. spec 变更分级: 小改直接编辑 | 中改加载 brainstorming | 大改暂停等用户确认拆分
79
+
80
+ ## Verify 阶段专项
81
+
82
+ 1. 第一步运行 `comet-state scale <name>` 确定验证级别
83
+ 2. 验证失败后列出失败项等用户选择,CRITICAL 必须修
84
+ 3. 连续 3 次失败后必须让用户选择接受偏差或继续修
85
+
86
+ ## 上下文压缩恢复
87
+
88
+ 如果怀疑发生上下文压缩(之前对话被摘要、找不到之前讨论的内容),立即运行:
89
+
90
+ ```bash
91
+ "$COMET_BASH" "$COMET_STATE" check <name> <phase> --recover
92
+ ```
93
+
94
+ 按脚本输出的 **Recovery action** 决定下一步。
95
+
96
+ 恢复后必须先用「阶段进入自洽性校验」表复查一遍:若发现 `phase` 与产物不自洽(design_doc/三件套/verify_result 任一不匹配),按非法空跳处理,回对应阶段补齐,不得信任 `phase` 字段直接续跑。
97
+
98
+ **特别注意 `build_mode`**:若恢复脚本输出 `build_mode: subagent-driven-development`,你是协调者,不是执行者。必须:
99
+ 1. 使用 Skill 工具重新加载 Superpowers `subagent-driven-development` 技能 (Use the Skill tool to reload the Superpowers `subagent-driven-development` skill)
100
+ 2. 读取 `comet/reference/subagent-dispatch.md` 获取 Comet 专属扩展 (re-read `comet/reference/subagent-dispatch.md` for Comet-specific extensions)
101
+ 3. 读取 `openspec/changes/<name>/.comet/subagent-progress.md` 恢复精确阶段、证据和审查-修复轮次 (Read `openspec/changes/<name>/.comet/subagent-progress.md` to recover the exact stage, evidence, and review-fix round)
102
+ 4. 禁止在主会话中直接执行 task (Do not execute the pending task directly in the main window)
103
+ 5. 按检查点恢复;缺失或不匹配时才从第一个未勾选 task 开始
104
+ 6. 已提交但未通过双审查的 task 保持未勾选,继续审查/修复循环
105
+ 7. task 通过双审查和定向勾选验证后立即继续下一个 task,不得总结或询问是否继续
106
+
107
+ ## 阶段退出后自动过渡
108
+
109
+ guard `--apply` 成功后,不得在本规则中硬编码下一阶段 skill。必须先运行:
110
+
111
+ ```bash
112
+ comet-state next <change-name>
113
+ ```
114
+
115
+ 若已通过 `comet-env.sh` 定位脚本,等价运行:
116
+
117
+ ```bash
118
+ "$COMET_BASH" "$COMET_STATE" next <change-name>
119
+ ```
120
+
121
+ 按脚本输出决定下一步:
122
+
123
+ - `NEXT: auto` → 使用 Skill 工具加载 `SKILL` 指向的 skill
124
+ - `NEXT: manual` → 不加载下一 skill,按 `HINT` 提示用户手动继续
125
+ - `NEXT: done` → 流程已完成,无需继续
@@ -427,6 +427,26 @@ tdd_mode_selected() {
427
427
  esac
428
428
  }
429
429
 
430
+ review_mode_selected() {
431
+ local workflow review_mode
432
+ workflow=$(yaml_field_value "workflow" 2>/dev/null || true)
433
+ review_mode=$(yaml_field_value "review_mode" 2>/dev/null || true)
434
+
435
+ case "$workflow" in
436
+ hotfix|tweak) return 0 ;;
437
+ esac
438
+
439
+ case "$review_mode" in
440
+ off|standard|thorough) return 0 ;;
441
+ *)
442
+ echo "review_mode must be off, standard, or thorough before leaving build, got '${review_mode:-null}'" >&2
443
+ echo "Next: ask the user to choose code review mode, then run:" >&2
444
+ echo " \"\$COMET_BASH\" \"\$COMET_STATE\" set $CHANGE review_mode <off|standard|thorough>" >&2
445
+ return 1
446
+ ;;
447
+ esac
448
+ }
449
+
430
450
  verify_result_is_pass() {
431
451
  local result
432
452
  result=$(yaml_field_value "verify_result" 2>/dev/null || true)
@@ -609,8 +629,13 @@ archived_is_true() {
609
629
  guard_open() {
610
630
  echo "=== Guard: open → next ===" >&2
611
631
 
632
+ local workflow
633
+ workflow=$(yaml_field_value "workflow" 2>/dev/null || true)
634
+
612
635
  check "proposal.md exists and non-empty" file_nonempty "$CHANGE_DIR/proposal.md"
613
- check "design.md exists and non-empty" file_nonempty "$CHANGE_DIR/design.md"
636
+ if [ "$workflow" = "full" ]; then
637
+ check "design.md exists and non-empty" file_nonempty "$CHANGE_DIR/design.md"
638
+ fi
614
639
  check "tasks.md exists and non-empty" file_nonempty "$CHANGE_DIR/tasks.md"
615
640
  check "tasks.md has at least one task" tasks_has_any
616
641
  }
@@ -665,6 +690,7 @@ guard_build() {
665
690
  check "build_mode allowed for workflow" build_mode_allowed_for_workflow
666
691
  check "subagent dispatch confirmed" subagent_dispatch_confirmed
667
692
  check "tdd_mode selected" tdd_mode_selected
693
+ check "review_mode selected" review_mode_selected
668
694
  check "tasks.md all tasks checked" tasks_all_done
669
695
  check "Superpowers plan all tasks checked" plan_tasks_all_done
670
696
  check "proposal.md exists" file_nonempty "$CHANGE_DIR/proposal.md"
@@ -50,41 +50,6 @@ fi
50
50
  # Normalize to forward slashes, collapse doubles from JSON escaping (\\ → //)
51
51
  TARGET=$(printf '%s' "$TARGET" | sed 's|\\|/|g' | sed 's|///*|/|g')
52
52
 
53
- # ── Find active Comet change ─────────────────────────────────────
54
-
55
- YAML_FILE=""
56
- if [ -d "openspec/changes" ]; then
57
- for dir in openspec/changes/*/; do
58
- [ -d "$dir" ] || continue
59
- # Skip archived changes
60
- case "$dir" in
61
- */archive/*) continue ;;
62
- esac
63
- if [ -f "${dir}.comet.yaml" ]; then
64
- YAML_FILE="${dir}.comet.yaml"
65
- break
66
- fi
67
- done
68
- fi
69
-
70
- # No active change — allow all writes
71
- if [ -z "$YAML_FILE" ]; then
72
- echo "[COMET-HOOK] allowed: no active comet change" >&2
73
- exit 0
74
- fi
75
-
76
- # ── Read current phase ───────────────────────────────────────────
77
-
78
- PHASE=$(grep "^phase:" "$YAML_FILE" 2>/dev/null \
79
- | awk '{print $2}' \
80
- | tr -d '[:space:][:cntrl:]' \
81
- || true)
82
-
83
- if [ -z "$PHASE" ]; then
84
- echo "[COMET-HOOK] allowed: no phase in .comet.yaml" >&2
85
- exit 0
86
- fi
87
-
88
53
  # ── Resolve to project-relative path ─────────────────────────────
89
54
 
90
55
  # Normalize helper: forward slashes only
@@ -120,6 +85,95 @@ case "$RELPATH" in
120
85
  ;;
121
86
  esac
122
87
 
88
+ # ── Helpers to read .comet.yaml fields ───────────────────────────
89
+
90
+ is_archived() {
91
+ grep "^archived:" "$1" 2>/dev/null \
92
+ | awk '{print $2}' | tr -d '[:space:][:cntrl:]' || true
93
+ }
94
+
95
+ read_phase() {
96
+ grep "^phase:" "$1" 2>/dev/null \
97
+ | awk '{print $2}' | tr -d '[:space:][:cntrl:]' || true
98
+ }
99
+
100
+ read_field() {
101
+ grep "^$1:" "$2" 2>/dev/null \
102
+ | head -1 | awk '{print $2}' | tr -d '[:space:][:cntrl:]' || true
103
+ }
104
+
105
+ # ── Determine the governing Comet change + phase ─────────────────
106
+ #
107
+ # A write targeting a specific change directory (openspec/changes/<name>/...)
108
+ # must be governed by THAT change's own phase — never by an unrelated
109
+ # active change. Otherwise a change left in the `archive` phase would
110
+ # wrongly block artifact writes for a brand-new change created alongside it.
111
+
112
+ PHASE=""
113
+ # Path to the .comet.yaml that governs this write (used for deeper invariant checks)
114
+ GOV_YAML=""
115
+
116
+ case "$RELPATH" in
117
+ openspec/changes/*/*)
118
+ _rest="${RELPATH#openspec/changes/}"
119
+ _own_change="${_rest%%/*}"
120
+ if [ -n "$_own_change" ] && [ "$_own_change" != "archive" ]; then
121
+ _own_yaml="openspec/changes/${_own_change}/.comet.yaml"
122
+ if [ -f "$_own_yaml" ]; then
123
+ if [ "$(is_archived "$_own_yaml")" = "true" ]; then
124
+ # This change is already archived — its own writes are unrestricted
125
+ echo "[COMET-HOOK] allowed: $RELPATH (own change archived)" >&2
126
+ exit 0
127
+ fi
128
+ PHASE=$(read_phase "$_own_yaml")
129
+ GOV_YAML="$_own_yaml"
130
+ else
131
+ # Change directory exists but state file not yet written
132
+ # (artifacts are created before .comet.yaml during /comet-open).
133
+ # Treat as `open` so proposal/design/tasks/specs are allowed.
134
+ PHASE="open"
135
+ fi
136
+ fi
137
+ ;;
138
+ esac
139
+
140
+ # Fallback: writes outside a specific change directory are governed by
141
+ # the first active (non-archived) change.
142
+ if [ -z "$PHASE" ]; then
143
+ YAML_FILE=""
144
+ if [ -d "openspec/changes" ]; then
145
+ for dir in openspec/changes/*/; do
146
+ [ -d "$dir" ] || continue
147
+ # Skip archived changes directory
148
+ case "$dir" in
149
+ */archive/*) continue ;;
150
+ esac
151
+ if [ -f "${dir}.comet.yaml" ]; then
152
+ # Skip changes already marked as archived
153
+ if [ "$(is_archived "${dir}.comet.yaml")" = "true" ]; then
154
+ continue
155
+ fi
156
+ YAML_FILE="${dir}.comet.yaml"
157
+ break
158
+ fi
159
+ done
160
+ fi
161
+
162
+ # No active change — allow all writes
163
+ if [ -z "$YAML_FILE" ]; then
164
+ echo "[COMET-HOOK] allowed: no active comet change" >&2
165
+ exit 0
166
+ fi
167
+
168
+ PHASE=$(read_phase "$YAML_FILE")
169
+ GOV_YAML="$YAML_FILE"
170
+ fi
171
+
172
+ if [ -z "$PHASE" ]; then
173
+ echo "[COMET-HOOK] allowed: no phase in .comet.yaml" >&2
174
+ exit 0
175
+ fi
176
+
123
177
  # ── Whitelist: phase-aware allowed paths ─────────────────────────
124
178
 
125
179
  case "$RELPATH" in
@@ -222,6 +276,28 @@ esac
222
276
 
223
277
  case "$PHASE" in
224
278
  build|verify)
279
+ # Full workflow must have a Design Doc before any source write in build/verify.
280
+ # Catches illegal open→build / design→build jumps that skipped the design phase
281
+ # (e.g. misclassified preset, direct `set phase`, or bare transition).
282
+ if [ -n "$GOV_YAML" ]; then
283
+ _wf=$(read_field "workflow" "$GOV_YAML")
284
+ _dd=$(read_field "design_doc" "$GOV_YAML")
285
+ if [ "$_wf" = "full" ] && { [ -z "$_dd" ] || [ "$_dd" = "null" ]; }; then
286
+ echo "" >&2
287
+ echo "╔══════════════════════════════════════════╗" >&2
288
+ echo "║ COMET PHASE GUARD — WRITE BLOCKED ║" >&2
289
+ echo "╚══════════════════════════════════════════╝" >&2
290
+ echo "" >&2
291
+ echo " Current phase: $PHASE (workflow: full), but design_doc is empty" >&2
292
+ echo " Target file: $RELPATH" >&2
293
+ echo "" >&2
294
+ echo " ❌ Illegal phase jump detected: full workflow entered $PHASE without a Design Doc" >&2
295
+ echo " ✅ Correct flow: create the Design Doc in design phase, then run comet-guard design --apply" >&2
296
+ echo " 💡 Run /comet-design to fill the missing design; for repair, set design_doc with comet-state" >&2
297
+ echo "" >&2
298
+ exit 2
299
+ fi
300
+ fi
225
301
  # Code writes allowed in build and verify
226
302
  echo "[COMET-HOOK] allowed: $RELPATH (phase: $PHASE)" >&2
227
303
  exit 0
@@ -232,23 +308,23 @@ case "$PHASE" in
232
308
  echo "║ COMET PHASE GUARD — WRITE BLOCKED ║" >&2
233
309
  echo "╚══════════════════════════════════════════╝" >&2
234
310
  echo "" >&2
235
- echo " 当前阶段: $PHASE" >&2
236
- echo " 目标文件: $RELPATH" >&2
311
+ echo " Current phase: $PHASE" >&2
312
+ echo " Target file: $RELPATH" >&2
237
313
  echo "" >&2
238
314
  case "$PHASE" in
239
315
  open)
240
- echo " ❌ open 阶段不允许写源代码" >&2
241
- echo " ✅ 允许: 创建 proposal/design/tasks, 运行 guard" >&2
242
- echo " 💡 完成需求澄清和 artifact 创建后运行 guard --apply" >&2
316
+ echo " ❌ open phase does not allow source code writes" >&2
317
+ echo " ✅ Allowed: create proposal/design/tasks and run guard" >&2
318
+ echo " 💡 After clarification and artifact creation, run guard --apply" >&2
243
319
  ;;
244
320
  design)
245
- echo " ❌ design 阶段不允许写源代码" >&2
246
- echo " ✅ 允许: brainstorming, 创建 Design Doc, 运行 guard" >&2
247
- echo " 💡 完成 Design Doc 后运行 comet-guard design --apply 进入 build" >&2
321
+ echo " ❌ design phase does not allow source code writes" >&2
322
+ echo " ✅ Allowed: brainstorming, create the Design Doc, and run guard" >&2
323
+ echo " 💡 After the Design Doc is ready, run comet-guard design --apply to enter build" >&2
248
324
  ;;
249
325
  archive)
250
- echo " ❌ archive 阶段不允许写源代码" >&2
251
- echo " ✅ 允许: 确认归档, 运行归档脚本" >&2
326
+ echo " ❌ archive phase does not allow source code writes" >&2
327
+ echo " ✅ Allowed: confirm archive intent and run the archive script" >&2
252
328
  ;;
253
329
  esac
254
330
  echo "" >&2