@sienklogic/plan-build-run 2.34.0 → 2.38.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 (160) hide show
  1. package/CHANGELOG.md +683 -0
  2. package/dashboard/public/css/command-center.css +152 -65
  3. package/dashboard/public/css/explorer.css +22 -41
  4. package/dashboard/public/css/layout.css +119 -1
  5. package/dashboard/public/css/tokens.css +13 -0
  6. package/dashboard/src/components/Layout.tsx +32 -6
  7. package/dashboard/src/components/explorer/tabs/PhasesTab.tsx +11 -1
  8. package/dashboard/src/components/explorer/tabs/TodosTab.tsx +18 -2
  9. package/dashboard/src/components/partials/AttentionPanel.tsx +7 -1
  10. package/dashboard/src/components/partials/CurrentPhaseCard.tsx +26 -24
  11. package/dashboard/src/components/partials/QuickActions.tsx +21 -11
  12. package/dashboard/src/components/partials/StatCardGrid.tsx +67 -0
  13. package/dashboard/src/components/partials/StatusHeader.tsx +1 -0
  14. package/dashboard/src/routes/command-center.routes.tsx +8 -7
  15. package/dashboard/src/routes/index.routes.tsx +32 -29
  16. package/package.json +2 -2
  17. package/plugins/copilot-pbr/agents/audit.agent.md +129 -16
  18. package/plugins/copilot-pbr/agents/codebase-mapper.agent.md +49 -1
  19. package/plugins/copilot-pbr/agents/debugger.agent.md +50 -1
  20. package/plugins/copilot-pbr/agents/dev-sync.agent.md +23 -0
  21. package/plugins/copilot-pbr/agents/executor.agent.md +153 -8
  22. package/plugins/copilot-pbr/agents/general.agent.md +46 -1
  23. package/plugins/copilot-pbr/agents/integration-checker.agent.md +55 -2
  24. package/plugins/copilot-pbr/agents/plan-checker.agent.md +50 -2
  25. package/plugins/copilot-pbr/agents/planner.agent.md +80 -1
  26. package/plugins/copilot-pbr/agents/researcher.agent.md +50 -2
  27. package/plugins/copilot-pbr/agents/synthesizer.agent.md +49 -1
  28. package/plugins/copilot-pbr/agents/verifier.agent.md +114 -13
  29. package/plugins/copilot-pbr/commands/test.md +5 -0
  30. package/plugins/copilot-pbr/hooks/hooks.json +11 -0
  31. package/plugins/copilot-pbr/plugin.json +1 -1
  32. package/plugins/copilot-pbr/references/agent-contracts.md +27 -0
  33. package/plugins/copilot-pbr/references/checkpoints.md +32 -1
  34. package/plugins/copilot-pbr/references/context-quality-tiers.md +45 -0
  35. package/plugins/copilot-pbr/references/pbr-tools-cli.md +115 -0
  36. package/plugins/copilot-pbr/references/questioning.md +21 -1
  37. package/plugins/copilot-pbr/references/verification-patterns.md +96 -18
  38. package/plugins/copilot-pbr/skills/audit/SKILL.md +19 -3
  39. package/plugins/copilot-pbr/skills/begin/SKILL.md +57 -4
  40. package/plugins/copilot-pbr/skills/build/SKILL.md +39 -2
  41. package/plugins/copilot-pbr/skills/config/SKILL.md +12 -2
  42. package/plugins/copilot-pbr/skills/debug/SKILL.md +12 -1
  43. package/plugins/copilot-pbr/skills/explore/SKILL.md +13 -2
  44. package/plugins/copilot-pbr/skills/health/SKILL.md +13 -5
  45. package/plugins/copilot-pbr/skills/import/SKILL.md +26 -1
  46. package/plugins/copilot-pbr/skills/milestone/SKILL.md +15 -3
  47. package/plugins/copilot-pbr/skills/plan/SKILL.md +50 -0
  48. package/plugins/copilot-pbr/skills/quick/SKILL.md +21 -0
  49. package/plugins/copilot-pbr/skills/review/SKILL.md +45 -0
  50. package/plugins/copilot-pbr/skills/scan/SKILL.md +20 -0
  51. package/plugins/copilot-pbr/skills/setup/SKILL.md +9 -1
  52. package/plugins/copilot-pbr/skills/shared/context-budget.md +10 -0
  53. package/plugins/copilot-pbr/skills/shared/universal-anti-patterns.md +6 -0
  54. package/plugins/copilot-pbr/skills/test/SKILL.md +210 -0
  55. package/plugins/copilot-pbr/templates/SUMMARY-complex.md.tmpl +95 -0
  56. package/plugins/copilot-pbr/templates/SUMMARY-minimal.md.tmpl +48 -0
  57. package/plugins/cursor-pbr/.cursor-plugin/plugin.json +1 -1
  58. package/plugins/cursor-pbr/agents/audit.md +52 -5
  59. package/plugins/cursor-pbr/agents/codebase-mapper.md +49 -1
  60. package/plugins/cursor-pbr/agents/debugger.md +50 -1
  61. package/plugins/cursor-pbr/agents/dev-sync.md +23 -0
  62. package/plugins/cursor-pbr/agents/executor.md +153 -8
  63. package/plugins/cursor-pbr/agents/general.md +46 -1
  64. package/plugins/cursor-pbr/agents/integration-checker.md +54 -1
  65. package/plugins/cursor-pbr/agents/plan-checker.md +49 -1
  66. package/plugins/cursor-pbr/agents/planner.md +80 -1
  67. package/plugins/cursor-pbr/agents/researcher.md +49 -1
  68. package/plugins/cursor-pbr/agents/synthesizer.md +49 -1
  69. package/plugins/cursor-pbr/agents/verifier.md +113 -12
  70. package/plugins/cursor-pbr/commands/test.md +5 -0
  71. package/plugins/cursor-pbr/hooks/hooks.json +9 -0
  72. package/plugins/cursor-pbr/references/agent-contracts.md +27 -0
  73. package/plugins/cursor-pbr/references/checkpoints.md +32 -1
  74. package/plugins/cursor-pbr/references/context-quality-tiers.md +45 -0
  75. package/plugins/cursor-pbr/references/pbr-tools-cli.md +115 -0
  76. package/plugins/cursor-pbr/references/questioning.md +21 -1
  77. package/plugins/cursor-pbr/references/verification-patterns.md +96 -18
  78. package/plugins/cursor-pbr/skills/audit/SKILL.md +19 -3
  79. package/plugins/cursor-pbr/skills/begin/SKILL.md +57 -4
  80. package/plugins/cursor-pbr/skills/build/SKILL.md +37 -2
  81. package/plugins/cursor-pbr/skills/config/SKILL.md +12 -2
  82. package/plugins/cursor-pbr/skills/debug/SKILL.md +12 -1
  83. package/plugins/cursor-pbr/skills/explore/SKILL.md +13 -2
  84. package/plugins/cursor-pbr/skills/health/SKILL.md +14 -5
  85. package/plugins/cursor-pbr/skills/import/SKILL.md +26 -1
  86. package/plugins/cursor-pbr/skills/milestone/SKILL.md +15 -3
  87. package/plugins/cursor-pbr/skills/plan/SKILL.md +50 -0
  88. package/plugins/cursor-pbr/skills/quick/SKILL.md +21 -0
  89. package/plugins/cursor-pbr/skills/review/SKILL.md +45 -0
  90. package/plugins/cursor-pbr/skills/scan/SKILL.md +20 -0
  91. package/plugins/cursor-pbr/skills/setup/SKILL.md +9 -1
  92. package/plugins/cursor-pbr/skills/shared/context-budget.md +10 -0
  93. package/plugins/cursor-pbr/skills/shared/universal-anti-patterns.md +6 -0
  94. package/plugins/cursor-pbr/skills/test/SKILL.md +211 -0
  95. package/plugins/cursor-pbr/templates/SUMMARY-complex.md.tmpl +95 -0
  96. package/plugins/cursor-pbr/templates/SUMMARY-minimal.md.tmpl +48 -0
  97. package/plugins/pbr/.claude-plugin/plugin.json +1 -1
  98. package/plugins/pbr/agents/audit.md +45 -0
  99. package/plugins/pbr/agents/codebase-mapper.md +48 -0
  100. package/plugins/pbr/agents/debugger.md +49 -0
  101. package/plugins/pbr/agents/dev-sync.md +23 -0
  102. package/plugins/pbr/agents/executor.md +151 -6
  103. package/plugins/pbr/agents/general.md +45 -0
  104. package/plugins/pbr/agents/integration-checker.md +53 -0
  105. package/plugins/pbr/agents/plan-checker.md +48 -0
  106. package/plugins/pbr/agents/planner.md +78 -1
  107. package/plugins/pbr/agents/researcher.md +48 -0
  108. package/plugins/pbr/agents/synthesizer.md +48 -0
  109. package/plugins/pbr/agents/verifier.md +112 -11
  110. package/plugins/pbr/commands/test.md +5 -0
  111. package/plugins/pbr/hooks/hooks.json +9 -0
  112. package/plugins/pbr/references/agent-contracts.md +27 -0
  113. package/plugins/pbr/references/checkpoints.md +32 -0
  114. package/plugins/pbr/references/context-quality-tiers.md +45 -0
  115. package/plugins/pbr/references/pbr-tools-cli.md +115 -0
  116. package/plugins/pbr/references/questioning.md +21 -0
  117. package/plugins/pbr/references/verification-patterns.md +96 -17
  118. package/plugins/pbr/scripts/check-plan-format.js +13 -1
  119. package/plugins/pbr/scripts/check-state-sync.js +26 -7
  120. package/plugins/pbr/scripts/check-subagent-output.js +30 -2
  121. package/plugins/pbr/scripts/config-schema.json +11 -1
  122. package/plugins/pbr/scripts/context-bridge.js +265 -0
  123. package/plugins/pbr/scripts/lib/config.js +271 -0
  124. package/plugins/pbr/scripts/lib/core.js +587 -0
  125. package/plugins/pbr/scripts/lib/history.js +73 -0
  126. package/plugins/pbr/scripts/lib/init.js +166 -0
  127. package/plugins/pbr/scripts/lib/migrate.js +169 -0
  128. package/plugins/pbr/scripts/lib/phase.js +364 -0
  129. package/plugins/pbr/scripts/lib/roadmap.js +175 -0
  130. package/plugins/pbr/scripts/lib/state.js +397 -0
  131. package/plugins/pbr/scripts/lib/todo.js +300 -0
  132. package/plugins/pbr/scripts/pbr-tools.js +425 -1310
  133. package/plugins/pbr/scripts/post-write-dispatch.js +5 -4
  134. package/plugins/pbr/scripts/pre-write-dispatch.js +1 -1
  135. package/plugins/pbr/scripts/progress-tracker.js +1 -1
  136. package/plugins/pbr/scripts/suggest-compact.js +1 -1
  137. package/plugins/pbr/scripts/track-context-budget.js +53 -2
  138. package/plugins/pbr/scripts/validate-task.js +20 -28
  139. package/plugins/pbr/skills/audit/SKILL.md +19 -3
  140. package/plugins/pbr/skills/begin/SKILL.md +48 -2
  141. package/plugins/pbr/skills/build/SKILL.md +39 -2
  142. package/plugins/pbr/skills/config/SKILL.md +12 -2
  143. package/plugins/pbr/skills/debug/SKILL.md +12 -1
  144. package/plugins/pbr/skills/debug/templates/continuation-prompt.md.tmpl +12 -1
  145. package/plugins/pbr/skills/debug/templates/initial-investigation-prompt.md.tmpl +12 -5
  146. package/plugins/pbr/skills/explore/SKILL.md +13 -2
  147. package/plugins/pbr/skills/health/SKILL.md +14 -3
  148. package/plugins/pbr/skills/help/SKILL.md +2 -0
  149. package/plugins/pbr/skills/import/SKILL.md +26 -1
  150. package/plugins/pbr/skills/milestone/SKILL.md +15 -3
  151. package/plugins/pbr/skills/plan/SKILL.md +52 -2
  152. package/plugins/pbr/skills/quick/SKILL.md +21 -0
  153. package/plugins/pbr/skills/review/SKILL.md +46 -0
  154. package/plugins/pbr/skills/scan/SKILL.md +20 -0
  155. package/plugins/pbr/skills/setup/SKILL.md +9 -1
  156. package/plugins/pbr/skills/shared/context-budget.md +10 -0
  157. package/plugins/pbr/skills/shared/universal-anti-patterns.md +6 -0
  158. package/plugins/pbr/skills/test/SKILL.md +212 -0
  159. package/plugins/pbr/templates/SUMMARY-complex.md.tmpl +95 -0
  160. package/plugins/pbr/templates/SUMMARY-minimal.md.tmpl +48 -0
@@ -55,11 +55,12 @@ function checkRoadmapWrite(data) {
55
55
  if (!fs.existsSync(filePath)) return null;
56
56
 
57
57
  const content = fs.readFileSync(filePath, 'utf8');
58
- const errors = validateRoadmap(content);
59
- if (errors && errors.length > 0) {
58
+ const result = validateRoadmap(content);
59
+ const combined = [...(result.errors || []), ...(result.warnings || [])];
60
+ if (combined.length > 0) {
60
61
  return {
61
62
  output: {
62
- additionalContext: `[ROADMAP Validation] ${errors.join('; ')}`
63
+ additionalContext: `[ROADMAP Validation] ${combined.join('; ')}`
63
64
  }
64
65
  };
65
66
  }
@@ -127,7 +128,7 @@ function main() {
127
128
  const normalizedPath = filePath.replace(/\\/g, '/');
128
129
  if (filePath && !normalizedPath.includes('.planning/') && !normalizedPath.includes('.planning\\')) {
129
130
  try {
130
- const cwd = process.cwd();
131
+ const cwd = process.env.PBR_PROJECT_ROOT || process.cwd();
131
132
  const planningDir = path.join(cwd, '.planning');
132
133
  const llmConfig = (() => {
133
134
  try {
@@ -129,7 +129,7 @@ function main() {
129
129
  if (phaseMatch) {
130
130
  const fs = require('fs');
131
131
  const path = require('path');
132
- const statePath = path.join(process.cwd(), '.planning', 'STATE.md');
132
+ const statePath = path.join(process.env.PBR_PROJECT_ROOT || process.cwd(), '.planning', 'STATE.md');
133
133
  try {
134
134
  const stateContent = fs.readFileSync(statePath, 'utf8');
135
135
  const currentPhase = stateContent.match(/Phase:\s*(\d+)\s+of/);
@@ -18,7 +18,7 @@ const { configLoad } = require('./pbr-tools');
18
18
  const { resolveConfig, checkHealth, warmUp } = require('./local-llm/health');
19
19
 
20
20
  async function main() {
21
- const cwd = process.cwd();
21
+ const cwd = process.env.PBR_PROJECT_ROOT || process.cwd();
22
22
  const planningDir = path.join(cwd, '.planning');
23
23
  const stateFile = path.join(planningDir, 'STATE.md');
24
24
 
@@ -26,7 +26,7 @@ function main() {
26
26
  process.stdin.resume();
27
27
  process.stdin.on('end', () => {
28
28
  try {
29
- const cwd = process.cwd();
29
+ const cwd = process.env.PBR_PROJECT_ROOT || process.cwd();
30
30
  const planningDir = path.join(cwd, '.planning');
31
31
  if (!fs.existsSync(planningDir)) {
32
32
  process.exit(0);
@@ -4,6 +4,10 @@
4
4
  * PostToolUse hook on Read: Tracks cumulative file reads per skill invocation.
5
5
  *
6
6
  * Maintains a session-scoped counter in .planning/.context-tracker.
7
+ * Integrates with context-bridge.js: if .planning/.context-budget.json exists
8
+ * and is fresh (< 60 seconds), uses its tier-based warnings instead of the
9
+ * heuristic char/file milestones.
10
+ *
7
11
  * Warns only at meaningful thresholds to reduce noise:
8
12
  * - Unique files read crosses milestone (10, 20, 30, ...)
9
13
  * - Total chars read crosses milestone (50k, 100k, 150k, ...)
@@ -18,6 +22,8 @@ const fs = require('fs');
18
22
  const path = require('path');
19
23
  const { logHook } = require('./hook-logger');
20
24
 
25
+ const BRIDGE_STALENESS_MS = 60000; // 60 seconds
26
+
21
27
  const UNIQUE_FILE_MILESTONE = 10; // warn every 10 unique files
22
28
  const CHAR_MILESTONE = 50000; // warn every 50k chars
23
29
  const LARGE_FILE_THRESHOLD = 5000; // warn if single read > 5k chars
@@ -29,7 +35,7 @@ function main() {
29
35
  process.stdin.on('data', (chunk) => { input += chunk; });
30
36
  process.stdin.on('end', () => {
31
37
  try {
32
- const cwd = process.cwd();
38
+ const cwd = process.env.PBR_PROJECT_ROOT || process.cwd();
33
39
  const planningDir = path.join(cwd, '.planning');
34
40
  if (!fs.existsSync(planningDir)) {
35
41
  process.exit(0);
@@ -103,6 +109,19 @@ function main() {
103
109
  try { fs.unlinkSync(trackerPath + '.' + process.pid); } catch (_e2) { /* best-effort cleanup */ }
104
110
  }
105
111
 
112
+ // Check bridge file for tier-based context warnings
113
+ const bridgeTier = checkBridge(planningDir);
114
+ if (bridgeTier) {
115
+ // Bridge is fresh and providing tier warnings — skip heuristic milestones
116
+ // (the bridge's context-bridge.js already handles tier debounce)
117
+ logHook('track-context-budget', 'PostToolUse', 'bridge-active', {
118
+ reads: tracker.reads,
119
+ total_chars: tracker.total_chars,
120
+ tier: bridgeTier,
121
+ });
122
+ process.exit(0);
123
+ }
124
+
106
125
  // Check thresholds — only warn at milestone crossings, not every read
107
126
  const warnings = [];
108
127
 
@@ -165,4 +184,36 @@ function loadTracker(trackerPath) {
165
184
  }
166
185
  }
167
186
 
168
- main();
187
+ /**
188
+ * Check the context bridge file for tier-based warnings.
189
+ * Returns the current tier name if the bridge is fresh, null otherwise.
190
+ *
191
+ * @param {string} planningDir - Path to .planning/
192
+ * @returns {string|null} Tier name if bridge is active and fresh, null if stale/missing
193
+ */
194
+ function checkBridge(planningDir) {
195
+ const bridgePath = path.join(planningDir, '.context-budget.json');
196
+ try {
197
+ if (!fs.existsSync(bridgePath)) return null;
198
+
199
+ const stats = fs.statSync(bridgePath);
200
+ const ageMs = Date.now() - stats.mtimeMs;
201
+ if (ageMs > BRIDGE_STALENESS_MS) return null;
202
+
203
+ const content = fs.readFileSync(bridgePath, 'utf8');
204
+ const bridge = JSON.parse(content);
205
+
206
+ // Only trust bridge data that has a real source or recent update
207
+ if (!bridge.estimated_percent && bridge.estimated_percent !== 0) return null;
208
+
209
+ const { getTier } = require('./context-bridge');
210
+ const tier = getTier(bridge.estimated_percent);
211
+ return tier.name;
212
+ } catch (_e) {
213
+ return null;
214
+ }
215
+ }
216
+
217
+ module.exports = { checkBridge, BRIDGE_STALENESS_MS };
218
+
219
+ if (require.main === module || process.argv[1] === __filename) { main(); }
@@ -23,6 +23,7 @@ const { logHook } = require('./hook-logger');
23
23
  const { resolveConfig } = require('./local-llm/health');
24
24
  const { validateTask: llmValidateTask } = require('./local-llm/operations/validate-task');
25
25
  const { checkNonPbrAgent } = require('./enforce-pbr-workflow');
26
+ const { KNOWN_AGENTS } = require('./pbr-tools');
26
27
 
27
28
  /**
28
29
  * Load and resolve the local_llm config block from .planning/config.json.
@@ -39,21 +40,6 @@ function loadLocalLlmConfig(cwd) {
39
40
  }
40
41
  }
41
42
 
42
- const KNOWN_AGENTS = [
43
- 'researcher',
44
- 'planner',
45
- 'plan-checker',
46
- 'executor',
47
- 'verifier',
48
- 'integration-checker',
49
- 'debugger',
50
- 'codebase-mapper',
51
- 'synthesizer',
52
- 'general',
53
- 'audit',
54
- 'dev-sync'
55
- ];
56
-
57
43
  const MAX_DESCRIPTION_LENGTH = 100;
58
44
 
59
45
  /**
@@ -115,7 +101,7 @@ function checkQuickExecutorGate(data) {
115
101
  // Only gate pbr:executor
116
102
  if (subagentType !== 'pbr:executor') return null;
117
103
 
118
- const cwd = process.cwd();
104
+ const cwd = process.env.PBR_PROJECT_ROOT || process.cwd();
119
105
  const planningDir = path.join(cwd, '.planning');
120
106
  const activeSkillFile = path.join(planningDir, '.active-skill');
121
107
 
@@ -181,7 +167,7 @@ function checkBuildExecutorGate(data) {
181
167
  // Only gate pbr:executor
182
168
  if (subagentType !== 'pbr:executor') return null;
183
169
 
184
- const cwd = process.cwd();
170
+ const cwd = process.env.PBR_PROJECT_ROOT || process.cwd();
185
171
  const planningDir = path.join(cwd, '.planning');
186
172
  const activeSkillFile = path.join(planningDir, '.active-skill');
187
173
 
@@ -253,7 +239,7 @@ function checkPlanExecutorGate(data) {
253
239
  // Only gate pbr:executor
254
240
  if (subagentType !== 'pbr:executor') return null;
255
241
 
256
- const cwd = process.cwd();
242
+ const cwd = process.env.PBR_PROJECT_ROOT || process.cwd();
257
243
  const planningDir = path.join(cwd, '.planning');
258
244
  const activeSkillFile = path.join(planningDir, '.active-skill');
259
245
 
@@ -282,7 +268,7 @@ function checkReviewPlannerGate(data) {
282
268
  // Only gate pbr:planner
283
269
  if (subagentType !== 'pbr:planner') return null;
284
270
 
285
- const cwd = process.cwd();
271
+ const cwd = process.env.PBR_PROJECT_ROOT || process.cwd();
286
272
  const planningDir = path.join(cwd, '.planning');
287
273
  const activeSkillFile = path.join(planningDir, '.active-skill');
288
274
 
@@ -336,7 +322,7 @@ function checkReviewVerifierGate(data) {
336
322
  // Only gate pbr:verifier
337
323
  if (subagentType !== 'pbr:verifier') return null;
338
324
 
339
- const cwd = process.cwd();
325
+ const cwd = process.env.PBR_PROJECT_ROOT || process.cwd();
340
326
  const planningDir = path.join(cwd, '.planning');
341
327
  const activeSkillFile = path.join(planningDir, '.active-skill');
342
328
 
@@ -396,7 +382,7 @@ function checkMilestoneCompleteGate(data) {
396
382
  const subagentType = toolInput.subagent_type || '';
397
383
  const description = toolInput.description || '';
398
384
 
399
- const cwd = process.cwd();
385
+ const cwd = process.env.PBR_PROJECT_ROOT || process.cwd();
400
386
  const planningDir = path.join(cwd, '.planning');
401
387
  const activeSkillFile = path.join(planningDir, '.active-skill');
402
388
 
@@ -503,7 +489,7 @@ function checkBuildDependencyGate(data) {
503
489
  // Only gate pbr:executor
504
490
  if (subagentType !== 'pbr:executor') return null;
505
491
 
506
- const cwd = process.cwd();
492
+ const cwd = process.env.PBR_PROJECT_ROOT || process.cwd();
507
493
  const planningDir = path.join(cwd, '.planning');
508
494
  const activeSkillFile = path.join(planningDir, '.active-skill');
509
495
 
@@ -607,14 +593,15 @@ function checkDebuggerAdvisory(data) {
607
593
  const subagentType = data.tool_input?.subagent_type || '';
608
594
  if (subagentType !== 'pbr:debugger') return null;
609
595
  // Only advise when spawned from the debug skill
610
- const activeSkillPath = path.join(process.cwd(), '.planning', '.active-skill');
596
+ const debugCwd = process.env.PBR_PROJECT_ROOT || process.cwd();
597
+ const activeSkillPath = path.join(debugCwd, '.planning', '.active-skill');
611
598
  try {
612
599
  const activeSkill = fs.readFileSync(activeSkillPath, 'utf8').trim();
613
600
  if (activeSkill !== 'debug') return null;
614
601
  } catch (_e) {
615
602
  return null; // No .active-skill file — skip advisory
616
603
  }
617
- const debugDir = path.join(process.cwd(), '.planning', 'debug');
604
+ const debugDir = path.join(debugCwd, '.planning', 'debug');
618
605
  if (!fs.existsSync(debugDir)) {
619
606
  return 'Debugger advisory: .planning/debug/ does not exist. Create it before spawning the debugger so output has a target location.';
620
607
  }
@@ -627,7 +614,7 @@ function checkCheckpointManifest(data) {
627
614
 
628
615
  if (subagentType !== 'pbr:executor') return null;
629
616
 
630
- const cwd = process.cwd();
617
+ const cwd = process.env.PBR_PROJECT_ROOT || process.cwd();
631
618
  const planningDir = path.join(cwd, '.planning');
632
619
  const activeSkillFile = path.join(planningDir, '.active-skill');
633
620
 
@@ -676,7 +663,11 @@ function checkActiveSkillIntegrity(data) {
676
663
 
677
664
  if (typeof subagentType !== 'string' || !subagentType.startsWith('pbr:')) return null;
678
665
 
679
- const cwd = process.cwd();
666
+ // Advisory agents that run without an active skill context — exempt from .active-skill checks
667
+ const EXEMPT_AGENTS = ['pbr:researcher', 'pbr:synthesizer', 'pbr:audit', 'pbr:dev-sync', 'pbr:general'];
668
+ if (EXEMPT_AGENTS.includes(subagentType)) return null;
669
+
670
+ const cwd = process.env.PBR_PROJECT_ROOT || process.cwd();
680
671
  const planningDir = path.join(cwd, '.planning');
681
672
 
682
673
  // Only check if .planning/ exists (PBR project)
@@ -815,8 +806,9 @@ function main() {
815
806
 
816
807
  // LLM task coherence check — advisory only
817
808
  try {
818
- const llmConfig = loadLocalLlmConfig(process.cwd());
819
- const planningDir = path.join(process.cwd(), '.planning');
809
+ const llmCwd = process.env.PBR_PROJECT_ROOT || process.cwd();
810
+ const llmConfig = loadLocalLlmConfig(llmCwd);
811
+ const planningDir = path.join(llmCwd, '.planning');
820
812
  const llmResult = await llmValidateTask(llmConfig, planningDir, data.tool_input || {}, data.session_id);
821
813
  if (llmResult && !llmResult.coherent) {
822
814
  warnings.push('LLM task coherence advisory: ' + (llmResult.issue || 'Task description may not match intended operation.') + ' (confidence: ' + (llmResult.confidence * 100).toFixed(0) + '%)');
@@ -137,7 +137,12 @@ For each session:
137
137
  ```
138
138
  Task({
139
139
  subagent_type: "pbr:audit",
140
- prompt: "<audit_assignment>
140
+ prompt: "<files_to_read>
141
+ CRITICAL: Read these files BEFORE any other action:
142
+ 1. {absolute_path_to_session.jsonl} — session log to analyze
143
+ 2. {subagent log paths, if any} — subagent session logs
144
+ </files_to_read>
145
+ <audit_assignment>
141
146
  Session JSONL: {absolute_path_to_session.jsonl}
142
147
  Subagent logs: {list of subagent jsonl paths, or 'none'}
143
148
  Audit mode: {mode}
@@ -173,7 +178,9 @@ Display progress:
173
178
 
174
179
  ## Step 5 — Collect and Synthesize
175
180
 
176
- As agents complete, collect their findings. Wait for all agents before proceeding.
181
+ As agents complete, check each audit agent's Task() output for `## AUDIT COMPLETE`. If the marker is absent, mark that session as "analysis failed" in the synthesis and skip its findings — do not treat incomplete output as valid analysis. Log: `⚠ Session {id}: audit agent did not return completion marker — skipping.`
182
+
183
+ Wait for all agents before proceeding.
177
184
 
178
185
  Synthesize across all sessions:
179
186
 
@@ -258,6 +265,15 @@ The report should follow this structure:
258
265
 
259
266
  ---
260
267
 
268
+ ## Step 6b — Spot-Check Artifacts
269
+
270
+ **Before displaying results, verify the report landed on disk:**
271
+
272
+ 1. Glob `.planning/audits/{YYYY-MM-DD}-session-audit.md` to confirm the file exists
273
+ 2. If missing: re-attempt the write (Step 6). If still missing, display an error and include findings inline instead.
274
+
275
+ ---
276
+
261
277
  ## Step 7 — Display Summary
262
278
 
263
279
  After writing the report, display inline (keep it concise — the full report is on disk):
@@ -289,7 +305,7 @@ Full report: .planning/audits/{filename}
289
305
  - If todos identified: **Create todos** → `/pbr:todo add "{description}"`
290
306
  - Default: **See project status** → `/pbr:status`
291
307
 
292
- `/clear` first → fresh context window
308
+ <sub>`/clear` first → fresh context window</sub>
293
309
  ```
294
310
 
295
311
  ---
@@ -220,6 +220,7 @@ Spawn parallel Task() subagents for research. Each researcher writes to `.planni
220
220
  ```
221
221
  Task({
222
222
  subagent_type: "pbr:researcher",
223
+ // After researcher: check for ## RESEARCH COMPLETE or ## RESEARCH BLOCKED
223
224
  prompt: <see researcher prompt template below>
224
225
  })
225
226
  ```
@@ -234,6 +235,14 @@ For each researcher, construct the prompt by reading the template and filling in
234
235
 
235
236
  Read `skills/begin/templates/researcher-prompt.md.tmpl` for the prompt structure.
236
237
 
238
+ **Prepend this block to the researcher prompt before sending:**
239
+ ```
240
+ <files_to_read>
241
+ CRITICAL: Read these files BEFORE any other action:
242
+ 1. .planning/REQUIREMENTS.md — scoped requirements (if exists)
243
+ </files_to_read>
244
+ ```
245
+
237
246
  **Placeholders to fill:**
238
247
  - `{project name from questioning}` — project name gathered in Step 2
239
248
  - `{2-3 sentence description from questioning}` — project description from Step 2
@@ -303,10 +312,36 @@ Task({
303
312
 
304
313
  Read `skills/begin/templates/synthesis-prompt.md.tmpl` for the prompt structure.
305
314
 
315
+ **Prepend this block to the synthesizer prompt before sending:**
316
+ ```
317
+ <files_to_read>
318
+ CRITICAL: Read these files BEFORE any other action:
319
+ 1. .planning/research/*.md — all research output files from Step 5
320
+ </files_to_read>
321
+ ```
322
+
306
323
  **Placeholders to fill:**
307
324
  - `{List all .planning/research/*.md files that were created}` — list the research files produced in Step 5
308
325
 
309
- **After the synthesizer completes**, display:
326
+ **After the synthesizer completes**, check for completion markers in the Task() output:
327
+
328
+ - If `## SYNTHESIS COMPLETE` is present: proceed normally
329
+ - If `## SYNTHESIS BLOCKED` is present: warn the user and offer to proceed without synthesis:
330
+ ```
331
+ ⚠ Synthesizer reported BLOCKED: {reason from output}
332
+ Research files are still available individually in .planning/research/.
333
+ ```
334
+ Use AskUserQuestion (pattern: yes-no from `skills/shared/gate-prompts.md`):
335
+ question: "Synthesis was blocked. Continue without synthesis?"
336
+ header: "Blocked"
337
+ options:
338
+ - label: "Yes" description: "Proceed to requirements — use individual research files"
339
+ - label: "No" description: "Stop and investigate"
340
+ - If "Yes": proceed to Step 7 without SUMMARY.md
341
+ - If "No": stop and suggest reviewing .planning/research/ files
342
+ - If neither marker is found: warn the user that the synthesizer may not have completed successfully, but proceed if SUMMARY.md exists on disk
343
+
344
+ If synthesis succeeded, display:
310
345
  ```
311
346
  ✓ Research synthesis complete — see .planning/research/SUMMARY.md
312
347
  ```
@@ -367,6 +402,7 @@ Spawn the planner in roadmap mode:
367
402
  ```
368
403
  Task({
369
404
  subagent_type: "pbr:planner",
405
+ // After planner: check for ## PLANNING COMPLETE or ## PLANNING FAILED
370
406
  prompt: <roadmap prompt>
371
407
  })
372
408
  ```
@@ -379,12 +415,22 @@ Task({
379
415
 
380
416
  Read `skills/begin/templates/roadmap-prompt.md.tmpl` for the prompt structure.
381
417
 
418
+ **Prepend this block to the roadmap planner prompt before sending:**
419
+ ```
420
+ <files_to_read>
421
+ CRITICAL: Read these files BEFORE any other action:
422
+ 1. .planning/REQUIREMENTS.md — scoped requirements for phase planning
423
+ 2. .planning/research/SUMMARY.md — research synthesis (if exists)
424
+ </files_to_read>
425
+ ```
426
+
382
427
  **Placeholders to fill:**
383
428
  - `{project name}` — project name from Step 2
384
429
  - `{description}` — project description from Step 2
385
430
  - `{quick|standard|comprehensive}` — depth setting from Step 3
386
431
 
387
432
  **After the planner completes:**
433
+ - **Spot-check:** Verify `.planning/ROADMAP.md` exists on disk using Glob before attempting to read it. If missing, the planner may have failed silently — warn: `⚠ ROADMAP.md not found after planner completed. Re-spawning planner...` and retry once.
388
434
  - Read `.planning/ROADMAP.md`
389
435
  - Count the phases from the roadmap content
390
436
  - Verify the roadmap contains a `## Milestone:` section wrapping the phases (the planner should generate this). If not, the initial set of phases constitutes the first milestone — add the section header yourself.
@@ -532,7 +578,7 @@ Delete `.planning/.active-skill` if it exists. This must happen on all paths (su
532
578
 
533
579
  After all steps complete, present the final summary using the stage banner format from Read `references/ui-formatting.md`:
534
580
 
535
- Display the `PROJECT INITIALIZED ✓` banner with project name, core value, phase list, and requirement counts. Then display the "Next Up" block (see § "Next Up Block" in ui-formatting.md) pointing to `/pbr:discuss 1` with alternatives: `/pbr:explore`, `/pbr:plan 1`, `/pbr:milestone new`, `/pbr:config`.
581
+ Display the `PROJECT INITIALIZED ✓` banner with project name, core value, phase list, and requirement counts. Then display the "Next Up" block (see § "Next Up Block" in ui-formatting.md) pointing to `/pbr:discuss 1` with alternatives: `/pbr:explore`, `/pbr:plan 1`, `/pbr:milestone new`, `/pbr:config`. Include `<sub>/clear first → fresh context window</sub>` inside the Next Up routing block.
536
582
 
537
583
  ---
538
584
 
@@ -134,6 +134,8 @@ Phase {N} depends on Phase {M}, which is not complete.
134
134
 
135
135
  ### Step 2: Load Config (inline)
136
136
 
137
+ **Init-first pattern**: When spawning agents, pass the output of `node plugins/pbr/scripts/pbr-tools.js init execute-phase {N}` as context rather than having the agent read multiple files separately. This reduces file reads and prevents context-loading failures.
138
+
137
139
  Read configuration values needed for execution. See `skills/shared/config-loading.md` for the full field reference; build uses: `parallelization.*`, `features.goal_verification`, `features.inline_verify`, `features.atomic_commits`, `features.auto_continue`, `features.auto_advance`, `planning.commit_docs`, `git.commit_format`, `git.branching`.
138
140
 
139
141
  ---
@@ -303,6 +305,13 @@ Construct the executor prompt:
303
305
  ```
304
306
  You are the executor agent. Execute the following plan.
305
307
 
308
+ <files_to_read>
309
+ CRITICAL: Read these files BEFORE any other action:
310
+ 1. .planning/phases/{NN}-{slug}/{plan_id}-PLAN.md — the full plan with task details
311
+ 2. .planning/CONTEXT.md — locked decisions and constraints (if exists)
312
+ 3. .planning/STATE.md — current project state and progress
313
+ </files_to_read>
314
+
306
315
  <plan_summary>
307
316
  [Inline only the ## Summary section from PLAN.md]
308
317
  </plan_summary>
@@ -372,7 +381,9 @@ Task({
372
381
  prompt: <executor prompt constructed above>
373
382
  })
374
383
 
375
- NOTE: The pbr:executor subagent type auto-loads the agent definition. Do NOT inline it.
384
+ NOTE: The pbr:executor subagent type auto-loads the agent definition.
385
+
386
+ After executor completes, check for completion markers: `## PLAN COMPLETE`, `## PLAN FAILED`, or `## CHECKPOINT: {TYPE}`. Route accordingly — PLAN COMPLETE proceeds to next plan, PLAN FAILED triggers failure handling, CHECKPOINT triggers checkpoint flow. Do NOT inline it.
376
387
  ```
377
388
 
378
389
  **Path resolution**: Before constructing the agent prompt, resolve `${CLAUDE_PLUGIN_ROOT}` to its absolute path. Do not pass the variable literally in prompts — Task() contexts may not expand it. Use the resolved absolute path for any pbr-tools.js or template references included in the prompt.
@@ -408,6 +419,11 @@ After reading each SUMMARY, perform a lightweight verification:
408
419
  - If ANY spot-check fails, warn the user before proceeding to the next wave:
409
420
  "Spot-check failed for plan {id}: {detail}. Inspect before continuing?"
410
421
 
422
+ **Additional wave spot-checks:**
423
+ - Check for `## Self-Check: FAILED` in SUMMARY.md — if present, warn user before proceeding to next wave
424
+ - Between waves: verify no file conflicts from parallel executors (check `git status` for uncommitted changes)
425
+ - If ANY spot-check fails, present user with: **Retry this plan** / **Continue to next wave** / **Abort build**
426
+
411
427
  **Read executor deviations:**
412
428
 
413
429
  After all executors in the wave complete, read all SUMMARY frontmatter and:
@@ -450,7 +466,14 @@ For each plan that completed successfully in this wave:
450
466
  Task({
451
467
  subagent_type: "pbr:verifier",
452
468
  model: "haiku",
453
- prompt: "Targeted inline verification for plan {plan_id}.
469
+ prompt: "<files_to_read>
470
+ CRITICAL: Read these files BEFORE any other action:
471
+ 1. .planning/phases/{NN}-{slug}/{plan_id}-PLAN.md — must-haves to verify against
472
+ 2. .planning/phases/{NN}-{slug}/SUMMARY-{plan_id}.md — what the executor claims was built
473
+ 3. .planning/phases/{NN}-{slug}/VERIFICATION.md — prior verification results (if exists)
474
+ </files_to_read>
475
+
476
+ Targeted inline verification for plan {plan_id}.
454
477
 
455
478
  Verify ONLY these files: {comma-separated key_files list}
456
479
 
@@ -655,6 +678,8 @@ Task({
655
678
  })
656
679
 
657
680
  NOTE: The pbr:verifier subagent type auto-loads the agent definition. Do NOT inline it.
681
+
682
+ After verifier completes, check for completion marker: `## VERIFICATION COMPLETE`. Read VERIFICATION.md frontmatter for status.
658
683
  ```
659
684
 
660
685
  **Path resolution**: Before constructing the agent prompt, resolve `${CLAUDE_PLUGIN_ROOT}` to its absolute path. Do not pass the variable literally in prompts — Task() contexts may not expand it. Use the resolved absolute path for any pbr-tools.js or template references included in the prompt.
@@ -663,6 +688,16 @@ NOTE: The pbr:verifier subagent type auto-loads the agent definition. Do NOT inl
663
688
 
664
689
  Use the same verifier prompt template as defined in `/pbr:review`: read `skills/review/templates/verifier-prompt.md.tmpl` and fill in its placeholders with the phase's PLAN.md must_haves and SUMMARY.md file paths. This avoids maintaining duplicate verifier prompts across skills.
665
690
 
691
+ **Prepend this block to the verifier prompt before sending:**
692
+ ```
693
+ <files_to_read>
694
+ CRITICAL: Read these files BEFORE any other action:
695
+ 1. .planning/phases/{NN}-{slug}/PLAN-*.md — must-haves to verify against
696
+ 2. .planning/phases/{NN}-{slug}/SUMMARY-*.md — executor build summaries
697
+ 3. .planning/phases/{NN}-{slug}/VERIFICATION.md — prior verification results (if exists)
698
+ </files_to_read>
699
+ ```
700
+
666
701
  After the verifier returns, read the VERIFICATION.md frontmatter and display the results:
667
702
 
668
703
  - If status is `passed`: display `✓ Verifier: {X}/{Y} must-haves verified` (where X = `must_haves_passed` and Y = `must_haves_checked`)
@@ -827,6 +862,8 @@ Then present the appropriate branded banner from Read `references/ui-formatting.
827
862
  - **If `passed` + last phase:** Use the "Milestone Complete" template. Fill in phase count.
828
863
  - **If `gaps_found`:** Use the "Gaps Found" template. Fill in phase number, name, score, and gap summaries from VERIFICATION.md.
829
864
 
865
+ Include `<sub>/clear first → fresh context window</sub>` inside the Next Up routing block of the completion template.
866
+
830
867
  **8g. Display USER-SETUP.md (conditional):**
831
868
 
832
869
  Check if `.planning/phases/{NN}-{slug}/USER-SETUP.md` exists. If it does:
@@ -115,10 +115,11 @@ Use AskUserQuestion:
115
115
  - label: "Depth" description: "quick/standard/comprehensive"
116
116
  - label: "Model profile" description: "quality/balanced/budget/adaptive"
117
117
  - label: "Features" description: "Toggle workflow features, gates, status line"
118
- - label: "Git settings" description: "branching strategy, commit mode"
118
+ - label: "Git settings" description: "branching strategy, commit mode"
119
+ - label: "Save as defaults" description: "Save current config as user-level defaults for new projects"
119
120
  multiSelect: false
120
121
 
121
- Note: The original 7 categories are condensed to 4. "Models" (per-agent) is accessible through "Model profile" with a follow-up option. "Gates", "Parallelization", and "Status Line" are grouped under "Features".
122
+ Note: The original 7 categories are condensed to 5. "Models" (per-agent) is accessible through "Model profile" with a follow-up option. "Gates", "Parallelization", and "Status Line" are grouped under "Features". "Save as defaults" exports to ~/.claude/pbr-defaults.json.
122
123
 
123
124
  **Follow-up based on selection:**
124
125
 
@@ -181,6 +182,15 @@ Use AskUserQuestion:
181
182
  - label: "Disabled" description: "No git integration"
182
183
  multiSelect: false
183
184
 
185
+ If user selects "Save as defaults":
186
+ Save current project config as user-level defaults for future projects:
187
+
188
+ ```bash
189
+ node "${CLAUDE_PLUGIN_ROOT}/scripts/pbr-tools.js" config save-defaults
190
+ ```
191
+
192
+ Display: "Saved your preferences to ~/.claude/pbr-defaults.json. New projects created with /pbr:setup will use these as starting values."
193
+
184
194
  If user types something else (freeform): interpret as a direct setting command and handle via Step 2 argument parsing logic.
185
195
 
186
196
  ### 4. Apply Changes
@@ -213,7 +213,18 @@ Continuing investigation...
213
213
 
214
214
  ### Step 4: Handle Debugger Results
215
215
 
216
- When the debugger agent completes, display: `✓ Debug session complete {N} hypotheses tested` (read the hypothesis count from the debug file's Hypotheses table).
216
+ When the debugger agent completes, first check for completion markers in the Task() output before routing:
217
+
218
+ | Marker in Task() Output | Route To |
219
+ |--------------------------|----------|
220
+ | `## DEBUG COMPLETE` | ROOT CAUSE FOUND + FIX path |
221
+ | `## ROOT CAUSE FOUND` | ROOT CAUSE FOUND (no fix) path |
222
+ | `## DEBUG SESSION PAUSED` | CHECKPOINT path |
223
+ | No marker found | INCONCLUSIVE path |
224
+
225
+ **Spot-check:** Before routing, verify `.planning/debug/{NNN}-{slug}.md` exists and was recently updated (modified timestamp is newer than the Task() spawn time). If the debug file was not updated, warn: `⚠ Debug file not updated by agent — results may be incomplete.`
226
+
227
+ Display: `✓ Debug session complete — {N} hypotheses tested` (read the hypothesis count from the debug file's Hypotheses table).
217
228
 
218
229
  The debugger returns one of four outcomes:
219
230
 
@@ -1,6 +1,13 @@
1
1
  <!-- Source: skills/debug/SKILL.md | Purpose: Spawn prompt for continuation debugger investigation -->
2
2
  You are debugger. Continue investigating the following issue.
3
3
 
4
+ <files_to_read>
5
+ CRITICAL: Read these files BEFORE any other action:
6
+ 1. .planning/debug/{NNN}-{slug}.md — the debug session file with all prior findings
7
+ 2. .planning/CONTEXT.md — locked decisions and constraints (if exists)
8
+ 3. .planning/STATE.md — current project state (if exists)
9
+ </files_to_read>
10
+
4
11
  Debug file: .planning/debug/{NNN}-{slug}.md
5
12
  Mode: continuation
6
13
 
@@ -13,4 +20,8 @@ Instructions:
13
20
  3. Formulate NEW hypotheses based on prior findings
14
21
  4. Continue systematic investigation
15
22
  5. Update the debug file
16
- 6. Return: ROOT_CAUSE_FOUND, CHECKPOINT, or INCONCLUSIVE
23
+ 6. Return one of these markers as a heading in your response:
24
+ - `## DEBUG COMPLETE` — root cause found + fix applied
25
+ - `## ROOT CAUSE FOUND` — root cause identified, no fix applied
26
+ - `## DEBUG SESSION PAUSED` — checkpoint, need user input
27
+ - If no root cause found after exhausting hypotheses, return without a marker (treated as INCONCLUSIVE)
@@ -1,6 +1,13 @@
1
1
  <!-- Source: skills/debug/SKILL.md | Purpose: Spawn prompt for initial debugger investigation -->
2
2
  You are debugger. Investigate the following issue systematically.
3
3
 
4
+ <files_to_read>
5
+ CRITICAL: Read these files BEFORE any other action:
6
+ 1. .planning/debug/{NNN}-{slug}.md — the debug session file with symptoms and context
7
+ 2. .planning/CONTEXT.md — locked decisions and constraints (if exists)
8
+ 3. .planning/STATE.md — current project state (if exists)
9
+ </files_to_read>
10
+
4
11
  Debug file: .planning/debug/{NNN}-{slug}.md
5
12
  Mode: initial_investigation
6
13
 
@@ -20,8 +27,8 @@ Instructions:
20
27
  c. Execute the test
21
28
  d. Record the result (confirmed, rejected, inconclusive)
22
29
  4. Update the debug file with findings
23
- 5. Return one of:
24
- - ROOT_CAUSE_FOUND: {cause} + FIX: {what to change}
25
- - ROOT_CAUSE_FOUND: {cause} (if find_root_cause_only mode)
26
- - CHECKPOINT: {what was found, what to investigate next}
27
- - INCONCLUSIVE: {findings so far, suggested next approaches}
30
+ 5. Return one of these markers as a heading in your response:
31
+ - `## DEBUG COMPLETE` — root cause found + fix applied: {cause} + {what was changed}
32
+ - `## ROOT CAUSE FOUND` — root cause identified, no fix applied (if find_root_cause_only mode): {cause}
33
+ - `## DEBUG SESSION PAUSED` — checkpoint, need user input: {what was found, what to investigate next}
34
+ - If no root cause found after exhausting hypotheses, return without a marker (treated as INCONCLUSIVE)
@@ -122,7 +122,12 @@ Display to the user: `◐ Spawning researcher...`
122
122
  ```
123
123
  Task({
124
124
  subagent_type: "pbr:researcher",
125
- prompt: "<research_assignment>
125
+ prompt: "<files_to_read>
126
+ CRITICAL: Read these files BEFORE any other action:
127
+ 1. .planning/CONTEXT.md — locked decisions and constraints (if exists)
128
+ 2. .planning/STATE.md — current project state (if exists)
129
+ </files_to_read>
130
+ <research_assignment>
126
131
  Topic: {specific research question}
127
132
  Output file: .planning/research/{topic-slug}.md
128
133
  Mode: project-research
@@ -134,7 +139,13 @@ Task({
134
139
  })
135
140
  ```
136
141
 
137
- After the researcher completes, display: `✓ Research complete results in .planning/research/{topic-slug}.md`
142
+ After the researcher completes, check for completion markers in the Task() output:
143
+
144
+ - If `## RESEARCH COMPLETE` is present: proceed normally
145
+ - If `## RESEARCH BLOCKED` is present: display the blocker reason and offer to retry:
146
+ `⚠ Research blocked: {reason}. Try a different angle or continue without research.`
147
+
148
+ Display: `✓ Research complete — results in .planning/research/{topic-slug}.md`
138
149
 
139
150
  Then:
140
151
  - Read ONLY the frontmatter and summary section of the research file (not the full document)