Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
f66dd4f
feat: add deterministic change recovery resolution
MageByte-Zero Jul 19, 2026
39463c7
feat: aggregate auditable change recovery context
MageByte-Zero Jul 19, 2026
9559705
fix: preserve recovery blockers for malformed plans
MageByte-Zero Jul 19, 2026
3dd0bce
feat: add resume and switch commands
MageByte-Zero Jul 19, 2026
cd84f00
fix: validate recovery command arguments
MageByte-Zero Jul 19, 2026
8522024
fix: reject blank switch targets
MageByte-Zero Jul 19, 2026
7a3e883
feat: add checkpoint-compatible save command
MageByte-Zero Jul 19, 2026
993035f
fix: classify save usage errors before writes
MageByte-Zero Jul 19, 2026
27e0f6a
fix: avoid rereading checkpoints after save
MageByte-Zero Jul 19, 2026
fb7a9f4
fix: classify recovery parse errors as usage
MageByte-Zero Jul 19, 2026
6ec8ea9
feat: add ssf recovery slash commands
MageByte-Zero Jul 19, 2026
0d63d87
fix: quote recovery slash command arguments
MageByte-Zero Jul 19, 2026
95db157
test: harden recovery command argument checks
MageByte-Zero Jul 19, 2026
26eff0d
feat: distribute recovery commands to WorkBuddy
MageByte-Zero Jul 19, 2026
a9d7fef
fix: reject linked WorkBuddy commands
MageByte-Zero Jul 19, 2026
21fc41b
fix: validate complete WorkBuddy command tree
MageByte-Zero Jul 19, 2026
6ea8994
fix: snapshot WorkBuddy command assets
MageByte-Zero Jul 19, 2026
e7a7659
docs: publish issue 47 recovery workflow
MageByte-Zero Jul 19, 2026
a265826
docs: harden issue 47 recovery contract
MageByte-Zero Jul 19, 2026
06672df
fix: complete issue 47 recovery release guards
MageByte-Zero Jul 19, 2026
b95ae2f
Merge branch 'main' into codex/fix-issue-47-recovery-codebuddy
MageByte-Zero Jul 20, 2026
82d1b7c
Merge remote-tracking branch 'origin/main' into codex/fix-issue-47-re…
MageByte-Zero Jul 20, 2026
29820f4
Merge remote-tracking branch 'origin/codex/fix-issue-47-recovery-code…
MageByte-Zero Jul 20, 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
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ The format loosely follows Keep a Changelog.

## [Unreleased]

### Added

- **Closes #47 — Recovery workflow commands**: publish `ssf resume`, `ssf switch`, and `ssf save` as a control-plane overlay. Resume/switch are read-only; save writes only the compatible checkpoint and never automatically commits, pushes, or syncs. WorkBuddy distributes the canonical `/ssf:resume`, `/ssf:switch`, and `/ssf:save` Markdown command adapters.

### Fixed

- **#64 — closing 终态生命周期对齐**:将 `release-archivist` 验证、`spec-merger` 同步和归档确认明确为 `executing` 内的 pre-closing 收尾步骤;`closing` 是 `CLOSED` 成功终态,且没有 next skill。
Expand Down
12 changes: 10 additions & 2 deletions INSTALL.md
Original file line number Diff line number Diff line change
Expand Up @@ -339,6 +339,8 @@ rm -rf your-project/.agents/skills

WorkBuddy 把 Skill 作为 marketplace 插件管理。安装器把 spec-superflow 部署为单个插件,包含 9 个 skill、运行时依赖(scripts/docs/templates/dist/hooks)、phase-guard 规则和 `.codebuddy-plugin/plugin.json` 清单,写入 `~/.workbuddy/plugins/marketplaces/<marketplace>/plugins/spec-superflow/`。

安装器还会分发三份 canonical Markdown command adapter:`/ssf:resume`、`/ssf:switch`、`/ssf:save`。它们仅在 CodeBuddy/WorkBuddy 的 command 机制中提供这些 slash 名称,并调用同一组 CLI guard;不表示所有平台都有完全相同的 slash 命令。

### 安装(推荐:一键脚本)

```bash
Expand All @@ -362,6 +364,7 @@ ssf install-workbuddy --dry-run
```text
~/.workbuddy/plugins/marketplaces/cb_teams_marketplace/plugins/spec-superflow/
├── .codebuddy-plugin/plugin.json ← 插件清单(name, version, skills[])
├── commands/ssf/ ← resume、switch、save Markdown command adapter
├── skills/ ← 9 个 skill(${CLAUDE_PLUGIN_ROOT} 已重写)
├── rules/phase-guard.md ← phase-guard 规则(WorkBuddy 自动加载)
├── scripts/ docs/ templates/ ← 运行时依赖
Expand Down Expand Up @@ -759,8 +762,7 @@ ssf execution review changes/my-change --wave foundation --base <sha> --head <sh
report 本身必须为普通、非空、非符号链接文件。

每一个 wave 均须有当前 `pass` review receipt,才可启动依赖 wave 或进入 closing;
修订计划会废止旧 receipt。#47 所提出的恢复、切换与手动保存 slash command 尚未实现,
不能假定有 `/ssf:*` 命令。
修订计划会废止旧 receipt。恢复、切换和手动保存属于 control-plane overlay,不增加第九个状态。

Delta spec 的规范路径是 `specs/<capability>/spec.md`。扁平的 `specs/<capability>.md` 和根级 `specs/spec.md` 都不会被当作合法规范静默通过。

Expand All @@ -776,6 +778,10 @@ ssf inject changes/my-change --platforms all
### 会话恢复与可选 prototype

```bash
ssf resume # 恰好一个活跃 change 时才自动选择
ssf resume changes/my-change # 只读恢复指定 change 摘要
ssf switch changes/another-change # 只读返回明确 change 的恢复上下文
ssf save changes/my-change --task 1.1 --next "Run focused tests"
ssf checkpoint save changes/my-change --task 1.1 --next "Run focused tests"
ssf checkpoint list changes/my-change
ssf checkpoint show changes/my-change 1.1
Expand All @@ -785,6 +791,8 @@ ssf handoff finish changes/my-change <handoff-id>
ssf handoff resolve changes/my-change <handoff-id> --decision accept
```

`resume` 与 `switch` 是只读恢复操作;`resume` 只会在恰好一个活跃 change 时自动选择。`switch` 只返回明确目标的恢复上下文,不修改 cwd、TUI 会话或任何隐藏指针;CLI 本身不切换当前对话关注对象,CodeBuddy/WorkBuddy adapter 或宿主 Agent 可用该上下文完成该动作。`save` 只手动复用既有 checkpoint 协议,不自动 commit、push 或 sync。`/ssf:resume`、`/ssf:switch`、`/ssf:save` 是 CodeBuddy/WorkBuddy Markdown command adapter,会分发至相同的 CLI guard,不为其他平台承诺完全相同的 slash 名称。

Checkpoint 是任务级恢复上下文。`result-ready` handoff 在继续受影响的工作前必须显式审阅并 resolve。Prototype 只在用户明确确认后创建;后端、CLI、配置和内部重构不会自动进入 prototype 流程。handoff 结果不会自动修改 `design.md` 或 `tasks.md`。

## 验证
Expand Down
13 changes: 11 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,9 @@ npx spec-superflow list # 或通过 npx 使用
| `ssf checkpoint save <dir> --task <id> --next <text>` | 保存任务级会话恢复点 |
| `ssf checkpoint list <dir>` | 列出 checkpoint 及 stale 状态 |
| `ssf checkpoint show <dir> <id>` | 查看单个恢复点 |
| `ssf resume [change]` | 只读恢复摘要;唯一活跃 change 可自动选择 |
| `ssf switch <change>` | 只读返回明确 change 的恢复上下文;adapter 可据此切换当前 AI 对话关注对象 |
| `ssf save <change> --task <id> --next <text>` | 手动写入兼容 checkpoint;不自动 commit、push 或 sync |
| `ssf handoff create <dir> --type <type> ...` | 创建 prototype/research/experiment handoff |
| `ssf handoff list <dir>` | 列出 handoff 生命周期状态 |
| `ssf handoff finish <dir> <id>` | 校验 handoff 结果 |
Expand Down Expand Up @@ -182,11 +185,17 @@ ssf inject changes/my-change --platforms all
会话恢复与可选 prototype:

```bash
ssf resume # 只在唯一活跃 change 时自动选择
ssf resume changes/my-change # 只读恢复指定 change 的摘要
ssf switch changes/another-change # 只读返回明确 change 的恢复上下文
ssf save changes/my-change --task 1.1 --next "Run focused tests"
ssf checkpoint save changes/my-change --task 1.1 --next "Run focused tests"
ssf checkpoint list changes/my-change
ssf handoff create changes/my-change --type research --objective "Compare approaches" --expected-output "Recommendation" --acceptance "Evidence recorded"
```

`resume` 与 `switch` 都是只读恢复操作;`resume` 只会在恰好一个活跃 change 时自动选择目标。`switch` 只返回明确目标的恢复上下文,不修改 cwd、TUI 会话或任何隐藏指针;CLI 本身不切换当前对话关注对象,CodeBuddy/WorkBuddy adapter 或宿主 Agent 可用该上下文完成该动作。`save` 仅手动写入既有 checkpoint 协议,绝不自动 commit、push 或 sync。`/ssf:resume`、`/ssf:switch`、`/ssf:save` 是 CodeBuddy/WorkBuddy 使用的 Markdown command adapter:它们分发到同一 CLI guard,不为其他平台承诺完全相同的 slash 名称。

Prototype 只在用户明确确认后创建;后端、CLI、配置和内部重构不会自动进入 prototype 流程。handoff 结果不会自动修改 `design.md` 或 `tasks.md`。

Delta spec 的规范路径是 `specs/<capability>/spec.md`;扁平的 `specs/<capability>.md` 和根级 `specs/spec.md` 不会被视为合法规范。
Expand Down Expand Up @@ -231,8 +240,8 @@ ssf execution review changes/my-change --wave foundation --base <sha> --head <sh
report 本身必须为普通、非空、非符号链接文件。

每个 wave 的 review receipt 必须是当前 revision 的 `pass`,依赖 wave 和 closing
才会放行;修订计划会使旧 receipt 失效。恢复、切换和手动保存等 #47 的 slash
command 尚未实现,不能据此假定存在 `/ssf:*` 命令
才会放行;修订计划会使旧 receipt 失效。恢复、切换和手动保存是 control-plane
overlay,不会增加第九个状态;其 CLI 与 CodeBuddy/WorkBuddy Markdown adapter 保持相同 guard

---

Expand Down
10 changes: 10 additions & 0 deletions commands/ssf/resume.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---

description: 恢复一个 spec-superflow change,并按现有状态机继续
argument-hint: "[change-name-or-path]"
allowed-tools: Bash(npx:*)
---

先检查 `$ARGUMENTS` 是否为非空目标:为空时运行 `npx --yes --package spec-superflow@0.10.0 ssf resume --json`,让 CLI 按唯一活跃 change 的既有确定性规则选择;非空时运行 `npx --yes --package spec-superflow@0.10.0 ssf resume --json "$ARGUMENTS"`,将整个目标作为单一字面参数。

只使用返回的 `change`、`blockers` 和 `next_action`:存在 blocker 时停止并展示修复命令;否则通过 `workflow-start` 进入 `next_action` 指定的下一 skill。不要直接修改状态文件。
10 changes: 10 additions & 0 deletions commands/ssf/save.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---

description: 为一个 spec-superflow change 保存兼容 checkpoint
argument-hint: "<change-name-or-path> --task <id> --next <next-step>"
allowed-tools: Bash(npx:*)
---

只把 `$ARGUMENTS` 作为对话输入,从中提取明确的 change、task 和 next,以及用户明确提供的可选 evidence 字段。信息不足时先询问一次;不要编造 verification 或 review 证据。

确认参数后运行 `npx --yes --package spec-superflow@0.10.0 ssf save "<change>" --task "<task-id>" --next "<next-step>" [--completed "<completed>"] [--verification "<verification>"] [--review "<review>"] [--risk "<risk>"] [--commit-start "<commit-start>"] [--commit-end "<commit-end>"] --json`。每个值必须来自已提取或已确认的信息,并作为单独引用的字面参数传入。只报告 CLI 返回的 checkpoint 结果,并保留现有状态机和存储边界。
10 changes: 10 additions & 0 deletions commands/ssf/switch.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---

description: 切换当前对话关注的 spec-superflow change
argument-hint: "<change-name-or-path>"
allowed-tools: Bash(npx:*)
---

`$ARGUMENTS` 必须提供一个非空的 change 名称或路径;若未提供,先询问用户选择哪个 change。

确认目标非空后运行 `npx --yes --package spec-superflow@0.10.0 ssf switch --json "$ARGUMENTS"`,将整个目标作为单一字面参数。只使用返回的恢复上下文切换当前对话的关注对象。存在 blocker 时停止并展示修复命令;不得改变文件、工作目录或任何隐藏指针。
14 changes: 12 additions & 2 deletions docs/README_en.md
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,9 @@ npm install -g spec-superflow
| `ssf checkpoint save <dir> --task <id> --next <text>` | Save a task-level recovery checkpoint |
| `ssf checkpoint list <dir>` | List checkpoints and stale status |
| `ssf checkpoint show <dir> <id>` | Show one recovery checkpoint |
| `ssf resume [change]` | Read-only recovery summary; auto-selects the only active change |
| `ssf switch <change>` | Read-only recovery context for an explicit change; an adapter may use it to focus the current AI conversation |
| `ssf save <change> --task <id> --next <text>` | Manually reuses the existing checkpoint protocol; never commits, pushes, or syncs automatically |
| `ssf handoff create <dir> --type <type> ...` | Create a prototype/research/experiment handoff |
| `ssf handoff list <dir>` | List handoff lifecycle status |
| `ssf handoff finish <dir> <id>` | Validate a handoff result |
Expand Down Expand Up @@ -144,11 +147,17 @@ If `--platforms` is omitted, injection only proceeds when exactly one project ma
Session recovery and optional prototypes:

```bash
ssf resume # auto-select only when exactly one change is active
ssf resume changes/my-change # read-only summary for one explicit change
ssf switch changes/another-change # read-only recovery context for one explicit change
ssf save changes/my-change --task 1.1 --next "Run focused tests"
ssf checkpoint save changes/my-change --task 1.1 --next "Run focused tests"
ssf checkpoint list changes/my-change
ssf handoff create changes/my-change --type research --objective "Compare approaches" --expected-output "Recommendation" --acceptance "Evidence recorded"
```

`resume` and `switch` are read-only recovery operations; `resume` auto-selects a target only when exactly one active change exists. `switch` only returns the explicit target's recovery context and never changes cwd, a TUI session, or a hidden pointer; the CLI itself does not mutate conversation focus, while a CodeBuddy/WorkBuddy adapter or host agent may use that context to focus the conversation. `save` only manually reuses the existing checkpoint protocol; it never commits, pushes, or syncs automatically. `/ssf:resume`, `/ssf:switch`, and `/ssf:save` are Markdown command adapters for CodeBuddy/WorkBuddy that dispatch to the same CLI guards; other platforms are not promised identical slash names.

Prototype work starts only after explicit user confirmation. Backend, CLI,
configuration, and internal-refactor work does not enter the prototype route
automatically. Handoff results never edit `design.md` or `tasks.md` automatically.
Expand Down Expand Up @@ -276,8 +285,9 @@ non-symlink file.

Every planned wave needs a current `pass` review receipt before dependent
waves or closing may proceed; revising a plan invalidates earlier receipts.
The recovery, switching, and manual-save slash commands proposed in #47 are
not implemented, so this documentation does not claim `/ssf:*` commands.
Recovery, switching, and manual save form a control-plane overlay, not a ninth
workflow state; their CLI and CodeBuddy/WorkBuddy Markdown adapters keep the
same guards.

### Fast Paths (hotfix / tweak)

Expand Down
18 changes: 15 additions & 3 deletions docs/artifact-contract.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,9 +71,21 @@ required for every wave before dependent work or closing proceeds. `tweak` is
exempt from execution-plan and review-receipt gates. `ssf execution revise`
retains or upgrades an existing plan as `sdd`, requires fresh confirmation,
creates a new revision, and
clears prior review receipts; it never permits a downgrade. #47 slash commands for recovery,
switching, and manual save are not implemented, so `/ssf:*` commands must not
be claimed.
clears prior review receipts; it never permits a downgrade.

### Recovery control-plane overlay

Recovery commands operate beside the eight-state workflow, without creating a
ninth state or a new transition. `ssf resume [change-dir]` and `ssf switch
<change-dir>` are read-only: resume returns a recovery summary and chooses a
target automatically only when there is one active change; switch returns the
explicit target's recovery context and never changes cwd, a TUI session, or a
hidden pointer. Its CodeBuddy/WorkBuddy adapter may use that context to focus a
conversation. `ssf save <change-dir> --task <id> --next <text>` manually writes a
compatible checkpoint through the existing checkpoint save protocol. It never
commits, pushes, or syncs automatically. `/ssf:resume`, `/ssf:switch`, and
`/ssf:save` are CodeBuddy/WorkBuddy Markdown command adapters that dispatch to
the same CLI guards; other platforms are not promised identical slash names.

## Mapping

Expand Down
34 changes: 33 additions & 1 deletion docs/release-checklist.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ Use this checklist before publishing a new version of `spec-superflow`.
- templates reflect the current workflow expectations
- `docs/artifact-contract.md` matches the templates and skills
- `docs/state-machine.md` matches the actual workflow routing model
- Recovery remains a control-plane overlay: resume/switch are read-only, save writes only the compatible checkpoint, and no ninth state is documented.
- examples still demonstrate the documented workflow

## Example Quality
Expand All @@ -46,7 +47,38 @@ For each example in `docs/examples/`:
- `node scripts/spec-superflow.mjs version <version> --dry-run` — reports all files in sync
- `node scripts/check-version-consistency.mjs` — exits 0
- `node scripts/spec-superflow.mjs --help` — all subcommands listed
- `node scripts/spec-superflow.mjs install-workbuddy --dry-run` — finds all 9 skills and target paths
- Verify `commands/ssf/resume.md`, `commands/ssf/switch.md`, and `commands/ssf/save.md` are complete canonical Markdown command assets.
- `node --test tests/lib/recovery-command-assets.test.mjs` — scans every command asset for checkout-specific absolute paths; any failure is a release blocker.
- `node scripts/spec-superflow.mjs install-workbuddy --dry-run` — finds all 9 skills, all 3 recovery commands, and target paths.
- Run `install-workbuddy` against a temporary home and verify it installs `ssf:resume`, `ssf:switch`, and `ssf:save` as complete command assets.

```bash
# Local release-candidate smoke: never writes ~/.workbuddy or downloads latest.
SSF_WORKBUDDY_SMOKE_HOME="$(mktemp -d)"
if grep -R -F "$PWD/" commands/ssf; then
echo "Canonical command assets contain the local checkout path" >&2
exit 1
fi
node scripts/spec-superflow.mjs install-workbuddy --local "$PWD" --home "$SSF_WORKBUDDY_SMOKE_HOME"
SSF_WORKBUDDY_PLUGIN="$SSF_WORKBUDDY_SMOKE_HOME/.workbuddy/plugins/marketplaces/cb_teams_marketplace/plugins/spec-superflow"
test -f "$SSF_WORKBUDDY_PLUGIN/commands/ssf/resume.md"
test -f "$SSF_WORKBUDDY_PLUGIN/commands/ssf/switch.md"
test -f "$SSF_WORKBUDDY_PLUGIN/commands/ssf/save.md"
if grep -R -F "$PWD/" "$SSF_WORKBUDDY_PLUGIN/commands/ssf"; then
echo "Installed command assets contain the local checkout path" >&2
exit 1
fi
test "$(find "$SSF_WORKBUDDY_PLUGIN/skills" -mindepth 1 -maxdepth 1 -type d | wc -l | tr -d ' ')" = 9
test -d "$SSF_WORKBUDDY_PLUGIN/scripts"
test -d "$SSF_WORKBUDDY_PLUGIN/docs"
test -d "$SSF_WORKBUDDY_PLUGIN/templates"
test -d "$SSF_WORKBUDDY_PLUGIN/dist"
test -d "$SSF_WORKBUDDY_PLUGIN/hooks"
test -f "$SSF_WORKBUDDY_PLUGIN/rules/phase-guard.md"
test -f "$SSF_WORKBUDDY_PLUGIN/.codebuddy-plugin/plugin.json"
node --input-type=module -e 'import { readFileSync } from "node:fs"; const settings = JSON.parse(readFileSync(process.argv[1], "utf8")); if (settings.enabledPlugins?.["spec-superflow@cb_teams_marketplace"] !== true) throw new Error("WorkBuddy plugin is not enabled");' "$SSF_WORKBUDDY_SMOKE_HOME/.workbuddy/settings.json"
node --test tests/lib/cmd-install-workbuddy.test.mjs
```
- `npm run test:raw-mode` — packs the current source and runs a canonical runtime in an empty directory with no plugin-root variables or global `ssf`.
- Run a representative local-installer smoke test.
- `spec-superflow.config.json` absence still works (backward compatible defaults)
Expand Down
14 changes: 12 additions & 2 deletions docs/state-machine.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,9 @@ are eligible. Each completed wave must have a current
wave or `closing` can proceed. `ssf execution revise` retains or upgrades an
existing plan as `sdd`; that new revision requires a fresh confirmation (and
acknowledgement when it differs from the new recommendation), invalidates old
review receipts, and does not permit a downgrade. #47 recovery/switch/save
slash commands are not implemented; do not assume `/ssf:*` commands exist.
review receipts, and does not permit a downgrade. Recovery, switching, and
manual save are a control-plane overlay; they do not create a ninth workflow
state.

### `debugging`

Expand Down Expand Up @@ -96,6 +97,12 @@ Checkpoints, handoffs, and prototypes are durable overlays, not workflow states.
They do not add transitions to the state machine or change the meaning of the
eight core states.

- `ssf resume [change-dir]` is read-only and returns a recovery summary. With no
target, it auto-selects only the unique active change.
- `ssf switch <change-dir>` is read-only and returns the explicit target's
recovery context; it never changes cwd, a TUI session, or a hidden pointer.
- `ssf save <change-dir> --task <id> --next <text>` manually writes a compatible
checkpoint. It never commits, pushes, or syncs automatically.
- `ssf checkpoint save <change-dir> --task <id> --next <text>` records task-level
recovery context under `.superpowers/sdd/checkpoints/`.
- `ssf handoff create <change-dir> --type <type> ...` creates explicit side-work
Expand All @@ -105,6 +112,9 @@ eight core states.
审查和 resolve;stale checkpoint 仅保留为历史证据。
- Prototype work is optional and requires explicit user confirmation. Results
are reviewed manually and never mutate `design.md` or `tasks.md`.
- `/ssf:resume`, `/ssf:switch`, and `/ssf:save` are CodeBuddy/WorkBuddy Markdown
command adapters for these CLI guards. The switch adapter may use its returned
context to focus a conversation; these names are not promised on every platform.

## Transitions

Expand Down
Loading
Loading