@rpamis/comet 0.3.8 → 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 (60) hide show
  1. package/README.md +16 -18
  2. package/assets/skills/comet/reference/dirty-worktree.md +59 -59
  3. package/assets/skills/comet/rules/comet-phase-guard.en.md +29 -5
  4. package/assets/skills/comet/rules/comet-phase-guard.md +31 -5
  5. package/assets/skills/comet/scripts/comet-guard.sh +27 -1
  6. package/assets/skills/comet/scripts/comet-hook-guard.sh +121 -45
  7. package/assets/skills/comet/scripts/comet-state.sh +100 -7
  8. package/assets/skills/comet/scripts/comet-yaml-validate.sh +3 -1
  9. package/assets/skills/comet-open/SKILL.md +18 -1
  10. package/assets/skills-zh/comet/SKILL.md +1 -1
  11. package/assets/skills-zh/comet/reference/comet-yaml-fields.md +3 -0
  12. package/assets/skills-zh/comet/reference/context-recovery.md +1 -1
  13. package/assets/skills-zh/comet/reference/debug-gate.md +2 -2
  14. package/assets/skills-zh/comet/reference/dirty-worktree.md +59 -59
  15. package/assets/skills-zh/comet/reference/subagent-dispatch.md +21 -14
  16. package/assets/skills-zh/comet-build/SKILL.md +20 -7
  17. package/assets/skills-zh/comet-design/SKILL.md +2 -2
  18. package/assets/skills-zh/comet-hotfix/SKILL.md +2 -2
  19. package/assets/skills-zh/comet-open/SKILL.md +18 -1
  20. package/assets/skills-zh/comet-verify/SKILL.md +2 -2
  21. package/dist/cli/index.js +2 -1
  22. package/dist/cli/index.js.map +1 -1
  23. package/dist/commands/doctor.d.ts.map +1 -1
  24. package/dist/commands/doctor.js +5 -1
  25. package/dist/commands/doctor.js.map +1 -1
  26. package/dist/commands/i18n.d.ts +4 -0
  27. package/dist/commands/i18n.d.ts.map +1 -0
  28. package/dist/commands/i18n.js +154 -0
  29. package/dist/commands/i18n.js.map +1 -0
  30. package/dist/commands/init.d.ts +3 -0
  31. package/dist/commands/init.d.ts.map +1 -1
  32. package/dist/commands/init.js +122 -70
  33. package/dist/commands/init.js.map +1 -1
  34. package/dist/commands/uninstall.d.ts.map +1 -1
  35. package/dist/commands/uninstall.js +34 -15
  36. package/dist/commands/uninstall.js.map +1 -1
  37. package/dist/commands/update.d.ts +2 -1
  38. package/dist/commands/update.d.ts.map +1 -1
  39. package/dist/commands/update.js +45 -37
  40. package/dist/commands/update.js.map +1 -1
  41. package/dist/core/codegraph.d.ts +4 -2
  42. package/dist/core/codegraph.d.ts.map +1 -1
  43. package/dist/core/codegraph.js +66 -11
  44. package/dist/core/codegraph.js.map +1 -1
  45. package/dist/core/detect.d.ts +6 -1
  46. package/dist/core/detect.d.ts.map +1 -1
  47. package/dist/core/detect.js +28 -11
  48. package/dist/core/detect.js.map +1 -1
  49. package/dist/core/openspec.d.ts +1 -1
  50. package/dist/core/openspec.d.ts.map +1 -1
  51. package/dist/core/openspec.js +13 -7
  52. package/dist/core/openspec.js.map +1 -1
  53. package/dist/core/skills.d.ts.map +1 -1
  54. package/dist/core/skills.js +9 -1
  55. package/dist/core/skills.js.map +1 -1
  56. package/dist/core/superpowers.d.ts +1 -1
  57. package/dist/core/superpowers.d.ts.map +1 -1
  58. package/dist/core/superpowers.js +4 -1
  59. package/dist/core/superpowers.js.map +1 -1
  60. package/package.json +2 -2
package/README.md CHANGED
@@ -40,13 +40,11 @@ Superpowers handles **HOW** (technical design, planning, execution, wrap-up).
40
40
  Comet chains both into a five-phase automated pipeline.
41
41
 
42
42
  > [!IMPORTANT]
43
- > **0.3.7 Highlights** — One-step [CodeGraph](https://github.com/colbymchenry/codegraph) semantic code indexing (official: cost **↓16%**, tool calls **↓58%**);
43
+ > **0.3.9** — Review mode (`off|standard|thorough`) controls Build/Verify code review with project defaults; init/update now use optional dependency prompts, broader CLI i18n, stronger phase guards, and macOS executable bits.
44
44
  >
45
- > New **Beta context compression** cutting Build-phase input tokens by **25–30%**;
46
- > New active context compression mechanism to release context consumed by reading specs and brainstorming, preserving window space for the subsequent Build phase.
47
- > 6 default-on workflow token optimizations; New `auto_transition` config for automatic or manual phase handoff;
48
- > Hook+Rule anti-drift phase guard; Optional TDD mode and subagent dispatch confirmation;
49
- > Large PRD split into multiple changes; Pre-archive confirmation with reopen, verify retry limit, systematic debugging interception, and verification completion check.
45
+ > **0.3.8** Adds Kimi Code support, safe multi-platform `comet uninstall`, extended subagent dispatch, shared progressive-loading references, update checks, and pre-commit formatting.
46
+ >
47
+ > **0.3.7** Adds CodeGraph semantic indexing, Beta context compression, active context compression, token optimizations, `auto_transition`, phase guards, optional TDD, and safer archive/verification flow.
50
48
  >
51
49
  > See [NEWS.md](NEWS.md) for details.
52
50
 
@@ -134,15 +132,14 @@ comet init
134
132
  1. Prompt you to select AI platforms (auto-detects existing configs)
135
133
  2. Choose install scope: project-level (current directory) or global (home directory)
136
134
  3. Select language for Comet skills: English or 中文
137
- 4. Install [OpenSpec](https://github.com/Fission-AI/OpenSpec) skills
138
- 5. Install [Superpowers](https://github.com/obra/superpowers) skills
135
+ 4. Select npm dependencies to install/upgrade — [OpenSpec](https://github.com/Fission-AI/OpenSpec) CLI, [Superpowers](https://github.com/obra/superpowers) (via `npx skills add`), and [CodeGraph](https://github.com/colbymchenry/codegraph) CLI. Items not yet detected default to checked; already-installed items default to unchecked so you can opt in to upgrades.
136
+ 5. Install the selected dependencies and deploy their skills
139
137
  6. Deploy Comet skills (in your chosen language) to selected platforms
140
138
  7. Create `docs/superpowers/specs/` and `docs/superpowers/plans/` working directories for project-scope installs
141
139
 
142
140
  > [!TIP]
143
- > update version
144
- >
145
- > `comet update` or `npm install -g @rpamis/comet@latest` to get the latest features and fixes.
141
+ > Superpowers v6.0.0+ is recommended — about 2× faster and ~50% fewer tokens than older versions.
142
+ > To upgrade Comet itself later: `comet update` or `npm install -g @rpamis/comet@latest`.
146
143
 
147
144
  ## Support for OpenClaw and Hermes, and other AI platforms
148
145
 
@@ -168,13 +165,14 @@ npx skills add rpamis/comet
168
165
 
169
166
  Initializes OpenSpec, Superpowers, and Comet skills for selected AI coding platforms.
170
167
 
171
- | Option | Description |
172
- |-------------------|--------------------------------------------------------------------------------|
173
- | `--yes` | Non-interactive mode, auto-select detected platforms (or all if none detected) |
174
- | `--scope <scope>` | Install scope: `project` or `global` |
175
- | `--skip-existing` | Skip already installed components |
176
- | `--overwrite` | Overwrite already installed components |
177
- | `--json` | Output structured JSON |
168
+ | Option | Description |
169
+ |---------------------|--------------------------------------------------------------------------------|
170
+ | `--yes` | Non-interactive mode, auto-select detected platforms (or all if none detected) |
171
+ | `--scope <scope>` | Install scope: `project` or `global` |
172
+ | `--language <lang>` | Skill language: `en` or `zh` (skips interactive language prompt) |
173
+ | `--skip-existing` | Skip already installed components |
174
+ | `--overwrite` | Overwrite already installed components |
175
+ | `--json` | Output structured JSON |
178
176
 
179
177
  When multiple existing components are found on the same platform, interactive init offers one bulk choice: overwrite
180
178
  all, skip all, or choose per component.
@@ -1,59 +1,59 @@
1
- # Dirty Worktree Protocol
2
-
3
- Canonical path: `comet/reference/dirty-worktree.md`
4
-
5
- This protocol is shared by all Comet sub-skills that may modify code. When an agent resumes context or continues execution, it must handle uncommitted working tree changes through this protocol.
6
-
7
- ## 1. Checks
8
-
9
- Before continuing or starting code changes, run:
10
-
11
- ```bash
12
- git status --short
13
- git diff --stat
14
- git diff --cached --stat
15
- git ls-files --others --exclude-standard
16
- ```
17
-
18
- When needed, inspect `git diff`, `git diff --cached`, and newly created file contents.
19
-
20
- ## 2. Core Rules
21
-
22
- - The user may not say which files they changed. If the worktree is dirty, including new files shown as `??` in Git status, assume changes may come from the user or mixed sources.
23
- - **Build artifact exclusion**: `??` files matching `.gitignore` patterns (e.g., `node_modules/`, `dist/`, `__pycache__/`, `*.o`, `target/`, `build/`) are automatically skipped during attribution and not treated as user changes.
24
- - A dirty worktree is code evidence only. It does not automatically advance `.comet.yaml` `phase` or check off `tasks.md`; Comet state may advance only after attribution, verification, required document synchronization, and the relevant phase guard.
25
-
26
- ## 3. Attribution
27
-
28
- Classify dirty diffs into three groups:
29
-
30
- 1. **Belongs to the current change**: Files and content match the current change goal, tasks.md, plan, or delta spec. Incorporate the diff into the current task and avoid redoing the same work.
31
- 2. **Does not belong to the current change**: Files or content are unrelated. Pause and ask whether to include it in the current change, split it into a new change, leave it alone, or discard it with explicit authorization.
32
- 3. **Unclear source**: The diff and documents are not enough to determine ownership. Pause, report the file list and reasoning, and do not advance the phase.
33
-
34
- ## 4. Common Patterns
35
-
36
- ### Implemented But tasks.md Is Not Checked
37
-
38
- Verify the implementation with build and tests. If it passes, check off the task. Do not redo work just because the task is unchecked, and do not ignore code evidence because state files lag behind. If the current sub-skill defines a phase-specific rule, follow that sub-skill.
39
-
40
- ### Plan Or Scope Changed
41
-
42
- Follow the current sub-skill's escalation, incremental-update, or rollback rules. This protocol does not repeat phase-specific details.
43
-
44
- ### Ambiguous Resume Intent
45
-
46
- When the user says things like "continue", "keep going", "I changed a bit", "I wasn't happy with it", "redo it", "code changed", or "use what is there", follow this protocol. Do not require the user to remember exactly what they changed.
47
-
48
- ### Code Changes During open/design
49
-
50
- If the current phase is still `open` or `design` but the dirty worktree already contains code changes, first attribute the changes through this protocol and do not advance the phase directly:
51
-
52
- - If the changes belong to the current change, treat them as requirements or design input and record them in proposal/design/spec/design doc/tasks as appropriate. The current phase guard must still pass before entering build.
53
- - If the changes do not belong to the current change or ownership is unclear, pause and ask whether to include them, split them into a new change, leave them alone, or discard them with explicit authorization.
54
- - Do not treat code changes made during open/design as completed implementation ready for verify.
55
-
56
- ## 5. Prohibitions
57
-
58
- - Do not overwrite, revert, reformat over, or ignore user changes before understanding the dirty diff source.
59
- - Do not mark verification as passed while dirty diff remains unexplained.
1
+ # Dirty Worktree Protocol
2
+
3
+ Canonical path: `comet/reference/dirty-worktree.md`
4
+
5
+ This protocol is shared by all Comet sub-skills that may modify code. When an agent resumes context or continues execution, it must handle uncommitted working tree changes through this protocol.
6
+
7
+ ## 1. Checks
8
+
9
+ Before continuing or starting code changes, run:
10
+
11
+ ```bash
12
+ git status --short
13
+ git diff --stat
14
+ git diff --cached --stat
15
+ git ls-files --others --exclude-standard
16
+ ```
17
+
18
+ When needed, inspect `git diff`, `git diff --cached`, and newly created file contents.
19
+
20
+ ## 2. Core Rules
21
+
22
+ - The user may not say which files they changed. If the worktree is dirty, including new files shown as `??` in Git status, assume changes may come from the user or mixed sources.
23
+ - **Build artifact exclusion**: `??` files matching `.gitignore` patterns (e.g., `node_modules/`, `dist/`, `__pycache__/`, `*.o`, `target/`, `build/`) are automatically skipped during attribution and not treated as user changes.
24
+ - A dirty worktree is code evidence only. It does not automatically advance `.comet.yaml` `phase` or check off `tasks.md`; Comet state may advance only after attribution, verification, required document synchronization, and the relevant phase guard.
25
+
26
+ ## 3. Attribution
27
+
28
+ Classify dirty diffs into three groups:
29
+
30
+ 1. **Belongs to the current change**: Files and content match the current change goal, tasks.md, plan, or delta spec. Incorporate the diff into the current task and avoid redoing the same work.
31
+ 2. **Does not belong to the current change**: Files or content are unrelated. Pause and ask whether to include it in the current change, split it into a new change, leave it alone, or discard it with explicit authorization.
32
+ 3. **Unclear source**: The diff and documents are not enough to determine ownership. Pause, report the file list and reasoning, and do not advance the phase.
33
+
34
+ ## 4. Common Patterns
35
+
36
+ ### Implemented But tasks.md Is Not Checked
37
+
38
+ Verify the implementation with build and tests. If it passes, check off the task. Do not redo work just because the task is unchecked, and do not ignore code evidence because state files lag behind. If the current sub-skill defines a phase-specific rule, follow that sub-skill.
39
+
40
+ ### Plan Or Scope Changed
41
+
42
+ Follow the current sub-skill's escalation, incremental-update, or rollback rules. This protocol does not repeat phase-specific details.
43
+
44
+ ### Ambiguous Resume Intent
45
+
46
+ When the user says things like "continue", "keep going", "I changed a bit", "I wasn't happy with it", "redo it", "code changed", or "use what is there", follow this protocol. Do not require the user to remember exactly what they changed.
47
+
48
+ ### Code Changes During open/design
49
+
50
+ If the current phase is still `open` or `design` but the dirty worktree already contains code changes, first attribute the changes through this protocol and do not advance the phase directly:
51
+
52
+ - If the changes belong to the current change, treat them as requirements or design input and record them in proposal/design/spec/design doc/tasks as appropriate. The current phase guard must still pass before entering build.
53
+ - If the changes do not belong to the current change or ownership is unclear, pause and ask whether to include them, split them into a new change, leave them alone, or discard them with explicit authorization.
54
+ - Do not treat code changes made during open/design as completed implementation ready for verify.
55
+
56
+ ## 5. Prohibitions
57
+
58
+ - Do not overwrite, revert, reformat over, or ignore user changes before understanding the dirty diff source.
59
+ - Do not mark verification as passed while dirty diff remains unexplained.
@@ -19,7 +19,17 @@ When there is an active comet change (`openspec/changes/<name>/.comet.yaml` exis
19
19
  | `build` | Write source code, tests, execute plans | Skip user confirmation points |
20
20
  | `verify` | Verification, branch handling | Skip failure handling |
21
21
  | `archive` | Confirm archive, run archive script | Write source code |
22
+ ### Phase-Entry Self-Consistency Check (Before Writing Source Code)
22
23
 
24
+ Reading the `phase` field alone is not enough — you must also confirm **how** that phase was reached. Before writing any source code, self-check whether `.comet.yaml` is in an **illegal jump** state (a prior phase was skipped) using the table below. If any row matches, immediately stop writing source code, go back to the corresponding phase to fill the missing artifact, and do not trust the `phase` field to keep going.
25
+
26
+ | Detected | Verdict | Action |
27
+ |----------|---------|--------|
28
+ | `phase: build` + `workflow: full` + `design_doc` empty/null | Skipped design | Stop writing source; run `/comet-design` to create the Design Doc and pass guard |
29
+ | `phase: build/verify` + any of proposal/design/tasks missing or empty | Skipped open | Return to `/comet-open` to fill the three artifacts |
30
+ | `phase: archive` + `verify_result` ≠ `pass` | Skipped verify | Return to `/comet-verify` to complete verification |
31
+
32
+ Exception: `workflow: hotfix/tweak` intentionally skips design, so an empty `design_doc` is normal and not an illegal jump.
23
33
  ### Skill Invocation (Cannot Replace with Normal Conversation)
24
34
 
25
35
  The following operations must be loaded through the Skill tool. When Skill is unavailable, stop the workflow and prompt to install:
@@ -37,6 +47,7 @@ The following operations must be loaded through the Skill tool. When Skill is un
37
47
  - **Phase exit**: `comet-guard <name> <phase> --apply` (must see ALL CHECKS PASSED)
38
48
  - **Compression recovery**: `comet-state check <name> <phase> --recover`
39
49
  - **State update**: After key operations, update fields through `comet-state set`; manually editing .comet.yaml is prohibited
50
+ - **Phase advancement only via guard/transition**: directly running `comet-state set <name> phase <value>` to jump phases is prohibited (it bypasses evidence checks and the script now hard-blocks it); use the `COMET_FORCE_PHASE=1` escape hatch only to repair a malformed state
40
51
  - **handoff generation**: `comet-handoff <name> design --write` (handwriting summaries is prohibited)
41
52
 
42
53
  ### User Confirmation (Cannot Auto-Skip)
@@ -80,6 +91,8 @@ If context compression is suspected (previous conversation was summarized, previ
80
91
 
81
92
  Decide next step according to the script's **Recovery action** output.
82
93
 
94
+ After recovery, first re-run the "Phase-Entry Self-Consistency Check" table: if `phase` is inconsistent with the artifacts (design_doc / three artifacts / verify_result mismatch), treat it as an illegal jump, return to the corresponding phase to fill the gap, and do not trust the `phase` field to keep going.
95
+
83
96
  **Special attention to `build_mode`**: If recovery script outputs `build_mode: subagent-driven-development`, you are the coordinator, not the executor. Must:
84
97
  1. Use the Skill tool to reload the Superpowers `subagent-driven-development` skill
85
98
  2. Re-read `comet/reference/subagent-dispatch.md` for Comet-specific extensions
@@ -91,9 +104,20 @@ Decide next step according to the script's **Recovery action** output.
91
104
 
92
105
  ## Automatic Transition After Phase Exit
93
106
 
94
- After guard `--apply` succeeds, must invoke the next phase's skill:
107
+ After guard `--apply` succeeds, do not hardcode the next skill in this rule. First run:
108
+
109
+ ```bash
110
+ comet-state next <change-name>
111
+ ```
112
+
113
+ If `comet-env.sh` has already located the scripts, the equivalent command is:
114
+
115
+ ```bash
116
+ "$COMET_BASH" "$COMET_STATE" next <change-name>
117
+ ```
118
+
119
+ Decide the next step from the script output:
95
120
 
96
- - open`comet-design` (full) / `comet-build` (hotfix/tweak)
97
- - design → `comet-build`
98
- - build`comet-verify`
99
- - verify → `comet-archive`
121
+ - `NEXT: auto` use the Skill tool to load the skill named by `SKILL`
122
+ - `NEXT: manual` do not load the next skill; show `HINT` so the user can continue manually
123
+ - `NEXT: done` the workflow is complete; no further action is needed
@@ -20,6 +20,18 @@
20
20
  | `verify` | 验证、branch handling | 跳过失败处理 |
21
21
  | `archive` | 确认归档、运行归档脚本 | 写源代码 |
22
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
+
23
35
  ### Skill 调用(不可用普通对话替代)
24
36
 
25
37
  以下操作必须通过 Skill 工具加载,Skill 不可用时应停止流程并提示安装:
@@ -37,6 +49,7 @@
37
49
  - **阶段退出**: `comet-guard <name> <phase> --apply`(必须看到 ALL CHECKS PASSED)
38
50
  - **压缩恢复**: `comet-state check <name> <phase> --recover`
39
51
  - **状态更新**: 关键操作后通过 `comet-state set` 更新字段,禁止手工编辑 .comet.yaml
52
+ - **阶段推进只能经 guard/transition**: 禁止用 `comet-state set <name> phase <值>` 手动跳阶段(会绕过证据校验,脚本已硬拦截);确需修复畸形状态时才用 `COMET_FORCE_PHASE=1` 逃生阀
40
53
  - **handoff 生成**: `comet-handoff <name> design --write`(禁止手写摘要)
41
54
 
42
55
  ### 用户确认(不可自动跳过)
@@ -80,6 +93,8 @@
80
93
 
81
94
  按脚本输出的 **Recovery action** 决定下一步。
82
95
 
96
+ 恢复后必须先用「阶段进入自洽性校验」表复查一遍:若发现 `phase` 与产物不自洽(design_doc/三件套/verify_result 任一不匹配),按非法空跳处理,回对应阶段补齐,不得信任 `phase` 字段直接续跑。
97
+
83
98
  **特别注意 `build_mode`**:若恢复脚本输出 `build_mode: subagent-driven-development`,你是协调者,不是执行者。必须:
84
99
  1. 使用 Skill 工具重新加载 Superpowers `subagent-driven-development` 技能 (Use the Skill tool to reload the Superpowers `subagent-driven-development` skill)
85
100
  2. 读取 `comet/reference/subagent-dispatch.md` 获取 Comet 专属扩展 (re-read `comet/reference/subagent-dispatch.md` for Comet-specific extensions)
@@ -91,9 +106,20 @@
91
106
 
92
107
  ## 阶段退出后自动过渡
93
108
 
94
- guard `--apply` 成功后,必须调用下一阶段的 skill
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
+ 按脚本输出决定下一步:
95
122
 
96
- - open → `comet-design`(full)/ `comet-build`(hotfix/tweak)
97
- - design → `comet-build`
98
- - build`comet-verify`
99
- - verify → `comet-archive`
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