Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
31b3e7e
feat: add bound_branch field to classic state model
1919chichi Jul 18, 2026
757bd6d
feat: add shared branch-binding verdict module
1919chichi Jul 18, 2026
a0027e7
feat: bind current-isolation drift detection to bound_branch
1919chichi Jul 18, 2026
b604961
feat: capture bound_branch on set isolation current
1919chichi Jul 18, 2026
bd16c37
feat: enforce bound_branch drift in state check
1919chichi Jul 18, 2026
5f09d3d
feat: add state rebind subcommand with audit trail
1919chichi Jul 18, 2026
90b0b32
feat: mirror bound_branch drift check in phase guard
1919chichi Jul 18, 2026
974bafc
fix: clear bound_branch when preset-escalate clears isolation
1919chichi Jul 18, 2026
b9dd01e
test: reconcile existing fixtures with bound_branch drift checks
1919chichi Jul 18, 2026
3b4e132
feat: ask preset workflows to choose isolation explicitly
1919chichi Jul 18, 2026
177eaba
docs: add current-isolation workflow decisions
1919chichi Jul 18, 2026
9469694
feat: surface current-isolation binding in status
1919chichi Jul 18, 2026
776fa2c
fix: tolerate malformed skill frontmatter in discovery
1919chichi Jul 18, 2026
f29d532
chore: release 0.4.0-beta.6 with current-isolation binding
1919chichi Jul 18, 2026
a6726bd
fix: allow current isolation for full workflow
1919chichi Jul 18, 2026
9c9300c
docs: document current isolation for full workflow
1919chichi Jul 18, 2026
a271b9a
fix: bind branch workspace modes
1919chichi Jul 18, 2026
b080308
docs: document branch-bound workspace modes
1919chichi Jul 18, 2026
9ed387f
fix: handle legacy branch binding compatibility
1919chichi Jul 18, 2026
eb38d17
docs: clarify current isolation changelog issue reference
1919chichi Jul 18, 2026
fece1af
fix: harden workspace branch binding drift enforcement
1919chichi Jul 19, 2026
5ad8eee
docs: clarify bound_branch rebind and drift semantics
1919chichi Jul 19, 2026
dc13773
docs: fold branch binding fixes into changelog entries
1919chichi Jul 19, 2026
96183ee
fix: validate bound_branch is a string or null
1919chichi Jul 19, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,25 @@

All notable changes to @rpamis/comet will be documented in this file.

## What's Changed [0.4.0-beta.6] - 2026-07-18

### Added

- **`comet state rebind`**: New command to explicitly re-bind an `isolation: current` change to the current branch after user confirmation, recording an audit event; refuses to run while HEAD is detached or before an initial binding exists.

### Changed

- **Current-isolation drift detection**: `isolation: current` now records the branch it was established on in the change state, so switching branches mid-change is reliably detected at every build/verify/archive entry check and by the write guard — including when only a single change is active — and is no longer silently reset by re-selecting the current change. Selecting a change whose bound branch has drifted is refused instead of reported as successful. Legacy changes without a recorded binding bind to the current Git branch on their next select or check, projects that are not Git worktrees are never blocked by branch binding, and establishing `isolation: current` on a detached HEAD is rejected.
- **Branch/worktree drift detection**: `isolation: branch` and `isolation: worktree` now use the same bound-branch safety checks as current-branch isolation, so switching branches inside those workspace modes blocks entry checks and write guards until the user switches back or explicitly rebinds the change. Switching a change between workspace modes re-points the binding to the current branch, while repeating the same mode keeps the existing binding.
- **`comet status`**: Now surfaces the selected isolation mode and bound branch for branch-bound workspace modes in both text and `--json` output.
- **Archive branch handling for `current` isolation**: No longer offers feature-branch-oriented merge/PR/keep choices; instead asks whether to push the current branch or keep it local.
- **Hotfix/tweak workspace isolation**: No longer defaults silently to the current branch; both presets now pause to ask the user to choose between working directly on the current branch, creating a new branch, or creating a worktree.
- **Full workflow current-branch isolation**: Full workflows can now let users explicitly keep working on the current branch instead of forcing a new branch or worktree, while preserving the same bound-branch drift checks used by hotfix and tweak ([#190](https://github.com/rpamis/comet/issues/190)).

### Fixed

- **Skill discovery resilience**: Malformed YAML frontmatter in an unrelated local Skill no longer crashes bundle factory guidance or candidate discovery; Comet now skips the broken description and continues scanning.

## What's Changed [0.4.0-beta.5] - 2026-07-14

### Changed
Expand Down
6 changes: 4 additions & 2 deletions README-zh.md
Original file line number Diff line number Diff line change
Expand Up @@ -499,7 +499,8 @@ build_mode: subagent-driven-development # 构建方式:subage
build_pause: null # `build_pause` 记录 build 阶段内部暂停点:null 无暂停,`plan-ready` 表示 plan 已生成
subagent_dispatch: null # subagent 分派确认;进入 verify 前需 confirmed
tdd_mode: null # full workflow 的 build 选择:tdd | direct
isolation: branch # 隔离方式:branch | worktree
isolation: branch # 隔离方式:current | branch | worktree
bound_branch: null # current/branch/worktree 模式绑定的 Git 分支;切换分支会触发阻塞
verify_mode: null # 验证模式:light | full
design_doc: docs/superpowers/specs/<design-doc>.md # 设计文档路径
plan: docs/superpowers/plans/YYYY-MM-DD-feature.md # 实现计划路径
Expand Down Expand Up @@ -541,7 +542,8 @@ Comet 通过自动化状态转换确保 agent 执行可靠性:
- 检测未知/拼写错误字段

4. **Build 决策强制** — Guard 和状态转换同时拦截跳过关键选择
- `isolation` 必须是 `branch` 或 `worktree`
- `isolation` 必须是 `current`、`branch` 或 `worktree`
- `isolation: current`、`branch`、`worktree` 都会绑定当前 Git 分支,后续入口检查会拦截意外切换分支
- `build_mode` 必须已选择
- `build_pause: plan-ready` 是 plan 生成后的可恢复暂停点,不是 `build_mode`
- full workflow 的 `build_mode: direct` 必须有 `direct_override: true`
Expand Down
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -537,7 +537,8 @@ build_mode: subagent-driven-development # Build mode: subagent-
build_pause: null # `build_pause` records an internal build-phase pause point: null none, `plan-ready` means the plan has been generated
subagent_dispatch: null # Dispatch confirmation; confirm before verify
tdd_mode: null # Full-workflow build choice: tdd | direct
isolation: branch # Isolation mode: branch | worktree
isolation: branch # Isolation mode: current | branch | worktree
bound_branch: null # Git branch bound by current/branch/worktree isolation; branch drift blocks progress
verify_mode: null # Verification mode: light | full
design_doc: docs/superpowers/specs/<design-doc>.md # Design doc path
plan: docs/superpowers/plans/YYYY-MM-DD-feature.md # Implementation plan path
Expand Down Expand Up @@ -581,7 +582,8 @@ Comet ensures agent execution reliability through automated state transitions:
- Detects unknown/typos fields

4. **Build Decision Enforcement** — Guard and state transitions both block skipped build choices
- `isolation` must be `branch` or `worktree`
- `isolation` must be `current`, `branch`, or `worktree`
- `isolation: current`, `branch`, and `worktree` bind the current Git branch, and later entry checks block accidental branch drift
- `build_mode` must be selected before leaving build
- `build_pause: plan-ready` is a recoverable pause after plan generation, not a `build_mode`
- Full workflow `build_mode: direct` requires `direct_override: true`
Expand Down
12 changes: 12 additions & 0 deletions app/commands/status.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
latestCommandCheck,
type RecordedCommandCheck,
} from '../../domains/comet-classic/classic-command-checks.js';
import { requiresBranchBinding } from '../../domains/comet-classic/classic-branch-binding.js';

export interface ChangeStatus {
name: string;
Expand All @@ -17,6 +18,7 @@ export interface ChangeStatus {
phase: string | null;
buildMode: string | null;
isolation: string | null;
boundBranch: string | null;
verifyMode: string | null;
verifyResult: string | null;
designDoc: string | null;
Expand Down Expand Up @@ -73,6 +75,7 @@ async function getActiveChanges(projectPath: string): Promise<ChangeStatus[]> {
phase: null,
buildMode: null,
isolation: null,
boundBranch: null,
verifyMode: null,
verifyResult: null,
designDoc: null,
Expand Down Expand Up @@ -100,6 +103,7 @@ async function getActiveChanges(projectPath: string): Promise<ChangeStatus[]> {
phase: 'invalid',
buildMode: projection.classic?.buildMode ?? null,
isolation: projection.classic?.isolation ?? null,
boundBranch: projection.classic?.boundBranch ?? null,
verifyMode: projection.classic?.verifyMode ?? null,
verifyResult: projection.classic?.verifyResult ?? 'pending',
designDoc: projection.classic?.designDoc ?? null,
Expand Down Expand Up @@ -133,6 +137,7 @@ async function getActiveChanges(projectPath: string): Promise<ChangeStatus[]> {
phase: diagnostic.phase,
buildMode: projection.classic.buildMode,
isolation: projection.classic.isolation,
boundBranch: projection.classic.boundBranch,
verifyMode: projection.classic.verifyMode,
verifyResult: projection.classic.verifyResult,
designDoc: projection.classic.designDoc,
Expand Down Expand Up @@ -162,6 +167,7 @@ async function getActiveChanges(projectPath: string): Promise<ChangeStatus[]> {
phase: diagnostic.phase,
buildMode: projection.classic?.buildMode ?? null,
isolation: projection.classic?.isolation ?? null,
boundBranch: projection.classic?.boundBranch ?? null,
verifyMode: projection.classic?.verifyMode ?? null,
verifyResult: projection.classic?.verifyResult ?? 'pending',
designDoc: projection.classic?.designDoc ?? null,
Expand All @@ -185,6 +191,7 @@ async function getActiveChanges(projectPath: string): Promise<ChangeStatus[]> {
phase: 'invalid',
buildMode: null,
isolation: null,
boundBranch: null,
verifyMode: null,
verifyResult: 'pending',
designDoc: null,
Expand Down Expand Up @@ -250,6 +257,11 @@ function displayStatus(changes: ChangeStatus[]): void {
continue;
}
console.log(` workflow: ${c.workflow} | build_mode: ${c.buildMode}`);
if (c.isolation) {
const branchSuffix =
requiresBranchBinding(c.isolation) && c.boundBranch ? ` (bound: ${c.boundBranch})` : '';
console.log(` isolation: ${c.isolation}${branchSuffix}`);
}
if (c.currentStep) console.log(` run_step: ${c.currentStep}`);
console.log(` runtime_mode: ${c.runtimeMode}`);
if (c.runtimeEval) {
Expand Down
2 changes: 1 addition & 1 deletion assets/manifest.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"version": "0.4.0-beta.5",
"version": "0.4.0-beta.6",
"skills": [
"comet/SKILL.md",
"comet/reference/auto-transition.md",
Expand Down
13 changes: 6 additions & 7 deletions assets/skills-zh/comet-archive/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ comet state check <name> archive

验证通过后继续 Step 1。验证失败时脚本会输出具体失败原因。

若上述 `select` / `check` 输出 `BLOCKED`,且原因是 `bound_branch` 与当前分支不一致,立即按 `comet/reference/decision-point.md` 暂停,让用户单选:切回绑定分支后重新运行入口验证,或在用户明确确认当前分支应接管该 change 后运行 `comet state rebind <change-name>` 并重新入口验证。不得自行切换分支,不得自行换绑。

### 1. 归档前最终确认(阻塞点)

入口验证通过后,**必须按 `comet/reference/decision-point.md` 的协议暂停并等待用户确认是否立即归档**。不得在用户确认前运行 `comet archive "<change-name>"`。
Expand Down Expand Up @@ -104,15 +106,12 @@ git commit -m "chore: archive <change-name>"

### 5. 归档提交后的分支处理

归档提交成功后,**立即执行:** 使用 Skill 工具加载 Superpowers `finishing-a-development-branch` 技能。该步骤必须位于归档与归档提交之后,确保最终分支/PR 包含 spec 合并和归档元数据。

如该技能不可用,停止流程并提示安装或启用;不得把 `branch_status` 标记为完成。技能加载后,按 `comet/reference/decision-point.md` 暂停让用户选择:
归档提交成功后,先读取 `comet state get <change-name> isolation`,按隔离方式分流:

1. 本地合并到主分支
2. 推送并创建 PR
3. 保持当前分支稍后处理
- `isolation !== current`:**立即执行:** 使用 Skill 工具加载 Superpowers `finishing-a-development-branch` 技能。该步骤必须位于归档与归档提交之后,确保最终分支/PR 包含 spec 合并和归档元数据。如该技能不可用,停止流程并提示安装或启用;不得把 `branch_status` 标记为完成。技能加载后,按 `comet/reference/decision-point.md` 暂停让用户选择:本地合并到主分支、推送并创建 PR、保持当前分支稍后处理。
- `isolation === current`:跳过 Superpowers `finishing-a-development-branch`。按 `comet/reference/decision-point.md` 暂停让用户二选一:推送当前分支,或暂不推送并保留本地状态。

归档已经完成,因此这里不提供“丢弃工作”选项。只有用户选择的操作成功完成(或明确选择保持分支)后,才运行:
归档已经完成,因此这里不提供“丢弃工作”选项。只有用户选择的操作成功完成、明确选择保持分支,或在 `current` 模式下明确选择暂不推送后,才运行:

```bash
comet state set <change-name> branch_status handled
Expand Down
26 changes: 16 additions & 10 deletions assets/skills-zh/comet-build/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ comet state check <name> build

验证通过后继续 Step 1。验证失败时脚本会输出具体失败原因。

若上述 `select` / `check` 输出 `BLOCKED`,且原因是 `bound_branch` 与当前分支不一致,立即按 `comet/reference/decision-point.md` 暂停,让用户单选:切回绑定分支后重新运行入口验证,或在用户明确确认当前分支应接管该 change 后运行 `comet state rebind <change-name>` 并重新入口验证。不得自行切换分支,不得自行换绑。

**幂等性**:build 阶段所有操作可安全重复执行。读取 `.comet.yaml` 的 `phase` 字段确认仍在 build 阶段,读取 plan 文件头的 `base-ref`,再按文档顺序解析 tasks.md 的复选框,从第一个未勾选任务继续执行。已提交的任务不得重复提交。

### 1. 制定计划(Subagent Offload)
Expand Down Expand Up @@ -116,12 +118,14 @@ comet state set <name> build_pause null

| 选项 | 方式 | 说明 |
|------|------|------|
| A | 创建分支 | 在当前仓库创建新分支,简单快速 |
| B | 创建 Worktree | 隔离工作区,完全独立,适合并行开发 |
| A | 当前分支直接工作 | 不创建新分支,如实绑定当前 Git 分支 |
| B | 创建分支 | 在当前仓库创建新分支,简单快速 |
| C | 创建 Worktree | 隔离工作区,完全独立,适合并行开发 |

**推荐规则**:
- 变更涉及 ≤ 3 个文件 → 推荐 A
- 需要并行开发、当前分支有未提交工作 → 推荐 B
- 用户明确希望沿用当前分支,或当前分支本身就是该 change 的目标分支 → 推荐 A
- 变更涉及 ≤ 3 个文件且当前分支干净 → 推荐 B
- 需要并行开发、当前分支有未提交工作 → 推荐 C

**执行方式**:

Expand All @@ -135,12 +139,12 @@ comet state set <name> build_pause null
- 任务数 ≤ 2 且无跨模块依赖 → 推荐 B
- 来自 hotfix 路径 → 推荐 B

这些表格是 Step 2 联合决策的一部分,不再单独暂停。先移除能力预检判定为不可执行的选项;在剩余多个合法选项时,不得根据推荐规则自行选择 `branch` 或 `worktree`,也不得自行选择执行方式、TDD 模式或代码审查模式。推荐规则只能用于说明建议,不能替代用户确认。
这些表格是 Step 2 联合决策的一部分,不再单独暂停。先移除能力预检判定为不可执行的选项;在剩余多个合法选项时,不得根据推荐规则自行选择 `current`、`branch` 或 `worktree`,也不得自行选择执行方式、TDD 模式或代码审查模式。推荐规则只能用于说明建议,不能替代用户确认。

用户选择后,更新 `isolation`、执行方式、TDD 模式和代码审查模式相关字段:

```bash
comet state set <name> isolation <branch|worktree>
comet state set <name> isolation <current|branch|worktree>
```

- 若用户选择 `executing-plans`:运行 `comet state set <name> subagent_dispatch null`,再运行 `comet state set <name> build_mode executing-plans`
Expand All @@ -166,7 +170,7 @@ comet state set <name> isolation <branch|worktree>

运行 `comet state set <name> review_mode <off|standard|thorough>`

`isolation` 是脚本级硬约束。full workflow 初始化时可以为 `null`,但只允许存在到本步骤之前。若保持 `null`,`build → verify` 的 guard 和 `comet state transition build-complete` 都会失败。
`isolation` 是脚本级硬约束。full workflow 初始化时可以为 `null`,但只允许存在到本步骤之前。若保持 `null`,`build → verify` 的 guard 和 `comet state transition build-complete` 都会失败。full workflow 允许 `current`、`branch` 或 `worktree`,但 `current` 必须通过用户在 Step 2 显式选择后写入,不得静默默认。

`subagent_dispatch` 是脚本级硬约束。`build_mode: subagent-driven-development` 离开 build 阶段前必须同时满足 `subagent_dispatch: confirmed`,否则 `comet guard build --apply` 和 `comet state transition build-complete` 都会失败。

Expand All @@ -185,6 +189,8 @@ comet state set <name> build_mode direct

**执行隔离**:

- **current**:不创建新分支或 worktree,直接在当前 Git 分支执行。立即运行 `comet state set <name> isolation current`;该命令会把当前分支写入 `bound_branch`。如果当前是 detached HEAD,必须停止并让用户先切回真实分支,因为没有可审计的绑定分支。

- **branch**:使用 Step 2 已确认的分支名,不得再次暂停。若旧状态恢复时缺少该次联合决策中的分支名,重新进入 Step 2 的同一个联合决策;不得创建第二个独立分支命名决策点。

分支命名规范:
Expand All @@ -196,7 +202,7 @@ comet state set <name> build_mode direct

示例:如果 change 名称为 `fix-login-bug`,今天是 2026-06-09,则推荐 `feature/20260609/fix-login-bug`

分支名由 Step 2 确认后,立即执行 `git checkout -b <branch-name>`,后续工作在新分支上进行。
分支名由 Step 2 确认后,立即执行 `git checkout -b <branch-name>`,然后运行 `comet state set <name> isolation branch`,把新分支写入 `bound_branch`。后续工作在新分支上进行。

- **worktree**:必须使用 Skill 工具加载 Superpowers `using-git-worktrees` 技能创建隔离工作区。禁止用普通 shell 命令或原生工具绕过该技能;如该技能不可用,停止流程并提示安装或启用 Superpowers 技能。

Expand All @@ -207,7 +213,7 @@ git add docs/superpowers/plans/YYYY-MM-DD-feature.md
git commit -m "chore: add implementation plan"
```

进入最终执行分支或 worktree 后,必须在该实际工作区重新绑定当前 change。branch 切换会使入口绑定失效,新 worktree 也不会继承原工作区的本地选择文件
进入最终执行分支或 worktree 后,必须在该实际工作区重新绑定当前 change。branch 模式已在切换后通过 `isolation branch` 绑定;worktree 模式必须在新工作区运行 `comet state set <name> isolation worktree`,把 worktree 的当前分支写入 `bound_branch`。新 worktree 不会继承原工作区的本地选择文件,因此还必须选择当前 change

```bash
comet state select <change-name>
Expand Down Expand Up @@ -288,7 +294,7 @@ Build 是最长阶段,可能跨越大量任务。为支持上下文压缩后
- tasks.md 全部勾选
- 代码已提交
- 已显式运行项目对应的构建/测试命令并通过(不要只依赖 guard 自动猜测)
- `isolation` 已写为 `branch` 或 `worktree`
- `isolation` 已写为 `current`、`branch` 或 `worktree`
- `build_mode` 已写为 `subagent-driven-development`、`executing-plans` 或带显式 override 的 `direct`;若为 `subagent-driven-development`,`subagent_dispatch` 必须为 `confirmed`
- `tdd_mode` 已写为 `tdd` 或 `direct`
- `review_mode` 已写为 `off`、`standard` 或 `thorough`
Expand Down
Loading
Loading