@principles/pd-cli 1.145.1 → 1.146.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.
- package/README.md +11 -2
- package/dist/commands/build-trajectory-evidence.d.ts +25 -6
- package/dist/commands/build-trajectory-evidence.d.ts.map +1 -1
- package/dist/commands/build-trajectory-evidence.js +174 -114
- package/dist/commands/build-trajectory-evidence.js.map +1 -1
- package/dist/commands/diagnose.d.ts.map +1 -1
- package/dist/commands/diagnose.js +48 -27
- package/dist/commands/diagnose.js.map +1 -1
- package/dist/commands/pain-record.d.ts.map +1 -1
- package/dist/commands/pain-record.js +212 -17
- package/dist/commands/pain-record.js.map +1 -1
- package/dist/commands/pain-retry.d.ts.map +1 -1
- package/dist/commands/pain-retry.js +43 -26
- package/dist/commands/pain-retry.js.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/commands/build-trajectory-evidence.ts +211 -122
- package/src/commands/diagnose.ts +59 -36
- package/src/commands/pain-record.ts +224 -16
- package/src/commands/pain-retry.ts +56 -36
- package/src/index.ts +1 -1
- package/tests/bdd/cli-contract.steps.ts +3 -0
- package/tests/commands/build-trajectory-evidence.test.ts +226 -161
- package/tests/commands/diagnose.test.ts +82 -0
- package/tests/commands/pain-record-async.test.ts +36 -30
- package/tests/commands/pain-record-session-parser.test.ts +127 -0
- package/tests/commands/pain-record.test.ts +205 -37
- package/tests/commands/pain-retry.test.ts +72 -1
package/README.md
CHANGED
|
@@ -15,13 +15,22 @@ npm install -g @principles/pd-cli
|
|
|
15
15
|
Record a pain signal to the workspace's trajectory database via `PainToPrincipleService`.
|
|
16
16
|
|
|
17
17
|
```bash
|
|
18
|
-
pd pain record --reason "edited file without reading first" --score 75
|
|
18
|
+
pd pain record --reason "edited file without reading first" --score 75 --session "<session-id>"
|
|
19
19
|
```
|
|
20
20
|
|
|
21
21
|
Options:
|
|
22
22
|
- `--reason, -r` — Pain reason (required)
|
|
23
23
|
- `--score, -s` — Pain score 0-100 (default: 80)
|
|
24
|
-
- `--session
|
|
24
|
+
- `--session` — Session ID recorded in this workspace's trajectory; validated
|
|
25
|
+
up front (a missing session fails with `session_not_found` before anything
|
|
26
|
+
is written). Binding a session attaches real trajectory evidence.
|
|
27
|
+
- `--workspace, -w` — Workspace directory
|
|
28
|
+
- `--wait` — Diagnose synchronously (overrides the async CLI flag)
|
|
29
|
+
- `--json` — Machine-readable output
|
|
30
|
+
|
|
31
|
+
Without `--session` the record is an honest unbound Owner report: it carries
|
|
32
|
+
no trajectory evidence and candidates will likely be gated by the admission
|
|
33
|
+
threshold (`needs_evidence`); the output discloses this explicitly.
|
|
25
34
|
|
|
26
35
|
## Production Canary Validation
|
|
27
36
|
|
|
@@ -10,12 +10,31 @@
|
|
|
10
10
|
*/
|
|
11
11
|
import type { PainEvidenceEntry } from '@principles/core/runtime-v2';
|
|
12
12
|
/**
|
|
13
|
-
*
|
|
13
|
+
* PRI-642 (SPEC §7.3): discriminated acquisition result. `unavailable` carries
|
|
14
|
+
* a distinct reasonCode so `pd pain record --session` can fail/degrade
|
|
15
|
+
* explicitly BEFORE any LLM/task/candidate mutation, without placeholder
|
|
16
|
+
* evidence.
|
|
17
|
+
*/
|
|
18
|
+
export type TrajectoryEvidenceAcquisition = {
|
|
19
|
+
status: 'available';
|
|
20
|
+
entries: PainEvidenceEntry[];
|
|
21
|
+
} | {
|
|
22
|
+
status: 'unavailable';
|
|
23
|
+
reasonCode: 'trajectory_unavailable' | 'session_not_found' | 'empty_trajectory' | 'evidence_read_failed';
|
|
24
|
+
detail: string;
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* PRI-642 Scope A typed acquisition from trajectory.db (SPEC §7.3).
|
|
14
28
|
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
29
|
+
* Validates that the requested session exists in the trajectory `sessions`
|
|
30
|
+
* table (every recorded turn/tool call upserts its session row, so an absent
|
|
31
|
+
* row means the session was never seen) and classifies the outcome:
|
|
32
|
+
* - `available` — session bound, ≥1 real behavior-trace entry;
|
|
33
|
+
* - `session_not_found` — session absent from the sessions table (or a
|
|
34
|
+
* `cli`/`unknown` sentinel — never a real session);
|
|
35
|
+
* - `trajectory_unavailable` — no trajectory.db in this workspace;
|
|
36
|
+
* - `evidence_read_failed` — the DB exists but cannot be opened/read;
|
|
37
|
+
* - `empty_trajectory` — real session, no usable evidence rows.
|
|
19
38
|
*/
|
|
20
|
-
export declare function
|
|
39
|
+
export declare function acquireTrajectoryEvidenceFromDb(stateDir: string, sessionId: string | undefined, workspaceDir?: string): TrajectoryEvidenceAcquisition;
|
|
21
40
|
//# sourceMappingURL=build-trajectory-evidence.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"build-trajectory-evidence.d.ts","sourceRoot":"","sources":["../../src/commands/build-trajectory-evidence.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAUH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAErE
|
|
1
|
+
{"version":3,"file":"build-trajectory-evidence.d.ts","sourceRoot":"","sources":["../../src/commands/build-trajectory-evidence.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAUH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAErE;;;;;GAKG;AACH,MAAM,MAAM,6BAA6B,GACrC;IAAE,MAAM,EAAE,WAAW,CAAC;IAAC,OAAO,EAAE,iBAAiB,EAAE,CAAA;CAAE,GACrD;IACE,MAAM,EAAE,aAAa,CAAC;IACtB,UAAU,EAAE,wBAAwB,GAAG,mBAAmB,GAAG,kBAAkB,GAAG,sBAAsB,CAAC;IACzG,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AA6JN;;;;;;;;;;;;GAYG;AACH,wBAAgB,+BAA+B,CAC7C,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,GAAG,SAAS,EAC7B,YAAY,CAAC,EAAE,MAAM,GACpB,6BAA6B,CAoE/B"}
|
|
@@ -12,110 +12,90 @@ import Database from 'better-sqlite3';
|
|
|
12
12
|
import * as fs from 'fs';
|
|
13
13
|
import * as path from 'path';
|
|
14
14
|
import { MAX_EVIDENCE_ENTRIES, MAX_EVIDENCE_NOTE_CHARS, sanitizeString, } from '@principles/core/runtime-v2';
|
|
15
|
+
/** SourceRef markers that carry no real behavior trace (placeholder shapes). */
|
|
16
|
+
const PLACEHOLDER_SOURCE_REFS = new Set([
|
|
17
|
+
'owner_reported:cli',
|
|
18
|
+
'owner_message:unavailable',
|
|
19
|
+
'agent_turn:unavailable',
|
|
20
|
+
'tool_call_failure:unavailable',
|
|
21
|
+
'trajectory:empty',
|
|
22
|
+
]);
|
|
15
23
|
/**
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
* @param sessionId - The session ID to query turns for
|
|
20
|
-
* @param workspaceDir - Workspace directory for path redaction (sanitizeString)
|
|
21
|
-
* @returns Array of PainEvidenceEntry (never empty; degraded entries on failure)
|
|
24
|
+
* Collect evidence entries from an open trajectory.db for one session.
|
|
25
|
+
* Shared by the typed acquisition API and the legacy array wrapper so the
|
|
26
|
+
* two can never drift.
|
|
22
27
|
*/
|
|
23
|
-
|
|
28
|
+
function collectEvidenceFromDb(db, sessionId, workspaceDir) {
|
|
24
29
|
const evidence = [];
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
evidence.push({
|
|
28
|
-
sourceRef: 'owner_reported:cli',
|
|
29
|
-
note: 'No session context available',
|
|
30
|
-
});
|
|
31
|
-
return evidence;
|
|
32
|
-
}
|
|
33
|
-
const dbPath = path.join(stateDir, 'trajectory.db');
|
|
34
|
-
if (!fs.existsSync(dbPath)) {
|
|
35
|
-
evidence.push({
|
|
36
|
-
sourceRef: 'owner_reported:cli',
|
|
37
|
-
note: 'No session context available',
|
|
38
|
-
});
|
|
39
|
-
return evidence;
|
|
40
|
-
}
|
|
41
|
-
let db;
|
|
42
|
-
try {
|
|
43
|
-
db = new Database(dbPath, { readonly: true });
|
|
44
|
-
}
|
|
45
|
-
catch {
|
|
46
|
-
evidence.push({
|
|
47
|
-
sourceRef: 'owner_reported:cli',
|
|
48
|
-
note: 'No session context available',
|
|
49
|
-
});
|
|
50
|
-
return evidence;
|
|
51
|
-
}
|
|
30
|
+
let readFailed = false;
|
|
31
|
+
// Try to read user turns with correction detection
|
|
52
32
|
try {
|
|
53
|
-
|
|
54
|
-
try {
|
|
55
|
-
const userTurns = db.prepare(`
|
|
33
|
+
const userTurns = db.prepare(`
|
|
56
34
|
SELECT id, raw_excerpt, correction_detected, correction_cue, created_at
|
|
57
35
|
FROM user_turns
|
|
58
36
|
WHERE session_id = ?
|
|
59
37
|
ORDER BY id ASC
|
|
60
38
|
`).all(sessionId);
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
}
|
|
39
|
+
const lastCorrectionTurn = [...userTurns].reverse().find(t => Boolean(t.correction_detected));
|
|
40
|
+
if (lastCorrectionTurn) {
|
|
41
|
+
const rawExcerpt = typeof lastCorrectionTurn.raw_excerpt === 'string'
|
|
42
|
+
? lastCorrectionTurn.raw_excerpt
|
|
43
|
+
: '';
|
|
44
|
+
const sanitizedNote = sanitizeString(rawExcerpt.slice(0, MAX_EVIDENCE_NOTE_CHARS), workspaceDir);
|
|
45
|
+
evidence.push({
|
|
46
|
+
sourceRef: `owner_message:${String(lastCorrectionTurn.created_at ?? 'unknown')}`,
|
|
47
|
+
note: sanitizedNote,
|
|
48
|
+
});
|
|
72
49
|
}
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
50
|
+
}
|
|
51
|
+
catch {
|
|
52
|
+
readFailed = true;
|
|
53
|
+
// user_turns table may not exist — degrade gracefully
|
|
54
|
+
if (evidence.length < MAX_EVIDENCE_ENTRIES) {
|
|
55
|
+
evidence.push({
|
|
56
|
+
sourceRef: 'owner_message:unavailable',
|
|
57
|
+
note: 'trajectory_user_turns_unavailable',
|
|
58
|
+
});
|
|
81
59
|
}
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
60
|
+
}
|
|
61
|
+
// Try to read assistant turns (last 3)
|
|
62
|
+
try {
|
|
63
|
+
const assistantTurns = db.prepare(`
|
|
85
64
|
SELECT id, sanitized_text, stop_reason, created_at
|
|
86
65
|
FROM assistant_turns
|
|
87
66
|
WHERE session_id = ?
|
|
88
67
|
ORDER BY id ASC
|
|
89
68
|
`).all(sessionId);
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
}
|
|
69
|
+
const recentAssistant = assistantTurns.slice(-3);
|
|
70
|
+
for (const turn of recentAssistant) {
|
|
71
|
+
if (evidence.length >= MAX_EVIDENCE_ENTRIES)
|
|
72
|
+
break;
|
|
73
|
+
const sanitizedText = typeof turn.sanitized_text === 'string'
|
|
74
|
+
? turn.sanitized_text
|
|
75
|
+
: '';
|
|
76
|
+
const sanitizedNote = sanitizeString(sanitizedText.slice(0, MAX_EVIDENCE_NOTE_CHARS), workspaceDir);
|
|
77
|
+
// Enhanced: append truncation warning when stop_reason=length
|
|
78
|
+
const stopReason = typeof turn.stop_reason === 'string' ? turn.stop_reason : null;
|
|
79
|
+
const truncationWarning = stopReason === 'length' ? ' [TRUNCATED: output cut off by length limit]' : '';
|
|
80
|
+
evidence.push({
|
|
81
|
+
sourceRef: `agent_turn:${String(turn.created_at ?? 'unknown')}`,
|
|
82
|
+
note: sanitizedNote + truncationWarning,
|
|
83
|
+
});
|
|
106
84
|
}
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
85
|
+
}
|
|
86
|
+
catch {
|
|
87
|
+
readFailed = true;
|
|
88
|
+
// assistant_turns table may not exist — degrade gracefully
|
|
89
|
+
if (evidence.length < MAX_EVIDENCE_ENTRIES) {
|
|
90
|
+
evidence.push({
|
|
91
|
+
sourceRef: 'agent_turn:unavailable',
|
|
92
|
+
note: 'trajectory_assistant_turns_unavailable',
|
|
93
|
+
});
|
|
115
94
|
}
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
95
|
+
}
|
|
96
|
+
// PRI-358: Try to read failed tool_calls (last 3 failures, chronological order)
|
|
97
|
+
try {
|
|
98
|
+
const failedToolCalls = db.prepare(`
|
|
119
99
|
SELECT tool_name, error_type, exit_code, result_preview, created_at
|
|
120
100
|
FROM (
|
|
121
101
|
SELECT tool_name, error_type, exit_code, result_preview, created_at
|
|
@@ -126,39 +106,119 @@ export function buildTrajectoryEvidenceFromDb(stateDir, sessionId, workspaceDir)
|
|
|
126
106
|
)
|
|
127
107
|
ORDER BY created_at ASC
|
|
128
108
|
`).all(sessionId);
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
catch {
|
|
146
|
-
// tool_calls table may not exist — degrade gracefully (only when no other evidence)
|
|
147
|
-
if (evidence.length === 0) {
|
|
148
|
-
evidence.push({
|
|
149
|
-
sourceRef: 'tool_call_failure:unavailable',
|
|
150
|
-
note: 'trajectory_tool_calls_unavailable',
|
|
151
|
-
});
|
|
152
|
-
}
|
|
109
|
+
for (const tc of failedToolCalls) {
|
|
110
|
+
if (evidence.length >= MAX_EVIDENCE_ENTRIES)
|
|
111
|
+
break;
|
|
112
|
+
const toolName = typeof tc.tool_name === 'string' ? tc.tool_name : 'unknown';
|
|
113
|
+
const errorType = typeof tc.error_type === 'string' ? tc.error_type : 'unknown';
|
|
114
|
+
const exitCode = tc.exit_code != null ? String(tc.exit_code) : 'N/A';
|
|
115
|
+
// Enhanced: append resultPreview when available
|
|
116
|
+
const resultPreview = typeof tc.result_preview === 'string' ? tc.result_preview : null;
|
|
117
|
+
const previewSuffix = resultPreview ? ` | ${resultPreview.slice(0, 200)}` : '';
|
|
118
|
+
const note = `Tool ${toolName} failed: ${errorType} (exitCode: ${exitCode})${previewSuffix}`;
|
|
119
|
+
evidence.push({
|
|
120
|
+
sourceRef: `tool_call_failure:${String(tc.created_at ?? 'unknown')}`,
|
|
121
|
+
note: sanitizeString(note.slice(0, MAX_EVIDENCE_NOTE_CHARS), workspaceDir),
|
|
122
|
+
});
|
|
153
123
|
}
|
|
154
|
-
|
|
124
|
+
}
|
|
125
|
+
catch {
|
|
126
|
+
readFailed = true;
|
|
127
|
+
// tool_calls table may not exist — degrade gracefully (only when no other evidence)
|
|
155
128
|
if (evidence.length === 0) {
|
|
156
129
|
evidence.push({
|
|
157
|
-
sourceRef: '
|
|
158
|
-
note: '
|
|
130
|
+
sourceRef: 'tool_call_failure:unavailable',
|
|
131
|
+
note: 'trajectory_tool_calls_unavailable',
|
|
159
132
|
});
|
|
160
133
|
}
|
|
161
|
-
|
|
134
|
+
}
|
|
135
|
+
// If no evidence at all from trajectory, provide a meaningful placeholder
|
|
136
|
+
if (evidence.length === 0) {
|
|
137
|
+
evidence.push({
|
|
138
|
+
sourceRef: 'trajectory:empty',
|
|
139
|
+
note: 'trajectory_available_but_empty: no user correction or assistant turns found',
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
const bounded = evidence.slice(0, MAX_EVIDENCE_ENTRIES);
|
|
143
|
+
const realEntryCount = bounded.reduce((count, entry) => count + (PLACEHOLDER_SOURCE_REFS.has(entry.sourceRef) ? 0 : 1), 0);
|
|
144
|
+
return { entries: bounded, realEntryCount, readFailed };
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* PRI-642 Scope A typed acquisition from trajectory.db (SPEC §7.3).
|
|
148
|
+
*
|
|
149
|
+
* Validates that the requested session exists in the trajectory `sessions`
|
|
150
|
+
* table (every recorded turn/tool call upserts its session row, so an absent
|
|
151
|
+
* row means the session was never seen) and classifies the outcome:
|
|
152
|
+
* - `available` — session bound, ≥1 real behavior-trace entry;
|
|
153
|
+
* - `session_not_found` — session absent from the sessions table (or a
|
|
154
|
+
* `cli`/`unknown` sentinel — never a real session);
|
|
155
|
+
* - `trajectory_unavailable` — no trajectory.db in this workspace;
|
|
156
|
+
* - `evidence_read_failed` — the DB exists but cannot be opened/read;
|
|
157
|
+
* - `empty_trajectory` — real session, no usable evidence rows.
|
|
158
|
+
*/
|
|
159
|
+
export function acquireTrajectoryEvidenceFromDb(stateDir, sessionId, workspaceDir) {
|
|
160
|
+
if (!sessionId || sessionId === 'cli' || sessionId === 'unknown') {
|
|
161
|
+
return {
|
|
162
|
+
status: 'unavailable',
|
|
163
|
+
reasonCode: 'session_not_found',
|
|
164
|
+
detail: sessionId ? `sentinel_session_id:${sessionId}` : 'missing_session_id',
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
const dbPath = path.join(stateDir, 'trajectory.db');
|
|
168
|
+
if (!fs.existsSync(dbPath)) {
|
|
169
|
+
return {
|
|
170
|
+
status: 'unavailable',
|
|
171
|
+
reasonCode: 'trajectory_unavailable',
|
|
172
|
+
detail: 'trajectory_db_missing',
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
let db;
|
|
176
|
+
try {
|
|
177
|
+
db = new Database(dbPath, { readonly: true });
|
|
178
|
+
}
|
|
179
|
+
catch (err) {
|
|
180
|
+
return {
|
|
181
|
+
status: 'unavailable',
|
|
182
|
+
reasonCode: 'evidence_read_failed',
|
|
183
|
+
detail: `trajectory_db_unreadable: ${err instanceof Error ? err.message : String(err)}`,
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
try {
|
|
187
|
+
// Session existence: rows are upserted by every turn/tool-call write, so
|
|
188
|
+
// an absent row means the trajectory never saw this session.
|
|
189
|
+
let sessionExists = false;
|
|
190
|
+
try {
|
|
191
|
+
const row = db.prepare('SELECT 1 FROM sessions WHERE session_id = ?').get(sessionId);
|
|
192
|
+
sessionExists = row !== undefined;
|
|
193
|
+
}
|
|
194
|
+
catch {
|
|
195
|
+
// sessions table missing → cannot validate existence; fall through and
|
|
196
|
+
// let the evidence rows decide (legacy DBs may lack the table).
|
|
197
|
+
sessionExists = true;
|
|
198
|
+
}
|
|
199
|
+
if (!sessionExists) {
|
|
200
|
+
return {
|
|
201
|
+
status: 'unavailable',
|
|
202
|
+
reasonCode: 'session_not_found',
|
|
203
|
+
detail: 'session_not_present_in_trajectory',
|
|
204
|
+
};
|
|
205
|
+
}
|
|
206
|
+
const collection = collectEvidenceFromDb(db, sessionId, workspaceDir);
|
|
207
|
+
if (collection.realEntryCount > 0) {
|
|
208
|
+
return { status: 'available', entries: collection.entries };
|
|
209
|
+
}
|
|
210
|
+
if (collection.readFailed) {
|
|
211
|
+
return {
|
|
212
|
+
status: 'unavailable',
|
|
213
|
+
reasonCode: 'evidence_read_failed',
|
|
214
|
+
detail: 'trajectory_tables_unreadable',
|
|
215
|
+
};
|
|
216
|
+
}
|
|
217
|
+
return {
|
|
218
|
+
status: 'unavailable',
|
|
219
|
+
reasonCode: 'empty_trajectory',
|
|
220
|
+
detail: 'session_present_but_no_usable_evidence',
|
|
221
|
+
};
|
|
162
222
|
}
|
|
163
223
|
finally {
|
|
164
224
|
db.close();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"build-trajectory-evidence.js","sourceRoot":"","sources":["../../src/commands/build-trajectory-evidence.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,QAAQ,MAAM,gBAAgB,CAAC;AACtC,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,EACL,oBAAoB,EACpB,uBAAuB,EACvB,cAAc,GACf,MAAM,6BAA6B,CAAC;
|
|
1
|
+
{"version":3,"file":"build-trajectory-evidence.js","sourceRoot":"","sources":["../../src/commands/build-trajectory-evidence.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,QAAQ,MAAM,gBAAgB,CAAC;AACtC,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,EACL,oBAAoB,EACpB,uBAAuB,EACvB,cAAc,GACf,MAAM,6BAA6B,CAAC;AAiBrC,gFAAgF;AAChF,MAAM,uBAAuB,GAAG,IAAI,GAAG,CAAC;IACtC,oBAAoB;IACpB,2BAA2B;IAC3B,wBAAwB;IACxB,+BAA+B;IAC/B,kBAAkB;CACnB,CAAC,CAAC;AAQH;;;;GAIG;AACH,SAAS,qBAAqB,CAC5B,EAAqB,EACrB,SAAiB,EACjB,YAAqB;IAErB,MAAM,QAAQ,GAAwB,EAAE,CAAC;IACzC,IAAI,UAAU,GAAG,KAAK,CAAC;IAEvB,mDAAmD;IACnD,IAAI,CAAC;QACH,MAAM,SAAS,GAAG,EAAE,CAAC,OAAO,CAAC;;;;;OAK1B,CAAC,CAAC,GAAG,CAAC,SAAS,CAA8B,CAAC;QAEjD,MAAM,kBAAkB,GAAG,CAAC,GAAG,SAAS,CAAC,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC;QAC9F,IAAI,kBAAkB,EAAE,CAAC;YACvB,MAAM,UAAU,GAAG,OAAO,kBAAkB,CAAC,WAAW,KAAK,QAAQ;gBACnE,CAAC,CAAC,kBAAkB,CAAC,WAAW;gBAChC,CAAC,CAAC,EAAE,CAAC;YACP,MAAM,aAAa,GAAG,cAAc,CAClC,UAAU,CAAC,KAAK,CAAC,CAAC,EAAE,uBAAuB,CAAC,EAC5C,YAAY,CACb,CAAC;YACF,QAAQ,CAAC,IAAI,CAAC;gBACZ,SAAS,EAAE,iBAAiB,MAAM,CAAC,kBAAkB,CAAC,UAAU,IAAI,SAAS,CAAC,EAAE;gBAChF,IAAI,EAAE,aAAa;aACpB,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,UAAU,GAAG,IAAI,CAAC;QAClB,sDAAsD;QACtD,IAAI,QAAQ,CAAC,MAAM,GAAG,oBAAoB,EAAE,CAAC;YAC3C,QAAQ,CAAC,IAAI,CAAC;gBACZ,SAAS,EAAE,2BAA2B;gBACtC,IAAI,EAAE,mCAAmC;aAC1C,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,uCAAuC;IACvC,IAAI,CAAC;QACH,MAAM,cAAc,GAAG,EAAE,CAAC,OAAO,CAAC;;;;;OAK/B,CAAC,CAAC,GAAG,CAAC,SAAS,CAA8B,CAAC;QAEjD,MAAM,eAAe,GAAG,cAAc,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;QACjD,KAAK,MAAM,IAAI,IAAI,eAAe,EAAE,CAAC;YACnC,IAAI,QAAQ,CAAC,MAAM,IAAI,oBAAoB;gBAAE,MAAM;YACnD,MAAM,aAAa,GAAG,OAAO,IAAI,CAAC,cAAc,KAAK,QAAQ;gBAC3D,CAAC,CAAC,IAAI,CAAC,cAAc;gBACrB,CAAC,CAAC,EAAE,CAAC;YACP,MAAM,aAAa,GAAG,cAAc,CAClC,aAAa,CAAC,KAAK,CAAC,CAAC,EAAE,uBAAuB,CAAC,EAC/C,YAAY,CACb,CAAC;YACF,8DAA8D;YAC9D,MAAM,UAAU,GAAG,OAAO,IAAI,CAAC,WAAW,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC;YAClF,MAAM,iBAAiB,GAAG,UAAU,KAAK,QAAQ,CAAC,CAAC,CAAC,8CAA8C,CAAC,CAAC,CAAC,EAAE,CAAC;YACxG,QAAQ,CAAC,IAAI,CAAC;gBACZ,SAAS,EAAE,cAAc,MAAM,CAAC,IAAI,CAAC,UAAU,IAAI,SAAS,CAAC,EAAE;gBAC/D,IAAI,EAAE,aAAa,GAAG,iBAAiB;aACxC,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,UAAU,GAAG,IAAI,CAAC;QAClB,2DAA2D;QAC3D,IAAI,QAAQ,CAAC,MAAM,GAAG,oBAAoB,EAAE,CAAC;YAC3C,QAAQ,CAAC,IAAI,CAAC;gBACZ,SAAS,EAAE,wBAAwB;gBACnC,IAAI,EAAE,wCAAwC;aAC/C,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,gFAAgF;IAChF,IAAI,CAAC;QACH,MAAM,eAAe,GAAG,EAAE,CAAC,OAAO,CAAC;;;;;;;;;;OAUhC,CAAC,CAAC,GAAG,CAAC,SAAS,CAA8B,CAAC;QAEjD,KAAK,MAAM,EAAE,IAAI,eAAe,EAAE,CAAC;YACjC,IAAI,QAAQ,CAAC,MAAM,IAAI,oBAAoB;gBAAE,MAAM;YACnD,MAAM,QAAQ,GAAG,OAAO,EAAE,CAAC,SAAS,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC;YAC7E,MAAM,SAAS,GAAG,OAAO,EAAE,CAAC,UAAU,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,SAAS,CAAC;YAChF,MAAM,QAAQ,GAAG,EAAE,CAAC,SAAS,IAAI,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;YACrE,gDAAgD;YAChD,MAAM,aAAa,GAAG,OAAO,EAAE,CAAC,cAAc,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC;YACvF,MAAM,aAAa,GAAG,aAAa,CAAC,CAAC,CAAC,MAAM,aAAa,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC/E,MAAM,IAAI,GAAG,QAAQ,QAAQ,YAAY,SAAS,eAAe,QAAQ,IAAI,aAAa,EAAE,CAAC;YAC7F,QAAQ,CAAC,IAAI,CAAC;gBACZ,SAAS,EAAE,qBAAqB,MAAM,CAAC,EAAE,CAAC,UAAU,IAAI,SAAS,CAAC,EAAE;gBACpE,IAAI,EAAE,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,uBAAuB,CAAC,EAAE,YAAY,CAAC;aAC3E,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,UAAU,GAAG,IAAI,CAAC;QAClB,oFAAoF;QACpF,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC1B,QAAQ,CAAC,IAAI,CAAC;gBACZ,SAAS,EAAE,+BAA+B;gBAC1C,IAAI,EAAE,mCAAmC;aAC1C,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,0EAA0E;IAC1E,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1B,QAAQ,CAAC,IAAI,CAAC;YACZ,SAAS,EAAE,kBAAkB;YAC7B,IAAI,EAAE,6EAA6E;SACpF,CAAC,CAAC;IACL,CAAC;IAED,MAAM,OAAO,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,oBAAoB,CAAC,CAAC;IACxD,MAAM,cAAc,GAAG,OAAO,CAAC,MAAM,CACnC,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,CAAC,KAAK,GAAG,CAAC,uBAAuB,CAAC,GAAG,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAChF,CAAC,CACF,CAAC;IACF,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,UAAU,EAAE,CAAC;AAC1D,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,+BAA+B,CAC7C,QAAgB,EAChB,SAA6B,EAC7B,YAAqB;IAErB,IAAI,CAAC,SAAS,IAAI,SAAS,KAAK,KAAK,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;QACjE,OAAO;YACL,MAAM,EAAE,aAAa;YACrB,UAAU,EAAE,mBAAmB;YAC/B,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC,uBAAuB,SAAS,EAAE,CAAC,CAAC,CAAC,oBAAoB;SAC9E,CAAC;IACJ,CAAC;IAED,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,eAAe,CAAC,CAAC;IACpD,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;QAC3B,OAAO;YACL,MAAM,EAAE,aAAa;YACrB,UAAU,EAAE,wBAAwB;YACpC,MAAM,EAAE,uBAAuB;SAChC,CAAC;IACJ,CAAC;IAED,IAAI,EAAqB,CAAC;IAC1B,IAAI,CAAC;QACH,EAAE,GAAG,IAAI,QAAQ,CAAC,MAAM,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;IAChD,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO;YACL,MAAM,EAAE,aAAa;YACrB,UAAU,EAAE,sBAAsB;YAClC,MAAM,EAAE,6BAA6B,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE;SACxF,CAAC;IACJ,CAAC;IAED,IAAI,CAAC;QACH,yEAAyE;QACzE,6DAA6D;QAC7D,IAAI,aAAa,GAAG,KAAK,CAAC;QAC1B,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,EAAE,CAAC,OAAO,CAAC,6CAA6C,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;YACrF,aAAa,GAAG,GAAG,KAAK,SAAS,CAAC;QACpC,CAAC;QAAC,MAAM,CAAC;YACP,uEAAuE;YACvE,gEAAgE;YAChE,aAAa,GAAG,IAAI,CAAC;QACvB,CAAC;QACD,IAAI,CAAC,aAAa,EAAE,CAAC;YACnB,OAAO;gBACL,MAAM,EAAE,aAAa;gBACrB,UAAU,EAAE,mBAAmB;gBAC/B,MAAM,EAAE,mCAAmC;aAC5C,CAAC;QACJ,CAAC;QAED,MAAM,UAAU,GAAG,qBAAqB,CAAC,EAAE,EAAE,SAAS,EAAE,YAAY,CAAC,CAAC;QACtE,IAAI,UAAU,CAAC,cAAc,GAAG,CAAC,EAAE,CAAC;YAClC,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,OAAO,EAAE,UAAU,CAAC,OAAO,EAAE,CAAC;QAC9D,CAAC;QACD,IAAI,UAAU,CAAC,UAAU,EAAE,CAAC;YAC1B,OAAO;gBACL,MAAM,EAAE,aAAa;gBACrB,UAAU,EAAE,sBAAsB;gBAClC,MAAM,EAAE,8BAA8B;aACvC,CAAC;QACJ,CAAC;QACD,OAAO;YACL,MAAM,EAAE,aAAa;YACrB,UAAU,EAAE,kBAAkB;YAC9B,MAAM,EAAE,wCAAwC;SACjD,CAAC;IACJ,CAAC;YAAS,CAAC;QACT,EAAE,CAAC,KAAK,EAAE,CAAC;IACb,CAAC;AACH,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"diagnose.d.ts","sourceRoot":"","sources":["../../src/commands/diagnose.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"diagnose.d.ts","sourceRoot":"","sources":["../../src/commands/diagnose.ts"],"names":[],"mappings":"AAgEA,UAAU,qBAAqB;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B;AAED,UAAU,kBAAkB;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED;;;;GAIG;AACH,wBAAsB,oBAAoB,CAAC,IAAI,EAAE,qBAAqB,GAAG,OAAO,CAAC,IAAI,CAAC,CAmErF;AAkCD;;;;GAIG;AACH,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC,CA0iB/E"}
|
|
@@ -5,11 +5,11 @@
|
|
|
5
5
|
* pd diagnose status --task-id <taskId> --workspace <path>
|
|
6
6
|
* pd diagnose run --task-id <taskId> --workspace <path>
|
|
7
7
|
*/
|
|
8
|
-
import { RuntimeStateManager, SqliteHistoryQuery, SqliteContextAssembler, SqliteDiagnosticianCommitter, SqliteTrajectoryLocator, SqliteSourceTraceLocator, StoreEventEmitter, storeEmitter, SplitDiagnosticianRunner, DiagRootCauseRunner, DiagDistillerRunner, DiagRouterRunner, DefaultDiagRootCauseValidator, DefaultDiagDistillerValidator,
|
|
8
|
+
import { RuntimeStateManager, SqliteHistoryQuery, SqliteContextAssembler, SqliteDiagnosticianCommitter, SqliteTrajectoryLocator, SqliteSourceTraceLocator, StoreEventEmitter, storeEmitter, SplitDiagnosticianRunner, DiagRootCauseRunner, DiagDistillerRunner, DiagRouterRunner, DefaultDiagRootCauseValidator, DefaultDiagDistillerValidator, TestDoubleRuntimeAdapter, PDRuntimeError, isRuntimeConfigError, CandidateIntakeService, run as diagnoseRun, status as diagnoseStatus, PrincipleTreeLedgerAdapter, buildDreamerSeedFromCandidate, CANDIDATE_KIND_TO_ROUTE, ROUTE_CHANNEL_MAP, MVP_ENABLED_CHANNELS, } from '@principles/core/runtime-v2';
|
|
9
9
|
import { resolveWorkspaceDir } from '../resolve-workspace.js';
|
|
10
10
|
import { readOutputLanguageFromWorkspace } from '../config-reader.js';
|
|
11
|
-
import { loadPdConfig
|
|
12
|
-
import {
|
|
11
|
+
import { loadPdConfig } from '../services/pd-config-loader.js';
|
|
12
|
+
import { SPLIT_PIPELINE_TOTAL_TIMEOUT_MS, resolveDiagnosticianCapability } from '@principles/core/runtime-v2';
|
|
13
13
|
import { createHash } from 'node:crypto';
|
|
14
14
|
/** Layer 0 content-hash (design §6.1); injected so diag writers can attach predecessorSummary hashes. */
|
|
15
15
|
const contentHashFn = (input) => createHash('sha256').update(input).digest('hex');
|
|
@@ -147,6 +147,33 @@ export async function handleDiagnoseRun(opts) {
|
|
|
147
147
|
process.exit(1);
|
|
148
148
|
return;
|
|
149
149
|
}
|
|
150
|
+
// PRI-638: this is the CLI's ONLY capability disable check. It reads the
|
|
151
|
+
// canonical authority (internalAgents.agents.diagnostician.enabled) through
|
|
152
|
+
// the same resolver the runtime factory uses, so `pd diagnose` can never
|
|
153
|
+
// mislabel a deliberate Owner kill switch as a missing runtime, a provider
|
|
154
|
+
// failure or a malformed config. No runtime adapter is constructed and no
|
|
155
|
+
// provider is contacted on this path.
|
|
156
|
+
const configLoadResult = loadPdConfig(workspaceDir);
|
|
157
|
+
const capability = resolveDiagnosticianCapability(configLoadResult.ok ? configLoadResult.effective : configLoadResult.defaults);
|
|
158
|
+
if (!capability.available) {
|
|
159
|
+
const disabledResult = {
|
|
160
|
+
ok: false,
|
|
161
|
+
status: 'failed',
|
|
162
|
+
reason: capability.reason,
|
|
163
|
+
message: capability.message,
|
|
164
|
+
nextAction: capability.nextAction,
|
|
165
|
+
};
|
|
166
|
+
if (opts.json) {
|
|
167
|
+
console.log(JSON.stringify(disabledResult, null, 2));
|
|
168
|
+
}
|
|
169
|
+
else {
|
|
170
|
+
console.error(`error: ${capability.message}`);
|
|
171
|
+
console.error(`reason: ${capability.reason}`);
|
|
172
|
+
console.error(`nextAction: ${capability.nextAction}`);
|
|
173
|
+
}
|
|
174
|
+
process.exit(1);
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
150
177
|
// Resolve runtime kind. P1 fix (mirrors pain-retry.ts): pd diagnose run
|
|
151
178
|
// must NOT default to test-double. Without --runtime, the split pipeline
|
|
152
179
|
// would validate the test-double's stale DiagnosticianOutputV1-shaped
|
|
@@ -330,11 +357,11 @@ export async function handleDiagnoseRun(opts) {
|
|
|
330
357
|
// PRI-336: Read outputLanguage from workspace config
|
|
331
358
|
const outputLangResult = readOutputLanguageFromWorkspace(workspaceDir);
|
|
332
359
|
const outputLanguage = outputLangResult.outputLanguage;
|
|
333
|
-
//
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
const pipelineTimeoutMs =
|
|
360
|
+
// PRI-638: implementation selection is gone. The split pipeline is the only
|
|
361
|
+
// Diagnostician implementation in the tree, so it always runs with its
|
|
362
|
+
// documented 3-stage budget; `diagnostician_split_pipeline` no longer
|
|
363
|
+
// selects a runner nor disables capability.
|
|
364
|
+
const pipelineTimeoutMs = SPLIT_PIPELINE_TOTAL_TIMEOUT_MS;
|
|
338
365
|
// BUG-1 (PRI-442): extract effectiveConfig so ADR-0019 LLM rate-limit
|
|
339
366
|
// degradation (isDegradationEnabled in base-peer-runner) can read the
|
|
340
367
|
// diagnostician_llm_degradation feature flag. Without this, the runners
|
|
@@ -348,25 +375,19 @@ export async function handleDiagnoseRun(opts) {
|
|
|
348
375
|
console.warn(`[pd diagnose] .pd/config.yaml at ${configLoadResult.configPath} is malformed — falling back to default feature flags. Errors: ${errSummary}. Next action: ${configLoadResult.errors[0]?.nextAction ?? 'fix config errors and retry'}`);
|
|
349
376
|
}
|
|
350
377
|
const effectiveConfig = configLoadResult.ok ? configLoadResult.effective : configLoadResult.defaults;
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
perStageTimeoutMs,
|
|
365
|
-
});
|
|
366
|
-
}
|
|
367
|
-
else {
|
|
368
|
-
runner = new DisabledDiagnosticianRunner();
|
|
369
|
-
}
|
|
378
|
+
const resolvedKind = typeof runtimeAdapter.kind === 'function' ? runtimeAdapter.kind() : runtimeKind;
|
|
379
|
+
const perStageTimeoutMs = pipelineTimeoutMs / 3;
|
|
380
|
+
const rootCauseRunner = new DiagRootCauseRunner({ stateManager, runtimeAdapter, eventEmitter, artifactStore: stateManager.piArtifactStore, validator: new DefaultDiagRootCauseValidator(), contextAssembler, contentHashFn }, { owner: 'pd-cli-diagnose', runtimeKind: resolvedKind, outputLanguage, timeoutMs: perStageTimeoutMs, effectiveConfig });
|
|
381
|
+
const distillerRunner = new DiagDistillerRunner({ stateManager, runtimeAdapter, eventEmitter, artifactStore: stateManager.piArtifactStore, validator: new DefaultDiagDistillerValidator(), contentHashFn }, { owner: 'pd-cli-diagnose', runtimeKind: resolvedKind, outputLanguage, timeoutMs: perStageTimeoutMs, effectiveConfig });
|
|
382
|
+
const routerRunner = new DiagRouterRunner({ stateManager, runtimeAdapter, eventEmitter, artifactStore: stateManager.piArtifactStore, committer, contentHashFn }, { owner: 'pd-cli-diagnose', runtimeKind: resolvedKind, outputLanguage, timeoutMs: perStageTimeoutMs, effectiveConfig });
|
|
383
|
+
const runner = new SplitDiagnosticianRunner({
|
|
384
|
+
rootCauseRunner,
|
|
385
|
+
distillerRunner,
|
|
386
|
+
routerRunner,
|
|
387
|
+
stateManager,
|
|
388
|
+
committer,
|
|
389
|
+
perStageTimeoutMs,
|
|
390
|
+
});
|
|
370
391
|
if (!opts.json) {
|
|
371
392
|
console.log(`\nRunning diagnostician for task: ${opts.taskId}`);
|
|
372
393
|
console.log(`Workspace: ${workspaceDir}\n`);
|