@sienklogic/plan-build-run 2.19.0 → 2.21.0

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 (28) hide show
  1. package/CHANGELOG.md +22 -0
  2. package/package.json +1 -1
  3. package/plugins/copilot-pbr/hooks/hooks.json +102 -0
  4. package/plugins/copilot-pbr/plugin.json +1 -1
  5. package/plugins/copilot-pbr/skills/discuss/SKILL.md +1 -1
  6. package/plugins/copilot-pbr/skills/help/SKILL.md +23 -0
  7. package/plugins/copilot-pbr/skills/milestone/SKILL.md +61 -0
  8. package/plugins/copilot-pbr/skills/shared/error-recovery-strategies.md +51 -0
  9. package/plugins/cursor-pbr/.cursor-plugin/plugin.json +1 -1
  10. package/plugins/cursor-pbr/hooks/hooks.json +11 -0
  11. package/plugins/cursor-pbr/skills/discuss/SKILL.md +1 -1
  12. package/plugins/cursor-pbr/skills/help/SKILL.md +23 -0
  13. package/plugins/cursor-pbr/skills/milestone/SKILL.md +61 -0
  14. package/plugins/cursor-pbr/skills/shared/error-recovery-strategies.md +51 -0
  15. package/plugins/pbr/.claude-plugin/plugin.json +1 -1
  16. package/plugins/pbr/agents/plan-checker.md +1 -0
  17. package/plugins/pbr/agents/verifier.md +1 -0
  18. package/plugins/pbr/hooks/hooks.json +11 -0
  19. package/plugins/pbr/scripts/auto-continue.js +9 -3
  20. package/plugins/pbr/scripts/check-config-change.js +130 -0
  21. package/plugins/pbr/scripts/check-roadmap-sync.js +8 -2
  22. package/plugins/pbr/scripts/hooks-schema.json +1 -0
  23. package/plugins/pbr/scripts/progress-tracker.js +19 -4
  24. package/plugins/pbr/scripts/track-context-budget.js +5 -0
  25. package/plugins/pbr/skills/discuss/SKILL.md +1 -1
  26. package/plugins/pbr/skills/help/SKILL.md +23 -0
  27. package/plugins/pbr/skills/milestone/SKILL.md +61 -0
  28. package/plugins/pbr/skills/shared/error-recovery-strategies.md +51 -0
package/CHANGELOG.md CHANGED
@@ -5,6 +5,28 @@ All notable changes to Plan-Build-Run will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [2.21.0](https://github.com/SienkLogic/plan-build-run/compare/plan-build-run-v2.20.0...plan-build-run-v2.21.0) (2026-02-23)
9
+
10
+
11
+ ### Features
12
+
13
+ * **tools:** add help docs, concurrent tests, and discuss requirements surfacing ([02e9cc9](https://github.com/SienkLogic/plan-build-run/commit/02e9cc997d5b7d1aed3fc43cd8f8160c6e08d78b))
14
+ * **tools:** add milestone preview subcommand across all plugins ([fa6dca7](https://github.com/SienkLogic/plan-build-run/commit/fa6dca75d78adc952a5ffffd92baf17d8dd23e8e))
15
+ * **tools:** resolve exploration backlog — fix script bugs, add copilot hooks, improve recovery ([8a956dd](https://github.com/SienkLogic/plan-build-run/commit/8a956dd33a7182c402307d5569e0d8d37dbdaf1c))
16
+
17
+
18
+ ### Bug Fixes
19
+
20
+ * **tools:** handle concurrent write corruption in flaky test across platforms ([e4e9b4d](https://github.com/SienkLogic/plan-build-run/commit/e4e9b4d524e5c08665b72a3c99555452f8e09089))
21
+ * **tools:** handle empty string race in concurrent .active-skill test on Windows ([9cb294a](https://github.com/SienkLogic/plan-build-run/commit/9cb294a1c7db67c1fe80d9672d4580c8951011c4))
22
+
23
+ ## [2.20.0](https://github.com/SienkLogic/plan-build-run/compare/plan-build-run-v2.19.0...plan-build-run-v2.20.0) (2026-02-23)
24
+
25
+
26
+ ### Features
27
+
28
+ * **tools:** add worktree isolation, ConfigChange hook, and claude agents docs ([d704f34](https://github.com/SienkLogic/plan-build-run/commit/d704f340c636fa41f988d27a661a1e1918b04c87))
29
+
8
30
  ## [2.19.0](https://github.com/SienkLogic/plan-build-run/compare/plan-build-run-v2.18.1...plan-build-run-v2.19.0) (2026-02-22)
9
31
 
10
32
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sienklogic/plan-build-run",
3
- "version": "2.19.0",
3
+ "version": "2.21.0",
4
4
  "description": "Plan it, Build it, Run it — structured development workflow for Claude Code",
5
5
  "keywords": [
6
6
  "claude-code",
@@ -139,6 +139,108 @@
139
139
  ]
140
140
  }
141
141
  ],
142
+ "postToolUseFailure": [
143
+ {
144
+ "hooks": [
145
+ {
146
+ "type": "command",
147
+ "bash": "node \"$(cd \"$(dirname \"$0\")\" && pwd)/../../pbr/scripts/run-hook.js\" log-tool-failure.js",
148
+ "powershell": "node (Join-Path (Split-Path -Parent $PSScriptRoot) 'pbr\\scripts\\run-hook.js') log-tool-failure.js",
149
+ "cwd": ".",
150
+ "timeoutSec": 15
151
+ }
152
+ ]
153
+ }
154
+ ],
155
+ "preCompact": [
156
+ {
157
+ "hooks": [
158
+ {
159
+ "type": "command",
160
+ "bash": "node \"$(cd \"$(dirname \"$0\")\" && pwd)/../../pbr/scripts/run-hook.js\" context-budget-check.js",
161
+ "powershell": "node (Join-Path (Split-Path -Parent $PSScriptRoot) 'pbr\\scripts\\run-hook.js') context-budget-check.js",
162
+ "cwd": ".",
163
+ "timeoutSec": 15
164
+ }
165
+ ]
166
+ }
167
+ ],
168
+ "stop": [
169
+ {
170
+ "hooks": [
171
+ {
172
+ "type": "command",
173
+ "bash": "node \"$(cd \"$(dirname \"$0\")\" && pwd)/../../pbr/scripts/run-hook.js\" auto-continue.js",
174
+ "powershell": "node (Join-Path (Split-Path -Parent $PSScriptRoot) 'pbr\\scripts\\run-hook.js') auto-continue.js",
175
+ "cwd": ".",
176
+ "timeoutSec": 15
177
+ }
178
+ ]
179
+ }
180
+ ],
181
+ "subagentStart": [
182
+ {
183
+ "hooks": [
184
+ {
185
+ "type": "command",
186
+ "bash": "node \"$(cd \"$(dirname \"$0\")\" && pwd)/../../pbr/scripts/run-hook.js\" log-subagent.js start",
187
+ "powershell": "node (Join-Path (Split-Path -Parent $PSScriptRoot) 'pbr\\scripts\\run-hook.js') log-subagent.js start",
188
+ "cwd": ".",
189
+ "timeoutSec": 15
190
+ }
191
+ ]
192
+ }
193
+ ],
194
+ "subagentStop": [
195
+ {
196
+ "hooks": [
197
+ {
198
+ "type": "command",
199
+ "bash": "node \"$(cd \"$(dirname \"$0\")\" && pwd)/../../pbr/scripts/run-hook.js\" log-subagent.js stop",
200
+ "powershell": "node (Join-Path (Split-Path -Parent $PSScriptRoot) 'pbr\\scripts\\run-hook.js') log-subagent.js stop",
201
+ "cwd": ".",
202
+ "timeoutSec": 15
203
+ }
204
+ ]
205
+ },
206
+ {
207
+ "hooks": [
208
+ {
209
+ "type": "command",
210
+ "bash": "node \"$(cd \"$(dirname \"$0\")\" && pwd)/../../pbr/scripts/run-hook.js\" event-handler.js",
211
+ "powershell": "node (Join-Path (Split-Path -Parent $PSScriptRoot) 'pbr\\scripts\\run-hook.js') event-handler.js",
212
+ "cwd": ".",
213
+ "timeoutSec": 15
214
+ }
215
+ ]
216
+ }
217
+ ],
218
+ "taskCompleted": [
219
+ {
220
+ "hooks": [
221
+ {
222
+ "type": "command",
223
+ "bash": "node \"$(cd \"$(dirname \"$0\")\" && pwd)/../../pbr/scripts/run-hook.js\" task-completed.js",
224
+ "powershell": "node (Join-Path (Split-Path -Parent $PSScriptRoot) 'pbr\\scripts\\run-hook.js') task-completed.js",
225
+ "cwd": ".",
226
+ "timeoutSec": 15
227
+ }
228
+ ]
229
+ }
230
+ ],
231
+ "configChange": [
232
+ {
233
+ "hooks": [
234
+ {
235
+ "type": "command",
236
+ "bash": "node \"$(cd \"$(dirname \"$0\")\" && pwd)/../../pbr/scripts/run-hook.js\" check-config-change.js",
237
+ "powershell": "node (Join-Path (Split-Path -Parent $PSScriptRoot) 'pbr\\scripts\\run-hook.js') check-config-change.js",
238
+ "cwd": ".",
239
+ "timeoutSec": 15
240
+ }
241
+ ]
242
+ }
243
+ ],
142
244
  "sessionEnd": [
143
245
  {
144
246
  "hooks": [
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "pbr",
3
3
  "displayName": "Plan-Build-Run",
4
- "version": "2.19.0",
4
+ "version": "2.21.0",
5
5
  "description": "Plan-Build-Run — Structured development workflow for GitHub Copilot CLI. Solves context rot through disciplined agent delegation, structured planning, atomic execution, and goal-backward verification.",
6
6
  "author": {
7
7
  "name": "SienkLogic",
@@ -78,7 +78,7 @@ Read the following files to understand what this phase needs to accomplish:
78
78
  - What patterns have been established (`patterns` field)
79
79
  - What decisions were already made (`key_decisions` field)
80
80
 
81
- 3. **REQUIREMENTS.md** (if exists) — Read project requirements relevant to this phase
81
+ 3. **REQUIREMENTS.md** (if exists) — Read project requirements relevant to this phase. **CRITICAL**: After reading, display to the user which specific requirements map to this phase. Flag any requirements that could constrain decisions. If the user's discussion decisions later contradict a stated requirement, surface the contradiction immediately — don't wait until planning.
82
82
 
83
83
  4. **CONTEXT.md** (if exists in the phase directory) — Check if a prior discussion already happened
84
84
  - If CONTEXT.md exists, inform the user and use the **context-handling** pattern from `skills/shared/gate-prompts.md`:
@@ -91,6 +91,7 @@ Display the following reference to the user:
91
91
  |---------|-------------|
92
92
  | `/pbr:milestone new` | Start a new milestone cycle. |
93
93
  | `/pbr:milestone complete` | Archive completed milestone. |
94
+ | `/pbr:milestone preview` | Dry-run of complete — show what would happen. |
94
95
  | `/pbr:milestone audit` | Verify milestone completion. |
95
96
  | `/pbr:milestone gaps` | Create phases to close audit gaps. |
96
97
  | `/pbr:todo add\|list\|done` | Persistent file-based todos. |
@@ -135,6 +136,7 @@ Display the following reference to the user:
135
136
  - **Depth**: `quick` (skip research, ~50% cheaper) | `standard` | `comprehensive` (~2x cost)
136
137
  - **State files**: `.planning/STATE.md` (position), `.planning/ROADMAP.md` (phases), `.planning/config.json` (settings)
137
138
  - **Configure**: `/pbr:config` to change depth, models, gates, parallelization
139
+ - **List agents**: Run `claude agents` in your terminal to see all registered PBR agents and verify loading
138
140
  - **Tip**: Use `/pbr:quick` for creative/visual work where structured planning adds overhead without benefit.
139
141
  - **PR hygiene**: When creating PRs from a Plan-Build-Run project, `.planning/` commits can be filtered using phase branching (`git.branching: phase`) which squash-merges code-only changes to main.
140
142
  - **Seeds**: `/pbr:explore` can create seed files (`.planning/seeds/`) with trigger conditions. Seeds auto-inject into planning when their trigger phase is reached.
@@ -149,6 +151,27 @@ Plan-Build-Run includes three behavioral contexts in `contexts/` that adjust how
149
151
 
150
152
  Skills automatically activate the appropriate context: `/pbr:build` uses dev context, `/pbr:discuss` uses research context, `/pbr:review` uses review context.
151
153
 
154
+ ## When to Use Quick vs Plan+Build
155
+
156
+ | Use `/pbr:quick` when... | Use `/pbr:plan` + `/pbr:build` when... |
157
+ |--------------------------|----------------------------------------|
158
+ | Change touches ≤3 files | Change touches 4+ files |
159
+ | ≤100 lines of code | 100+ lines of code |
160
+ | Single subsystem | Multiple subsystems or cross-cutting |
161
+ | No architectural decisions | Requires design choices |
162
+ | Bug fix, small feature, docs | New feature, refactor, migration |
163
+
164
+ ## Setup vs Begin
165
+
166
+ - **`/pbr:begin`** — Use this to start a new project. It handles everything: questioning, research, requirements, roadmap, AND config initialization. This is the standard entry point.
167
+ - **`/pbr:setup`** — Use this only to reconfigure an existing project's settings (model profiles, gates, depth, parallelization) without re-running the full begin flow.
168
+
169
+ If you're unsure, start with `/pbr:begin`. It will detect existing config and offer to reuse or overwrite.
170
+
171
+ ## Team Discussions
172
+
173
+ The `features.team_discussions` config flag (and `/pbr:build --team`) enables **Agent Teams** for complex builds. When enabled, executor agents can coordinate with each other during parallel wave execution — sharing context about what they've built, resolving interface conflicts, and avoiding duplicate work. Best for phases where multiple plans have shared dependencies. Configure via `/pbr:config`.
174
+
152
175
  ## Getting Started
153
176
 
154
177
  ```
@@ -52,6 +52,7 @@ Examples:
52
52
  "new User Auth" → subcommand=new, arg="User Auth"
53
53
  "complete v1.0" → subcommand=complete, arg="v1.0"
54
54
  "complete 1.0" → subcommand=complete, arg="v1.0" (auto-prefix v)
55
+ "preview v1.0" → subcommand=preview, arg="v1.0"
55
56
  "audit v1.0" → subcommand=audit, arg="v1.0"
56
57
  "audit" → subcommand=audit, arg=current milestone
57
58
  "gaps" → subcommand=gaps, arg=most recent audit
@@ -64,6 +65,7 @@ Usage: /pbr:milestone <subcommand> [version]
64
65
  Subcommands:
65
66
  new [name] — Start a new milestone cycle
66
67
  complete [ver] — Archive completed milestone
68
+ preview [ver] — Dry-run of complete (show what would happen)
67
69
  audit [ver] — Verify milestone completion
68
70
  gaps — Create phases to close audit gaps
69
71
  ```
@@ -189,6 +191,65 @@ Start a new milestone cycle with new phases.
189
191
 
190
192
  ---
191
193
 
194
+ ## Subcommand: `preview`
195
+
196
+ Dry-run of milestone completion — shows what would happen without making any changes.
197
+
198
+ ### Flow
199
+
200
+ 1. **Determine version:**
201
+ - Same logic as `complete`: use `$ARGUMENTS` or ask via AskUserQuestion
202
+
203
+ 2. **Identify milestone phases:**
204
+ - Read ROADMAP.md to find phases belonging to this milestone
205
+ - List each phase with its current status (from STATE.md or VERIFICATION.md)
206
+
207
+ 3. **Verification status check:**
208
+ - For each milestone phase, check if VERIFICATION.md exists and its `result` frontmatter
209
+ - Flag phases that are unverified or have stale verification (SUMMARY.md newer than VERIFICATION.md)
210
+
211
+ 4. **Preview archive structure:**
212
+ - Show what the archive directory would look like:
213
+ ```
214
+ .planning/milestones/v{version}/
215
+ ├── ROADMAP.md (snapshot)
216
+ ├── STATS.md (would be generated)
217
+ ├── REQUIREMENTS.md (snapshot)
218
+ └── phases/
219
+ ├── {NN}-{slug}/ (moved from .planning/phases/)
220
+ │ ├── PLAN-01.md
221
+ │ ├── SUMMARY.md
222
+ │ └── VERIFICATION.md
223
+ └── ...
224
+ ```
225
+
226
+ 5. **Show what would change:**
227
+ - Which phase directories would be moved
228
+ - What ROADMAP.md section would be collapsed
229
+ - What STATE.md updates would occur
230
+ - What git tag would be created
231
+
232
+ 6. **Display summary:**
233
+ ```
234
+ ╔══════════════════════════════════════════════════════════════╗
235
+ ║ MILESTONE PREVIEW — v{version} ║
236
+ ╚══════════════════════════════════════════════════════════════╝
237
+
238
+ Phases to archive: {count}
239
+ ✓ Verified: {verified_count}
240
+ ⚠ Unverified: {unverified_count}
241
+ ⚠ Stale verification: {stale_count}
242
+
243
+ Archive location: .planning/milestones/v{version}/
244
+ Git tag: v{version}
245
+
246
+ Ready to complete? Run: /pbr:milestone complete v{version}
247
+ ```
248
+
249
+ **CRITICAL**: This subcommand is READ-ONLY. Do not create directories, move files, modify STATE.md, modify ROADMAP.md, or create git tags. Only read and display.
250
+
251
+ ---
252
+
192
253
  ## Subcommand: `complete`
193
254
 
194
255
  Archive a completed milestone and prepare for the next one.
@@ -0,0 +1,51 @@
1
+ # Error Recovery Strategies Fragment
2
+
3
+ Standard recovery patterns for skills and agents when operations fail. Reference `error-reporting.md` for display formats.
4
+
5
+ ## Strategy 1: Retry with Backoff
6
+
7
+ For transient failures (file locks, network timeouts, tool failures):
8
+
9
+ 1. Wait briefly, then retry the same operation (max 2 retries)
10
+ 2. If still failing after retries, fall through to Strategy 2
11
+
12
+ Use for: git operations, file writes blocked by antivirus, API calls.
13
+
14
+ ## Strategy 2: Degrade Gracefully
15
+
16
+ When a non-critical step fails, skip it and continue:
17
+
18
+ 1. Log a warning using the recoverable error format
19
+ 2. Note the skipped step in SUMMARY.md `deferred` field
20
+ 3. Continue with remaining work
21
+
22
+ Use for: optional validations, dashboard launch, hook logger writes, note/todo updates.
23
+
24
+ ## Strategy 3: Escalate to User
25
+
26
+ When a critical step fails and no automated fix exists:
27
+
28
+ 1. Display the fatal error format with actionable suggestions
29
+ 2. Do NOT attempt workarounds that could corrupt state
30
+ 3. Suggest `/pbr:health` as the first diagnostic step
31
+ 4. If in an agent context, return the error in the agent's output so the orchestrator can relay it
32
+
33
+ Use for: STATE.md corruption, missing phase directories, config parse failures, git conflicts.
34
+
35
+ ## Strategy 4: Checkpoint and Abort
36
+
37
+ When a multi-step operation partially fails:
38
+
39
+ 1. Commit any completed work (don't lose progress)
40
+ 2. Update STATE.md with accurate status (not the target status)
41
+ 3. Write a `.continue-here.md` breadcrumb if mid-phase
42
+ 4. Report what completed and what remains
43
+
44
+ Use for: build phase with mixed plan results, verification with partial failures.
45
+
46
+ ## Anti-Patterns
47
+
48
+ - **Never silently swallow errors** in catch blocks — at minimum call `logHook()` with the error message
49
+ - **Never retry destructive operations** (deletes, force-pushes, state resets)
50
+ - **Never auto-fix by deleting user artifacts** — only delete PBR internal state files (.active-skill, .context-tracker, .auto-next)
51
+ - **Never continue building after STATE.md write failure** — state integrity is non-negotiable
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "pbr",
3
3
  "displayName": "Plan-Build-Run",
4
- "version": "2.19.0",
4
+ "version": "2.21.0",
5
5
  "description": "Plan-Build-Run — Structured development workflow for Cursor. Solves context rot through disciplined subagent delegation, structured planning, atomic execution, and goal-backward verification.",
6
6
  "author": {
7
7
  "name": "SienkLogic",
@@ -196,6 +196,17 @@
196
196
  ]
197
197
  }
198
198
  ],
199
+ "ConfigChange": [
200
+ {
201
+ "hooks": [
202
+ {
203
+ "type": "command",
204
+ "command": "node -e \"var r=process.env.CLAUDE_PLUGIN_ROOT||'',m=r.match(/^\\/([a-zA-Z])\\/(.*)/);if(m)r=m[1]+String.fromCharCode(58)+String.fromCharCode(92)+m[2];require(require('path').resolve(r,'..','pbr','scripts','run-hook.js'))\" check-config-change.js",
205
+ "statusMessage": "Validating configuration..."
206
+ }
207
+ ]
208
+ }
209
+ ],
199
210
  "SessionEnd": [
200
211
  {
201
212
  "hooks": [
@@ -79,7 +79,7 @@ Read the following files to understand what this phase needs to accomplish:
79
79
  - What patterns have been established (`patterns` field)
80
80
  - What decisions were already made (`key_decisions` field)
81
81
 
82
- 3. **REQUIREMENTS.md** (if exists) — Read project requirements relevant to this phase
82
+ 3. **REQUIREMENTS.md** (if exists) — Read project requirements relevant to this phase. **CRITICAL**: After reading, display to the user which specific requirements map to this phase. Flag any requirements that could constrain decisions. If the user's discussion decisions later contradict a stated requirement, surface the contradiction immediately — don't wait until planning.
83
83
 
84
84
  4. **CONTEXT.md** (if exists in the phase directory) — Check if a prior discussion already happened
85
85
  - If CONTEXT.md exists, inform the user and use the **context-handling** pattern from `skills/shared/gate-prompts.md`:
@@ -91,6 +91,7 @@ Display the following reference to the user:
91
91
  |---------|-------------|
92
92
  | `/pbr:milestone new` | Start a new milestone cycle. |
93
93
  | `/pbr:milestone complete` | Archive completed milestone. |
94
+ | `/pbr:milestone preview` | Dry-run of complete — show what would happen. |
94
95
  | `/pbr:milestone audit` | Verify milestone completion. |
95
96
  | `/pbr:milestone gaps` | Create phases to close audit gaps. |
96
97
  | `/pbr:todo add\|list\|done` | Persistent file-based todos. |
@@ -135,6 +136,7 @@ Display the following reference to the user:
135
136
  - **Depth**: `quick` (skip research, ~50% cheaper) | `standard` | `comprehensive` (~2x cost)
136
137
  - **State files**: `.planning/STATE.md` (position), `.planning/ROADMAP.md` (phases), `.planning/config.json` (settings)
137
138
  - **Configure**: `/pbr:config` to change depth, models, gates, parallelization
139
+ - **List agents**: Run `claude agents` in your terminal to see all registered PBR agents and verify loading
138
140
  - **Tip**: Use `/pbr:quick` for creative/visual work where structured planning adds overhead without benefit.
139
141
  - **PR hygiene**: When creating PRs from a Plan-Build-Run project, `.planning/` commits can be filtered using phase branching (`git.branching: phase`) which squash-merges code-only changes to main.
140
142
  - **Seeds**: `/pbr:explore` can create seed files (`.planning/seeds/`) with trigger conditions. Seeds auto-inject into planning when their trigger phase is reached.
@@ -149,6 +151,27 @@ Plan-Build-Run includes three behavioral contexts in `contexts/` that adjust how
149
151
 
150
152
  Skills automatically activate the appropriate context: `/pbr:build` uses dev context, `/pbr:discuss` uses research context, `/pbr:review` uses review context.
151
153
 
154
+ ## When to Use Quick vs Plan+Build
155
+
156
+ | Use `/pbr:quick` when... | Use `/pbr:plan` + `/pbr:build` when... |
157
+ |--------------------------|----------------------------------------|
158
+ | Change touches ≤3 files | Change touches 4+ files |
159
+ | ≤100 lines of code | 100+ lines of code |
160
+ | Single subsystem | Multiple subsystems or cross-cutting |
161
+ | No architectural decisions | Requires design choices |
162
+ | Bug fix, small feature, docs | New feature, refactor, migration |
163
+
164
+ ## Setup vs Begin
165
+
166
+ - **`/pbr:begin`** — Use this to start a new project. It handles everything: questioning, research, requirements, roadmap, AND config initialization. This is the standard entry point.
167
+ - **`/pbr:setup`** — Use this only to reconfigure an existing project's settings (model profiles, gates, depth, parallelization) without re-running the full begin flow.
168
+
169
+ If you're unsure, start with `/pbr:begin`. It will detect existing config and offer to reuse or overwrite.
170
+
171
+ ## Team Discussions
172
+
173
+ The `features.team_discussions` config flag (and `/pbr:build --team`) enables **Agent Teams** for complex builds. When enabled, executor agents can coordinate with each other during parallel wave execution — sharing context about what they've built, resolving interface conflicts, and avoiding duplicate work. Best for phases where multiple plans have shared dependencies. Configure via `/pbr:config`.
174
+
152
175
  ## Getting Started
153
176
 
154
177
  ```
@@ -53,6 +53,7 @@ Examples:
53
53
  "new User Auth" → subcommand=new, arg="User Auth"
54
54
  "complete v1.0" → subcommand=complete, arg="v1.0"
55
55
  "complete 1.0" → subcommand=complete, arg="v1.0" (auto-prefix v)
56
+ "preview v1.0" → subcommand=preview, arg="v1.0"
56
57
  "audit v1.0" → subcommand=audit, arg="v1.0"
57
58
  "audit" → subcommand=audit, arg=current milestone
58
59
  "gaps" → subcommand=gaps, arg=most recent audit
@@ -65,6 +66,7 @@ Usage: /pbr:milestone <subcommand> [version]
65
66
  Subcommands:
66
67
  new [name] — Start a new milestone cycle
67
68
  complete [ver] — Archive completed milestone
69
+ preview [ver] — Dry-run of complete (show what would happen)
68
70
  audit [ver] — Verify milestone completion
69
71
  gaps — Create phases to close audit gaps
70
72
  ```
@@ -190,6 +192,65 @@ Start a new milestone cycle with new phases.
190
192
 
191
193
  ---
192
194
 
195
+ ## Subcommand: `preview`
196
+
197
+ Dry-run of milestone completion — shows what would happen without making any changes.
198
+
199
+ ### Flow
200
+
201
+ 1. **Determine version:**
202
+ - Same logic as `complete`: use `$ARGUMENTS` or ask via AskUserQuestion
203
+
204
+ 2. **Identify milestone phases:**
205
+ - Read ROADMAP.md to find phases belonging to this milestone
206
+ - List each phase with its current status (from STATE.md or VERIFICATION.md)
207
+
208
+ 3. **Verification status check:**
209
+ - For each milestone phase, check if VERIFICATION.md exists and its `result` frontmatter
210
+ - Flag phases that are unverified or have stale verification (SUMMARY.md newer than VERIFICATION.md)
211
+
212
+ 4. **Preview archive structure:**
213
+ - Show what the archive directory would look like:
214
+ ```
215
+ .planning/milestones/v{version}/
216
+ ├── ROADMAP.md (snapshot)
217
+ ├── STATS.md (would be generated)
218
+ ├── REQUIREMENTS.md (snapshot)
219
+ └── phases/
220
+ ├── {NN}-{slug}/ (moved from .planning/phases/)
221
+ │ ├── PLAN-01.md
222
+ │ ├── SUMMARY.md
223
+ │ └── VERIFICATION.md
224
+ └── ...
225
+ ```
226
+
227
+ 5. **Show what would change:**
228
+ - Which phase directories would be moved
229
+ - What ROADMAP.md section would be collapsed
230
+ - What STATE.md updates would occur
231
+ - What git tag would be created
232
+
233
+ 6. **Display summary:**
234
+ ```
235
+ ╔══════════════════════════════════════════════════════════════╗
236
+ ║ MILESTONE PREVIEW — v{version} ║
237
+ ╚══════════════════════════════════════════════════════════════╝
238
+
239
+ Phases to archive: {count}
240
+ ✓ Verified: {verified_count}
241
+ ⚠ Unverified: {unverified_count}
242
+ ⚠ Stale verification: {stale_count}
243
+
244
+ Archive location: .planning/milestones/v{version}/
245
+ Git tag: v{version}
246
+
247
+ Ready to complete? Run: /pbr:milestone complete v{version}
248
+ ```
249
+
250
+ **CRITICAL**: This subcommand is READ-ONLY. Do not create directories, move files, modify STATE.md, modify ROADMAP.md, or create git tags. Only read and display.
251
+
252
+ ---
253
+
193
254
  ## Subcommand: `complete`
194
255
 
195
256
  Archive a completed milestone and prepare for the next one.
@@ -0,0 +1,51 @@
1
+ # Error Recovery Strategies Fragment
2
+
3
+ Standard recovery patterns for skills and agents when operations fail. Reference `error-reporting.md` for display formats.
4
+
5
+ ## Strategy 1: Retry with Backoff
6
+
7
+ For transient failures (file locks, network timeouts, tool failures):
8
+
9
+ 1. Wait briefly, then retry the same operation (max 2 retries)
10
+ 2. If still failing after retries, fall through to Strategy 2
11
+
12
+ Use for: git operations, file writes blocked by antivirus, API calls.
13
+
14
+ ## Strategy 2: Degrade Gracefully
15
+
16
+ When a non-critical step fails, skip it and continue:
17
+
18
+ 1. Log a warning using the recoverable error format
19
+ 2. Note the skipped step in SUMMARY.md `deferred` field
20
+ 3. Continue with remaining work
21
+
22
+ Use for: optional validations, dashboard launch, hook logger writes, note/todo updates.
23
+
24
+ ## Strategy 3: Escalate to User
25
+
26
+ When a critical step fails and no automated fix exists:
27
+
28
+ 1. Display the fatal error format with actionable suggestions
29
+ 2. Do NOT attempt workarounds that could corrupt state
30
+ 3. Suggest `/pbr:health` as the first diagnostic step
31
+ 4. If in an agent context, return the error in the agent's output so the orchestrator can relay it
32
+
33
+ Use for: STATE.md corruption, missing phase directories, config parse failures, git conflicts.
34
+
35
+ ## Strategy 4: Checkpoint and Abort
36
+
37
+ When a multi-step operation partially fails:
38
+
39
+ 1. Commit any completed work (don't lose progress)
40
+ 2. Update STATE.md with accurate status (not the target status)
41
+ 3. Write a `.continue-here.md` breadcrumb if mid-phase
42
+ 4. Report what completed and what remains
43
+
44
+ Use for: build phase with mixed plan results, verification with partial failures.
45
+
46
+ ## Anti-Patterns
47
+
48
+ - **Never silently swallow errors** in catch blocks — at minimum call `logHook()` with the error message
49
+ - **Never retry destructive operations** (deletes, force-pushes, state resets)
50
+ - **Never auto-fix by deleting user artifacts** — only delete PBR internal state files (.active-skill, .context-tracker, .auto-next)
51
+ - **Never continue building after STATE.md write failure** — state integrity is non-negotiable
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pbr",
3
- "version": "2.19.0",
3
+ "version": "2.21.0",
4
4
  "description": "Plan-Build-Run — Structured development workflow for Claude Code. Solves context rot through disciplined subagent delegation, structured planning, atomic execution, and goal-backward verification.",
5
5
  "author": {
6
6
  "name": "SienkLogic",
@@ -3,6 +3,7 @@ name: plan-checker
3
3
  description: "Verifies plans will achieve phase goals before execution. Goal-backward analysis of plan quality across 10 dimensions."
4
4
  model: sonnet
5
5
  memory: none
6
+ isolation: worktree
6
7
  tools:
7
8
  - Read
8
9
  - Bash
@@ -3,6 +3,7 @@ name: verifier
3
3
  description: "Goal-backward phase verification. Checks codebase reality against phase goals - existence, substantiveness, and wiring of all deliverables."
4
4
  model: sonnet
5
5
  memory: none
6
+ isolation: worktree
6
7
  tools:
7
8
  - Read
8
9
  - Bash
@@ -192,6 +192,17 @@
192
192
  ]
193
193
  }
194
194
  ],
195
+ "ConfigChange": [
196
+ {
197
+ "hooks": [
198
+ {
199
+ "type": "command",
200
+ "command": "node -e \"var r=process.env.CLAUDE_PLUGIN_ROOT||'',m=r.match(/^\\/([a-zA-Z])\\/(.*)/);if(m)r=m[1]+String.fromCharCode(58)+String.fromCharCode(92)+m[2];require(require('path').resolve(r,'scripts','run-hook.js'))\" check-config-change.js",
201
+ "statusMessage": "Validating configuration..."
202
+ }
203
+ ]
204
+ }
205
+ ],
195
206
  "SessionEnd": [
196
207
  {
197
208
  "hooks": [
@@ -78,10 +78,16 @@ function main() {
78
78
  if (attempt === 2) {
79
79
  logHook('auto-continue', 'Stop', 'unlink-failed', { error: unlinkErr.message });
80
80
  } else {
81
- // Exponential backoff: 100ms, 200ms
81
+ // Exponential backoff: 100ms, 200ms — use Atomics.wait for non-spinning delay
82
82
  const delay = 100 * Math.pow(2, attempt);
83
- const start = Date.now();
84
- while (Date.now() - start < delay) { /* busy-wait */ }
83
+ try {
84
+ const buf = new SharedArrayBuffer(4);
85
+ Atomics.wait(new Int32Array(buf), 0, 0, delay);
86
+ } catch (_atomicsErr) {
87
+ // Fallback for environments without SharedArrayBuffer
88
+ const end = Date.now() + delay;
89
+ while (Date.now() < end) { /* fallback busy-wait */ }
90
+ }
85
91
  }
86
92
  }
87
93
  }
@@ -0,0 +1,130 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * ConfigChange hook: Validates config.json changes and warns about inconsistencies.
5
+ *
6
+ * Fires when Claude Code detects configuration file changes (v2.1.49+).
7
+ * Checks .planning/config.json for:
8
+ * - Required top-level keys
9
+ * - Semantic conflicts (e.g., parallel agents enabled with max=1)
10
+ * - Version field presence
11
+ *
12
+ * Exit codes:
13
+ * 0 = always (advisory hook, never blocks)
14
+ */
15
+
16
+ const fs = require('fs');
17
+ const path = require('path');
18
+ const { logHook } = require('./hook-logger');
19
+ const { logEvent } = require('./event-logger');
20
+
21
+ function readStdin() {
22
+ return new Promise((resolve) => {
23
+ let input = '';
24
+ process.stdin.setEncoding('utf8');
25
+ process.stdin.on('data', (chunk) => { input += chunk; });
26
+ process.stdin.on('end', () => {
27
+ try {
28
+ resolve(JSON.parse(input));
29
+ } catch (_e) {
30
+ resolve({});
31
+ }
32
+ });
33
+ });
34
+ }
35
+
36
+ function findPlanningDir() {
37
+ let dir = process.cwd();
38
+ const root = path.parse(dir).root;
39
+ while (dir !== root) {
40
+ const candidate = path.join(dir, '.planning');
41
+ if (fs.existsSync(candidate)) return candidate;
42
+ dir = path.dirname(dir);
43
+ }
44
+ return null;
45
+ }
46
+
47
+ function validateConfig(configPath) {
48
+ const warnings = [];
49
+
50
+ let config;
51
+ try {
52
+ const raw = fs.readFileSync(configPath, 'utf8');
53
+ config = JSON.parse(raw);
54
+ } catch (e) {
55
+ warnings.push(`config.json parse error: ${e.message}`);
56
+ return warnings;
57
+ }
58
+
59
+ // Check required top-level keys
60
+ const requiredKeys = ['version', 'features', 'models', 'gates'];
61
+ for (const key of requiredKeys) {
62
+ if (!(key in config)) {
63
+ warnings.push(`Missing required key: ${key}`);
64
+ }
65
+ }
66
+
67
+ // Check version
68
+ if (config.version && config.version < 2) {
69
+ warnings.push(`Config version ${config.version} is outdated — expected version 2+`);
70
+ }
71
+
72
+ // Check semantic conflicts
73
+ if (config.parallelization) {
74
+ const p = config.parallelization;
75
+ if (p.enabled && p.max_concurrent_agents === 1) {
76
+ warnings.push('Semantic conflict: parallelization.enabled=true but max_concurrent_agents=1');
77
+ }
78
+ if (!p.enabled && (p.plan_level || p.task_level)) {
79
+ warnings.push('Semantic conflict: parallelization.enabled=false but plan_level/task_level are true');
80
+ }
81
+ }
82
+
83
+ // Check model values
84
+ if (config.models) {
85
+ const validModels = ['sonnet', 'opus', 'haiku', 'inherit'];
86
+ for (const [role, model] of Object.entries(config.models)) {
87
+ if (!validModels.includes(model)) {
88
+ warnings.push(`Invalid model "${model}" for ${role} — expected: ${validModels.join(', ')}`);
89
+ }
90
+ }
91
+ }
92
+
93
+ return warnings;
94
+ }
95
+
96
+ async function main() {
97
+ await readStdin();
98
+ const startTime = Date.now();
99
+
100
+ const planningDir = findPlanningDir();
101
+ if (!planningDir) {
102
+ logHook('check-config-change', 'ConfigChange', 'skip', { reason: 'no .planning dir' }, startTime);
103
+ process.exit(0);
104
+ }
105
+
106
+ const configPath = path.join(planningDir, 'config.json');
107
+ if (!fs.existsSync(configPath)) {
108
+ logHook('check-config-change', 'ConfigChange', 'skip', { reason: 'no config.json' }, startTime);
109
+ process.exit(0);
110
+ }
111
+
112
+ const warnings = validateConfig(configPath);
113
+
114
+ if (warnings.length > 0) {
115
+ const msg = `⚠️ Config validation (${warnings.length} issue${warnings.length > 1 ? 's' : ''}):\n${warnings.map(w => ` - ${w}`).join('\n')}`;
116
+
117
+ logHook('check-config-change', 'ConfigChange', 'warn', { warnings }, startTime);
118
+ logEvent('workflow', 'config-change', { warnings });
119
+
120
+ process.stdout.write(JSON.stringify({ additionalContext: msg }));
121
+ } else {
122
+ logHook('check-config-change', 'ConfigChange', 'ok', {}, startTime);
123
+ logEvent('workflow', 'config-change', { status: 'valid' });
124
+ }
125
+
126
+ process.exit(0);
127
+ }
128
+
129
+ if (require.main === module || process.argv[1] === __filename) main();
130
+ module.exports = { validateConfig, findPlanningDir };
@@ -108,7 +108,12 @@ function main() {
108
108
  }
109
109
 
110
110
  process.exit(0);
111
- } catch (_e) {
111
+ } catch (e) {
112
+ logHook('check-roadmap-sync', 'PostToolUse', 'error', { reason: 'parse failure in main', error: e.message });
113
+ const output = {
114
+ additionalContext: `[Roadmap Sync] Warning: Failed to parse STATE.md or ROADMAP.md — ${e.message}. Run /pbr:health to diagnose.`
115
+ };
116
+ process.stdout.write(JSON.stringify(output));
112
117
  process.exit(0);
113
118
  }
114
119
  });
@@ -326,7 +331,8 @@ function checkFilesystemDrift(roadmapContent, phasesDir) {
326
331
  let entries;
327
332
  try {
328
333
  entries = fs.readdirSync(phasesDir, { withFileTypes: true });
329
- } catch (_e) {
334
+ } catch (e) {
335
+ logHook('check-roadmap-sync', 'PostToolUse', 'error', { reason: 'failed to read phases dir', error: e.message });
330
336
  return warnings;
331
337
  }
332
338
 
@@ -18,6 +18,7 @@
18
18
  "SubagentStart": { "$ref": "#/definitions/hookEntryList" },
19
19
  "SubagentStop": { "$ref": "#/definitions/hookEntryList" },
20
20
  "TaskCompleted": { "$ref": "#/definitions/hookEntryList" },
21
+ "ConfigChange": { "$ref": "#/definitions/hookEntryList" },
21
22
  "SessionEnd": { "$ref": "#/definitions/hookEntryList" }
22
23
  },
23
24
  "additionalProperties": false
@@ -100,8 +100,16 @@ function buildContext(planningDir, stateFile) {
100
100
  const ageMs = Date.now() - stateStat.mtimeMs;
101
101
  const ageMinutes = Math.round(ageMs / 60000);
102
102
  if (ageMinutes > 30) {
103
- parts.push(`\nWarning: STATE.md shows status "Building" but was last modified ${ageMinutes} minutes ago. This may indicate a crashed executor. Run /pbr:health to diagnose.`);
104
- logHook('progress-tracker', 'SessionStart', 'stale-building', { ageMinutes });
103
+ // Auto-repair: reset stale "Building" status back to "Planned"
104
+ try {
105
+ const { stateUpdate } = require('./pbr-tools');
106
+ stateUpdate(planningDir, { status: 'planned' });
107
+ parts.push(`\nAuto-repaired: STATE.md was stuck in "Building" for ${ageMinutes} minutes (likely crashed executor). Reset to "Planned". Run /pbr:build to retry.`);
108
+ logHook('progress-tracker', 'SessionStart', 'stale-building-repaired', { ageMinutes });
109
+ } catch (_repairErr) {
110
+ parts.push(`\nWarning: STATE.md shows status "Building" but was last modified ${ageMinutes} minutes ago. This may indicate a crashed executor. Run /pbr:health to diagnose.`);
111
+ logHook('progress-tracker', 'SessionStart', 'stale-building', { ageMinutes });
112
+ }
105
113
  }
106
114
  } catch (_e) { /* best-effort */ }
107
115
  }
@@ -191,8 +199,15 @@ function buildContext(planningDir, stateFile) {
191
199
  const ageMinutes = Math.floor(ageMs / 60000);
192
200
  if (ageMinutes > 60) {
193
201
  const skill = fs.readFileSync(activeSkillFile, 'utf8').trim();
194
- parts.push(`\nWarning: .active-skill is ${ageMinutes} minutes old (skill: "${skill}"). This may be a stale lock from a crashed session or concurrent session conflict. Run /pbr:health to auto-fix, or delete .planning/.active-skill manually.`);
195
- logHook('progress-tracker', 'SessionStart', 'stale-active-skill', { ageMinutes, skill });
202
+ // Auto-cleanup stale .active-skill lock (> 60 minutes = certainly stale)
203
+ try {
204
+ fs.unlinkSync(activeSkillFile);
205
+ parts.push(`\nAuto-cleaned: Stale .active-skill lock removed (skill: "${skill}", age: ${ageMinutes} minutes). Was likely from a crashed or abandoned session.`);
206
+ logHook('progress-tracker', 'SessionStart', 'stale-active-skill-cleaned', { ageMinutes, skill });
207
+ } catch (_cleanupErr) {
208
+ parts.push(`\nWarning: .active-skill is ${ageMinutes} minutes old (skill: "${skill}"). Could not auto-remove — delete .planning/.active-skill manually.`);
209
+ logHook('progress-tracker', 'SessionStart', 'stale-active-skill', { ageMinutes, skill });
210
+ }
196
211
  }
197
212
  } catch (_e) {
198
213
  // Ignore errors
@@ -77,6 +77,11 @@ function main() {
77
77
  unique_files: tracker.files.length,
78
78
  });
79
79
  const prevCharsTotal = tracker.total_chars;
80
+ // Emit user-visible warning before resetting (was previously silent)
81
+ const resetWarning = {
82
+ additionalContext: `[Context Budget] Tracker reset: ${tracker.files.length} unique files read (~${Math.round(tracker.total_chars / 1000)}k chars). File list cleared but char total preserved. Consider delegating remaining work to a Task() subagent.`
83
+ };
84
+ process.stdout.write(JSON.stringify(resetWarning));
80
85
  tracker = { skill: currentSkill, reads: 0, total_chars: prevCharsTotal, files: [] };
81
86
  }
82
87
 
@@ -82,7 +82,7 @@ Read the following files to understand what this phase needs to accomplish:
82
82
  - What patterns have been established (`patterns` field)
83
83
  - What decisions were already made (`key_decisions` field)
84
84
 
85
- 3. **REQUIREMENTS.md** (if exists) — Read project requirements relevant to this phase
85
+ 3. **REQUIREMENTS.md** (if exists) — Read project requirements relevant to this phase. **CRITICAL**: After reading, display to the user which specific requirements map to this phase. Flag any requirements that could constrain decisions. If the user's discussion decisions later contradict a stated requirement, surface the contradiction immediately — don't wait until planning.
86
86
 
87
87
  4. **CONTEXT.md** (if exists in the phase directory) — Check if a prior discussion already happened
88
88
  - If CONTEXT.md exists, inform the user and use the **context-handling** pattern from `skills/shared/gate-prompts.md`:
@@ -94,6 +94,7 @@ Display the following reference to the user:
94
94
  |---------|-------------|
95
95
  | `/pbr:milestone new` | Start a new milestone cycle. |
96
96
  | `/pbr:milestone complete` | Archive completed milestone. |
97
+ | `/pbr:milestone preview` | Dry-run of complete — show what would happen. |
97
98
  | `/pbr:milestone audit` | Verify milestone completion. |
98
99
  | `/pbr:milestone gaps` | Create phases to close audit gaps. |
99
100
  | `/pbr:todo add\|list\|done` | Persistent file-based todos. |
@@ -138,6 +139,7 @@ Display the following reference to the user:
138
139
  - **Depth**: `quick` (skip research, ~50% cheaper) | `standard` | `comprehensive` (~2x cost)
139
140
  - **State files**: `.planning/STATE.md` (position), `.planning/ROADMAP.md` (phases), `.planning/config.json` (settings)
140
141
  - **Configure**: `/pbr:config` to change depth, models, gates, parallelization
142
+ - **List agents**: Run `claude agents` in your terminal to see all registered PBR agents and verify loading
141
143
  - **Tip**: Use `/pbr:quick` for creative/visual work where structured planning adds overhead without benefit.
142
144
  - **PR hygiene**: When creating PRs from a Plan-Build-Run project, `.planning/` commits can be filtered using phase branching (`git.branching: phase`) which squash-merges code-only changes to main.
143
145
  - **Seeds**: `/pbr:explore` can create seed files (`.planning/seeds/`) with trigger conditions. Seeds auto-inject into planning when their trigger phase is reached.
@@ -152,6 +154,27 @@ Plan-Build-Run includes three behavioral contexts in `contexts/` that adjust how
152
154
 
153
155
  Skills automatically activate the appropriate context: `/pbr:build` uses dev context, `/pbr:discuss` uses research context, `/pbr:review` uses review context.
154
156
 
157
+ ## When to Use Quick vs Plan+Build
158
+
159
+ | Use `/pbr:quick` when... | Use `/pbr:plan` + `/pbr:build` when... |
160
+ |--------------------------|----------------------------------------|
161
+ | Change touches ≤3 files | Change touches 4+ files |
162
+ | ≤100 lines of code | 100+ lines of code |
163
+ | Single subsystem | Multiple subsystems or cross-cutting |
164
+ | No architectural decisions | Requires design choices |
165
+ | Bug fix, small feature, docs | New feature, refactor, migration |
166
+
167
+ ## Setup vs Begin
168
+
169
+ - **`/pbr:begin`** — Use this to start a new project. It handles everything: questioning, research, requirements, roadmap, AND config initialization. This is the standard entry point.
170
+ - **`/pbr:setup`** — Use this only to reconfigure an existing project's settings (model profiles, gates, depth, parallelization) without re-running the full begin flow.
171
+
172
+ If you're unsure, start with `/pbr:begin`. It will detect existing config and offer to reuse or overwrite.
173
+
174
+ ## Team Discussions
175
+
176
+ The `features.team_discussions` config flag (and `/pbr:build --team`) enables **Agent Teams** for complex builds. When enabled, executor agents can coordinate with each other during parallel wave execution — sharing context about what they've built, resolving interface conflicts, and avoiding duplicate work. Best for phases where multiple plans have shared dependencies. Configure via `/pbr:config`.
177
+
155
178
  ## Getting Started
156
179
 
157
180
  ```
@@ -57,6 +57,7 @@ Examples:
57
57
  "new User Auth" → subcommand=new, arg="User Auth"
58
58
  "complete v1.0" → subcommand=complete, arg="v1.0"
59
59
  "complete 1.0" → subcommand=complete, arg="v1.0" (auto-prefix v)
60
+ "preview v1.0" → subcommand=preview, arg="v1.0"
60
61
  "audit v1.0" → subcommand=audit, arg="v1.0"
61
62
  "audit" → subcommand=audit, arg=current milestone
62
63
  "gaps" → subcommand=gaps, arg=most recent audit
@@ -69,6 +70,7 @@ Usage: /pbr:milestone <subcommand> [version]
69
70
  Subcommands:
70
71
  new [name] — Start a new milestone cycle
71
72
  complete [ver] — Archive completed milestone
73
+ preview [ver] — Dry-run of complete (show what would happen)
72
74
  audit [ver] — Verify milestone completion
73
75
  gaps — Create phases to close audit gaps
74
76
  ```
@@ -194,6 +196,65 @@ Start a new milestone cycle with new phases.
194
196
 
195
197
  ---
196
198
 
199
+ ## Subcommand: `preview`
200
+
201
+ Dry-run of milestone completion — shows what would happen without making any changes.
202
+
203
+ ### Flow
204
+
205
+ 1. **Determine version:**
206
+ - Same logic as `complete`: use `$ARGUMENTS` or ask via AskUserQuestion
207
+
208
+ 2. **Identify milestone phases:**
209
+ - Read ROADMAP.md to find phases belonging to this milestone
210
+ - List each phase with its current status (from STATE.md or VERIFICATION.md)
211
+
212
+ 3. **Verification status check:**
213
+ - For each milestone phase, check if VERIFICATION.md exists and its `result` frontmatter
214
+ - Flag phases that are unverified or have stale verification (SUMMARY.md newer than VERIFICATION.md)
215
+
216
+ 4. **Preview archive structure:**
217
+ - Show what the archive directory would look like:
218
+ ```
219
+ .planning/milestones/v{version}/
220
+ ├── ROADMAP.md (snapshot)
221
+ ├── STATS.md (would be generated)
222
+ ├── REQUIREMENTS.md (snapshot)
223
+ └── phases/
224
+ ├── {NN}-{slug}/ (moved from .planning/phases/)
225
+ │ ├── PLAN-01.md
226
+ │ ├── SUMMARY.md
227
+ │ └── VERIFICATION.md
228
+ └── ...
229
+ ```
230
+
231
+ 5. **Show what would change:**
232
+ - Which phase directories would be moved
233
+ - What ROADMAP.md section would be collapsed
234
+ - What STATE.md updates would occur
235
+ - What git tag would be created
236
+
237
+ 6. **Display summary:**
238
+ ```
239
+ ╔══════════════════════════════════════════════════════════════╗
240
+ ║ MILESTONE PREVIEW — v{version} ║
241
+ ╚══════════════════════════════════════════════════════════════╝
242
+
243
+ Phases to archive: {count}
244
+ ✓ Verified: {verified_count}
245
+ ⚠ Unverified: {unverified_count}
246
+ ⚠ Stale verification: {stale_count}
247
+
248
+ Archive location: .planning/milestones/v{version}/
249
+ Git tag: v{version}
250
+
251
+ Ready to complete? Run: /pbr:milestone complete v{version}
252
+ ```
253
+
254
+ **CRITICAL**: This subcommand is READ-ONLY. Do not create directories, move files, modify STATE.md, modify ROADMAP.md, or create git tags. Only read and display.
255
+
256
+ ---
257
+
197
258
  ## Subcommand: `complete`
198
259
 
199
260
  Archive a completed milestone and prepare for the next one.
@@ -0,0 +1,51 @@
1
+ # Error Recovery Strategies Fragment
2
+
3
+ Standard recovery patterns for skills and agents when operations fail. Reference `error-reporting.md` for display formats.
4
+
5
+ ## Strategy 1: Retry with Backoff
6
+
7
+ For transient failures (file locks, network timeouts, tool failures):
8
+
9
+ 1. Wait briefly, then retry the same operation (max 2 retries)
10
+ 2. If still failing after retries, fall through to Strategy 2
11
+
12
+ Use for: git operations, file writes blocked by antivirus, API calls.
13
+
14
+ ## Strategy 2: Degrade Gracefully
15
+
16
+ When a non-critical step fails, skip it and continue:
17
+
18
+ 1. Log a warning using the recoverable error format
19
+ 2. Note the skipped step in SUMMARY.md `deferred` field
20
+ 3. Continue with remaining work
21
+
22
+ Use for: optional validations, dashboard launch, hook logger writes, note/todo updates.
23
+
24
+ ## Strategy 3: Escalate to User
25
+
26
+ When a critical step fails and no automated fix exists:
27
+
28
+ 1. Display the fatal error format with actionable suggestions
29
+ 2. Do NOT attempt workarounds that could corrupt state
30
+ 3. Suggest `/pbr:health` as the first diagnostic step
31
+ 4. If in an agent context, return the error in the agent's output so the orchestrator can relay it
32
+
33
+ Use for: STATE.md corruption, missing phase directories, config parse failures, git conflicts.
34
+
35
+ ## Strategy 4: Checkpoint and Abort
36
+
37
+ When a multi-step operation partially fails:
38
+
39
+ 1. Commit any completed work (don't lose progress)
40
+ 2. Update STATE.md with accurate status (not the target status)
41
+ 3. Write a `.continue-here.md` breadcrumb if mid-phase
42
+ 4. Report what completed and what remains
43
+
44
+ Use for: build phase with mixed plan results, verification with partial failures.
45
+
46
+ ## Anti-Patterns
47
+
48
+ - **Never silently swallow errors** in catch blocks — at minimum call `logHook()` with the error message
49
+ - **Never retry destructive operations** (deletes, force-pushes, state resets)
50
+ - **Never auto-fix by deleting user artifacts** — only delete PBR internal state files (.active-skill, .context-tracker, .auto-next)
51
+ - **Never continue building after STATE.md write failure** — state integrity is non-negotiable