@sienklogic/plan-build-run 2.20.0 → 2.21.1
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.
- package/CHANGELOG.md +39 -0
- package/CLAUDE.md +2 -2
- package/package.json +1 -1
- package/plugins/copilot-pbr/agents/codebase-mapper.agent.md +1 -1
- package/plugins/copilot-pbr/agents/debugger.agent.md +2 -0
- package/plugins/copilot-pbr/agents/executor.agent.md +3 -1
- package/plugins/copilot-pbr/agents/general.agent.md +2 -1
- package/plugins/copilot-pbr/agents/integration-checker.agent.md +2 -0
- package/plugins/copilot-pbr/agents/plan-checker.agent.md +1 -1
- package/plugins/copilot-pbr/agents/planner.agent.md +3 -1
- package/plugins/copilot-pbr/agents/researcher.agent.md +5 -3
- package/plugins/copilot-pbr/agents/synthesizer.agent.md +1 -1
- package/plugins/copilot-pbr/agents/verifier.agent.md +3 -3
- package/plugins/copilot-pbr/hooks/hooks.json +89 -0
- package/plugins/copilot-pbr/plugin.json +1 -1
- package/plugins/copilot-pbr/skills/audit/SKILL.md +1 -1
- package/plugins/copilot-pbr/skills/build/SKILL.md +4 -5
- package/plugins/copilot-pbr/skills/config/SKILL.md +1 -1
- package/plugins/copilot-pbr/skills/debug/SKILL.md +1 -1
- package/plugins/copilot-pbr/skills/discuss/SKILL.md +1 -1
- package/plugins/copilot-pbr/skills/help/SKILL.md +23 -0
- package/plugins/copilot-pbr/skills/import/SKILL.md +1 -1
- package/plugins/copilot-pbr/skills/milestone/SKILL.md +61 -0
- package/plugins/copilot-pbr/skills/plan/SKILL.md +1 -1
- package/plugins/copilot-pbr/skills/review/SKILL.md +4 -4
- package/plugins/copilot-pbr/skills/scan/SKILL.md +4 -4
- package/plugins/copilot-pbr/skills/shared/config-loading.md +1 -1
- package/plugins/copilot-pbr/skills/shared/context-budget.md +3 -3
- package/plugins/copilot-pbr/skills/shared/error-recovery-strategies.md +51 -0
- package/plugins/copilot-pbr/skills/shared/state-loading.md +1 -1
- package/plugins/copilot-pbr/skills/shared/state-update.md +12 -4
- package/plugins/copilot-pbr/skills/shared/universal-anti-patterns.md +1 -1
- package/plugins/copilot-pbr/templates/ROADMAP.md.tmpl +7 -0
- package/plugins/cursor-pbr/.cursor-plugin/plugin.json +1 -1
- package/plugins/cursor-pbr/agents/codebase-mapper.md +1 -1
- package/plugins/cursor-pbr/agents/debugger.md +2 -0
- package/plugins/cursor-pbr/agents/executor.md +3 -1
- package/plugins/cursor-pbr/agents/general.md +2 -1
- package/plugins/cursor-pbr/agents/integration-checker.md +2 -0
- package/plugins/cursor-pbr/agents/plan-checker.md +1 -1
- package/plugins/cursor-pbr/agents/planner.md +3 -1
- package/plugins/cursor-pbr/agents/researcher.md +5 -3
- package/plugins/cursor-pbr/agents/synthesizer.md +1 -1
- package/plugins/cursor-pbr/agents/verifier.md +3 -3
- package/plugins/cursor-pbr/skills/audit/SKILL.md +1 -1
- package/plugins/cursor-pbr/skills/build/SKILL.md +4 -5
- package/plugins/cursor-pbr/skills/config/SKILL.md +1 -1
- package/plugins/cursor-pbr/skills/debug/SKILL.md +1 -1
- package/plugins/cursor-pbr/skills/discuss/SKILL.md +1 -1
- package/plugins/cursor-pbr/skills/help/SKILL.md +23 -0
- package/plugins/cursor-pbr/skills/import/SKILL.md +1 -1
- package/plugins/cursor-pbr/skills/milestone/SKILL.md +61 -0
- package/plugins/cursor-pbr/skills/plan/SKILL.md +1 -1
- package/plugins/cursor-pbr/skills/review/SKILL.md +4 -4
- package/plugins/cursor-pbr/skills/scan/SKILL.md +4 -4
- package/plugins/cursor-pbr/skills/shared/config-loading.md +1 -1
- package/plugins/cursor-pbr/skills/shared/context-budget.md +3 -3
- package/plugins/cursor-pbr/skills/shared/error-recovery-strategies.md +51 -0
- package/plugins/cursor-pbr/skills/shared/state-loading.md +1 -1
- package/plugins/cursor-pbr/skills/shared/state-update.md +12 -4
- package/plugins/cursor-pbr/skills/shared/universal-anti-patterns.md +1 -1
- package/plugins/cursor-pbr/templates/ROADMAP.md.tmpl +7 -0
- package/plugins/pbr/.claude-plugin/plugin.json +1 -1
- package/plugins/pbr/agents/codebase-mapper.md +1 -1
- package/plugins/pbr/agents/debugger.md +2 -0
- package/plugins/pbr/agents/executor.md +3 -1
- package/plugins/pbr/agents/general.md +2 -1
- package/plugins/pbr/agents/integration-checker.md +2 -0
- package/plugins/pbr/agents/plan-checker.md +0 -1
- package/plugins/pbr/agents/planner.md +2 -1
- package/plugins/pbr/agents/researcher.md +2 -0
- package/plugins/pbr/agents/synthesizer.md +0 -1
- package/plugins/pbr/agents/verifier.md +1 -1
- package/plugins/pbr/commands/do.md +5 -0
- package/plugins/pbr/scripts/auto-continue.js +9 -3
- package/plugins/pbr/scripts/check-phase-boundary.js +2 -8
- package/plugins/pbr/scripts/check-plan-format.js +78 -2
- package/plugins/pbr/scripts/check-roadmap-sync.js +8 -2
- package/plugins/pbr/scripts/check-skill-workflow.js +3 -11
- package/plugins/pbr/scripts/check-state-sync.js +18 -8
- package/plugins/pbr/scripts/check-subagent-output.js +78 -6
- package/plugins/pbr/scripts/log-tool-failure.js +1 -4
- package/plugins/pbr/scripts/pre-write-dispatch.js +0 -1
- package/plugins/pbr/scripts/progress-tracker.js +19 -4
- package/plugins/pbr/scripts/status-line.js +44 -11
- package/plugins/pbr/scripts/track-context-budget.js +5 -0
- package/plugins/pbr/scripts/validate-commit.js +8 -7
- package/plugins/pbr/scripts/validate-skill-args.js +2 -1
- package/plugins/pbr/scripts/validate-task.js +0 -5
- package/plugins/pbr/skills/build/SKILL.md +4 -5
- package/plugins/pbr/skills/discuss/SKILL.md +1 -1
- package/plugins/pbr/skills/health/SKILL.md +0 -2
- package/plugins/pbr/skills/help/SKILL.md +22 -0
- package/plugins/pbr/skills/milestone/SKILL.md +61 -0
- package/plugins/pbr/skills/plan/SKILL.md +1 -1
- package/plugins/pbr/skills/review/SKILL.md +4 -4
- package/plugins/pbr/skills/shared/error-recovery-strategies.md +51 -0
- package/plugins/pbr/skills/shared/state-update.md +10 -2
- package/plugins/pbr/templates/ROADMAP.md.tmpl +2 -0
|
@@ -197,6 +197,23 @@ function main() {
|
|
|
197
197
|
process.exit(0);
|
|
198
198
|
}
|
|
199
199
|
|
|
200
|
+
/**
|
|
201
|
+
* Parse YAML frontmatter from STATE.md content.
|
|
202
|
+
* Returns an object with frontmatter fields, or null if no frontmatter.
|
|
203
|
+
*/
|
|
204
|
+
function parseFrontmatter(content) {
|
|
205
|
+
if (!content.startsWith('---')) return null;
|
|
206
|
+
const endIdx = content.indexOf('---', 3);
|
|
207
|
+
if (endIdx === -1) return null;
|
|
208
|
+
const fm = content.substring(3, endIdx);
|
|
209
|
+
const result = {};
|
|
210
|
+
for (const line of fm.split(/\r?\n/)) {
|
|
211
|
+
const m = line.match(/^(\w[\w_]*):\s*"?([^"]*)"?\s*$/);
|
|
212
|
+
if (m) result[m[1]] = m[2];
|
|
213
|
+
}
|
|
214
|
+
return result;
|
|
215
|
+
}
|
|
216
|
+
|
|
200
217
|
function buildStatusLine(content, ctxPercent, cfg, stdinData) {
|
|
201
218
|
const config = cfg || DEFAULTS;
|
|
202
219
|
const sections = config.sections || DEFAULTS.sections;
|
|
@@ -205,15 +222,26 @@ function buildStatusLine(content, ctxPercent, cfg, stdinData) {
|
|
|
205
222
|
const barCfg = config.context_bar || DEFAULTS.context_bar;
|
|
206
223
|
const sd = stdinData || {};
|
|
207
224
|
|
|
225
|
+
// Prefer frontmatter (always up-to-date) over body text (may be stale)
|
|
226
|
+
const fm = parseFrontmatter(content);
|
|
227
|
+
|
|
208
228
|
const parts = [];
|
|
209
229
|
|
|
210
230
|
// Phase section (always includes brand text)
|
|
211
231
|
if (sections.includes('phase')) {
|
|
232
|
+
const fmPhase = fm && fm.current_phase;
|
|
233
|
+
const fmTotal = fm && fm.total_phases;
|
|
234
|
+
const fmName = fm && fm.phase_name;
|
|
212
235
|
const phaseMatch = content.match(/Phase:\s*(\d+)\s*of\s*(\d+)\s*(?:\(([^)]+)\))?/);
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
236
|
+
|
|
237
|
+
const phaseNum = fmPhase || (phaseMatch && phaseMatch[1]);
|
|
238
|
+
const phaseTotal = fmTotal || (phaseMatch && phaseMatch[2]);
|
|
239
|
+
const phaseName = fmName || (phaseMatch && phaseMatch[3]);
|
|
240
|
+
|
|
241
|
+
if (phaseNum && phaseTotal) {
|
|
242
|
+
parts.push(`${c.boldCyan}${brandText}${c.reset} ${c.bold}Phase ${phaseNum}/${phaseTotal}${c.reset}`);
|
|
243
|
+
if (phaseName) {
|
|
244
|
+
parts.push(`${c.magenta}${phaseName}${c.reset}`);
|
|
217
245
|
}
|
|
218
246
|
} else {
|
|
219
247
|
parts.push(`${c.boldCyan}${brandText}${c.reset}`);
|
|
@@ -222,10 +250,14 @@ function buildStatusLine(content, ctxPercent, cfg, stdinData) {
|
|
|
222
250
|
|
|
223
251
|
// Plan section
|
|
224
252
|
if (sections.includes('plan')) {
|
|
253
|
+
const fmComplete = fm && fm.plans_complete;
|
|
254
|
+
const fmTotal = fm && fm.plans_total;
|
|
225
255
|
const planMatch = content.match(/Plan:\s*(\d+)\s*of\s*(\d+)/);
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
256
|
+
|
|
257
|
+
const done = fmComplete != null ? parseInt(fmComplete, 10) : (planMatch ? parseInt(planMatch[1], 10) : null);
|
|
258
|
+
const total = fmTotal != null ? parseInt(fmTotal, 10) : (planMatch ? parseInt(planMatch[2], 10) : null);
|
|
259
|
+
|
|
260
|
+
if (done != null && total != null && total > 0) {
|
|
229
261
|
const planColor = done === total ? c.green : c.white;
|
|
230
262
|
parts.push(`${planColor}Plan ${done}/${total}${c.reset}`);
|
|
231
263
|
}
|
|
@@ -233,9 +265,10 @@ function buildStatusLine(content, ctxPercent, cfg, stdinData) {
|
|
|
233
265
|
|
|
234
266
|
// Status section
|
|
235
267
|
if (sections.includes('status')) {
|
|
236
|
-
const
|
|
237
|
-
|
|
238
|
-
|
|
268
|
+
const fmStatus = fm && fm.status;
|
|
269
|
+
const statusMatch = content.match(/^Status:\s*(.+)/m);
|
|
270
|
+
const text = fmStatus || (statusMatch && statusMatch[1].trim());
|
|
271
|
+
if (text) {
|
|
239
272
|
const short = text.length > maxLen ? text.slice(0, maxLen - 3) + '...' : text;
|
|
240
273
|
parts.push(`${statusColor(text)}${short}${c.reset}`);
|
|
241
274
|
}
|
|
@@ -285,4 +318,4 @@ function buildStatusLine(content, ctxPercent, cfg, stdinData) {
|
|
|
285
318
|
}
|
|
286
319
|
|
|
287
320
|
if (require.main === module || process.argv[1] === __filename) { main(); }
|
|
288
|
-
module.exports = { buildStatusLine, buildContextBar, getContextPercent, getGitInfo, formatDuration, loadStatusLineConfig, DEFAULTS };
|
|
321
|
+
module.exports = { buildStatusLine, buildContextBar, getContextPercent, getGitInfo, formatDuration, loadStatusLineConfig, parseFrontmatter, DEFAULTS };
|
|
@@ -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
|
|
|
@@ -178,6 +178,14 @@ function isGitCommit(command) {
|
|
|
178
178
|
}
|
|
179
179
|
|
|
180
180
|
function extractCommitMessage(command) {
|
|
181
|
+
// Try heredoc first: -m "$(cat <<'EOF'\n...\nEOF\n)" or -m "$(cat <<EOF\n...\nEOF\n)"
|
|
182
|
+
// Must check before generic -m patterns to avoid capturing heredoc syntax as the message
|
|
183
|
+
const heredocMatch = command.match(/<<'?EOF'?\s*\n([\s\S]*?)\nEOF/);
|
|
184
|
+
if (heredocMatch) {
|
|
185
|
+
// First line of heredoc is the commit message
|
|
186
|
+
return heredocMatch[1].trim().split('\n')[0].trim();
|
|
187
|
+
}
|
|
188
|
+
|
|
181
189
|
// Try -m "message" or -m 'message'
|
|
182
190
|
const mFlagMatch = command.match(/-m\s+["']([^"']+)["']/);
|
|
183
191
|
if (mFlagMatch) return mFlagMatch[1];
|
|
@@ -186,13 +194,6 @@ function extractCommitMessage(command) {
|
|
|
186
194
|
const mFlagMatch2 = command.match(/-m\s+"([^"]+)"/);
|
|
187
195
|
if (mFlagMatch2) return mFlagMatch2[1];
|
|
188
196
|
|
|
189
|
-
// Try heredoc: -m "$(cat <<'EOF'\n...\nEOF\n)"
|
|
190
|
-
const heredocMatch = command.match(/<<'?EOF'?\s*\n([\s\S]*?)\nEOF/);
|
|
191
|
-
if (heredocMatch) {
|
|
192
|
-
// First line of heredoc is the commit message
|
|
193
|
-
return heredocMatch[1].trim().split('\n')[0].trim();
|
|
194
|
-
}
|
|
195
|
-
|
|
196
197
|
return null;
|
|
197
198
|
}
|
|
198
199
|
|
|
@@ -101,7 +101,8 @@ function checkSkillArgs(data) {
|
|
|
101
101
|
|
|
102
102
|
return {
|
|
103
103
|
output: {
|
|
104
|
-
|
|
104
|
+
decision: 'block',
|
|
105
|
+
reason: [
|
|
105
106
|
'BLOCKED: /pbr:plan received freeform text instead of a phase number.',
|
|
106
107
|
'',
|
|
107
108
|
'The arguments "' + args.substring(0, 80) + (args.length > 80 ? '...' : '') + '" do not match any valid pattern.',
|
|
@@ -567,11 +567,6 @@ function checkBuildDependencyGate(data) {
|
|
|
567
567
|
return null;
|
|
568
568
|
}
|
|
569
569
|
|
|
570
|
-
/**
|
|
571
|
-
* Advisory check: when active skill is "build" and an executor is being
|
|
572
|
-
* spawned, warn if .checkpoint-manifest.json is missing in the phase dir.
|
|
573
|
-
* Returns a warning string or null.
|
|
574
|
-
*/
|
|
575
570
|
/**
|
|
576
571
|
* Parse VERIFICATION.md frontmatter to extract status field.
|
|
577
572
|
* Returns the status string or 'unknown' if not parseable.
|
|
@@ -720,11 +720,10 @@ These return `{ success, old_status, new_status }` or `{ success, old_plans, new
|
|
|
720
720
|
|
|
721
721
|
**CRITICAL: Update STATE.md NOW with phase completion status. Do NOT skip this step.**
|
|
722
722
|
|
|
723
|
-
**8b. Update STATE.md:**
|
|
724
|
-
-
|
|
725
|
-
- Plan
|
|
726
|
-
-
|
|
727
|
-
- Progress bar
|
|
723
|
+
**8b. Update STATE.md (CRITICAL — update BOTH frontmatter AND body):**
|
|
724
|
+
- Frontmatter: `status`, `plans_complete`, `last_activity`, `progress_percent`, `last_command`
|
|
725
|
+
- Body `## Current Position`: `Phase:` line, `Plan:` line, `Status:` line, `Last activity:` line, `Progress:` bar
|
|
726
|
+
- These MUST stay in sync — the status line reads frontmatter, humans read the body
|
|
728
727
|
|
|
729
728
|
**8c. Commit planning docs (if configured):**
|
|
730
729
|
Reference: `skills/shared/commit-planning-docs.md` for the standard commit pattern.
|
|
@@ -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`:
|
|
@@ -209,8 +209,6 @@ This ensures the user can recover the original STATE.md if the fix produces inco
|
|
|
209
209
|
|
|
210
210
|
4. If "Skip": Do nothing, continue to the rest of the output.
|
|
211
211
|
|
|
212
|
-
**Note:** When auto-fix is active, the health skill is no longer strictly read-only. The `allowed-tools` frontmatter must include `Write` and `AskUserQuestion` for auto-fix to work. Update the frontmatter accordingly.
|
|
213
|
-
|
|
214
212
|
---
|
|
215
213
|
|
|
216
214
|
## Bonus: Recent Decisions
|
|
@@ -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. |
|
|
@@ -153,6 +154,27 @@ Plan-Build-Run includes three behavioral contexts in `contexts/` that adjust how
|
|
|
153
154
|
|
|
154
155
|
Skills automatically activate the appropriate context: `/pbr:build` uses dev context, `/pbr:discuss` uses research context, `/pbr:review` uses review context.
|
|
155
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
|
+
|
|
156
178
|
## Getting Started
|
|
157
179
|
|
|
158
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.
|
|
@@ -492,7 +492,7 @@ Use AskUserQuestion (pattern: approve-revise-abort from `skills/shared/gate-prom
|
|
|
492
492
|
4. Update the `Plans Complete` column to `0/{N}` where N = number of plan files just created
|
|
493
493
|
5. Update the `Status` column to `planned`
|
|
494
494
|
6. Save the file — do NOT skip this step
|
|
495
|
-
- Update STATE.md
|
|
495
|
+
- Update STATE.md **(CRITICAL — update BOTH frontmatter AND body)**: set `status: "planned"`, `plans_total`, `last_command` in frontmatter AND update `Status:`, `Plan:` lines in body `## Current Position`
|
|
496
496
|
- **If `features.auto_advance` is `true` AND `mode` is `autonomous`:** Chain directly to build: `Skill({ skill: "pbr:build", args: "{N}" })`. This continues the build→review→plan→build cycle automatically.
|
|
497
497
|
- **Otherwise:** Suggest next action: `/pbr:build {N}`
|
|
498
498
|
|
|
@@ -331,10 +331,10 @@ If all automated checks and UAT items passed:
|
|
|
331
331
|
4. Update the `Status` column to `verified`
|
|
332
332
|
5. Update the `Completed` column to the current date (YYYY-MM-DD)
|
|
333
333
|
6. Save the file — do NOT skip this step
|
|
334
|
-
2. Update `.planning/STATE.md
|
|
335
|
-
-
|
|
336
|
-
- Progress
|
|
337
|
-
-
|
|
334
|
+
2. Update `.planning/STATE.md` **(CRITICAL — update BOTH frontmatter AND body):**
|
|
335
|
+
- Frontmatter: `status: "verified"`, `progress_percent`, `last_activity`, `last_command`
|
|
336
|
+
- Body `## Current Position`: `Status:` line, `Last activity:` line, `Progress:` bar
|
|
337
|
+
- These MUST stay in sync — see `skills/shared/state-update.md`
|
|
338
338
|
- **STATE.md size limit:** Follow size limit enforcement rules in `skills/shared/state-update.md` (150 lines max).
|
|
339
339
|
3. Update VERIFICATION.md with UAT results (append UAT section)
|
|
340
340
|
3. Present completion:
|
|
@@ -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
|
|
@@ -4,12 +4,17 @@ Standard pattern for updating `.planning/STATE.md`. Include this fragment in ski
|
|
|
4
4
|
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
+
**CRITICAL: STATE.md has TWO representations — YAML frontmatter AND markdown body. You MUST update BOTH when changing state. The status line reads frontmatter; humans and hooks read the body. If you only update frontmatter, the body goes stale and the status line shows wrong data. Do NOT skip body updates under any circumstances.**
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
7
11
|
## When to Update STATE.md
|
|
8
12
|
|
|
9
13
|
| Event | What to Update |
|
|
10
14
|
|-------|---------------|
|
|
11
|
-
| Phase status changes (planned, building, verified) | Current Position section |
|
|
12
|
-
| Plan completes or fails | Plan counter, status, last activity |
|
|
15
|
+
| Phase status changes (planned, building, verified) | Frontmatter fields AND Current Position section |
|
|
16
|
+
| Plan completes or fails | Frontmatter fields AND Plan counter, status, last activity |
|
|
17
|
+
| Phase advances to next phase | Frontmatter fields AND Phase line, Status, Last activity, Progress bar |
|
|
13
18
|
| New decision made | Accumulated Context > Decisions |
|
|
14
19
|
| Blocker discovered or resolved | Accumulated Context > Blockers/Concerns |
|
|
15
20
|
| Session starts or ends | Session Continuity section |
|
|
@@ -31,6 +36,9 @@ See: .planning/PROJECT.md (updated {date})
|
|
|
31
36
|
Update `Current focus` when phase changes.
|
|
32
37
|
|
|
33
38
|
### 2. Current Position (lines 9-14)
|
|
39
|
+
|
|
40
|
+
**CRITICAL: This section MUST match the frontmatter fields above it. When you update `current_phase` or `status` in frontmatter, you MUST also update the corresponding lines below. A hook will auto-fix drift, but do not rely on it.**
|
|
41
|
+
|
|
34
42
|
```
|
|
35
43
|
## Current Position
|
|
36
44
|
Phase: {N} of {total} ({Phase name})
|