Skip to content

Commit 183691a

Browse files
committed
✨ feat(state): add pre-worktree pending state
1 parent d66d81a commit 183691a

19 files changed

Lines changed: 545 additions & 93 deletions

File tree

README.md

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,13 @@ Issue-Flow ships two workflow state machines:
1818

1919
### `issue-flow`
2020

21-
The issue-driven workflow has two parts: a pre-phase that produces a GitHub Issue number, and a persistent state machine that tracks delivery from that point on.
21+
The issue-driven workflow has two parts: a pre-worktree phase that produces a GitHub Issue number, and a persistent state machine that tracks delivery from that point on.
2222

23-
**Pre-phase** (session-scoped, not persistable):
23+
**Pre-worktree phase** (short-lived pending state in the source repo):
2424

2525
- `issue-brainstorm` turns a rough request into a design direction
2626
- `issue-create` turns the design spec into a GitHub Issue number
27+
- `.issue-flow/pending.json` can recover this short phase before a target worktree exists
2728

2829
**Persistent state machine** (`.issue-flow/` created by `issue-pick`):
2930

@@ -47,6 +48,8 @@ The top-level `issue-flow` skill is the orchestrator. It reads the current sessi
4748

4849
The bugfix workflow is intentionally narrower. It is for cases where you already know there is a bug and want the agent to focus on reproducing, fixing, and verifying it before any commit or PR step.
4950

51+
Bugfix work usually goes directly to `bugfix-pick`. If it must pause before a worktree exists, `.bugfix-flow/pending.json` can hold that short-lived pending state in the source repo.
52+
5053
**Persistent state machine** (`.bugfix-flow/` created by `bugfix-pick`):
5154

5255
```text

docs/architecture.md

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ Everything else should remain delegated to focused skills or to `superpowers`.
2424

2525
### Orchestrator skill
2626

27-
`skills/issue-flow/SKILL.md` is the entry point. It reads session state from `.issue-flow/`, determines the current phase, and hands control to the next workflow skill.
27+
`skills/issue-flow/SKILL.md` is the entry point. It reads formal session state from `.issue-flow/` in the target worktree, or pending pre-worktree state from the source repository when a worktree does not exist yet. It then determines the current phase and hands control to the next workflow skill.
2828

2929
The orchestrator should stay small. It owns coordination, not execution details.
3030

@@ -57,11 +57,13 @@ The `skills/issue-*` files implement each phase of the lifecycle:
5757

5858
## State Model
5959

60-
Issue-Flow has two phases: a **pre-phase** and a **persistent state machine**.
60+
Issue-Flow has two phases: a **pre-worktree pending phase** and a **persistent state machine**.
6161

62-
The pre-phase (`issue-brainstorm` + `issue-create`) runs before `.issue-flow/` exists. These stages are session-scoped and cannot be persisted or recovered. Mode is passed via `$ARGUMENTS --auto` since the mode file does not exist yet.
62+
The pre-worktree phase (`issue-brainstorm` + `issue-create`, and the setup immediately before `issue-pick`) runs before the target worktree exists. During this phase, the source repository root may contain `.issue-flow/pending.json`. That file is a short-lived handoff record, not a formal state-machine state. It lets the orchestrator recover from interruptions before the target worktree has been created. The same pattern is available to `bugfix-flow` as `.bugfix-flow/pending.json`, but only when bugfix pick needs to pause for clarification.
6363

64-
The persistent state machine starts at `picked`, when `issue-pick` creates the `.issue-flow/` directory, worktree, and branch. From this point on, session state is persisted in `.issue-flow/` at the worktree root. Typical files include:
64+
Pending state is intentionally simple: one pending flow per repo root. If a new request finds an existing pending file in the same repo root, the orchestrator asks the user to recover, overwrite, or cancel instead of creating a multi-session registry.
65+
66+
The persistent state machine starts at `picked`, when `issue-pick` creates the worktree, branch, and formal `.issue-flow/` directory. From this point on, session state is persisted in `.issue-flow/` at the worktree root. Typical files include:
6567

6668
- `state` - current workflow phase
6769
- `mode` - manual or auto
@@ -70,7 +72,7 @@ The persistent state machine starts at `picked`, when `issue-pick` creates the `
7072
- `plan-path` - current implementation plan path
7173
- `verify-report.md` - verification output
7274

73-
The source of truth for valid states and transitions is [../skills/issue-flow/references/state-schema.md](../skills/issue-flow/references/state-schema.md).
75+
The source of truth for valid states and transitions is [../skills/issue-flow/references/state-schema.md](../skills/issue-flow/references/state-schema.md). The bugfix equivalent is [../skills/bugfix-flow/references/state-schema.md](../skills/bugfix-flow/references/state-schema.md).
7476

7577
## Why Issue-Flow Depends On Superpowers
7678

hooks/state-transition-guard

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,8 @@ declare -A TRANSITIONS
6767

6868
# issue-flow transitions
6969
TRANSITIONS[issue-brainstorm]="none"
70-
TRANSITIONS[issue-create]="brainstorm none"
71-
TRANSITIONS[issue-pick]="brainstorm none"
70+
TRANSITIONS[issue-create]="none"
71+
TRANSITIONS[issue-pick]="none"
7272
TRANSITIONS[issue-plan]="researching"
7373
TRANSITIONS[issue-research]="picked"
7474
TRANSITIONS[issue-implement]="planned reviewing"

skills/bugfix-finish/SKILL.md

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,17 @@ allowed-tools:
3131
- `auto`**auto 模式**
3232
- 其他/不存在 → **manual 模式**
3333

34-
### 3. 分支收尾
34+
同时读取并暂存最终报告需要的 bug 摘要、当前分支名、worktree 路径和未提交变更摘要。
35+
36+
### 3. 清理 `.bugfix-flow`
37+
38+
在任何可能移除 worktree 的操作之前,删除当前 worktree 根目录下的 `.bugfix-flow/`
39+
40+
```bash
41+
rm -rf .bugfix-flow
42+
```
43+
44+
### 4. 分支收尾
3545

3646
#### Manual 模式
3747

@@ -50,14 +60,6 @@ bugfix-flow 默认不要求在此阶段创建 PR。
5060
2. 清理 worktree
5161
3. 不自动 merge
5262

53-
### 4. 清理 `.bugfix-flow`
54-
55-
无论 manual 还是 auto,在收尾完成后删除 `.bugfix-flow/` 目录:
56-
57-
```bash
58-
rm -rf .bugfix-flow
59-
```
60-
6163
### 5. 输出
6264

6365
输出最终报告:
@@ -71,5 +73,5 @@ rm -rf .bugfix-flow
7173

7274
- 不自动 merge PR
7375
- 不自动删除远端 branch
74-
- `.bugfix-flow/``finished` 后必须清理
76+
- `.bugfix-flow/``finished` 后必须清理,并且必须先于 worktree 移除执行
7577
- 删除时仅清理当前 worktree 根目录下的 `.bugfix-flow/`

skills/bugfix-flow/SKILL.md

Lines changed: 49 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ allowed-tools:
2121
- Bash(gh issue view *)
2222
- Bash(mkdir *)
2323
- Bash(cat *)
24+
- Bash(date)
25+
- Bash(rm -f .bugfix-flow/pending.json)
2426
- Bash(rm -r .bugfix-flow)
2527
- Skill(bugfix-pick)
2628
- Skill(bugfix-implement)
@@ -50,7 +52,12 @@ allowed-tools:
5052

5153
## 状态持久化
5254

53-
开发会话状态保存在 worktree 根目录的 `.bugfix-flow/` 中:
55+
Bugfix-Flow 有两个状态位置:
56+
57+
1. **pre-worktree pending state**:默认不创建;仅在 pick 前需要澄清或暂停时,保存在启动命令所在仓库根目录的 `.bugfix-flow/pending.json`
58+
2. **正式状态机 state**:目标 worktree 创建后,状态保存在目标 worktree 根目录的 `.bugfix-flow/`
59+
60+
正式开发会话状态保存在 worktree 根目录的 `.bugfix-flow/` 中:
5461

5562
```text
5663
.bugfix-flow/
@@ -60,6 +67,8 @@ allowed-tools:
6067
verify-report.md # 验证报告
6168
```
6269

70+
`.bugfix-flow/pending.json` 不是正式状态机 state,只用于 pick 前的短期恢复。同一 repo root 只允许一个 pending 流程;若已存在 pending,新请求必须提示恢复、覆盖或取消。
71+
6372
持久化状态机(`.bugfix-flow/``bugfix-pick` 时创建):
6473

6574
```text
@@ -84,24 +93,29 @@ picked → implementing → ready → finished
8493

8594
```text
8695
bug 描述
87-
→ 1. bugfix-pick(创建 worktree + 分支 + .bugfix-flow/context.json)
96+
→ 1. bugfix-flow 在调用 `bugfix-pick` 前预检查输入是否包含最小复现线索、预期行为和验证目标
97+
→ 2. 如需澄清或暂停,bugfix-flow 写入 `.bugfix-flow/pending.json` 后再 AskUserQuestion
98+
→ 3. bugfix-pick(创建 worktree + 分支 + 正式 .bugfix-flow/)
99+
→ 4. bugfix-flow 删除源仓库的 `.bugfix-flow/pending.json`
88100
→ [进入状态机循环]
89101
```
90102

91103
### 模式 B:基于已有 Issue 修复
92104

93105
```text
94106
Issue #N
95-
→ 1. bugfix-pick(读取 Issue + 创建 worktree + 分支)
107+
→ 1. bugfix-pick(读取 Issue + 创建 worktree + 分支 + 正式 .bugfix-flow/)
108+
→ 2. bugfix-flow 删除源仓库的 `.bugfix-flow/pending.json`(如果存在)
96109
→ [进入状态机循环]
97110
```
98111

99112
### 模式 C:恢复会话
100113

101114
1. 查找当前目录或父目录中的 `.bugfix-flow/state`
102-
2. 读取 `state``mode`
103-
3. 按状态调用对应子 skill
104-
4. 更新状态后,根据 mode 决定是继续还是暂停
115+
2. 若找到正式 state,读取 `state``mode`,按状态调用对应子 skill
116+
3. 若未找到正式 state,查找当前 git 仓库根目录的 `.bugfix-flow/pending.json`
117+
4. 若找到 pending,则恢复 pick 前澄清流程;同一 repo root 只允许一个 pending 流程
118+
5. 若都未找到,视为新会话,进入模式 A 或 B
105119

106120
### 状态机循环
107121

@@ -132,8 +146,10 @@ Issue #N
132146

133147
1. 从当前目录开始,检查是否存在 `.bugfix-flow/state`
134148
2. 若不存在,向父目录逐级递归查找(最多到 git 仓库根目录)
135-
3. 若找到,以该目录为 worktree 根目录读取 `.bugfix-flow/` 下所有文件
136-
4. 若未找到,视为新会话,进入模式 A 或 B
149+
3. 若找到,以该目录为 worktree 根目录读取正式 `.bugfix-flow/` 下所有文件
150+
4. 若未找到正式 state,检查当前 git 仓库根目录的 `.bugfix-flow/pending.json`
151+
5. 若找到 pending,恢复 pick 前澄清流程
152+
6. 若都未找到,视为新会话,进入模式 A 或 B
137153

138154
## Mode 判定与写入
139155

@@ -148,13 +164,36 @@ Issue #N
148164
- `bugfix-flow` 先将 `.bugfix-flow/state` 写为 `finished`
149165
- 然后调用 `bugfix-finish`
150166

151-
新建会话时(模式 A/B),在调用 `bugfix-pick` 前创建 `.bugfix-flow/mode`
167+
新建会话时(模式 A/B),不得在源仓库根目录预先创建正式 `.bugfix-flow/state`
168+
仅在 pick 前需要澄清或暂停时,`bugfix-flow` 在源仓库根目录创建 `.bugfix-flow/pending.json`
169+
同一 repo root 已存在 pending 时,不自动覆盖;必须提示用户恢复、覆盖或取消。
170+
171+
调用 `bugfix-pick` 前,`bugfix-flow` 必须先检查 bug 描述是否包含最小复现线索、预期行为和至少一条验证目标:
172+
- 信息充足 → 调用 `bugfix-pick`
173+
- manual 模式信息不足 → 先写入 `.bugfix-flow/pending.json` 后再 AskUserQuestion
174+
- auto 模式信息不足 → 停止并说明缺失项,不调用 `bugfix-pick`
175+
176+
`bugfix-pick` 创建目标 worktree 后,必须在目标 worktree 根目录创建正式 `.bugfix-flow/` 并写入:
177+
178+
```text
179+
mode: manual | auto
180+
state: picked
181+
```
182+
183+
正式状态写入成功后,`bugfix-flow` 删除源仓库的 `.bugfix-flow/pending.json`(如果存在),完成 handoff。
184+
185+
pending 生命周期由 `bugfix-flow` 编排器统一维护:
186+
- `bugfix-flow` 负责创建、更新和删除源仓库 `.bugfix-flow/pending.json`
187+
- `bugfix-pick` 只负责在目标 worktree 创建正式 `.bugfix-flow/`
188+
- 删除 pending 必须在源仓库根目录执行 `rm -f .bugfix-flow/pending.json`
152189

153190
## 状态更新规则
154191

155192
`bugfix-flow` 统一负责更新 `.bugfix-flow/state`
156193

157194
- 子 skill 返回成功 → 按状态流转表写入下一个 state
195+
- 仅在 pick 前需要澄清或暂停时写入 `.bugfix-flow/pending.json`
196+
- `bugfix-pick` 成功写入正式状态后,`bugfix-flow` 回到源仓库根目录删除 `.bugfix-flow/pending.json`
158197
- `bugfix-verify` 失败 → 保持 `implementing`
159198
- `bugfix-finish` 只在用户显式要求收尾时触发,不因验证通过自动触发
160199

@@ -173,4 +212,5 @@ Issue #N
173212
- bug 描述不足以形成可验证修复目标 → manual 模式下澄清;auto 模式下停止并说明缺失项
174213
- 子 skill 执行失败 → 保留 `.bugfix-flow/` 和 worktree,输出失败详情,提示用户修复后继续
175214
- 找不到 `.bugfix-flow/` 但用户意图是恢复 → 提示用户先执行 `/bugfix-flow <bug 描述>``/bugfix-flow #<编号>`
215+
- 找到 `.bugfix-flow/pending.json` 但找不到正式 state → 恢复 pick 前澄清流程,不把 pending 当成正式 state
176216
- 用户要求 `finish` 但当前不在 `ready` → 停止,提示先完成验证

skills/bugfix-flow/references/state-machine.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
# Bugfix-Flow 状态机
22

3+
## 预阶段(可选 pending)
4+
5+
Bugfix-Flow 通常直接从输入进入 `bugfix-pick`。只有在 pick 前需要澄清或暂停时,才在源仓库根目录写入 `.bugfix-flow/pending.json`
6+
7+
`pending.json` 不是正式状态机 state;正式状态机仍从目标 worktree 的 `picked` 开始。
8+
39
## 持久化状态机(`.bugfix-flow/``bugfix-pick` 时创建)
410

511
```text

skills/bugfix-flow/references/state-schema.md

Lines changed: 48 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,12 @@
44

55
## 目录结构
66

7-
每个被 `bugfix-flow` 接管的开发会话,在 **worktree 根目录**下创建 `.bugfix-flow/`
7+
Bugfix-Flow 有两个状态位置:
8+
9+
- pre-worktree 阶段:默认不创建;仅在 pick 前需要澄清或暂停时,在启动命令所在仓库根目录使用 `.bugfix-flow/pending.json`
10+
- 正式状态机阶段:在目标 **worktree 根目录**下创建 `.bugfix-flow/`
11+
12+
每个被 `bugfix-flow` 接管的正式开发会话,在 **worktree 根目录**下创建 `.bugfix-flow/`
813

914
```text
1015
.bugfix-flow/
@@ -18,6 +23,29 @@
1823
1924
## 文件格式
2025

26+
### `pending.json`
27+
28+
`.bugfix-flow/pending.json` 是 pre-worktree 暂存文件,不是正式状态机 state。它只用于 pick 前澄清或暂停时的短期恢复。
29+
30+
建议格式:
31+
32+
```json
33+
{
34+
"flow": "bugfix-flow",
35+
"mode": "manual",
36+
"phase": "clarifying",
37+
"summary": "空配置文件会导致服务启动 panic",
38+
"created_at": "2026-04-30T12:00:00Z",
39+
"updated_at": "2026-04-30T12:05:00Z"
40+
}
41+
```
42+
43+
约束:
44+
45+
- `phase` 取值:`clarifying`, `picking`
46+
- 同一 repo root 只允许一个 pending 流程;如已存在,编排器必须提示用户恢复、覆盖或取消
47+
- `pending.json` 不参与 `state-transition-guard` 的正式 state 校验
48+
2149
### `state`
2250

2351
合法值(按流转顺序):
@@ -77,12 +105,28 @@ picked → implementing → ready → finished
77105
1. 当前目录是否存在 `.bugfix-flow/state`
78106
2. 若不存在,向父目录逐级递归查找
79107
3. 若找到,以找到 `.bugfix-flow/` 的目录为基准读取其他文件
80-
4. 若未找到,视为不在 bugfix-flow 会话中
108+
4. 若未找到正式 state,编排器可以读取当前 git 仓库根目录的 `.bugfix-flow/pending.json` 恢复 pick 前澄清流程
109+
5. 若正式 state 和 pending 都未找到,视为不在 bugfix-flow 会话中
81110

82111
## 子 skill 行为约定
83112

84113
- **读取**:子 skill 可以读取 `.bugfix-flow/` 中的文件获取上下文
85114
- **写入**:子 skill 可以写入 `context.json``verify-report.md` 等业务文件
86115
- 写入 `.bugfix-flow/` 状态文件时,优先使用 `Write`,不要依赖 shell 重定向
87-
- **状态更新**`.bugfix-flow/state``bugfix-flow` 编排器统一维护,子 skill 不应直接修改
88-
- **mode 适配**:子 skill 优先读取 `.bugfix-flow/mode`,若不存在则默认 `manual`
116+
- **初始状态**`bugfix-pick` 是唯一允许创建正式 `.bugfix-flow/state` 初始值的子 skill,初始 state 为 `picked`
117+
- **状态更新**:初始创建之后,`.bugfix-flow/state``bugfix-flow` 编排器统一维护,其他子 skill 不应直接修改
118+
- **mode 适配**:子 skill 在执行门控操作前,应按以下优先级检测运行模式:
119+
1. 检查 `$ARGUMENTS` 是否包含 `--auto`
120+
2. 读取 `.bugfix-flow/pending.json``mode`(用于 pick 前恢复阶段)
121+
3. 读取 `.bugfix-flow/mode`(用于持久化状态机阶段)
122+
4. 默认 `manual` 模式
123+
124+
## 新会话初始化顺序
125+
126+
新建会话时,编排器不得在源仓库预先创建正式 `.bugfix-flow/state`。仅当 pick 前需要澄清或暂停时,写入 `.bugfix-flow/pending.json`。正确顺序是:
127+
128+
1. 如需澄清或暂停,`bugfix-flow` 在源仓库根目录写入或更新 `.bugfix-flow/pending.json`
129+
2. `bugfix-pick` 创建目标 worktree 和分支
130+
3. `bugfix-pick` 在目标 worktree 根目录写入 `.bugfix-flow/mode``.bugfix-flow/state``.bugfix-flow/context.json`
131+
4. `bugfix-flow` 回到源仓库根目录并删除 `.bugfix-flow/pending.json`(如果存在)
132+
5. 正式状态机从 `picked` 开始恢复和推进

skills/bugfix-implement/SKILL.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ disable-model-invocation: false
77
allowed-tools:
88
- Read
99
- Write
10+
- Edit
11+
- MultiEdit
1012
- Glob
1113
- Grep
1214
- Bash(cat *)
@@ -46,6 +48,7 @@ allowed-tools:
4648
- 优先做最小可行修复,不扩大范围
4749
- 如需要补测试,测试内容应直接覆盖 `verification_targets`
4850
- 若当前 `state=ready` 且用户重新进入本阶段,视为处理验证中暴露的新缺口
51+
- 优先使用 `Edit` / `MultiEdit` 做局部修改;只有创建新文件或整体生成文件时才使用 `Write`
4952

5053
### 4. 输出
5154

0 commit comments

Comments
 (0)