@principles/pd-cli 1.133.0 → 1.134.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/__tests__/intent-flag-wiring.test.js +74 -3
- package/dist/commands/__tests__/intent-flag-wiring.test.js.map +1 -1
- package/dist/commands/__tests__/pain-retry-maxTokens-flag.test.d.ts +2 -0
- package/dist/commands/__tests__/pain-retry-maxTokens-flag.test.d.ts.map +1 -0
- package/dist/commands/__tests__/pain-retry-maxTokens-flag.test.js +60 -0
- package/dist/commands/__tests__/pain-retry-maxTokens-flag.test.js.map +1 -0
- package/dist/commands/__tests__/rulecode-flag-wiring.test.js +11 -4
- package/dist/commands/__tests__/rulecode-flag-wiring.test.js.map +1 -1
- package/dist/commands/__tests__/run-rulehost-flag-wiring.test.js +9 -0
- package/dist/commands/__tests__/run-rulehost-flag-wiring.test.js.map +1 -1
- package/dist/commands/admission-gate.d.ts +24 -0
- package/dist/commands/admission-gate.d.ts.map +1 -0
- package/dist/commands/admission-gate.js +29 -0
- package/dist/commands/admission-gate.js.map +1 -0
- package/dist/commands/candidate.d.ts.map +1 -1
- package/dist/commands/candidate.js +72 -6
- package/dist/commands/candidate.js.map +1 -1
- package/dist/commands/console.d.ts.map +1 -1
- package/dist/commands/console.js +40 -0
- package/dist/commands/console.js.map +1 -1
- package/dist/commands/demo-story-a.d.ts.map +1 -1
- package/dist/commands/demo-story-a.js +4 -2
- package/dist/commands/demo-story-a.js.map +1 -1
- package/dist/commands/diagnose.d.ts.map +1 -1
- package/dist/commands/diagnose.js +155 -8
- package/dist/commands/diagnose.js.map +1 -1
- package/dist/commands/errors-list.d.ts +25 -0
- package/dist/commands/errors-list.d.ts.map +1 -0
- package/dist/commands/errors-list.js +368 -0
- package/dist/commands/errors-list.js.map +1 -0
- package/dist/commands/health-codex.d.ts +7 -0
- package/dist/commands/health-codex.d.ts.map +1 -0
- package/dist/commands/health-codex.js +209 -0
- package/dist/commands/health-codex.js.map +1 -0
- package/dist/commands/health.d.ts +24 -0
- package/dist/commands/health.d.ts.map +1 -1
- package/dist/commands/health.js +48 -0
- package/dist/commands/health.js.map +1 -1
- package/dist/commands/intent.d.ts +21 -4
- package/dist/commands/intent.d.ts.map +1 -1
- package/dist/commands/intent.js +88 -27
- package/dist/commands/intent.js.map +1 -1
- package/dist/commands/pain-evidence.d.ts +6 -0
- package/dist/commands/pain-evidence.d.ts.map +1 -1
- package/dist/commands/pain-evidence.js +6 -0
- package/dist/commands/pain-evidence.js.map +1 -1
- package/dist/commands/pain-record.d.ts.map +1 -1
- package/dist/commands/pain-record.js +21 -0
- package/dist/commands/pain-record.js.map +1 -1
- package/dist/commands/pain-retry.d.ts +4 -0
- package/dist/commands/pain-retry.d.ts.map +1 -1
- package/dist/commands/pain-retry.js +327 -32
- package/dist/commands/pain-retry.js.map +1 -1
- package/dist/commands/proven-channel-baseline.d.ts.map +1 -1
- package/dist/commands/proven-channel-baseline.js +4 -2
- package/dist/commands/proven-channel-baseline.js.map +1 -1
- package/dist/commands/runtime-activation.d.ts +30 -0
- package/dist/commands/runtime-activation.d.ts.map +1 -1
- package/dist/commands/runtime-activation.js +567 -11
- package/dist/commands/runtime-activation.js.map +1 -1
- package/dist/commands/runtime-canary.d.ts.map +1 -1
- package/dist/commands/runtime-canary.js +32 -7
- package/dist/commands/runtime-canary.js.map +1 -1
- package/dist/commands/runtime-health-snapshot.d.ts.map +1 -1
- package/dist/commands/runtime-health-snapshot.js +4 -2
- package/dist/commands/runtime-health-snapshot.js.map +1 -1
- package/dist/commands/runtime-init.d.ts +43 -0
- package/dist/commands/runtime-init.d.ts.map +1 -0
- package/dist/commands/runtime-init.js +264 -0
- package/dist/commands/runtime-init.js.map +1 -0
- package/dist/commands/runtime-internalization-context-trace.d.ts +25 -0
- package/dist/commands/runtime-internalization-context-trace.d.ts.map +1 -0
- package/dist/commands/runtime-internalization-context-trace.js +374 -0
- package/dist/commands/runtime-internalization-context-trace.js.map +1 -0
- package/dist/commands/runtime-internalization-enqueue-successors.d.ts.map +1 -1
- package/dist/commands/runtime-internalization-enqueue-successors.js +3 -1
- package/dist/commands/runtime-internalization-enqueue-successors.js.map +1 -1
- package/dist/commands/runtime-internalization-integrity.d.ts.map +1 -1
- package/dist/commands/runtime-internalization-integrity.js +4 -2
- package/dist/commands/runtime-internalization-integrity.js.map +1 -1
- package/dist/commands/runtime-internalization-run-once.d.ts.map +1 -1
- package/dist/commands/runtime-internalization-run-once.js +20 -5
- package/dist/commands/runtime-internalization-run-once.js.map +1 -1
- package/dist/commands/runtime-internalization-run-rulehost.d.ts +1 -0
- package/dist/commands/runtime-internalization-run-rulehost.d.ts.map +1 -1
- package/dist/commands/runtime-internalization-run-rulehost.js +149 -6
- package/dist/commands/runtime-internalization-run-rulehost.js.map +1 -1
- package/dist/commands/runtime-uat.d.ts.map +1 -1
- package/dist/commands/runtime-uat.guard.test.js +13 -15
- package/dist/commands/runtime-uat.guard.test.js.map +1 -1
- package/dist/commands/runtime-uat.js +4 -3
- package/dist/commands/runtime-uat.js.map +1 -1
- package/dist/config-reader.js +1 -1
- package/dist/config-reader.js.map +1 -1
- package/dist/index.js +54 -78
- package/dist/index.js.map +1 -1
- package/dist/services/__tests__/evaluator-runner-deps.test.d.ts +2 -0
- package/dist/services/__tests__/evaluator-runner-deps.test.d.ts.map +1 -0
- package/dist/services/__tests__/evaluator-runner-deps.test.js +304 -0
- package/dist/services/__tests__/evaluator-runner-deps.test.js.map +1 -0
- package/dist/services/__tests__/rulehost-readiness.test.js.map +1 -1
- package/dist/services/__tests__/runtime-adapter-resolver.test.js.map +1 -1
- package/dist/services/config-doctor.d.ts.map +1 -1
- package/dist/services/config-doctor.js +9 -2
- package/dist/services/config-doctor.js.map +1 -1
- package/dist/services/pain-flood-simulation-runner.d.ts.map +1 -1
- package/dist/services/pain-flood-simulation-runner.js +9 -0
- package/dist/services/pain-flood-simulation-runner.js.map +1 -1
- package/dist/services/pd-config-loader.js +2 -2
- package/dist/services/pd-config-loader.js.map +1 -1
- package/dist/services/proven-channel-baseline-runner.d.ts.map +1 -1
- package/dist/services/proven-channel-baseline-runner.js +10 -2
- package/dist/services/proven-channel-baseline-runner.js.map +1 -1
- package/dist/services/quality-scorecard/data-extractor.js.map +1 -1
- package/dist/services/resolve-runtime-from-pd-config.js.map +1 -1
- package/dist/services/rulehost-pipeline-runner.d.ts +77 -1
- package/dist/services/rulehost-pipeline-runner.d.ts.map +1 -1
- package/dist/services/rulehost-pipeline-runner.js +111 -7
- package/dist/services/rulehost-pipeline-runner.js.map +1 -1
- package/dist/services/rulehost-readiness.js.map +1 -1
- package/dist/services/runtime-adapter-resolver.d.ts +1 -0
- package/dist/services/runtime-adapter-resolver.d.ts.map +1 -1
- package/dist/services/runtime-adapter-resolver.js +3 -0
- package/dist/services/runtime-adapter-resolver.js.map +1 -1
- package/dist/services/synthetic-baseline-runner.d.ts.map +1 -1
- package/dist/services/synthetic-baseline-runner.js +11 -0
- package/dist/services/synthetic-baseline-runner.js.map +1 -1
- package/dist/utils/production-workspace-guard.d.ts +4 -4
- package/dist/utils/production-workspace-guard.d.ts.map +1 -1
- package/dist/utils/production-workspace-guard.js +19 -16
- package/dist/utils/production-workspace-guard.js.map +1 -1
- package/dist/utils/production-workspace-guard.test.js +54 -19
- package/dist/utils/production-workspace-guard.test.js.map +1 -1
- package/package.json +8 -5
- package/src/commands/__tests__/intent-flag-wiring.test.ts +88 -3
- package/src/commands/__tests__/pain-retry-maxTokens-flag.test.ts +73 -0
- package/src/commands/__tests__/rulecode-flag-wiring.test.ts +31 -24
- package/src/commands/__tests__/run-rulehost-flag-wiring.test.ts +12 -0
- package/src/commands/admission-gate.ts +30 -0
- package/src/commands/candidate.ts +74 -6
- package/src/commands/console.ts +40 -0
- package/src/commands/demo-story-a.ts +4 -2
- package/src/commands/diagnose.ts +158 -10
- package/src/commands/errors-list.ts +440 -0
- package/src/commands/health-codex.ts +249 -0
- package/src/commands/health.ts +60 -0
- package/src/commands/intent.ts +98 -29
- package/src/commands/pain-evidence.ts +6 -0
- package/src/commands/pain-record.ts +21 -0
- package/src/commands/pain-retry.ts +353 -35
- package/src/commands/proven-channel-baseline.ts +4 -2
- package/src/commands/runtime-activation.ts +657 -12
- package/src/commands/runtime-canary.ts +31 -5
- package/src/commands/runtime-health-snapshot.ts +4 -2
- package/src/commands/runtime-init.ts +305 -0
- package/src/commands/runtime-internalization-context-trace.ts +445 -0
- package/src/commands/runtime-internalization-enqueue-successors.ts +3 -1
- package/src/commands/runtime-internalization-integrity.ts +4 -2
- package/src/commands/runtime-internalization-run-once.ts +20 -5
- package/src/commands/runtime-internalization-run-rulehost.ts +159 -6
- package/src/commands/runtime-uat.guard.test.ts +14 -16
- package/src/commands/runtime-uat.ts +4 -3
- package/src/config-reader.ts +1 -1
- package/src/index.ts +69 -78
- package/src/services/__tests__/evaluator-runner-deps.test.ts +341 -0
- package/src/services/config-doctor.ts +9 -2
- package/src/services/pain-flood-simulation-runner.ts +9 -0
- package/src/services/pd-config-loader.ts +2 -2
- package/src/services/proven-channel-baseline-runner.ts +10 -3
- package/src/services/rulehost-pipeline-runner.ts +157 -6
- package/src/services/runtime-adapter-resolver.ts +4 -0
- package/src/services/synthetic-baseline-runner.ts +11 -0
- package/src/utils/production-workspace-guard.test.ts +62 -20
- package/src/utils/production-workspace-guard.ts +19 -16
- package/tests/bdd/cli-contract.steps.ts +343 -0
- package/tests/bdd/context-trace.steps.ts +229 -0
- package/tests/bdd/support/gherkin-loader.ts +147 -0
- package/tests/bdd/support/repo-root.ts +62 -0
- package/tests/bdd/support/vitest-bdd.ts +179 -0
- package/tests/commands/admission-gate-coverage.test.ts +79 -0
- package/tests/commands/candidate-audit-repair.test.ts +77 -0
- package/tests/commands/candidate-intake.test.ts +155 -10
- package/tests/commands/candidate-internalization-backfill.test.ts +30 -0
- package/tests/commands/cli-help-snapshot.test.ts +15 -1
- package/tests/commands/console-open.test.ts +19 -0
- package/tests/commands/diagnose.test.ts +619 -14
- package/tests/commands/errors-list.test.ts +678 -0
- package/tests/commands/health-codex.test.ts +243 -0
- package/tests/commands/health-host-wiring.test.ts +76 -0
- package/tests/commands/intent.test.ts +4 -4
- package/tests/commands/pain-record.test.ts +80 -0
- package/tests/commands/pain-retry.test.ts +94 -3
- package/tests/commands/run-rulehost-handler.test.ts +133 -0
- package/tests/commands/runtime-activation-approve-flag-wiring.test.ts +227 -0
- package/tests/commands/runtime-activation-deactivate-flag-wiring.test.ts +167 -0
- package/tests/commands/runtime-activation-dispatch-flag-wiring.test.ts +262 -0
- package/tests/commands/runtime-activation-list-flag-wiring.test.ts +193 -0
- package/tests/commands/runtime-activation-promote-flag-wiring.test.ts +222 -0
- package/tests/commands/runtime-activation.test.ts +1090 -5
- package/tests/commands/runtime-canary.test.ts +50 -0
- package/tests/commands/runtime-features.test.ts +2 -0
- package/tests/commands/runtime-init-empty-workspace.test.ts +234 -0
- package/tests/commands/runtime-init.test.ts +346 -0
- package/tests/commands/runtime-internalization-context-trace.test.ts +110 -0
- package/tests/commands/runtime-internalization.test.ts +2 -2
- package/tests/config-reader.test.ts +6 -5
- package/tests/e2e/cross-package-acceptance.test.ts +55 -13
- package/tests/services/mainline-snapshot-assembler.test.ts +6 -3
- package/tests/services/resolve-runtime-from-pd-config.test.ts +2 -0
- package/tests/services/rulehost-pipeline-runner.test.ts +1 -1
- package/vitest.config.ts +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pain-record.js","sourceRoot":"","sources":["../../src/commands/pain-record.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EACL,sBAAsB,EACtB,0BAA0B,EAC1B,oBAAoB,EACpB,oBAAoB,EACpB,gBAAgB,GACjB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAC9D,OAAO,EAAE,YAAY,EAAE,0BAA0B,EAAE,MAAM,iCAAiC,CAAC;AAC3F,OAAO,EAAE,6BAA6B,EAAE,MAAM,gCAAgC,CAAC;AAY/E,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,IAAmB;IACxD,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;QACjB,OAAO,CAAC,KAAK,CAAC,oCAAoC,CAAC,CAAC;QACpD,OAAO,CAAC,KAAK,CAAC,oHAAoH,CAAC,CAAC;QACpI,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"pain-record.js","sourceRoot":"","sources":["../../src/commands/pain-record.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { Command } from 'commander';
|
|
1
2
|
interface PainRetryOptions {
|
|
2
3
|
painId: string;
|
|
3
4
|
workspace?: string;
|
|
@@ -12,8 +13,11 @@ interface PainRetryOptions {
|
|
|
12
13
|
apiKeyEnv?: string;
|
|
13
14
|
baseUrl?: string;
|
|
14
15
|
maxRetries?: number;
|
|
16
|
+
maxTokens?: number;
|
|
15
17
|
timeoutMs?: number;
|
|
16
18
|
}
|
|
17
19
|
export declare function handlePainRetry(opts: PainRetryOptions): Promise<void>;
|
|
20
|
+
/** Register the production `pd pain retry` command and its complete option contract. */
|
|
21
|
+
export declare function registerPainRetryCommand(painCmd: Command, handler?: (opts: PainRetryOptions) => Promise<void>): Command;
|
|
18
22
|
export {};
|
|
19
23
|
//# sourceMappingURL=pain-retry.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pain-retry.d.ts","sourceRoot":"","sources":["../../src/commands/pain-retry.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"pain-retry.d.ts","sourceRoot":"","sources":["../../src/commands/pain-retry.ts"],"names":[],"mappings":"AA6CA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAczC,UAAU,gBAAgB;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,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,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AA8JD,wBAAsB,eAAe,CAAC,IAAI,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAsnB3E;AAED,wFAAwF;AACxF,wBAAgB,wBAAwB,CACtC,OAAO,EAAE,OAAO,EAChB,OAAO,GAAE,CAAC,IAAI,EAAE,gBAAgB,KAAK,OAAO,CAAC,IAAI,CAAmB,GACnE,OAAO,CAsBT"}
|
|
@@ -10,11 +10,15 @@
|
|
|
10
10
|
* IMPORTANT: --runtime is required (no default). test-double would generate fake
|
|
11
11
|
* candidates/ledger in a real workspace, so it must be explicitly requested.
|
|
12
12
|
*/
|
|
13
|
-
import { RuntimeStateManager, SqliteHistoryQuery, SqliteContextAssembler, SqliteDiagnosticianCommitter, SqliteTrajectoryLocator, SqliteSourceTraceLocator, StoreEventEmitter, SplitDiagnosticianRunner, DiagRootCauseRunner, DiagDistillerRunner, DiagRouterRunner, DefaultDiagRootCauseValidator, DefaultDiagDistillerValidator, DisabledDiagnosticianRunner, TestDoubleRuntimeAdapter, OpenClawCliRuntimeAdapter, PiAiRuntimeAdapter, PDRuntimeError, isRuntimeConfigError, CandidateIntakeService, run as diagnoseRun, isFeatureEnabled, SPLIT_PIPELINE_TOTAL_TIMEOUT_MS, PrincipleTreeLedgerAdapter, } from '@principles/core/runtime-v2';
|
|
13
|
+
import { RuntimeStateManager, SqliteHistoryQuery, SqliteContextAssembler, SqliteDiagnosticianCommitter, SqliteTrajectoryLocator, SqliteSourceTraceLocator, StoreEventEmitter, SplitDiagnosticianRunner, DiagRootCauseRunner, DiagDistillerRunner, DiagRouterRunner, DefaultDiagRootCauseValidator, DefaultDiagDistillerValidator, DisabledDiagnosticianRunner, TestDoubleRuntimeAdapter, OpenClawCliRuntimeAdapter, PiAiRuntimeAdapter, PDRuntimeError, isRuntimeConfigError, CandidateIntakeService, run as diagnoseRun, isFeatureEnabled, SPLIT_PIPELINE_TOTAL_TIMEOUT_MS, PrincipleTreeLedgerAdapter, SqliteDeadLetterStore, PainSignalBridge, } from '@principles/core/runtime-v2';
|
|
14
14
|
import { loadPdConfig, computeFlagsFromLoadResult } from '../services/pd-config-loader.js';
|
|
15
15
|
import { resolveRuntimeFromPdConfig } from '../services/resolve-runtime-from-pd-config.js';
|
|
16
|
+
import { createHash } from 'node:crypto';
|
|
17
|
+
/** Layer 0 content-hash (design §6.1); injected so diag writers can attach predecessorSummary hashes. */
|
|
18
|
+
const contentHashFn = (input) => createHash('sha256').update(input).digest('hex');
|
|
16
19
|
import { readOutputLanguageFromWorkspace } from '../config-reader.js';
|
|
17
20
|
import { resolveWorkspaceDir } from '../resolve-workspace.js';
|
|
21
|
+
import { checkAdmissionGate } from './admission-gate.js';
|
|
18
22
|
import * as path from 'path';
|
|
19
23
|
/** Allowed task statuses for retry without --force. */
|
|
20
24
|
const RETRYABLE_STATUSES = new Set([
|
|
@@ -41,6 +45,109 @@ function resolveTaskIdFromPainId(painId) {
|
|
|
41
45
|
function readNonBlankString(value) {
|
|
42
46
|
return typeof value === 'string' && value.trim().length > 0 ? value : null;
|
|
43
47
|
}
|
|
48
|
+
/**
|
|
49
|
+
* Validate that an unknown value (read from dead_letter_pains.pain_data) has
|
|
50
|
+
* the shape of PainDetectedData.
|
|
51
|
+
*
|
|
52
|
+
* rc-1: Treat parsed JSON as unknown.
|
|
53
|
+
* rc-2: No `as` bypass — use typeof checks and literal narrowing.
|
|
54
|
+
* rc-3: Required fields (painId, painType, source, reason) fail loud.
|
|
55
|
+
* rc-5: Use Object.hasOwn for field presence checks on untrusted objects.
|
|
56
|
+
*/
|
|
57
|
+
function parsePainDetectedData(value) {
|
|
58
|
+
if (value === null || typeof value !== 'object' || Array.isArray(value)) {
|
|
59
|
+
return {
|
|
60
|
+
valid: false,
|
|
61
|
+
error: `painData is not an object (got ${value === null ? 'null' : Array.isArray(value) ? 'array' : typeof value})`,
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
const obj = value;
|
|
65
|
+
// Detect dead-letter error envelopes from SqliteDeadLetterStore parse/serialize failures.
|
|
66
|
+
if (Object.hasOwn(obj, '__deadLetterParseError') || Object.hasOwn(obj, '__deadLetterSerializeError')) {
|
|
67
|
+
return {
|
|
68
|
+
valid: false,
|
|
69
|
+
error: `painData contains dead-letter error envelope: ${JSON.stringify(obj)}`,
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
// Required string fields
|
|
73
|
+
if (typeof obj.painId !== 'string' || obj.painId.trim().length === 0) {
|
|
74
|
+
return { valid: false, error: `painData.painId is not a non-blank string (got ${JSON.stringify(obj.painId)})` };
|
|
75
|
+
}
|
|
76
|
+
if (typeof obj.source !== 'string') {
|
|
77
|
+
return { valid: false, error: `painData.source is not a string (got ${JSON.stringify(obj.source)})` };
|
|
78
|
+
}
|
|
79
|
+
if (typeof obj.reason !== 'string') {
|
|
80
|
+
return { valid: false, error: `painData.reason is not a string (got ${JSON.stringify(obj.reason)})` };
|
|
81
|
+
}
|
|
82
|
+
// painType: narrow to literal union without `as`.
|
|
83
|
+
const painTypeRaw = obj.painType;
|
|
84
|
+
if (painTypeRaw !== 'tool_failure' && painTypeRaw !== 'dispatch_error'
|
|
85
|
+
&& painTypeRaw !== 'subagent_error' && painTypeRaw !== 'user_frustration') {
|
|
86
|
+
return { valid: false, error: `painData.painType is not a valid pain type (got ${JSON.stringify(painTypeRaw)})` };
|
|
87
|
+
}
|
|
88
|
+
// After the narrowing check above, TypeScript infers painTypeRaw as the literal union.
|
|
89
|
+
const painType = painTypeRaw === 'dispatch_error' ? 'tool_failure' : painTypeRaw;
|
|
90
|
+
// Build the typed object field-by-field. Optional fields are added only when present and valid.
|
|
91
|
+
const data = {
|
|
92
|
+
painId: obj.painId,
|
|
93
|
+
painType,
|
|
94
|
+
source: obj.source,
|
|
95
|
+
reason: obj.reason,
|
|
96
|
+
};
|
|
97
|
+
if (Object.hasOwn(obj, 'score')) {
|
|
98
|
+
if (typeof obj.score !== 'number' || !Number.isFinite(obj.score)) {
|
|
99
|
+
return { valid: false, error: `painData.score is not a finite number (got ${JSON.stringify(obj.score)})` };
|
|
100
|
+
}
|
|
101
|
+
data.score = obj.score;
|
|
102
|
+
}
|
|
103
|
+
if (Object.hasOwn(obj, 'sessionId')) {
|
|
104
|
+
if (typeof obj.sessionId !== 'string')
|
|
105
|
+
return { valid: false, error: 'painData.sessionId is not a string' };
|
|
106
|
+
data.sessionId = obj.sessionId;
|
|
107
|
+
}
|
|
108
|
+
if (Object.hasOwn(obj, 'agentId')) {
|
|
109
|
+
if (typeof obj.agentId !== 'string')
|
|
110
|
+
return { valid: false, error: 'painData.agentId is not a string' };
|
|
111
|
+
data.agentId = obj.agentId;
|
|
112
|
+
}
|
|
113
|
+
if (Object.hasOwn(obj, 'taskId')) {
|
|
114
|
+
if (typeof obj.taskId !== 'string')
|
|
115
|
+
return { valid: false, error: 'painData.taskId is not a string' };
|
|
116
|
+
data.taskId = obj.taskId;
|
|
117
|
+
}
|
|
118
|
+
if (Object.hasOwn(obj, 'traceId')) {
|
|
119
|
+
if (typeof obj.traceId !== 'string')
|
|
120
|
+
return { valid: false, error: 'painData.traceId is not a string' };
|
|
121
|
+
data.traceId = obj.traceId;
|
|
122
|
+
}
|
|
123
|
+
if (Object.hasOwn(obj, 'provenance')) {
|
|
124
|
+
const prov = obj.provenance;
|
|
125
|
+
if (prov !== 'openclaw_context_bound' && prov !== 'owner_reported_no_host_trace' && prov !== 'automatic_hook') {
|
|
126
|
+
return { valid: false, error: `painData.provenance is not a known literal (got ${JSON.stringify(prov)})` };
|
|
127
|
+
}
|
|
128
|
+
data.provenance = prov;
|
|
129
|
+
}
|
|
130
|
+
if (Object.hasOwn(obj, 'evidence')) {
|
|
131
|
+
if (!Array.isArray(obj.evidence)) {
|
|
132
|
+
return { valid: false, error: 'painData.evidence is not an array' };
|
|
133
|
+
}
|
|
134
|
+
// Validate each entry has the PainEvidenceEntry shape { sourceRef: string, note: string }.
|
|
135
|
+
const evidence = [];
|
|
136
|
+
for (let i = 0; i < obj.evidence.length; i++) {
|
|
137
|
+
const entry = obj.evidence[i];
|
|
138
|
+
if (entry === null || typeof entry !== 'object' || Array.isArray(entry)) {
|
|
139
|
+
return { valid: false, error: `painData.evidence[${i}] is not an object` };
|
|
140
|
+
}
|
|
141
|
+
const e = entry;
|
|
142
|
+
if (typeof e.sourceRef !== 'string' || typeof e.note !== 'string') {
|
|
143
|
+
return { valid: false, error: `painData.evidence[${i}] missing string fields sourceRef/note` };
|
|
144
|
+
}
|
|
145
|
+
evidence.push({ sourceRef: e.sourceRef, note: e.note });
|
|
146
|
+
}
|
|
147
|
+
data.evidence = evidence;
|
|
148
|
+
}
|
|
149
|
+
return { valid: true, data };
|
|
150
|
+
}
|
|
44
151
|
/** Output a refused/not_found result, respecting --json mode. Exits with code 1. */
|
|
45
152
|
function refuseExit(opts, payload) {
|
|
46
153
|
if (opts.json) {
|
|
@@ -64,8 +171,9 @@ export async function handlePainRetry(opts) {
|
|
|
64
171
|
const workspaceDir = resolveWorkspaceDir(opts.workspace);
|
|
65
172
|
// Step 1: Resolve painId → taskId
|
|
66
173
|
const resolution = resolveTaskIdFromPainId(opts.painId);
|
|
174
|
+
// eslint-disable-next-line no-restricted-syntax -- 'in' required for discriminated union narrowing (taskId vs reason/nextAction)
|
|
67
175
|
if ('reason' in resolution) {
|
|
68
|
-
refuseExit(opts, { painId: opts.painId, reason: resolution.reason, nextAction: resolution.nextAction });
|
|
176
|
+
return refuseExit(opts, { painId: opts.painId, reason: resolution.reason, nextAction: resolution.nextAction });
|
|
69
177
|
}
|
|
70
178
|
const { taskId } = resolution;
|
|
71
179
|
// Step 2: Look up task and validate
|
|
@@ -73,18 +181,37 @@ export async function handlePainRetry(opts) {
|
|
|
73
181
|
try {
|
|
74
182
|
await stateManager.initialize();
|
|
75
183
|
const task = await stateManager.getTask(taskId);
|
|
184
|
+
// Dead letter replay: when no task exists, check if the pain signal was
|
|
185
|
+
// persisted to dead_letter_pains (rc-9: no silent failure in pain.ts).
|
|
186
|
+
// If found, replay it through PainSignalBridge.onPainDetected.
|
|
187
|
+
let deadLetterReplay = null;
|
|
76
188
|
if (!task) {
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
189
|
+
const dlStore = new SqliteDeadLetterStore(stateManager.connection);
|
|
190
|
+
const dlRow = dlStore.getByPainId(opts.painId);
|
|
191
|
+
if (!dlRow) {
|
|
192
|
+
return refuseExit(opts, {
|
|
193
|
+
status: 'not_found',
|
|
194
|
+
painId: opts.painId,
|
|
195
|
+
taskId,
|
|
196
|
+
reason: 'task_not_found',
|
|
197
|
+
message: `No task found for painId '${opts.painId}' (looked for taskId '${taskId}') and no dead letter found`,
|
|
198
|
+
nextAction: `Verify the painId is correct. Use 'pd task list --kind diagnostician' to see all diagnostician tasks.`,
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
const parseResult = parsePainDetectedData(dlRow.painData);
|
|
202
|
+
if (!parseResult.valid) {
|
|
203
|
+
return refuseExit(opts, {
|
|
204
|
+
painId: opts.painId,
|
|
205
|
+
taskId,
|
|
206
|
+
reason: 'dead_letter_corrupt',
|
|
207
|
+
message: `Dead letter for painId '${opts.painId}' has corrupt painData: ${parseResult.error}`,
|
|
208
|
+
nextAction: `The dead letter row cannot be replayed. Inspect the dead_letter_pains table directly: SELECT * FROM dead_letter_pains WHERE pain_id = '${opts.painId}'`,
|
|
209
|
+
});
|
|
210
|
+
}
|
|
211
|
+
deadLetterReplay = { data: parseResult.data, row: dlRow };
|
|
85
212
|
}
|
|
86
|
-
if (task.taskKind !== 'diagnostician') {
|
|
87
|
-
refuseExit(opts, {
|
|
213
|
+
if (task && task.taskKind !== 'diagnostician') {
|
|
214
|
+
return refuseExit(opts, {
|
|
88
215
|
painId: opts.painId,
|
|
89
216
|
taskId,
|
|
90
217
|
reason: 'wrong_task_kind',
|
|
@@ -92,10 +219,12 @@ export async function handlePainRetry(opts) {
|
|
|
92
219
|
nextAction: `pd pain retry only retries diagnostician tasks. Use 'pd diagnose run --task-id ${taskId}' for other task kinds.`,
|
|
93
220
|
});
|
|
94
221
|
}
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
222
|
+
// For dead letter replay there is no prior task; synthesize a status so the
|
|
223
|
+
// existing logging/output paths have a non-null value to print.
|
|
224
|
+
const previousTaskStatus = task ? task.status : 'dead_lettered';
|
|
225
|
+
const previousLastError = task ? (task.lastError ?? null) : null;
|
|
226
|
+
if (task && task.status === 'succeeded' && !opts.force) {
|
|
227
|
+
return refuseExit(opts, {
|
|
99
228
|
painId: opts.painId,
|
|
100
229
|
taskId,
|
|
101
230
|
reason: 'already_succeeded',
|
|
@@ -103,8 +232,8 @@ export async function handlePainRetry(opts) {
|
|
|
103
232
|
nextAction: `Add --force to retry: pd pain retry --pain-id ${opts.painId} --force`,
|
|
104
233
|
});
|
|
105
234
|
}
|
|
106
|
-
if (!RETRYABLE_STATUSES.has(task.status) && task.status !== 'succeeded') {
|
|
107
|
-
refuseExit(opts, {
|
|
235
|
+
if (task && !RETRYABLE_STATUSES.has(task.status) && task.status !== 'succeeded') {
|
|
236
|
+
return refuseExit(opts, {
|
|
108
237
|
painId: opts.painId,
|
|
109
238
|
taskId,
|
|
110
239
|
reason: 'status_not_retryable',
|
|
@@ -116,7 +245,7 @@ export async function handlePainRetry(opts) {
|
|
|
116
245
|
// P1 fix: --openclaw-local and --openclaw-gateway are mutually exclusive.
|
|
117
246
|
// Must output JSON when --json is set (CLI operator gate).
|
|
118
247
|
if (opts.openclawLocal && opts.openclawGateway) {
|
|
119
|
-
refuseExit(opts, {
|
|
248
|
+
return refuseExit(opts, {
|
|
120
249
|
painId: opts.painId,
|
|
121
250
|
taskId,
|
|
122
251
|
reason: 'conflicting_flags',
|
|
@@ -136,7 +265,7 @@ export async function handlePainRetry(opts) {
|
|
|
136
265
|
}
|
|
137
266
|
}
|
|
138
267
|
if (!runtimeKind) {
|
|
139
|
-
refuseExit(opts, {
|
|
268
|
+
return refuseExit(opts, {
|
|
140
269
|
painId: opts.painId,
|
|
141
270
|
taskId,
|
|
142
271
|
reason: 'missing_runtime',
|
|
@@ -150,14 +279,14 @@ export async function handlePainRetry(opts) {
|
|
|
150
279
|
const resolved = resolveRuntimeFromPdConfig(workspaceDir);
|
|
151
280
|
const configResult = resolved.result;
|
|
152
281
|
if (isRuntimeConfigError(configResult)) {
|
|
153
|
-
refuseExit(opts, { painId: opts.painId, taskId, reason: configResult.reason, message: configResult.message, nextAction: configResult.nextAction });
|
|
282
|
+
return refuseExit(opts, { painId: opts.painId, taskId, reason: configResult.reason, message: configResult.message, nextAction: configResult.nextAction });
|
|
154
283
|
}
|
|
155
284
|
const { openclawMode } = configResult;
|
|
156
285
|
// CLI flags override config (PRI-393)
|
|
157
286
|
const flagMode = opts.openclawLocal ? 'local' : opts.openclawGateway ? 'gateway' : undefined;
|
|
158
287
|
const effectiveMode = flagMode ?? openclawMode;
|
|
159
288
|
if (!effectiveMode) {
|
|
160
|
-
refuseExit(opts, {
|
|
289
|
+
return refuseExit(opts, {
|
|
161
290
|
painId: opts.painId,
|
|
162
291
|
taskId,
|
|
163
292
|
reason: 'missing_openclaw_mode',
|
|
@@ -214,6 +343,7 @@ export async function handlePainRetry(opts) {
|
|
|
214
343
|
const apiKeyEnv = opts.apiKeyEnv ?? policyConfig?.apiKeyEnv;
|
|
215
344
|
const baseUrl = opts.baseUrl ?? policyConfig?.baseUrl;
|
|
216
345
|
const maxRetries = opts.maxRetries ?? policyConfig?.maxRetries;
|
|
346
|
+
const maxTokens = opts.maxTokens ?? policyConfig?.maxTokens;
|
|
217
347
|
const effectiveTimeoutMs = opts.timeoutMs ?? policyConfig?.timeoutMs;
|
|
218
348
|
// Validate required string fields: must be non-blank strings
|
|
219
349
|
const missing = [];
|
|
@@ -224,7 +354,7 @@ export async function handlePainRetry(opts) {
|
|
|
224
354
|
if (readNonBlankString(apiKeyEnv) === null)
|
|
225
355
|
missing.push('apiKeyEnv');
|
|
226
356
|
if (missing.length > 0) {
|
|
227
|
-
refuseExit(opts, {
|
|
357
|
+
return refuseExit(opts, {
|
|
228
358
|
painId: opts.painId,
|
|
229
359
|
taskId,
|
|
230
360
|
reason: `missing_required_config: ${missing.join(', ')}`,
|
|
@@ -240,12 +370,15 @@ export async function handlePainRetry(opts) {
|
|
|
240
370
|
if (effectiveTimeoutMs !== undefined && effectiveTimeoutMs !== null && !(Number.isFinite(effectiveTimeoutMs) && effectiveTimeoutMs > 0)) {
|
|
241
371
|
invalidNumeric.push(`timeoutMs (got: ${effectiveTimeoutMs})`);
|
|
242
372
|
}
|
|
373
|
+
if (maxTokens !== undefined && maxTokens !== null && !(Number.isFinite(maxTokens) && maxTokens > 0)) {
|
|
374
|
+
invalidNumeric.push(`maxTokens (got: ${maxTokens})`);
|
|
375
|
+
}
|
|
243
376
|
if (invalidNumeric.length > 0) {
|
|
244
|
-
refuseExit(opts, {
|
|
377
|
+
return refuseExit(opts, {
|
|
245
378
|
painId: opts.painId,
|
|
246
379
|
taskId,
|
|
247
380
|
reason: `invalid_numeric_config: ${invalidNumeric.join(', ')}`,
|
|
248
|
-
message: `Invalid numeric pi-ai config: ${invalidNumeric.join(', ')}. maxRetries must be a non-negative integer; timeoutMs must be
|
|
381
|
+
message: `Invalid numeric pi-ai config: ${invalidNumeric.join(', ')}. maxRetries must be a non-negative integer; timeoutMs and maxTokens must be positive numbers.`,
|
|
249
382
|
nextAction: 'Fix the numeric values and retry.',
|
|
250
383
|
});
|
|
251
384
|
}
|
|
@@ -254,7 +387,7 @@ export async function handlePainRetry(opts) {
|
|
|
254
387
|
const validModel = readNonBlankString(model);
|
|
255
388
|
const validApiKeyEnv = readNonBlankString(apiKeyEnv);
|
|
256
389
|
if (validProvider === null || validModel === null || validApiKeyEnv === null) {
|
|
257
|
-
refuseExit(opts, {
|
|
390
|
+
return refuseExit(opts, {
|
|
258
391
|
painId: opts.painId,
|
|
259
392
|
taskId,
|
|
260
393
|
reason: 'internal_validation_error',
|
|
@@ -263,7 +396,7 @@ export async function handlePainRetry(opts) {
|
|
|
263
396
|
});
|
|
264
397
|
}
|
|
265
398
|
if (!process.env[validApiKeyEnv]) {
|
|
266
|
-
refuseExit(opts, {
|
|
399
|
+
return refuseExit(opts, {
|
|
267
400
|
painId: opts.painId,
|
|
268
401
|
taskId,
|
|
269
402
|
reason: 'missing_api_key',
|
|
@@ -277,12 +410,13 @@ export async function handlePainRetry(opts) {
|
|
|
277
410
|
apiKeyEnv: validApiKeyEnv,
|
|
278
411
|
baseUrl,
|
|
279
412
|
maxRetries,
|
|
413
|
+
maxTokens,
|
|
280
414
|
timeoutMs: effectiveTimeoutMs,
|
|
281
415
|
workspace: workspaceDir,
|
|
282
416
|
});
|
|
283
417
|
}
|
|
284
418
|
else {
|
|
285
|
-
refuseExit(opts, {
|
|
419
|
+
return refuseExit(opts, {
|
|
286
420
|
painId: opts.painId,
|
|
287
421
|
taskId,
|
|
288
422
|
reason: `unknown_runtime: '${runtimeKind}'`,
|
|
@@ -308,24 +442,142 @@ export async function handlePainRetry(opts) {
|
|
|
308
442
|
const featureFlags = computeFlagsFromLoadResult(configLoadResult);
|
|
309
443
|
const isSplitPipeline = isFeatureEnabled(featureFlags, 'diagnostician_split_pipeline');
|
|
310
444
|
const pipelineTimeoutMs = isSplitPipeline ? SPLIT_PIPELINE_TOTAL_TIMEOUT_MS : 300_000;
|
|
445
|
+
// BUG-1 (PRI-442): extract effectiveConfig so ADR-0019 LLM rate-limit
|
|
446
|
+
// degradation (isDegradationEnabled in base-peer-runner) can read the
|
|
447
|
+
// diagnostician_llm_degradation feature flag. Without this, the runners
|
|
448
|
+
// receive no effectiveConfig and degradation silently never fires.
|
|
449
|
+
// CR-1 (CodeRabbit P2, rc-9): warn when config load failed so the
|
|
450
|
+
// fallback to defaults is observable — no silent degradation.
|
|
451
|
+
if (!configLoadResult.ok) {
|
|
452
|
+
const errSummary = configLoadResult.errors
|
|
453
|
+
.map((e) => `${e.path}: ${e.reason}`)
|
|
454
|
+
.join('; ');
|
|
455
|
+
console.warn(`[pd pain retry] .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'}`);
|
|
456
|
+
}
|
|
457
|
+
const effectiveConfig = configLoadResult.ok ? configLoadResult.effective : configLoadResult.defaults;
|
|
311
458
|
let runner;
|
|
312
459
|
if (isSplitPipeline) {
|
|
313
460
|
const resolvedKind = typeof runtimeAdapter.kind === 'function' ? runtimeAdapter.kind() : runtimeKind;
|
|
314
|
-
const
|
|
315
|
-
const
|
|
316
|
-
const
|
|
461
|
+
const perStageTimeoutMs = pipelineTimeoutMs / 3;
|
|
462
|
+
const rootCauseRunner = new DiagRootCauseRunner({ stateManager, runtimeAdapter, eventEmitter, artifactStore: stateManager.piArtifactStore, validator: new DefaultDiagRootCauseValidator(), contextAssembler, contentHashFn }, { owner: 'pd-cli-pain-retry', runtimeKind: resolvedKind, outputLanguage, timeoutMs: perStageTimeoutMs, effectiveConfig });
|
|
463
|
+
const distillerRunner = new DiagDistillerRunner({ stateManager, runtimeAdapter, eventEmitter, artifactStore: stateManager.piArtifactStore, validator: new DefaultDiagDistillerValidator(), contentHashFn }, { owner: 'pd-cli-pain-retry', runtimeKind: resolvedKind, outputLanguage, timeoutMs: perStageTimeoutMs, effectiveConfig });
|
|
464
|
+
const routerRunner = new DiagRouterRunner({ stateManager, runtimeAdapter, eventEmitter, artifactStore: stateManager.piArtifactStore, committer, contentHashFn }, { owner: 'pd-cli-pain-retry', runtimeKind: resolvedKind, outputLanguage, timeoutMs: perStageTimeoutMs, effectiveConfig });
|
|
317
465
|
runner = new SplitDiagnosticianRunner({
|
|
318
466
|
rootCauseRunner,
|
|
319
467
|
distillerRunner,
|
|
320
468
|
routerRunner,
|
|
321
469
|
stateManager,
|
|
322
470
|
committer,
|
|
323
|
-
perStageTimeoutMs
|
|
471
|
+
perStageTimeoutMs,
|
|
324
472
|
});
|
|
325
473
|
}
|
|
326
474
|
else {
|
|
327
475
|
runner = new DisabledDiagnosticianRunner();
|
|
328
476
|
}
|
|
477
|
+
// ── Dead letter replay branch ──────────────────────────────────────────
|
|
478
|
+
// When task was null but a dead letter was found, replay the pain signal
|
|
479
|
+
// through PainSignalBridge.onPainDetected instead of calling diagnoseRun.
|
|
480
|
+
// On success/failure, markRetried updates the dead_letter_pains row.
|
|
481
|
+
if (deadLetterReplay) {
|
|
482
|
+
const dlStore = new SqliteDeadLetterStore(stateManager.connection);
|
|
483
|
+
if (!opts.json) {
|
|
484
|
+
console.log(`\nReplaying dead letter pain: ${opts.painId}`);
|
|
485
|
+
console.log(` Task ID: ${taskId}`);
|
|
486
|
+
console.log(` Dead Letter ID: ${deadLetterReplay.row.id}`);
|
|
487
|
+
console.log(` Failed At: ${deadLetterReplay.row.failedAt}`);
|
|
488
|
+
console.log(` Retry Count: ${deadLetterReplay.row.retryCount}`);
|
|
489
|
+
console.log(` Runtime: ${runtimeKind}`);
|
|
490
|
+
console.log(` Workspace: ${workspaceDir}\n`);
|
|
491
|
+
}
|
|
492
|
+
const ledgerAdapter = new PrincipleTreeLedgerAdapter({ stateDir: path.join(workspaceDir, '.state') });
|
|
493
|
+
const intakeService = new CandidateIntakeService({ stateManager, ledgerAdapter });
|
|
494
|
+
const bridge = new PainSignalBridge({
|
|
495
|
+
stateManager,
|
|
496
|
+
runner,
|
|
497
|
+
intakeService,
|
|
498
|
+
ledgerAdapter,
|
|
499
|
+
owner: 'pd-cli-pain-retry-dead-letter',
|
|
500
|
+
workspaceDir,
|
|
501
|
+
});
|
|
502
|
+
let bridgeResult;
|
|
503
|
+
try {
|
|
504
|
+
bridgeResult = await bridge.onPainDetected(deadLetterReplay.data);
|
|
505
|
+
}
|
|
506
|
+
catch (err) {
|
|
507
|
+
const errorMessage = err instanceof Error ? err.message : String(err);
|
|
508
|
+
const markFail = dlStore.markRetried(opts.painId, false);
|
|
509
|
+
if (opts.json) {
|
|
510
|
+
console.log(JSON.stringify({
|
|
511
|
+
status: 'failed',
|
|
512
|
+
painId: opts.painId,
|
|
513
|
+
taskId,
|
|
514
|
+
source: 'dead_letter',
|
|
515
|
+
deadLetterId: deadLetterReplay.row.id,
|
|
516
|
+
runtimeKind,
|
|
517
|
+
errorCategory: 'execution_failed',
|
|
518
|
+
message: errorMessage,
|
|
519
|
+
markRetriedOk: markFail.ok,
|
|
520
|
+
nextAction: 'Replay threw; retry_count incremented. Adjust parameters and run pd pain retry --pain-id again.',
|
|
521
|
+
}, null, 2));
|
|
522
|
+
}
|
|
523
|
+
else {
|
|
524
|
+
console.error(`error: ${errorMessage}`);
|
|
525
|
+
console.error(`nextAction: Replay threw; retry_count incremented. Adjust parameters and try again.`);
|
|
526
|
+
}
|
|
527
|
+
process.exit(1);
|
|
528
|
+
return;
|
|
529
|
+
}
|
|
530
|
+
const success = bridgeResult.status === 'succeeded';
|
|
531
|
+
const markResult = dlStore.markRetried(opts.painId, success);
|
|
532
|
+
if (opts.json) {
|
|
533
|
+
// cli-1-strict-json: exactly one parseable JSON object on stdout.
|
|
534
|
+
console.log(JSON.stringify({
|
|
535
|
+
status: success ? 'succeeded' : 'failed',
|
|
536
|
+
painId: opts.painId,
|
|
537
|
+
taskId,
|
|
538
|
+
source: 'dead_letter',
|
|
539
|
+
deadLetterId: deadLetterReplay.row.id,
|
|
540
|
+
runtimeKind,
|
|
541
|
+
bridgeStatus: bridgeResult.status,
|
|
542
|
+
candidateIds: bridgeResult.candidateIds,
|
|
543
|
+
ledgerEntryIds: bridgeResult.ledgerEntryIds,
|
|
544
|
+
markRetriedOk: markResult.ok,
|
|
545
|
+
message: bridgeResult.message ?? null,
|
|
546
|
+
nextAction: success
|
|
547
|
+
? (bridgeResult.candidateIds.length > 0
|
|
548
|
+
? `Dead letter replayed. Internalize candidates:\n ${bridgeResult.candidateIds.map((id) => `pd candidate internalize --candidate-id ${id} --workspace "${workspaceDir}"`).join('\n ')}`
|
|
549
|
+
: 'Dead letter replayed. No candidates generated.')
|
|
550
|
+
: `Replay did not succeed (status=${bridgeResult.status}). The dead letter remains available for future retry.`,
|
|
551
|
+
}, null, 2));
|
|
552
|
+
if (!success) {
|
|
553
|
+
process.exit(1);
|
|
554
|
+
}
|
|
555
|
+
return;
|
|
556
|
+
}
|
|
557
|
+
// Text output
|
|
558
|
+
console.log(`\nReplay ${success ? 'succeeded' : 'failed'}:`);
|
|
559
|
+
console.log(` Pain ID: ${opts.painId}`);
|
|
560
|
+
console.log(` Task ID: ${taskId}`);
|
|
561
|
+
console.log(` Dead Letter ID: ${deadLetterReplay.row.id}`);
|
|
562
|
+
console.log(` Bridge Status: ${bridgeResult.status}`);
|
|
563
|
+
if (bridgeResult.message) {
|
|
564
|
+
console.log(` Message: ${bridgeResult.message}`);
|
|
565
|
+
}
|
|
566
|
+
if (success) {
|
|
567
|
+
console.log(` Candidates: ${bridgeResult.candidateIds.length}`);
|
|
568
|
+
if (bridgeResult.candidateIds.length > 0) {
|
|
569
|
+
console.log(` Ledger Entries: ${bridgeResult.ledgerEntryIds.length}`);
|
|
570
|
+
}
|
|
571
|
+
}
|
|
572
|
+
console.log(` Mark Retried: ${markResult.ok ? 'ok' : `FAILED: ${markResult.error}`}`);
|
|
573
|
+
if (!success) {
|
|
574
|
+
console.log(`\n Next Action:`);
|
|
575
|
+
console.log(` Replay did not succeed. The dead letter remains available for future retry.`);
|
|
576
|
+
process.exit(1);
|
|
577
|
+
}
|
|
578
|
+
return;
|
|
579
|
+
}
|
|
580
|
+
// ── Normal retry branch ─────────────────────────────────────────────────
|
|
329
581
|
if (!opts.json) {
|
|
330
582
|
console.log(`\nRetrying diagnosis for pain: ${opts.painId}`);
|
|
331
583
|
console.log(` Task ID: ${taskId}`);
|
|
@@ -378,6 +630,23 @@ export async function handlePainRetry(opts) {
|
|
|
378
630
|
const ledgerAdapter = new PrincipleTreeLedgerAdapter({ stateDir: path.join(workspaceDir, '.state') });
|
|
379
631
|
const intakeService = new CandidateIntakeService({ stateManager, ledgerAdapter });
|
|
380
632
|
for (const candidate of candidates) {
|
|
633
|
+
// PRI-503: admission gate check — refuse non-admitted candidates before
|
|
634
|
+
// intake, mirroring candidate.ts (intake/repair/backfill). Without this,
|
|
635
|
+
// `pd pain retry` could bypass the gate and intake unreviewed candidates.
|
|
636
|
+
// cli-5-failure-no-mutation: refusal path does not call intake(), does
|
|
637
|
+
// not update candidate status, does not write ledger.
|
|
638
|
+
// cli-6-output-next-action: refusal result carries admissionBlock.nextAction.
|
|
639
|
+
const admissionBlock = checkAdmissionGate(candidate);
|
|
640
|
+
if (admissionBlock) {
|
|
641
|
+
intakeFailed = true;
|
|
642
|
+
intakeResults.push({
|
|
643
|
+
candidateId: candidate.candidateId,
|
|
644
|
+
status: 'intake_failed',
|
|
645
|
+
error: `Admission gate refused: ${admissionBlock.reason}`,
|
|
646
|
+
nextAction: admissionBlock.nextAction,
|
|
647
|
+
});
|
|
648
|
+
continue;
|
|
649
|
+
}
|
|
381
650
|
try {
|
|
382
651
|
const entry = await intakeService.intake(candidate.candidateId);
|
|
383
652
|
if (candidate.status !== 'consumed') {
|
|
@@ -458,6 +727,7 @@ export async function handlePainRetry(opts) {
|
|
|
458
727
|
console.log('');
|
|
459
728
|
if (intakeFailed) {
|
|
460
729
|
process.exit(1);
|
|
730
|
+
return;
|
|
461
731
|
}
|
|
462
732
|
}
|
|
463
733
|
catch (error) {
|
|
@@ -480,9 +750,34 @@ export async function handlePainRetry(opts) {
|
|
|
480
750
|
console.error(`error: ${message} (${errorCategory})`);
|
|
481
751
|
}
|
|
482
752
|
process.exit(1);
|
|
753
|
+
return;
|
|
483
754
|
}
|
|
484
755
|
finally {
|
|
485
756
|
await stateManager.close();
|
|
486
757
|
}
|
|
487
758
|
}
|
|
759
|
+
/** Register the production `pd pain retry` command and its complete option contract. */
|
|
760
|
+
export function registerPainRetryCommand(painCmd, handler = handlePainRetry) {
|
|
761
|
+
return painCmd
|
|
762
|
+
.command('retry')
|
|
763
|
+
.description('Retry a failed diagnosis by pain ID')
|
|
764
|
+
.requiredOption('-p, --pain-id <painId>', 'Pain ID to retry diagnosis for')
|
|
765
|
+
.option('-w, --workspace <path>', 'Workspace directory')
|
|
766
|
+
.option('-r, --runtime <kind>', "Runtime kind: 'openclaw-cli', 'test-double', 'pi-ai'")
|
|
767
|
+
.option('--openclaw-local', 'Use local OpenClaw (mutually exclusive with --openclaw-gateway)')
|
|
768
|
+
.option('--openclaw-gateway', 'Use gateway OpenClaw (mutually exclusive with --openclaw-local)')
|
|
769
|
+
.option('-a, --agent <agentId>', 'Agent ID to invoke')
|
|
770
|
+
.option('--provider <name>', 'LLM provider (e.g., openrouter) — for pi-ai, falls back to policy')
|
|
771
|
+
.option('--model <id>', 'Model ID (e.g., anthropic/claude-sonnet-4) — for pi-ai, falls back to policy')
|
|
772
|
+
.option('--apiKeyEnv <name>', 'Env var name for API key — for pi-ai, falls back to policy')
|
|
773
|
+
.option('--baseUrl <url>', 'Custom base URL — for pi-ai, falls back to policy')
|
|
774
|
+
.option('--maxRetries <n>', 'Max retry attempts for LLM failures — for pi-ai, falls back to policy', parseInt)
|
|
775
|
+
.option('--maxTokens <n>', 'Max output tokens (max_tokens) for pi-ai LLM calls — for pi-ai, falls back to policy', parseInt)
|
|
776
|
+
.option('--timeoutMs <ms>', 'Timeout in milliseconds — for pi-ai, falls back to policy', parseInt)
|
|
777
|
+
.option('--force', 'Allow retry of already-succeeded tasks')
|
|
778
|
+
.option('--json', 'Output raw JSON')
|
|
779
|
+
.action(async (opts) => {
|
|
780
|
+
await handler(opts);
|
|
781
|
+
});
|
|
782
|
+
}
|
|
488
783
|
//# sourceMappingURL=pain-retry.js.map
|