@principles/pd-cli 1.115.0 → 1.117.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/dist/commands/candidate.d.ts +23 -0
- package/dist/commands/candidate.d.ts.map +1 -1
- package/dist/commands/candidate.js +89 -3
- package/dist/commands/candidate.js.map +1 -1
- package/dist/commands/diagnose.d.ts.map +1 -1
- package/dist/commands/diagnose.js +153 -132
- package/dist/commands/diagnose.js.map +1 -1
- package/dist/commands/runtime-features.d.ts.map +1 -1
- package/dist/commands/runtime-features.js +2 -7
- package/dist/commands/runtime-features.js.map +1 -1
- package/dist/commands/runtime-internalization-integrity-repair.d.ts.map +1 -1
- package/dist/commands/runtime-internalization-integrity-repair.js +15 -31
- package/dist/commands/runtime-internalization-integrity-repair.js.map +1 -1
- package/dist/commands/runtime-internalization-run-once.d.ts.map +1 -1
- package/dist/commands/runtime-internalization-run-once.js +246 -326
- package/dist/commands/runtime-internalization-run-once.js.map +1 -1
- package/dist/commands/runtime-recovery.d.ts.map +1 -1
- package/dist/commands/runtime-recovery.js +9 -8
- package/dist/commands/runtime-recovery.js.map +1 -1
- package/dist/services/__tests__/cli-output.test.d.ts +18 -0
- package/dist/services/__tests__/cli-output.test.d.ts.map +1 -0
- package/dist/services/__tests__/cli-output.test.js +103 -0
- package/dist/services/__tests__/cli-output.test.js.map +1 -0
- package/dist/services/__tests__/runtime-adapter-resolver.test.d.ts +18 -0
- package/dist/services/__tests__/runtime-adapter-resolver.test.d.ts.map +1 -0
- package/dist/services/__tests__/runtime-adapter-resolver.test.js +651 -0
- package/dist/services/__tests__/runtime-adapter-resolver.test.js.map +1 -0
- package/dist/services/cli-output.d.ts +61 -0
- package/dist/services/cli-output.d.ts.map +1 -0
- package/dist/services/cli-output.js +72 -0
- package/dist/services/cli-output.js.map +1 -0
- package/dist/services/runtime-adapter-resolver.d.ts +105 -0
- package/dist/services/runtime-adapter-resolver.d.ts.map +1 -0
- package/dist/services/runtime-adapter-resolver.js +188 -0
- package/dist/services/runtime-adapter-resolver.js.map +1 -0
- package/package.json +1 -1
- package/src/commands/candidate.ts +92 -3
- package/src/commands/diagnose.ts +146 -138
- package/src/commands/runtime-features.ts +2 -6
- package/src/commands/runtime-internalization-integrity-repair.ts +16 -28
- package/src/commands/runtime-internalization-run-once.ts +242 -353
- package/src/commands/runtime-recovery.ts +9 -7
- package/src/services/__tests__/cli-output.test.ts +130 -0
- package/src/services/__tests__/runtime-adapter-resolver.test.ts +772 -0
- package/src/services/cli-output.ts +95 -0
- package/src/services/runtime-adapter-resolver.ts +339 -0
- package/tests/commands/candidate-internalization-backfill.test.ts +43 -3
- package/tests/commands/candidate-internalize-lineage.test.ts +521 -0
- package/tests/commands/candidate-internalize.test.ts +31 -5
- package/tests/commands/diagnose.test.ts +7 -3
- package/tests/commands/runtime-internalization-run-once.test.ts +11 -0
- package/tests/commands/runtime-recovery.test.ts +27 -4
- package/tests/services/rulehost-pipeline-e2e.test.ts +40 -7
|
@@ -18,19 +18,14 @@ import {
|
|
|
18
18
|
DefaultRolloutReviewerValidator,
|
|
19
19
|
DefaultTrainerValidator,
|
|
20
20
|
TestDoubleRuntimeAdapter,
|
|
21
|
-
PiAiRuntimeAdapter,
|
|
22
|
-
OpenClawCliRuntimeAdapter,
|
|
23
|
-
L2AgentLoopAdapter,
|
|
24
|
-
loadLedger,
|
|
25
|
-
isRuntimeConfigError,
|
|
26
|
-
validateRuntimeConfig,
|
|
27
21
|
} from '@principles/core/runtime-v2';
|
|
28
|
-
import type { PdL2ArtifactReader, PdL2PrincipleReader } from '@principles/core/runtime-v2';
|
|
29
|
-
import { loadEffectiveFeatureFlags } from '../services/feature-flag-loader.js';
|
|
30
22
|
import type { WakeOnceResult, DreamerRunnerResult, PhilosopherRunnerResult, ScribeRunnerResult, ArtificerRunnerResult, EvaluatorRunnerResult, RolloutReviewerRunnerResult, TrainerRunnerResult, PDRuntimeAdapter, PeerRunnerKind, OutputLanguage } from '@principles/core/runtime-v2';
|
|
31
23
|
import { resolveWorkspaceDir } from '../resolve-workspace.js';
|
|
32
24
|
import { readOutputLanguageFromWorkspace } from '../config-reader.js';
|
|
33
|
-
import {
|
|
25
|
+
import {
|
|
26
|
+
resolveRuntimeAdapterFromConfig,
|
|
27
|
+
ConfigResolutionError,
|
|
28
|
+
} from '../services/runtime-adapter-resolver.js';
|
|
34
29
|
|
|
35
30
|
interface RunOnceOptions {
|
|
36
31
|
workspace?: string;
|
|
@@ -45,13 +40,6 @@ interface RunOnceOptions {
|
|
|
45
40
|
const OWNER = 'pd-cli-internalization-run-once';
|
|
46
41
|
const RUNTIME_KIND = 'local-worker';
|
|
47
42
|
|
|
48
|
-
class ConfigResolutionError extends Error {
|
|
49
|
-
constructor(message: string) {
|
|
50
|
-
super(message);
|
|
51
|
-
this.name = 'ConfigResolutionError';
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
|
|
55
43
|
const SUPPORTED_RUNNERS = new Set(['dreamer', 'philosopher', 'scribe', 'artificer', 'evaluator', 'rollout_reviewer', 'trainer']);
|
|
56
44
|
|
|
57
45
|
interface RunOnceOutput {
|
|
@@ -207,275 +195,122 @@ function formatTextOutput(output: RunOnceOutput): string {
|
|
|
207
195
|
return lines.join('\n');
|
|
208
196
|
}
|
|
209
197
|
|
|
210
|
-
interface ResolveAdapterOptions {
|
|
211
|
-
runtimeKind: string;
|
|
212
|
-
taskId: string;
|
|
213
|
-
workspaceDir: string;
|
|
214
|
-
runnerKind: string;
|
|
215
|
-
timeoutMs?: number;
|
|
216
|
-
/** PRI-419: stateManager for the L2 artifact reader (only used when l2_dreamer is on). */
|
|
217
|
-
l2ArtifactReader?: PdL2ArtifactReader;
|
|
218
|
-
/** PRI-419: workspace stateDir for the L2 principle reader (only used when l2_dreamer is on). */
|
|
219
|
-
l2StateDir?: string;
|
|
220
|
-
}
|
|
221
|
-
|
|
222
198
|
/**
|
|
223
|
-
* PRI-
|
|
224
|
-
*
|
|
199
|
+
* PRI-431: Local test-double payload builder.
|
|
200
|
+
* The 7 runner-specific payloads are unique to run-once.ts; the shared resolver
|
|
201
|
+
* calls this via `testDoublePayloadBuilder` callback.
|
|
225
202
|
*/
|
|
226
|
-
function
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
if (opts.runtimeKind === 'test-double') {
|
|
247
|
-
if (opts.runnerKind === 'philosopher') {
|
|
248
|
-
return new TestDoubleRuntimeAdapter({
|
|
249
|
-
onPollRun: (_runId: string) => ({
|
|
250
|
-
runId: _runId,
|
|
251
|
-
status: 'succeeded',
|
|
252
|
-
startedAt: new Date().toISOString(),
|
|
253
|
-
endedAt: new Date().toISOString(),
|
|
254
|
-
}),
|
|
255
|
-
onFetchOutput: (_runId: string) => ({
|
|
256
|
-
runId: _runId,
|
|
257
|
-
payload: {
|
|
258
|
-
taskId: opts.taskId,
|
|
259
|
-
sourceDreamerArtifactId: 'pi-art-test-dreamer',
|
|
260
|
-
thesis: 'Test thesis from test-double',
|
|
261
|
-
principleCandidate: {
|
|
262
|
-
title: 'Test Principle',
|
|
263
|
-
rationale: 'Test rationale',
|
|
264
|
-
scope: 'Test scope',
|
|
265
|
-
confidence: 0.8,
|
|
266
|
-
},
|
|
267
|
-
risks: [],
|
|
268
|
-
generatedAt: new Date().toISOString(),
|
|
269
|
-
},
|
|
270
|
-
}),
|
|
271
|
-
});
|
|
272
|
-
}
|
|
273
|
-
if (opts.runnerKind === 'scribe') {
|
|
274
|
-
return new TestDoubleRuntimeAdapter({
|
|
275
|
-
onPollRun: (_runId: string) => ({
|
|
276
|
-
runId: _runId,
|
|
277
|
-
status: 'succeeded',
|
|
278
|
-
startedAt: new Date().toISOString(),
|
|
279
|
-
endedAt: new Date().toISOString(),
|
|
280
|
-
}),
|
|
281
|
-
onFetchOutput: (_runId: string) => ({
|
|
282
|
-
runId: _runId,
|
|
283
|
-
payload: {
|
|
284
|
-
taskId: opts.taskId,
|
|
285
|
-
sourcePhilosopherArtifactId: 'pi-art-test-philosopher',
|
|
286
|
-
principleDraft: {
|
|
287
|
-
title: 'Test Principle Draft',
|
|
288
|
-
statement: 'Test principle statement',
|
|
289
|
-
rationale: 'Test rationale',
|
|
290
|
-
applicability: ['All operations'],
|
|
291
|
-
antiPatterns: ['Ignoring validation'],
|
|
292
|
-
confidence: 0.8,
|
|
293
|
-
},
|
|
294
|
-
sourceTrace: {
|
|
295
|
-
philosopherArtifactId: 'pi-art-test-philosopher',
|
|
296
|
-
},
|
|
297
|
-
risks: [],
|
|
298
|
-
generatedAt: new Date().toISOString(),
|
|
203
|
+
function buildTestDoubleAdapter(runnerKind: string, taskId: string): PDRuntimeAdapter {
|
|
204
|
+
if (runnerKind === 'philosopher') {
|
|
205
|
+
return new TestDoubleRuntimeAdapter({
|
|
206
|
+
onPollRun: (_runId: string) => ({
|
|
207
|
+
runId: _runId,
|
|
208
|
+
status: 'succeeded',
|
|
209
|
+
startedAt: new Date().toISOString(),
|
|
210
|
+
endedAt: new Date().toISOString(),
|
|
211
|
+
}),
|
|
212
|
+
onFetchOutput: (_runId: string) => ({
|
|
213
|
+
runId: _runId,
|
|
214
|
+
payload: {
|
|
215
|
+
taskId,
|
|
216
|
+
sourceDreamerArtifactId: 'pi-art-test-dreamer',
|
|
217
|
+
thesis: 'Test thesis from test-double',
|
|
218
|
+
principleCandidate: {
|
|
219
|
+
title: 'Test Principle',
|
|
220
|
+
rationale: 'Test rationale',
|
|
221
|
+
scope: 'Test scope',
|
|
222
|
+
confidence: 0.8,
|
|
299
223
|
},
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
}
|
|
303
|
-
if (opts.runnerKind === 'artificer') {
|
|
304
|
-
let capturedSourceScribeArtifactId = 'pi-art-test-scribe';
|
|
305
|
-
return new TestDoubleRuntimeAdapter({
|
|
306
|
-
onStartRun: (input) => {
|
|
307
|
-
try {
|
|
308
|
-
const payloadStr = typeof input.inputPayload === 'string' ? input.inputPayload : JSON.stringify(input.inputPayload);
|
|
309
|
-
const parsed = JSON.parse(payloadStr);
|
|
310
|
-
if (typeof parsed.sourceScribeArtifactId === 'string' && parsed.sourceScribeArtifactId.trim() !== '') {
|
|
311
|
-
capturedSourceScribeArtifactId = parsed.sourceScribeArtifactId;
|
|
312
|
-
}
|
|
313
|
-
} catch { /* use default */ }
|
|
314
|
-
return { runId: `td-artificer-${Date.now()}`, runtimeKind: 'test-double', startedAt: new Date().toISOString() };
|
|
224
|
+
risks: [],
|
|
225
|
+
generatedAt: new Date().toISOString(),
|
|
315
226
|
},
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
generatedAt: new Date().toISOString(),
|
|
227
|
+
}),
|
|
228
|
+
});
|
|
229
|
+
}
|
|
230
|
+
if (runnerKind === 'scribe') {
|
|
231
|
+
return new TestDoubleRuntimeAdapter({
|
|
232
|
+
onPollRun: (_runId: string) => ({
|
|
233
|
+
runId: _runId,
|
|
234
|
+
status: 'succeeded',
|
|
235
|
+
startedAt: new Date().toISOString(),
|
|
236
|
+
endedAt: new Date().toISOString(),
|
|
237
|
+
}),
|
|
238
|
+
onFetchOutput: (_runId: string) => ({
|
|
239
|
+
runId: _runId,
|
|
240
|
+
payload: {
|
|
241
|
+
taskId,
|
|
242
|
+
sourcePhilosopherArtifactId: 'pi-art-test-philosopher',
|
|
243
|
+
principleDraft: {
|
|
244
|
+
title: 'Test Principle Draft',
|
|
245
|
+
statement: 'Test principle statement',
|
|
246
|
+
rationale: 'Test rationale',
|
|
247
|
+
applicability: ['All operations'],
|
|
248
|
+
antiPatterns: ['Ignoring validation'],
|
|
249
|
+
confidence: 0.8,
|
|
340
250
|
},
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
}
|
|
344
|
-
if (opts.runnerKind === 'evaluator') {
|
|
345
|
-
let capturedSourceArtificerArtifactId = 'pi-art-test-artificer';
|
|
346
|
-
return new TestDoubleRuntimeAdapter({
|
|
347
|
-
onStartRun: (input) => {
|
|
348
|
-
try {
|
|
349
|
-
const payloadStr = typeof input.inputPayload === 'string' ? input.inputPayload : JSON.stringify(input.inputPayload);
|
|
350
|
-
const parsed = JSON.parse(payloadStr);
|
|
351
|
-
if (typeof parsed.sourceArtificerArtifactId === 'string' && parsed.sourceArtificerArtifactId.trim() !== '') {
|
|
352
|
-
capturedSourceArtificerArtifactId = parsed.sourceArtificerArtifactId;
|
|
353
|
-
}
|
|
354
|
-
} catch { /* use default */ }
|
|
355
|
-
return { runId: `td-evaluator-${Date.now()}`, runtimeKind: 'test-double', startedAt: new Date().toISOString() };
|
|
356
|
-
},
|
|
357
|
-
onPollRun: (_runId: string) => ({
|
|
358
|
-
runId: _runId,
|
|
359
|
-
status: 'succeeded',
|
|
360
|
-
startedAt: new Date().toISOString(),
|
|
361
|
-
endedAt: new Date().toISOString(),
|
|
362
|
-
}),
|
|
363
|
-
onFetchOutput: (_runId: string) => ({
|
|
364
|
-
runId: _runId,
|
|
365
|
-
payload: {
|
|
366
|
-
taskId: opts.taskId,
|
|
367
|
-
sourceArtificerArtifactId: capturedSourceArtificerArtifactId,
|
|
368
|
-
evaluation: {
|
|
369
|
-
decision: 'approved',
|
|
370
|
-
summary: 'Test evaluation summary',
|
|
371
|
-
score: 0.85,
|
|
372
|
-
strengths: ['Well-structured plan'],
|
|
373
|
-
concerns: [],
|
|
374
|
-
requiredChanges: [],
|
|
375
|
-
},
|
|
376
|
-
sourceTrace: {
|
|
377
|
-
artificerArtifactId: capturedSourceArtificerArtifactId,
|
|
378
|
-
},
|
|
379
|
-
risks: [],
|
|
380
|
-
generatedAt: new Date().toISOString(),
|
|
251
|
+
sourceTrace: {
|
|
252
|
+
philosopherArtifactId: 'pi-art-test-philosopher',
|
|
381
253
|
},
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
}
|
|
385
|
-
if (opts.runnerKind === 'rollout_reviewer') {
|
|
386
|
-
let capturedSourceEvaluatorArtifactId = 'pi-art-test-evaluator';
|
|
387
|
-
return new TestDoubleRuntimeAdapter({
|
|
388
|
-
onStartRun: (input) => {
|
|
389
|
-
try {
|
|
390
|
-
const payloadStr = typeof input.inputPayload === 'string' ? input.inputPayload : JSON.stringify(input.inputPayload);
|
|
391
|
-
const parsed = JSON.parse(payloadStr);
|
|
392
|
-
if (typeof parsed.sourceEvaluatorArtifactId === 'string' && parsed.sourceEvaluatorArtifactId.trim() !== '') {
|
|
393
|
-
capturedSourceEvaluatorArtifactId = parsed.sourceEvaluatorArtifactId;
|
|
394
|
-
}
|
|
395
|
-
} catch { /* use default */ }
|
|
396
|
-
return { runId: `td-rollout-reviewer-${Date.now()}`, runtimeKind: 'test-double', startedAt: new Date().toISOString() };
|
|
254
|
+
risks: [],
|
|
255
|
+
generatedAt: new Date().toISOString(),
|
|
397
256
|
},
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
257
|
+
}),
|
|
258
|
+
});
|
|
259
|
+
}
|
|
260
|
+
if (runnerKind === 'artificer') {
|
|
261
|
+
let capturedSourceScribeArtifactId = 'pi-art-test-scribe';
|
|
262
|
+
return new TestDoubleRuntimeAdapter({
|
|
263
|
+
onStartRun: (input) => {
|
|
264
|
+
try {
|
|
265
|
+
const payloadStr = typeof input.inputPayload === 'string' ? input.inputPayload : JSON.stringify(input.inputPayload);
|
|
266
|
+
const parsed = JSON.parse(payloadStr);
|
|
267
|
+
if (typeof parsed.sourceScribeArtifactId === 'string' && parsed.sourceScribeArtifactId.trim() !== '') {
|
|
268
|
+
capturedSourceScribeArtifactId = parsed.sourceScribeArtifactId;
|
|
269
|
+
}
|
|
270
|
+
} catch { /* use default */ }
|
|
271
|
+
return { runId: `td-artificer-${Date.now()}`, runtimeKind: 'test-double', startedAt: new Date().toISOString() };
|
|
272
|
+
},
|
|
273
|
+
onPollRun: (_runId: string) => ({
|
|
274
|
+
runId: _runId,
|
|
275
|
+
status: 'succeeded',
|
|
276
|
+
startedAt: new Date().toISOString(),
|
|
277
|
+
endedAt: new Date().toISOString(),
|
|
278
|
+
}),
|
|
279
|
+
onFetchOutput: (_runId: string) => ({
|
|
280
|
+
runId: _runId,
|
|
281
|
+
payload: {
|
|
282
|
+
taskId,
|
|
283
|
+
sourceScribeArtifactId: capturedSourceScribeArtifactId,
|
|
284
|
+
implementationPlan: {
|
|
285
|
+
summary: 'Test implementation summary',
|
|
286
|
+
targetSurface: 'src/test/*.ts',
|
|
287
|
+
changes: ['Add validation to test module'],
|
|
288
|
+
tests: ['Unit test for validation'],
|
|
289
|
+
rolloutNotes: ['Deploy behind feature flag'],
|
|
290
|
+
confidence: 0.8,
|
|
422
291
|
},
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
}
|
|
426
|
-
if (opts.runnerKind === 'trainer') {
|
|
427
|
-
let capturedSourceRolloutReviewerArtifactId = 'pi-art-test-rollout-reviewer';
|
|
428
|
-
return new TestDoubleRuntimeAdapter({
|
|
429
|
-
onStartRun: (input) => {
|
|
430
|
-
try {
|
|
431
|
-
const payloadStr = typeof input.inputPayload === 'string' ? input.inputPayload : JSON.stringify(input.inputPayload);
|
|
432
|
-
const parsed = JSON.parse(payloadStr);
|
|
433
|
-
if (typeof parsed.sourceRolloutReviewerArtifactId === 'string' && parsed.sourceRolloutReviewerArtifactId.trim() !== '') {
|
|
434
|
-
capturedSourceRolloutReviewerArtifactId = parsed.sourceRolloutReviewerArtifactId;
|
|
435
|
-
}
|
|
436
|
-
} catch { /* use default */ }
|
|
437
|
-
return { runId: `td-trainer-${Date.now()}`, runtimeKind: 'test-double', startedAt: new Date().toISOString() };
|
|
438
|
-
},
|
|
439
|
-
onPollRun: (_runId: string) => ({
|
|
440
|
-
runId: _runId,
|
|
441
|
-
status: 'succeeded',
|
|
442
|
-
startedAt: new Date().toISOString(),
|
|
443
|
-
endedAt: new Date().toISOString(),
|
|
444
|
-
}),
|
|
445
|
-
onFetchOutput: (_runId: string) => ({
|
|
446
|
-
runId: _runId,
|
|
447
|
-
payload: {
|
|
448
|
-
taskId: opts.taskId,
|
|
449
|
-
sourceRolloutReviewerArtifactId: capturedSourceRolloutReviewerArtifactId,
|
|
450
|
-
ruleCandidate: {
|
|
451
|
-
toolScope: 'src/**/*.ts',
|
|
452
|
-
triggerCondition: 'TypeScript file edit with schema mismatch',
|
|
453
|
-
proposedDecision: 'auto_correct',
|
|
454
|
-
proposedCorrection: {
|
|
455
|
-
description: 'Auto-correct by adding input validation before processing',
|
|
456
|
-
proposedParams: {
|
|
457
|
-
strategy: 'prepend',
|
|
458
|
-
snippet: 'const validated = schema.parse(input); if (!validated.success) throw new ValidationError(validated.error);',
|
|
459
|
-
},
|
|
460
|
-
},
|
|
461
|
-
rationale: 'Auto-correct validates input before processing to prevent downstream errors',
|
|
462
|
-
confidence: 0.88,
|
|
463
|
-
},
|
|
464
|
-
safety: {
|
|
465
|
-
limitations: ['Requires schema definition for all input types', 'May not handle complex nested structures'],
|
|
466
|
-
falsePositiveRisks: ['Could over-correct on intentional dynamic patterns'],
|
|
467
|
-
requiredReplayCases: ['Schema validation edge case', 'Nested object validation'],
|
|
468
|
-
},
|
|
469
|
-
sourceTrace: {
|
|
470
|
-
rolloutReviewerArtifactId: capturedSourceRolloutReviewerArtifactId,
|
|
471
|
-
},
|
|
472
|
-
risks: [],
|
|
473
|
-
generatedAt: new Date().toISOString(),
|
|
292
|
+
sourceTrace: {
|
|
293
|
+
scribeArtifactId: capturedSourceScribeArtifactId,
|
|
474
294
|
},
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
295
|
+
risks: [],
|
|
296
|
+
generatedAt: new Date().toISOString(),
|
|
297
|
+
},
|
|
298
|
+
}),
|
|
299
|
+
});
|
|
300
|
+
}
|
|
301
|
+
if (runnerKind === 'evaluator') {
|
|
302
|
+
let capturedSourceArtificerArtifactId = 'pi-art-test-artificer';
|
|
478
303
|
return new TestDoubleRuntimeAdapter({
|
|
304
|
+
onStartRun: (input) => {
|
|
305
|
+
try {
|
|
306
|
+
const payloadStr = typeof input.inputPayload === 'string' ? input.inputPayload : JSON.stringify(input.inputPayload);
|
|
307
|
+
const parsed = JSON.parse(payloadStr);
|
|
308
|
+
if (typeof parsed.sourceArtificerArtifactId === 'string' && parsed.sourceArtificerArtifactId.trim() !== '') {
|
|
309
|
+
capturedSourceArtificerArtifactId = parsed.sourceArtificerArtifactId;
|
|
310
|
+
}
|
|
311
|
+
} catch { /* use default */ }
|
|
312
|
+
return { runId: `td-evaluator-${Date.now()}`, runtimeKind: 'test-double', startedAt: new Date().toISOString() };
|
|
313
|
+
},
|
|
479
314
|
onPollRun: (_runId: string) => ({
|
|
480
315
|
runId: _runId,
|
|
481
316
|
status: 'succeeded',
|
|
@@ -485,92 +320,145 @@ function resolveRuntimeAdapter(opts: ResolveAdapterOptions): PDRuntimeAdapter {
|
|
|
485
320
|
onFetchOutput: (_runId: string) => ({
|
|
486
321
|
runId: _runId,
|
|
487
322
|
payload: {
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
323
|
+
taskId,
|
|
324
|
+
sourceArtificerArtifactId: capturedSourceArtificerArtifactId,
|
|
325
|
+
evaluation: {
|
|
326
|
+
decision: 'approved',
|
|
327
|
+
summary: 'Test evaluation summary',
|
|
328
|
+
score: 0.85,
|
|
329
|
+
strengths: ['Well-structured plan'],
|
|
330
|
+
concerns: [],
|
|
331
|
+
requiredChanges: [],
|
|
332
|
+
},
|
|
333
|
+
sourceTrace: {
|
|
334
|
+
artificerArtifactId: capturedSourceArtificerArtifactId,
|
|
335
|
+
},
|
|
336
|
+
risks: [],
|
|
500
337
|
generatedAt: new Date().toISOString(),
|
|
501
338
|
},
|
|
502
339
|
}),
|
|
503
340
|
});
|
|
504
341
|
}
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
workspace: opts.workspaceDir,
|
|
537
|
-
totalBudgetMs: adapterTimeoutMs,
|
|
342
|
+
if (runnerKind === 'rollout_reviewer') {
|
|
343
|
+
let capturedSourceEvaluatorArtifactId = 'pi-art-test-evaluator';
|
|
344
|
+
return new TestDoubleRuntimeAdapter({
|
|
345
|
+
onStartRun: (input) => {
|
|
346
|
+
try {
|
|
347
|
+
const payloadStr = typeof input.inputPayload === 'string' ? input.inputPayload : JSON.stringify(input.inputPayload);
|
|
348
|
+
const parsed = JSON.parse(payloadStr);
|
|
349
|
+
if (typeof parsed.sourceEvaluatorArtifactId === 'string' && parsed.sourceEvaluatorArtifactId.trim() !== '') {
|
|
350
|
+
capturedSourceEvaluatorArtifactId = parsed.sourceEvaluatorArtifactId;
|
|
351
|
+
}
|
|
352
|
+
} catch { /* use default */ }
|
|
353
|
+
return { runId: `td-rollout-reviewer-${Date.now()}`, runtimeKind: 'test-double', startedAt: new Date().toISOString() };
|
|
354
|
+
},
|
|
355
|
+
onPollRun: (_runId: string) => ({
|
|
356
|
+
runId: _runId,
|
|
357
|
+
status: 'succeeded',
|
|
358
|
+
startedAt: new Date().toISOString(),
|
|
359
|
+
endedAt: new Date().toISOString(),
|
|
360
|
+
}),
|
|
361
|
+
onFetchOutput: (_runId: string) => ({
|
|
362
|
+
runId: _runId,
|
|
363
|
+
payload: {
|
|
364
|
+
taskId,
|
|
365
|
+
sourceEvaluatorArtifactId: capturedSourceEvaluatorArtifactId,
|
|
366
|
+
review: {
|
|
367
|
+
decision: 'approve_rollout',
|
|
368
|
+
summary: 'Test rollout review summary',
|
|
369
|
+
confidence: 0.9,
|
|
370
|
+
requiredChanges: [],
|
|
371
|
+
rolloutRisks: [],
|
|
372
|
+
safetyChecks: ['Verify feature flag is properly configured'],
|
|
538
373
|
},
|
|
539
|
-
{
|
|
540
|
-
|
|
541
|
-
principleReader: makeDreamerPrincipleReader(opts.l2StateDir),
|
|
374
|
+
sourceTrace: {
|
|
375
|
+
evaluatorArtifactId: capturedSourceEvaluatorArtifactId,
|
|
542
376
|
},
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
return new PiAiRuntimeAdapter({
|
|
548
|
-
provider: String(configResult.provider),
|
|
549
|
-
model: String(configResult.model),
|
|
550
|
-
apiKeyEnv: String(configResult.apiKeyEnv),
|
|
551
|
-
maxRetries: configResult.maxRetries,
|
|
552
|
-
timeoutMs: adapterTimeoutMs,
|
|
553
|
-
baseUrl: configResult.baseUrl,
|
|
554
|
-
workspace: opts.workspaceDir,
|
|
377
|
+
risks: [],
|
|
378
|
+
generatedAt: new Date().toISOString(),
|
|
379
|
+
},
|
|
380
|
+
}),
|
|
555
381
|
});
|
|
556
382
|
}
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
383
|
+
if (runnerKind === 'trainer') {
|
|
384
|
+
let capturedSourceRolloutReviewerArtifactId = 'pi-art-test-rollout-reviewer';
|
|
385
|
+
return new TestDoubleRuntimeAdapter({
|
|
386
|
+
onStartRun: (input) => {
|
|
387
|
+
try {
|
|
388
|
+
const payloadStr = typeof input.inputPayload === 'string' ? input.inputPayload : JSON.stringify(input.inputPayload);
|
|
389
|
+
const parsed = JSON.parse(payloadStr);
|
|
390
|
+
if (typeof parsed.sourceRolloutReviewerArtifactId === 'string' && parsed.sourceRolloutReviewerArtifactId.trim() !== '') {
|
|
391
|
+
capturedSourceRolloutReviewerArtifactId = parsed.sourceRolloutReviewerArtifactId;
|
|
392
|
+
}
|
|
393
|
+
} catch { /* use default */ }
|
|
394
|
+
return { runId: `td-trainer-${Date.now()}`, runtimeKind: 'test-double', startedAt: new Date().toISOString() };
|
|
395
|
+
},
|
|
396
|
+
onPollRun: (_runId: string) => ({
|
|
397
|
+
runId: _runId,
|
|
398
|
+
status: 'succeeded',
|
|
399
|
+
startedAt: new Date().toISOString(),
|
|
400
|
+
endedAt: new Date().toISOString(),
|
|
401
|
+
}),
|
|
402
|
+
onFetchOutput: (_runId: string) => ({
|
|
403
|
+
runId: _runId,
|
|
404
|
+
payload: {
|
|
405
|
+
taskId,
|
|
406
|
+
sourceRolloutReviewerArtifactId: capturedSourceRolloutReviewerArtifactId,
|
|
407
|
+
ruleCandidate: {
|
|
408
|
+
toolScope: 'src/**/*.ts',
|
|
409
|
+
triggerCondition: 'TypeScript file edit with schema mismatch',
|
|
410
|
+
proposedDecision: 'auto_correct',
|
|
411
|
+
proposedCorrection: {
|
|
412
|
+
description: 'Auto-correct by adding input validation before processing',
|
|
413
|
+
proposedParams: {
|
|
414
|
+
strategy: 'prepend',
|
|
415
|
+
snippet: 'const validated = schema.parse(input); if (!validated.success) throw new ValidationError(validated.error);',
|
|
416
|
+
},
|
|
417
|
+
},
|
|
418
|
+
rationale: 'Auto-correct validates input before processing to prevent downstream errors',
|
|
419
|
+
confidence: 0.88,
|
|
420
|
+
},
|
|
421
|
+
safety: {
|
|
422
|
+
limitations: ['Requires schema definition for all input types', 'May not handle complex nested structures'],
|
|
423
|
+
falsePositiveRisks: ['Could over-correct on intentional dynamic patterns'],
|
|
424
|
+
requiredReplayCases: ['Schema validation edge case', 'Nested object validation'],
|
|
425
|
+
},
|
|
426
|
+
sourceTrace: {
|
|
427
|
+
rolloutReviewerArtifactId: capturedSourceRolloutReviewerArtifactId,
|
|
428
|
+
},
|
|
429
|
+
risks: [],
|
|
430
|
+
generatedAt: new Date().toISOString(),
|
|
431
|
+
},
|
|
432
|
+
}),
|
|
570
433
|
});
|
|
571
434
|
}
|
|
572
|
-
|
|
573
|
-
|
|
435
|
+
// dreamer / default
|
|
436
|
+
return new TestDoubleRuntimeAdapter({
|
|
437
|
+
onPollRun: (_runId: string) => ({
|
|
438
|
+
runId: _runId,
|
|
439
|
+
status: 'succeeded',
|
|
440
|
+
startedAt: new Date().toISOString(),
|
|
441
|
+
endedAt: new Date().toISOString(),
|
|
442
|
+
}),
|
|
443
|
+
onFetchOutput: (_runId: string) => ({
|
|
444
|
+
runId: _runId,
|
|
445
|
+
payload: {
|
|
446
|
+
valid: true,
|
|
447
|
+
taskId,
|
|
448
|
+
candidates: [{
|
|
449
|
+
candidateIndex: 0,
|
|
450
|
+
badDecision: 'Ignored input validation requirement',
|
|
451
|
+
betterDecision: 'Validate all inputs against schema before processing',
|
|
452
|
+
rationale: 'Input validation prevents downstream errors and data corruption',
|
|
453
|
+
confidence: 0.85,
|
|
454
|
+
riskLevel: 'low',
|
|
455
|
+
strategicPerspective: 'defensive-programming',
|
|
456
|
+
}],
|
|
457
|
+
contextRefs: [],
|
|
458
|
+
generatedAt: new Date().toISOString(),
|
|
459
|
+
},
|
|
460
|
+
}),
|
|
461
|
+
});
|
|
574
462
|
}
|
|
575
463
|
|
|
576
464
|
export async function handleRuntimeInternalizationRunOnce(opts: RunOnceOptions): Promise<void> {
|
|
@@ -631,13 +519,14 @@ export async function handleRuntimeInternalizationRunOnce(opts: RunOnceOptions):
|
|
|
631
519
|
|
|
632
520
|
const eventEmitter = new StoreEventEmitter();
|
|
633
521
|
const artifactStore = stateManager.piArtifactStore;
|
|
634
|
-
const runtimeAdapter =
|
|
522
|
+
const runtimeAdapter = resolveRuntimeAdapterFromConfig({
|
|
635
523
|
runtimeKind,
|
|
636
|
-
taskId: wakeResult.taskId,
|
|
637
524
|
workspaceDir,
|
|
638
525
|
runnerKind,
|
|
639
526
|
timeoutMs: cliTimeoutMs,
|
|
640
|
-
|
|
527
|
+
allowTestDouble: true,
|
|
528
|
+
testDoublePayloadBuilder: () => buildTestDoubleAdapter(runnerKind, wakeResult.taskId),
|
|
529
|
+
// PRI-419: pass the L2 readers so the resolver can build an L2AgentLoopAdapter
|
|
641
530
|
// when l2_dreamer is enabled. Only consumed for dreamer; harmless for other runners.
|
|
642
531
|
l2ArtifactReader: artifactStore,
|
|
643
532
|
l2StateDir: `${workspaceDir}/.state`,
|