@sienklogic/plan-build-run 2.19.1 → 2.19.2
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 +29 -16
- package/README.md +3 -3
- package/dashboard/server/index.js +10 -1
- package/dashboard/server/routes/agents.js +23 -2
- package/dashboard/server/routes/health.js +7 -4
- package/dashboard/server/routes/telemetry.js +20 -1
- package/dashboard/server/services/planning-reader.js +3 -17
- package/package.json +1 -1
- package/plan-build-run/bin/config-schema.json +23 -145
- package/plugins/pbr/.claude-plugin/plugin.json +1 -1
- package/plugins/pbr/agents/advisor-researcher.md +1 -0
- package/plugins/pbr/agents/debugger.md +0 -4
- package/plugins/pbr/agents/researcher.md +0 -4
- package/plugins/pbr/agents/synthesizer.md +0 -4
- package/plugins/pbr/dist/check-config-change.js +0 -7
- package/plugins/pbr/dist/check-cross-plugin-sync.js +1 -1
- package/plugins/pbr/dist/check-plan-format.js +0 -32
- package/plugins/pbr/dist/check-roadmap-sync.js +15 -11
- package/plugins/pbr/dist/check-subagent-output.js +4 -60
- package/plugins/pbr/dist/check-summary-gate.js +3 -14
- package/plugins/pbr/dist/feedback-loop.js +12 -29
- package/plugins/pbr/dist/hook-server.js +58 -6
- package/plugins/pbr/dist/milestone-learnings.js +6 -56
- package/plugins/pbr/dist/pbr-tools.js +8 -91
- package/plugins/pbr/dist/post-bash-triage.js +5 -63
- package/plugins/pbr/dist/post-hoc.js +3 -52
- package/plugins/pbr/dist/post-write-dispatch.js +0 -36
- package/plugins/pbr/dist/pre-bash-dispatch.js +1 -7
- package/plugins/pbr/dist/pre-task-dispatch.js +0 -28
- package/plugins/pbr/dist/progress-tracker.js +2 -27
- package/plugins/pbr/dist/session-cleanup.js +1 -31
- package/plugins/pbr/dist/status-line.js +13 -11
- package/plugins/pbr/dist/suggest-compact.js +2 -10
- package/plugins/pbr/dist/validate-commit.js +8 -64
- package/plugins/pbr/dist/validate-task.js +0 -30
- package/plugins/pbr/references/config-reference.md +0 -96
- package/plugins/pbr/scripts/audit-checks/si-agent-hook-config-checks.js +2 -72
- package/plugins/pbr/scripts/audit-checks/workflow-compliance.js +5 -41
- package/plugins/pbr/scripts/check-config-change.js +0 -7
- package/plugins/pbr/scripts/check-cross-plugin-sync.js +1 -1
- package/plugins/pbr/scripts/check-plan-format.js +0 -32
- package/plugins/pbr/scripts/check-roadmap-sync.js +15 -11
- package/plugins/pbr/scripts/check-subagent-output.js +4 -60
- package/plugins/pbr/scripts/check-summary-gate.js +3 -14
- package/plugins/pbr/scripts/config-schema.json +16 -129
- package/plugins/pbr/scripts/feedback-loop.js +12 -29
- package/plugins/pbr/scripts/hook-server.js +58 -6
- package/plugins/pbr/scripts/lib/config.js +4 -11
- package/plugins/pbr/scripts/lib/contextual-help.js +5 -29
- package/plugins/pbr/scripts/lib/format-validators.js +1 -26
- package/plugins/pbr/scripts/lib/frontmatter.js +4 -4
- package/plugins/pbr/scripts/lib/gates/rich-agent-context.js +13 -19
- package/plugins/pbr/scripts/lib/health.js +4 -5
- package/plugins/pbr/scripts/lib/help.js +3 -54
- package/plugins/pbr/scripts/lib/phase.js +2 -4
- package/plugins/pbr/scripts/lib/pre-commit-checks.js +1 -1
- package/plugins/pbr/scripts/lib/pre-research.js +10 -17
- package/plugins/pbr/scripts/lib/roadmap.js +11 -35
- package/plugins/pbr/scripts/lib/smart-next-task.js +11 -20
- package/plugins/pbr/scripts/lib/spot-check.js +3 -106
- package/plugins/pbr/scripts/lib/state.js +25 -130
- package/plugins/pbr/scripts/lib/verify.js +56 -46
- package/plugins/pbr/scripts/milestone-learnings.js +6 -56
- package/plugins/pbr/scripts/pbr-tools.js +8 -91
- package/plugins/pbr/scripts/post-bash-triage.js +5 -63
- package/plugins/pbr/scripts/post-hoc.js +3 -52
- package/plugins/pbr/scripts/post-write-dispatch.js +0 -36
- package/plugins/pbr/scripts/pre-bash-dispatch.js +1 -7
- package/plugins/pbr/scripts/pre-task-dispatch.js +0 -28
- package/plugins/pbr/scripts/progress-tracker.js +2 -27
- package/plugins/pbr/scripts/session-cleanup.js +1 -31
- package/plugins/pbr/scripts/status-line.js +13 -11
- package/plugins/pbr/scripts/suggest-compact.js +2 -10
- package/plugins/pbr/scripts/test/state.test.js +5 -13
- package/plugins/pbr/scripts/validate-commit.js +8 -64
- package/plugins/pbr/scripts/validate-task.js +0 -30
- package/plugins/pbr/skills/begin/SKILL.md +1 -0
- package/plugins/pbr/skills/begin/templates/config.json.tmpl +0 -4
- package/plugins/pbr/skills/build/SKILL.md +6 -6
- package/plugins/pbr/skills/config/SKILL.md +1 -0
- package/plugins/pbr/skills/help/SKILL.md +1 -0
- package/plugins/pbr/skills/pause/SKILL.md +1 -0
- package/plugins/pbr/skills/profile-user/SKILL.md +1 -0
- package/plugins/pbr/skills/quick/SKILL.md +2 -1
- package/plugins/pbr/skills/resume/SKILL.md +1 -0
- package/plugins/pbr/skills/scan/SKILL.md +1 -0
- package/plugins/pbr/skills/setup/SKILL.md +1 -0
- package/plugins/pbr/skills/shared/state-update.md +2 -2
- package/plugins/pbr/skills/status/SKILL.md +1 -0
- package/plugins/pbr/references/behavioral-contexts.md +0 -53
- package/plugins/pbr/scripts/lib/autonomy.js +0 -91
- package/plugins/pbr/scripts/lib/circuit-state.js +0 -133
- package/plugins/pbr/scripts/lib/completion.js +0 -377
- package/plugins/pbr/scripts/lib/hypothesis-runner.js +0 -127
- package/plugins/pbr/scripts/lib/local-llm/client.js +0 -237
- package/plugins/pbr/scripts/lib/local-llm/health.js +0 -12
- package/plugins/pbr/scripts/lib/local-llm/index.js +0 -89
- package/plugins/pbr/scripts/lib/local-llm/metrics.js +0 -20
- package/plugins/pbr/scripts/lib/local-llm/operations/classify-artifact.js +0 -4
- package/plugins/pbr/scripts/lib/local-llm/operations/classify-commit.js +0 -4
- package/plugins/pbr/scripts/lib/local-llm/operations/classify-error.js +0 -4
- package/plugins/pbr/scripts/lib/local-llm/operations/classify-file-intent.js +0 -4
- package/plugins/pbr/scripts/lib/local-llm/operations/score-source.js +0 -72
- package/plugins/pbr/scripts/lib/local-llm/operations/summarize-context.js +0 -62
- package/plugins/pbr/scripts/lib/local-llm/operations/triage-test-output.js +0 -12
- package/plugins/pbr/scripts/lib/local-llm/operations/validate-task.js +0 -4
- package/plugins/pbr/scripts/lib/local-llm/router.js +0 -101
- package/plugins/pbr/scripts/lib/local-llm/shadow.js +0 -60
- package/plugins/pbr/scripts/lib/local-llm/threshold-tuner.js +0 -118
- package/plugins/pbr/scripts/lib/team-composer.js +0 -87
- package/plugins/pbr/scripts/lib/team-coordinator.js +0 -153
- package/plugins/pbr/scripts/lib/template.js +0 -222
- package/plugins/pbr/scripts/lib/test-cache.js +0 -54
- package/plugins/pbr/scripts/lib/trust-gate.js +0 -84
- package/plugins/pbr/scripts/lib/wiring-check.js +0 -196
|
@@ -84,119 +84,30 @@ function parseStateMd(content) {
|
|
|
84
84
|
progress: null,
|
|
85
85
|
status: null,
|
|
86
86
|
line_count: normalized.split('\n').length,
|
|
87
|
-
format: '
|
|
87
|
+
format: 'frontmatter'
|
|
88
88
|
};
|
|
89
89
|
|
|
90
90
|
// Check for YAML frontmatter (version 2 format)
|
|
91
91
|
const frontmatter = parseYamlFrontmatter(normalized);
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
result.session_resume = frontmatter.session_resume || null;
|
|
92
|
+
result.format = 'frontmatter';
|
|
93
|
+
result.current_phase = frontmatter.current_phase || null;
|
|
94
|
+
result.phase_name = frontmatter.phase_slug || frontmatter.phase_name || null;
|
|
95
|
+
result.status = frontmatter.status || null;
|
|
96
|
+
result.progress = frontmatter.progress_percent !== undefined ? frontmatter.progress_percent : null;
|
|
97
|
+
result.plans_total = frontmatter.plans_total || null;
|
|
98
|
+
result.plans_complete = frontmatter.plans_complete || null;
|
|
99
|
+
result.last_activity = frontmatter.last_activity || null;
|
|
100
|
+
result.last_command = frontmatter.last_command || null;
|
|
101
|
+
result.blockers = frontmatter.blockers || [];
|
|
102
|
+
result.velocity = frontmatter.velocity || null;
|
|
103
|
+
result.session_last = frontmatter.session_last || null;
|
|
104
|
+
result.session_stopped_at = frontmatter.session_stopped_at || null;
|
|
105
|
+
result.session_resume = frontmatter.session_resume || null;
|
|
107
106
|
return result;
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
// Legacy regex-based parsing (version 1 format, no frontmatter)
|
|
111
|
-
// DEPRECATED (2026-02): v1 STATE.md format (no YAML frontmatter) is deprecated.
|
|
112
|
-
// New projects should use v2 (frontmatter) format, generated by /pbr:setup.
|
|
113
|
-
// v1 support will be removed in a future major version.
|
|
114
|
-
process.stderr.write('[pbr] WARNING: STATE.md uses legacy v1 format. Run /pbr:setup to migrate to v2 format.\n');
|
|
115
|
-
|
|
116
|
-
// Extract "Phase: N of M"
|
|
117
|
-
const phaseMatch = normalized.match(/Phase:\s*(\d+)\s+of\s+(\d+)/);
|
|
118
|
-
if (phaseMatch) {
|
|
119
|
-
result.current_phase = parseInt(phaseMatch[1], 10);
|
|
120
|
-
result.total_phases = parseInt(phaseMatch[2], 10);
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
// Extract phase name (line after "Phase:")
|
|
124
|
-
const nameMatch = normalized.match(/--\s+(.+?)(?:\n|$)/);
|
|
125
|
-
if (nameMatch) {
|
|
126
|
-
result.phase_name = nameMatch[1].trim();
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
// Extract progress percentage
|
|
130
|
-
const progressMatch = normalized.match(/(\d+)%/);
|
|
131
|
-
if (progressMatch) {
|
|
132
|
-
result.progress = parseInt(progressMatch[1], 10);
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
// Extract plan status
|
|
136
|
-
const statusMatch = normalized.match(/Status:\s*(.+?)(?:\n|$)/i);
|
|
137
|
-
if (statusMatch) {
|
|
138
|
-
result.status = statusMatch[1].trim();
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
return result;
|
|
142
107
|
}
|
|
143
108
|
|
|
144
109
|
// --- Mutation helpers ---
|
|
145
110
|
|
|
146
|
-
/**
|
|
147
|
-
* Update a field in legacy (non-frontmatter) STATE.md content.
|
|
148
|
-
* Pure function: content in, content out.
|
|
149
|
-
*/
|
|
150
|
-
function updateLegacyStateField(content, field, value) {
|
|
151
|
-
const lines = content.replace(/\r\n/g, '\n').split('\n');
|
|
152
|
-
|
|
153
|
-
switch (field) {
|
|
154
|
-
case 'current_phase': {
|
|
155
|
-
const idx = lines.findIndex(l => /Phase:\s*\d+\s+of\s+\d+/.test(l));
|
|
156
|
-
if (idx !== -1) {
|
|
157
|
-
lines[idx] = lines[idx].replace(/(Phase:\s*)\d+/, (_, prefix) => `${prefix}${value}`);
|
|
158
|
-
}
|
|
159
|
-
break;
|
|
160
|
-
}
|
|
161
|
-
case 'status': {
|
|
162
|
-
const idx = lines.findIndex(l => /^Status:/i.test(l));
|
|
163
|
-
if (idx !== -1) {
|
|
164
|
-
lines[idx] = `Status: ${value}`;
|
|
165
|
-
} else {
|
|
166
|
-
const phaseIdx = lines.findIndex(l => /Phase:/.test(l));
|
|
167
|
-
if (phaseIdx !== -1) {
|
|
168
|
-
lines.splice(phaseIdx + 1, 0, `Status: ${value}`);
|
|
169
|
-
} else {
|
|
170
|
-
lines.push(`Status: ${value}`);
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
break;
|
|
174
|
-
}
|
|
175
|
-
case 'plans_complete': {
|
|
176
|
-
const idx = lines.findIndex(l => /Plan:\s*\d+\s+of\s+\d+/.test(l));
|
|
177
|
-
if (idx !== -1) {
|
|
178
|
-
lines[idx] = lines[idx].replace(/(Plan:\s*)\d+/, (_, prefix) => `${prefix}${value}`);
|
|
179
|
-
}
|
|
180
|
-
break;
|
|
181
|
-
}
|
|
182
|
-
case 'last_activity': {
|
|
183
|
-
const idx = lines.findIndex(l => /^Last Activity:/i.test(l));
|
|
184
|
-
if (idx !== -1) {
|
|
185
|
-
lines[idx] = `Last Activity: ${value}`;
|
|
186
|
-
} else {
|
|
187
|
-
const statusIdx = lines.findIndex(l => /^Status:/i.test(l));
|
|
188
|
-
if (statusIdx !== -1) {
|
|
189
|
-
lines.splice(statusIdx + 1, 0, `Last Activity: ${value}`);
|
|
190
|
-
} else {
|
|
191
|
-
lines.push(`Last Activity: ${value}`);
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
break;
|
|
195
|
-
}
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
return lines.join('\n');
|
|
199
|
-
}
|
|
200
111
|
|
|
201
112
|
/**
|
|
202
113
|
* Update a field in YAML frontmatter content.
|
|
@@ -428,7 +339,7 @@ function stateCheckProgress(planningDir) {
|
|
|
428
339
|
|
|
429
340
|
/**
|
|
430
341
|
* Atomically update a field in STATE.md using lockedFileUpdate.
|
|
431
|
-
*
|
|
342
|
+
* Updates frontmatter (v2) format STATE.md.
|
|
432
343
|
*
|
|
433
344
|
* @param {string} field - One of: current_phase, status, plans_complete, last_activity,
|
|
434
345
|
* progress_percent, phase_slug, total_phases, last_command, blockers
|
|
@@ -468,13 +379,9 @@ function stateUpdate(field, value, planningDir) {
|
|
|
468
379
|
}
|
|
469
380
|
|
|
470
381
|
const result = lockedFileUpdate(statePath, (content) => {
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
updated = syncBodyLine(updated, field, value);
|
|
475
|
-
return updated;
|
|
476
|
-
}
|
|
477
|
-
return updateLegacyStateField(content, field, value);
|
|
382
|
+
let updated = updateFrontmatterField(content, field, value);
|
|
383
|
+
updated = syncBodyLine(updated, field, value);
|
|
384
|
+
return updated;
|
|
478
385
|
});
|
|
479
386
|
|
|
480
387
|
if (result.success) {
|
|
@@ -501,19 +408,13 @@ function statePatch(jsonStr, planningDir) {
|
|
|
501
408
|
|
|
502
409
|
const result = lockedFileUpdate(statePath, (content) => {
|
|
503
410
|
let updated = content;
|
|
504
|
-
const fm = parseYamlFrontmatter(updated);
|
|
505
|
-
const isFrontmatter = fm.version === 2 || fm.current_phase !== undefined;
|
|
506
411
|
for (const [field, value] of Object.entries(fields)) {
|
|
507
412
|
let val = String(value);
|
|
508
413
|
if (field === 'last_activity' && val === 'now') {
|
|
509
414
|
val = new Date().toISOString().slice(0, 19).replace('T', ' ');
|
|
510
415
|
}
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
updated = syncBodyLine(updated, field, val);
|
|
514
|
-
} else {
|
|
515
|
-
updated = updateLegacyStateField(updated, field, val);
|
|
516
|
-
}
|
|
416
|
+
updated = updateFrontmatterField(updated, field, val);
|
|
417
|
+
updated = syncBodyLine(updated, field, val);
|
|
517
418
|
}
|
|
518
419
|
return updated;
|
|
519
420
|
});
|
|
@@ -546,15 +447,10 @@ function stateAdvancePlan(planningDir) {
|
|
|
546
447
|
resultData = { previous_plan: current, current_plan: next, total_plans: total, progress_percent: progressPct };
|
|
547
448
|
|
|
548
449
|
let updated = content;
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
updated = updateFrontmatterField(updated, 'progress_percent', String(progressPct));
|
|
554
|
-
updated = syncBodyLine(updated, 'progress_percent', String(progressPct));
|
|
555
|
-
} else {
|
|
556
|
-
updated = updateLegacyStateField(updated, 'plans_complete', String(next));
|
|
557
|
-
}
|
|
450
|
+
updated = updateFrontmatterField(updated, 'plans_complete', String(next));
|
|
451
|
+
updated = syncBodyLine(updated, 'plans_complete', String(next));
|
|
452
|
+
updated = updateFrontmatterField(updated, 'progress_percent', String(progressPct));
|
|
453
|
+
updated = syncBodyLine(updated, 'progress_percent', String(progressPct));
|
|
558
454
|
return updated;
|
|
559
455
|
});
|
|
560
456
|
|
|
@@ -1158,7 +1054,6 @@ function stateBackup(planningDir) {
|
|
|
1158
1054
|
|
|
1159
1055
|
module.exports = {
|
|
1160
1056
|
parseStateMd,
|
|
1161
|
-
updateLegacyStateField,
|
|
1162
1057
|
updateFrontmatterField,
|
|
1163
1058
|
syncBodyLine,
|
|
1164
1059
|
buildProgressBar,
|
|
@@ -183,7 +183,7 @@ function cmdVerifyPhaseCompleteness(cwd, phase, raw) {
|
|
|
183
183
|
|
|
184
184
|
// List plans and summaries
|
|
185
185
|
let files;
|
|
186
|
-
try { files = fs.readdirSync(phaseDir); } catch { output({ error: 'Cannot read phase directory' }, raw); return; }
|
|
186
|
+
try { files = fs.readdirSync(phaseDir); } catch (err) { if (process.env.PBR_DEBUG) console.error(`[verify] Cannot read phase directory ${phaseDir}: ${err.message}`); output({ error: 'Cannot read phase directory' }, raw); return; }
|
|
187
187
|
|
|
188
188
|
const plans = files.filter(f => f.match(/-PLAN\.md$/i));
|
|
189
189
|
const summaries = files.filter(f => f.match(/-SUMMARY\.md$/i));
|
|
@@ -409,7 +409,8 @@ function cmdVerifyKeyLinks(cwd, planFilePath, raw) {
|
|
|
409
409
|
check.detail = `Pattern "${link.pattern}" not found in source or target`;
|
|
410
410
|
}
|
|
411
411
|
}
|
|
412
|
-
} catch {
|
|
412
|
+
} catch (err) {
|
|
413
|
+
if (process.env.PBR_DEBUG) console.error(`[verify] Invalid regex pattern ${link.pattern}: ${err.message}`);
|
|
413
414
|
check.detail = `Invalid regex pattern: ${link.pattern}`;
|
|
414
415
|
}
|
|
415
416
|
} else {
|
|
@@ -466,7 +467,7 @@ function cmdValidateConsistency(cwd, raw) {
|
|
|
466
467
|
const dm = dir.match(/^(\d+[A-Z]?(?:\.\d+)*)/i);
|
|
467
468
|
if (dm) diskPhases.add(dm[1]);
|
|
468
469
|
}
|
|
469
|
-
} catch {}
|
|
470
|
+
} catch (err) { if (process.env.PBR_DEBUG) console.error(`[verify] Failed to read phases directory: ${err.message}`); }
|
|
470
471
|
|
|
471
472
|
// Check: phases in ROADMAP but not on disk
|
|
472
473
|
for (const p of roadmapPhases) {
|
|
@@ -528,7 +529,7 @@ function cmdValidateConsistency(cwd, raw) {
|
|
|
528
529
|
}
|
|
529
530
|
}
|
|
530
531
|
}
|
|
531
|
-
} catch {}
|
|
532
|
+
} catch (err) { if (process.env.PBR_DEBUG) console.error(`[verify] Failed to check plan numbering: ${err.message}`); }
|
|
532
533
|
|
|
533
534
|
// Check: frontmatter in plans has required fields
|
|
534
535
|
try {
|
|
@@ -548,7 +549,7 @@ function cmdValidateConsistency(cwd, raw) {
|
|
|
548
549
|
}
|
|
549
550
|
}
|
|
550
551
|
}
|
|
551
|
-
} catch {}
|
|
552
|
+
} catch (err) { if (process.env.PBR_DEBUG) console.error(`[verify] Failed to check plan frontmatter: ${err.message}`); }
|
|
552
553
|
|
|
553
554
|
const passed = errors.length === 0;
|
|
554
555
|
output({ passed, errors, warnings, warning_count: warnings.length }, raw, passed ? 'passed' : 'failed');
|
|
@@ -678,7 +679,7 @@ function cmdValidateHealth(cwd, options, raw) {
|
|
|
678
679
|
if (m) diskPhases.add(m[1]);
|
|
679
680
|
}
|
|
680
681
|
}
|
|
681
|
-
} catch {}
|
|
682
|
+
} catch (err) { if (process.env.PBR_DEBUG) console.error(`[verify] Failed to read phases for state validation: ${err.message}`); }
|
|
682
683
|
// Check for invalid references
|
|
683
684
|
for (const ref of phaseRefs) {
|
|
684
685
|
const normalizedRef = String(parseInt(ref, 10)).padStart(2, '0');
|
|
@@ -720,7 +721,7 @@ function cmdValidateHealth(cwd, options, raw) {
|
|
|
720
721
|
addIssue('warning', 'W008', 'config.json: workflow.nyquist_validation absent (defaults to enabled but agents may skip)', 'Run /pbr:health --repair to add key', true);
|
|
721
722
|
if (!repairs.includes('addNyquistKey')) repairs.push('addNyquistKey');
|
|
722
723
|
}
|
|
723
|
-
} catch {}
|
|
724
|
+
} catch (err) { if (process.env.PBR_DEBUG) console.error(`[verify] Failed to check nyquist key: ${err.message}`); }
|
|
724
725
|
}
|
|
725
726
|
|
|
726
727
|
// ─── Check 6: Phase directory naming (NN-name format) ─────────────────────
|
|
@@ -731,7 +732,7 @@ function cmdValidateHealth(cwd, options, raw) {
|
|
|
731
732
|
addIssue('warning', 'W005', `Phase directory "${e.name}" doesn't follow NN-name format`, 'Rename to match pattern (e.g., 01-setup)');
|
|
732
733
|
}
|
|
733
734
|
}
|
|
734
|
-
} catch {}
|
|
735
|
+
} catch (err) { if (process.env.PBR_DEBUG) console.error(`[verify] Failed to check phase directory naming: ${err.message}`); }
|
|
735
736
|
|
|
736
737
|
// ─── Check 7: Orphaned plans (PLAN without SUMMARY) ───────────────────────
|
|
737
738
|
try {
|
|
@@ -750,7 +751,7 @@ function cmdValidateHealth(cwd, options, raw) {
|
|
|
750
751
|
}
|
|
751
752
|
}
|
|
752
753
|
}
|
|
753
|
-
} catch {}
|
|
754
|
+
} catch (err) { if (process.env.PBR_DEBUG) console.error(`[verify] Failed to check orphaned plans: ${err.message}`); }
|
|
754
755
|
|
|
755
756
|
// ─── Check 7b: Nyquist VALIDATION.md consistency ────────────────────────
|
|
756
757
|
try {
|
|
@@ -768,7 +769,7 @@ function cmdValidateHealth(cwd, options, raw) {
|
|
|
768
769
|
}
|
|
769
770
|
}
|
|
770
771
|
}
|
|
771
|
-
} catch {}
|
|
772
|
+
} catch (err) { if (process.env.PBR_DEBUG) console.error(`[verify] Failed to check nyquist validation: ${err.message}`); }
|
|
772
773
|
|
|
773
774
|
// ─── Check 8: Run existing consistency checks ─────────────────────────────
|
|
774
775
|
// Inline subset of cmdValidateConsistency
|
|
@@ -790,7 +791,7 @@ function cmdValidateHealth(cwd, options, raw) {
|
|
|
790
791
|
if (dm) diskPhases.add(dm[1]);
|
|
791
792
|
}
|
|
792
793
|
}
|
|
793
|
-
} catch {}
|
|
794
|
+
} catch (err) { if (process.env.PBR_DEBUG) console.error(`[verify] Failed to read phases for roadmap check: ${err.message}`); }
|
|
794
795
|
|
|
795
796
|
// Phases in ROADMAP but not on disk
|
|
796
797
|
for (const p of roadmapPhases) {
|
|
@@ -909,20 +910,20 @@ function cmdValidateHealth(cwd, options, raw) {
|
|
|
909
910
|
} else {
|
|
910
911
|
feature_status.multi_phase_awareness = { enabled: false, status: 'disabled' };
|
|
911
912
|
}
|
|
912
|
-
} catch (
|
|
913
|
+
} catch (err) { if (process.env.PBR_DEBUG) console.error(`[verify] Config parse error (handled in Check 5): ${err.message}`); }
|
|
913
914
|
}
|
|
914
915
|
|
|
915
916
|
// ─── Check 11: Phase 05 feature status ────────────────────────────────────
|
|
916
917
|
{
|
|
917
918
|
let p05Config = {};
|
|
918
|
-
try { p05Config = JSON.parse(fs.readFileSync(configPath, 'utf-8')); } catch (
|
|
919
|
+
try { p05Config = JSON.parse(fs.readFileSync(configPath, 'utf-8')); } catch (err) { if (process.env.PBR_DEBUG) console.error(`[verify] Failed to parse config for phase05: ${err.message}`); }
|
|
919
920
|
var phase05_features = checkPhase05Features(planningDir, p05Config);
|
|
920
921
|
}
|
|
921
922
|
|
|
922
923
|
// ─── Check 12: Trust tracking health ──────────────────────────────────────
|
|
923
924
|
{
|
|
924
925
|
let config = {};
|
|
925
|
-
try { config = JSON.parse(fs.readFileSync(configPath, 'utf-8')); } catch (
|
|
926
|
+
try { config = JSON.parse(fs.readFileSync(configPath, 'utf-8')); } catch (err) { if (process.env.PBR_DEBUG) console.error(`[verify] Failed to parse config for trust: ${err.message}`); }
|
|
926
927
|
|
|
927
928
|
if (config.features && config.features.trust_tracking === false) {
|
|
928
929
|
addIssue('info', 'I-TRUST-DISABLED', 'trust_tracking is disabled in config', 'Enable features.trust_tracking in config.json if desired');
|
|
@@ -941,7 +942,8 @@ function cmdValidateHealth(cwd, options, raw) {
|
|
|
941
942
|
}
|
|
942
943
|
}
|
|
943
944
|
addIssue('info', 'I-TRUST-HEALTHY', `trust_tracking: healthy — ${agents.length} agents, ${totalOutcomes} outcomes tracked`, '');
|
|
944
|
-
} catch (
|
|
945
|
+
} catch (err) {
|
|
946
|
+
if (process.env.PBR_DEBUG) console.error(`[verify] Failed to parse agent-scores.json: ${err.message}`);
|
|
945
947
|
addIssue('info', 'I-TRUST-DEGRADED', 'trust_tracking: degraded — agent-scores.json exists but is malformed', 'Delete .planning/trust/agent-scores.json to reset');
|
|
946
948
|
}
|
|
947
949
|
}
|
|
@@ -957,7 +959,8 @@ function cmdValidateHealth(cwd, options, raw) {
|
|
|
957
959
|
try {
|
|
958
960
|
JSON.parse(fs.readFileSync(trustFile, 'utf-8'));
|
|
959
961
|
addIssue('info', 'I-CONFIDENCE-HEALTHY', 'confidence_calibration: healthy — trust data available for calibration', '');
|
|
960
|
-
} catch (
|
|
962
|
+
} catch (err) {
|
|
963
|
+
if (process.env.PBR_DEBUG) console.error(`[verify] Failed to parse trust data for confidence: ${err.message}`);
|
|
961
964
|
addIssue('info', 'I-CONFIDENCE-DEGRADED', 'confidence_calibration: degraded — trust data malformed', 'Delete .planning/trust/agent-scores.json to reset');
|
|
962
965
|
}
|
|
963
966
|
}
|
|
@@ -971,12 +974,12 @@ function cmdValidateHealth(cwd, options, raw) {
|
|
|
971
974
|
const guardHealth = graph.guardHealthCheck(planningDir);
|
|
972
975
|
feature_status.architecture_graph = graphHealth;
|
|
973
976
|
feature_status.architecture_guard = guardHealth;
|
|
974
|
-
} catch (
|
|
977
|
+
} catch (err) { if (process.env.PBR_DEBUG) console.error(`[verify] Graph module not available: ${err.message}`); }
|
|
975
978
|
|
|
976
979
|
// ─── Check 14: Phase 15 DX feature health ────────────────────────────────
|
|
977
980
|
{
|
|
978
981
|
let p15Config = {};
|
|
979
|
-
try { p15Config = JSON.parse(fs.readFileSync(configPath, 'utf-8')); } catch (
|
|
982
|
+
try { p15Config = JSON.parse(fs.readFileSync(configPath, 'utf-8')); } catch (err) { if (process.env.PBR_DEBUG) console.error(`[verify] Failed to parse config for phase15: ${err.message}`); }
|
|
980
983
|
const p15Features = (p15Config && p15Config.features) || {};
|
|
981
984
|
|
|
982
985
|
const checkDxFeature = (featureName, modulePath, exportName) => {
|
|
@@ -1004,17 +1007,17 @@ function cmdValidateHealth(cwd, options, raw) {
|
|
|
1004
1007
|
|
|
1005
1008
|
feature_status.progress_visualization = checkDxFeature(
|
|
1006
1009
|
'progress_visualization',
|
|
1007
|
-
path.join(__dirname, 'progress-visualization.
|
|
1010
|
+
path.join(__dirname, 'progress-visualization.js'),
|
|
1008
1011
|
'getProgressData'
|
|
1009
1012
|
);
|
|
1010
1013
|
feature_status.contextual_help = checkDxFeature(
|
|
1011
1014
|
'contextual_help',
|
|
1012
|
-
path.join(__dirname, 'contextual-help.
|
|
1015
|
+
path.join(__dirname, 'contextual-help.js'),
|
|
1013
1016
|
'getContextualHelp'
|
|
1014
1017
|
);
|
|
1015
1018
|
feature_status.team_onboarding = checkDxFeature(
|
|
1016
1019
|
'team_onboarding',
|
|
1017
|
-
path.join(__dirname, 'onboarding-generator.
|
|
1020
|
+
path.join(__dirname, 'onboarding-generator.js'),
|
|
1018
1021
|
'generateOnboardingGuide'
|
|
1019
1022
|
);
|
|
1020
1023
|
}
|
|
@@ -1022,7 +1025,7 @@ function cmdValidateHealth(cwd, options, raw) {
|
|
|
1022
1025
|
// ─── Check 15: Phase 14 Quality & Safety feature health ───────────────────
|
|
1023
1026
|
{
|
|
1024
1027
|
let p14Config = {};
|
|
1025
|
-
try { p14Config = JSON.parse(fs.readFileSync(configPath, 'utf-8')); } catch (
|
|
1028
|
+
try { p14Config = JSON.parse(fs.readFileSync(configPath, 'utf-8')); } catch (err) { if (process.env.PBR_DEBUG) console.error(`[verify] Failed to parse config for phase14: ${err.message}`); }
|
|
1026
1029
|
|
|
1027
1030
|
const p14Features = p14Config.features || {};
|
|
1028
1031
|
|
|
@@ -1040,7 +1043,8 @@ function cmdValidateHealth(cwd, options, raw) {
|
|
|
1040
1043
|
}
|
|
1041
1044
|
addIssue('warning', `W-${featureName.toUpperCase()}-DEGRADED`, `${featureName}: degraded (module validation failed)`, `Check ${modulePath} exports`);
|
|
1042
1045
|
return { enabled: true, status: 'degraded' };
|
|
1043
|
-
} catch (
|
|
1046
|
+
} catch (err) {
|
|
1047
|
+
if (process.env.PBR_DEBUG) console.error(`[verify] Feature ${featureName} module load failed: ${err.message}`);
|
|
1044
1048
|
addIssue('warning', `W-${featureName.toUpperCase()}-DEGRADED`, `${featureName}: degraded (module load failed)`, `Ensure ${modulePath} exists and is valid`);
|
|
1045
1049
|
return { enabled: true, status: 'degraded' };
|
|
1046
1050
|
}
|
|
@@ -1048,7 +1052,7 @@ function cmdValidateHealth(cwd, options, raw) {
|
|
|
1048
1052
|
|
|
1049
1053
|
// regression_prevention: default true
|
|
1050
1054
|
const rpEnabled = p14Features.regression_prevention !== false;
|
|
1051
|
-
const rpModPath = path.join(__dirname, 'test-selection.
|
|
1055
|
+
const rpModPath = path.join(__dirname, 'test-selection.js');
|
|
1052
1056
|
const rpHealth = checkFeatureHealth(
|
|
1053
1057
|
'regression_prevention',
|
|
1054
1058
|
rpEnabled,
|
|
@@ -1062,7 +1066,7 @@ function cmdValidateHealth(cwd, options, raw) {
|
|
|
1062
1066
|
|
|
1063
1067
|
// security_scanning: default true
|
|
1064
1068
|
const ssEnabled = p14Features.security_scanning !== false;
|
|
1065
|
-
const ssModPath = path.join(__dirname, 'security-scan.
|
|
1069
|
+
const ssModPath = path.join(__dirname, 'security-scan.js');
|
|
1066
1070
|
const ssHealth = checkFeatureHealth(
|
|
1067
1071
|
'security_scanning',
|
|
1068
1072
|
ssEnabled,
|
|
@@ -1074,7 +1078,7 @@ function cmdValidateHealth(cwd, options, raw) {
|
|
|
1074
1078
|
const ssMod = require(ssModPath);
|
|
1075
1079
|
const ruleCount = ssMod.SECURITY_RULES.length;
|
|
1076
1080
|
addIssue('info', 'I-SS-HEALTHY', `security_scanning: healthy (${ruleCount} rules loaded)`, '');
|
|
1077
|
-
} catch (
|
|
1081
|
+
} catch (err) { if (process.env.PBR_DEBUG) console.error(`[verify] Failed to load security rules: ${err.message}`); }
|
|
1078
1082
|
}
|
|
1079
1083
|
feature_status.security_scanning = ssHealth;
|
|
1080
1084
|
}
|
|
@@ -1082,7 +1086,7 @@ function cmdValidateHealth(cwd, options, raw) {
|
|
|
1082
1086
|
// ─── Check 16: Phase 11 Spec-Driven Development feature health ───────────
|
|
1083
1087
|
{
|
|
1084
1088
|
let p11Config = {};
|
|
1085
|
-
try { p11Config = JSON.parse(fs.readFileSync(configPath, 'utf-8')); } catch (
|
|
1089
|
+
try { p11Config = JSON.parse(fs.readFileSync(configPath, 'utf-8')); } catch (err) { if (process.env.PBR_DEBUG) console.error(`[verify] Failed to parse config for phase11: ${err.message}`); }
|
|
1086
1090
|
const p11Features = p11Config.features || {};
|
|
1087
1091
|
|
|
1088
1092
|
const checkSpecFeatureHealth = (featureName, defaultEnabled, modulePath, exportName) => {
|
|
@@ -1096,29 +1100,30 @@ function cmdValidateHealth(cwd, options, raw) {
|
|
|
1096
1100
|
return { status: 'healthy', enabled: true, details: `${exportName} loaded` };
|
|
1097
1101
|
}
|
|
1098
1102
|
return { status: 'degraded', enabled: true, details: `${exportName} not a function` };
|
|
1099
|
-
} catch (
|
|
1100
|
-
|
|
1103
|
+
} catch (err) {
|
|
1104
|
+
if (process.env.PBR_DEBUG) console.error(`[verify] Cannot load spec module: ${err.message}`);
|
|
1105
|
+
return { status: 'degraded', enabled: true, details: `Cannot load module: ${err.message}` };
|
|
1101
1106
|
}
|
|
1102
1107
|
};
|
|
1103
1108
|
|
|
1104
1109
|
feature_status.machine_executable_plans = checkSpecFeatureHealth(
|
|
1105
|
-
'machine_executable_plans', false, path.join(__dirname, 'spec-engine.
|
|
1110
|
+
'machine_executable_plans', false, path.join(__dirname, 'spec-engine.js'), 'parsePlanToSpec'
|
|
1106
1111
|
);
|
|
1107
1112
|
feature_status.spec_diffing = checkSpecFeatureHealth(
|
|
1108
|
-
'spec_diffing', true, path.join(__dirname, 'spec-diff.
|
|
1113
|
+
'spec_diffing', true, path.join(__dirname, 'spec-diff.js'), 'diffSpecs'
|
|
1109
1114
|
);
|
|
1110
1115
|
feature_status.reverse_spec = checkSpecFeatureHealth(
|
|
1111
|
-
'reverse_spec', true, path.join(__dirname, 'reverse-spec.
|
|
1116
|
+
'reverse_spec', true, path.join(__dirname, 'reverse-spec.js'), 'generateReverseSpec'
|
|
1112
1117
|
);
|
|
1113
1118
|
feature_status.predictive_impact = checkSpecFeatureHealth(
|
|
1114
|
-
'predictive_impact', true, path.join(__dirname, 'impact-analysis.
|
|
1119
|
+
'predictive_impact', true, path.join(__dirname, 'impact-analysis.js'), 'analyzeImpact'
|
|
1115
1120
|
);
|
|
1116
1121
|
}
|
|
1117
1122
|
|
|
1118
1123
|
// ─── Check 17: Phase 16 cross-project intelligence feature health ────────
|
|
1119
1124
|
{
|
|
1120
1125
|
let p16Config = {};
|
|
1121
|
-
try { p16Config = JSON.parse(fs.readFileSync(configPath, 'utf-8')); } catch (
|
|
1126
|
+
try { p16Config = JSON.parse(fs.readFileSync(configPath, 'utf-8')); } catch (err) { if (process.env.PBR_DEBUG) console.error(`[verify] Failed to parse config for phase16: ${err.message}`); }
|
|
1122
1127
|
const p16Features = p16Config.features || {};
|
|
1123
1128
|
|
|
1124
1129
|
// Helper: check if a feature is enabled (default true unless explicitly false)
|
|
@@ -1138,7 +1143,7 @@ function cmdValidateHealth(cwd, options, raw) {
|
|
|
1138
1143
|
const patternsDir = require('path').join(require('os').homedir(), '.claude', 'patterns');
|
|
1139
1144
|
return fs.existsSync(patternsDir) &&
|
|
1140
1145
|
fs.readdirSync(patternsDir).some(f => f.endsWith('.json'));
|
|
1141
|
-
} catch (
|
|
1146
|
+
} catch (err) { if (process.env.PBR_DEBUG) console.error(`[verify] Failed to check patterns dir: ${err.message}`); return false; }
|
|
1142
1147
|
}
|
|
1143
1148
|
);
|
|
1144
1149
|
|
|
@@ -1155,7 +1160,7 @@ function cmdValidateHealth(cwd, options, raw) {
|
|
|
1155
1160
|
try {
|
|
1156
1161
|
const learningsPath = require('path').join(require('os').homedir(), '.claude', 'learnings.jsonl');
|
|
1157
1162
|
return fs.existsSync(learningsPath);
|
|
1158
|
-
} catch (
|
|
1163
|
+
} catch (err) { if (process.env.PBR_DEBUG) console.error(`[verify] Failed to check learnings path: ${err.message}`); return false; }
|
|
1159
1164
|
}
|
|
1160
1165
|
);
|
|
1161
1166
|
}
|
|
@@ -1163,7 +1168,7 @@ function cmdValidateHealth(cwd, options, raw) {
|
|
|
1163
1168
|
// ─── Check 18: Phase 3 (zero-friction) feature status ────────────────────
|
|
1164
1169
|
{
|
|
1165
1170
|
let p3Config = {};
|
|
1166
|
-
try { p3Config = JSON.parse(fs.readFileSync(configPath, 'utf-8')); } catch (
|
|
1171
|
+
try { p3Config = JSON.parse(fs.readFileSync(configPath, 'utf-8')); } catch (err) { if (process.env.PBR_DEBUG) console.error(`[verify] Failed to parse config for phase3: ${err.message}`); }
|
|
1167
1172
|
const p3Features = p3Config.features || {};
|
|
1168
1173
|
|
|
1169
1174
|
const zfqEnabled = p3Features.zero_friction_quick !== false;
|
|
@@ -1176,7 +1181,7 @@ function cmdValidateHealth(cwd, options, raw) {
|
|
|
1176
1181
|
// ─── Check 19: Phase 4 (NL routing) feature status ───────────────────────
|
|
1177
1182
|
{
|
|
1178
1183
|
let p4Config = {};
|
|
1179
|
-
try { p4Config = JSON.parse(fs.readFileSync(configPath, 'utf-8')); } catch (
|
|
1184
|
+
try { p4Config = JSON.parse(fs.readFileSync(configPath, 'utf-8')); } catch (err) { if (process.env.PBR_DEBUG) console.error(`[verify] Failed to parse config for phase4: ${err.message}`); }
|
|
1180
1185
|
const p4Features = p4Config.features || {};
|
|
1181
1186
|
const pluginRoot = path.resolve(__dirname, '..', '..', '..', 'plugins', 'pbr');
|
|
1182
1187
|
|
|
@@ -1188,7 +1193,8 @@ function cmdValidateHealth(cwd, options, raw) {
|
|
|
1188
1193
|
try {
|
|
1189
1194
|
require(path.join(pluginRoot, 'scripts', 'lib', 'alternatives.js'));
|
|
1190
1195
|
feature_status.natural_language_routing = { enabled: true, status: 'healthy' };
|
|
1191
|
-
} catch (
|
|
1196
|
+
} catch (err) {
|
|
1197
|
+
if (process.env.PBR_DEBUG) console.error(`[verify] Failed to load alternatives.js: ${err.message}`);
|
|
1192
1198
|
feature_status.natural_language_routing = { enabled: true, status: 'degraded' };
|
|
1193
1199
|
}
|
|
1194
1200
|
}
|
|
@@ -1204,7 +1210,7 @@ function cmdValidateHealth(cwd, options, raw) {
|
|
|
1204
1210
|
// ─── Check 20: Phase 6 (convention memory) feature status ────────────────
|
|
1205
1211
|
{
|
|
1206
1212
|
let p6Config = {};
|
|
1207
|
-
try { p6Config = JSON.parse(fs.readFileSync(configPath, 'utf-8')); } catch (
|
|
1213
|
+
try { p6Config = JSON.parse(fs.readFileSync(configPath, 'utf-8')); } catch (err) { if (process.env.PBR_DEBUG) console.error(`[verify] Failed to parse config for phase6: ${err.message}`); }
|
|
1208
1214
|
const p6Features = p6Config.features || {};
|
|
1209
1215
|
const pluginRoot = path.resolve(__dirname, '..', '..', '..', 'plugins', 'pbr');
|
|
1210
1216
|
|
|
@@ -1216,7 +1222,8 @@ function cmdValidateHealth(cwd, options, raw) {
|
|
|
1216
1222
|
try {
|
|
1217
1223
|
require(path.join(pluginRoot, 'scripts', 'lib', 'convention-detector.js'));
|
|
1218
1224
|
feature_status.convention_memory = { enabled: true, status: 'healthy' };
|
|
1219
|
-
} catch (
|
|
1225
|
+
} catch (err) {
|
|
1226
|
+
if (process.env.PBR_DEBUG) console.error(`[verify] Failed to load convention-detector.js: ${err.message}`);
|
|
1220
1227
|
feature_status.convention_memory = { enabled: true, status: 'degraded' };
|
|
1221
1228
|
}
|
|
1222
1229
|
}
|
|
@@ -1229,7 +1236,8 @@ function cmdValidateHealth(cwd, options, raw) {
|
|
|
1229
1236
|
try {
|
|
1230
1237
|
require(path.join(pluginRoot, 'scripts', 'lib', 'snapshot-manager.js'));
|
|
1231
1238
|
feature_status.mental_model_snapshots = { enabled: true, status: 'healthy' };
|
|
1232
|
-
} catch (
|
|
1239
|
+
} catch (err) {
|
|
1240
|
+
if (process.env.PBR_DEBUG) console.error(`[verify] Failed to load snapshot-manager.js: ${err.message}`);
|
|
1233
1241
|
feature_status.mental_model_snapshots = { enabled: true, status: 'degraded' };
|
|
1234
1242
|
}
|
|
1235
1243
|
}
|
|
@@ -1238,7 +1246,7 @@ function cmdValidateHealth(cwd, options, raw) {
|
|
|
1238
1246
|
// ─── Check 21: Phase 9 (proactive intelligence) feature status ───────────
|
|
1239
1247
|
{
|
|
1240
1248
|
let p9Config = {};
|
|
1241
|
-
try { p9Config = JSON.parse(fs.readFileSync(configPath, 'utf-8')); } catch (
|
|
1249
|
+
try { p9Config = JSON.parse(fs.readFileSync(configPath, 'utf-8')); } catch (err) { if (process.env.PBR_DEBUG) console.error(`[verify] Failed to parse config for phase9: ${err.message}`); }
|
|
1242
1250
|
const scriptsDir = path.resolve(__dirname, '..', '..', '..', 'plugins', 'pbr', 'scripts');
|
|
1243
1251
|
const { checkFeatureHealth: checkPhase9FeatureHealth } = require('./health');
|
|
1244
1252
|
const phase9Features = [
|
|
@@ -1274,7 +1282,8 @@ function cmdValidateHealth(cwd, options, raw) {
|
|
|
1274
1282
|
enabled: metricsResult.enabled,
|
|
1275
1283
|
status: metricsResult.status,
|
|
1276
1284
|
};
|
|
1277
|
-
} catch (
|
|
1285
|
+
} catch (err) {
|
|
1286
|
+
if (process.env.PBR_DEBUG) console.error(`[verify] Failed to load health-checks.js: ${err.message}`);
|
|
1278
1287
|
// health-checks.js not available — mark all as degraded
|
|
1279
1288
|
feature_status.post_hoc_artifacts = { enabled: true, status: 'degraded' };
|
|
1280
1289
|
feature_status.agent_feedback_loop = { enabled: true, status: 'degraded' };
|
|
@@ -1285,7 +1294,7 @@ function cmdValidateHealth(cwd, options, raw) {
|
|
|
1285
1294
|
// ─── Check 23: Phase 13 (multi-agent) feature status ─────────────────────
|
|
1286
1295
|
{
|
|
1287
1296
|
let p13Config = {};
|
|
1288
|
-
try { p13Config = JSON.parse(fs.readFileSync(configPath, 'utf-8')); } catch (
|
|
1297
|
+
try { p13Config = JSON.parse(fs.readFileSync(configPath, 'utf-8')); } catch (err) { if (process.env.PBR_DEBUG) console.error(`[verify] Failed to parse config for phase13: ${err.message}`); }
|
|
1289
1298
|
const { checkMultiAgentHealth } = require('./health');
|
|
1290
1299
|
const multiAgentResults = checkMultiAgentHealth(p13Config);
|
|
1291
1300
|
for (const result of multiAgentResults) {
|
|
@@ -1407,7 +1416,8 @@ function checkFeatureModuleHealth(featureName, planningDir, pluginRoot, modulePa
|
|
|
1407
1416
|
if (fs.existsSync(configPath)) {
|
|
1408
1417
|
config = JSON.parse(fs.readFileSync(configPath, 'utf-8'));
|
|
1409
1418
|
}
|
|
1410
|
-
} catch (
|
|
1419
|
+
} catch (err) {
|
|
1420
|
+
if (process.env.PBR_DEBUG) console.error(`[verify] Config unreadable for feature health: ${err.message}`);
|
|
1411
1421
|
// Config unreadable — treat as defaults
|
|
1412
1422
|
}
|
|
1413
1423
|
|