@principles/pd-cli 1.133.0 → 1.135.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 +42 -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/console-launcher.d.ts +6 -0
- package/dist/services/console-launcher.d.ts.map +1 -1
- package/dist/services/console-launcher.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 +41 -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/console-launcher.ts +6 -0
- 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 +229 -32
- 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
|
@@ -24,6 +24,7 @@
|
|
|
24
24
|
* - --dry-run and --confirm are mutually exclusive
|
|
25
25
|
*/
|
|
26
26
|
import * as path from 'path';
|
|
27
|
+
import * as fs from 'node:fs';
|
|
27
28
|
import type { Command } from 'commander';
|
|
28
29
|
import { runRuleHostPipeline } from '../services/rulehost-pipeline-runner.js';
|
|
29
30
|
import type { RuleHostPipelineResult, CodeRuleCapability, RuleHostAgentAdapters } from '../services/rulehost-pipeline-runner.js';
|
|
@@ -37,6 +38,7 @@ import {
|
|
|
37
38
|
isFeatureEnabled,
|
|
38
39
|
} from '@principles/core/runtime-v2';
|
|
39
40
|
import type { EffectivePdConfig, InternalAgentName, PDRuntimeAdapter } from '@principles/core/runtime-v2';
|
|
41
|
+
import type { BehaviorExamplePack } from '@principles/core/runtime-v2';
|
|
40
42
|
import { resolveRuntimeFromPdConfig } from '../services/resolve-runtime-from-pd-config.js';
|
|
41
43
|
import { resolveRuleHostReadiness } from '../services/rulehost-readiness.js';
|
|
42
44
|
import type { RuleHostReadinessResult } from '../services/rulehost-readiness.js';
|
|
@@ -47,6 +49,7 @@ export interface RunRuleHostOptions {
|
|
|
47
49
|
channel?: string;
|
|
48
50
|
maxRounds?: number;
|
|
49
51
|
timeoutMs?: number;
|
|
52
|
+
behaviorExamples?: string;
|
|
50
53
|
json?: boolean;
|
|
51
54
|
/** Dry-run mode (default). Validates inputs + config, reports capability status, does NOT run the pipeline. */
|
|
52
55
|
dryRun?: boolean;
|
|
@@ -68,6 +71,49 @@ interface ResolvedRunRuleHostRuntime {
|
|
|
68
71
|
readonly agentRuntimeProfiles: Partial<Record<InternalAgentName, string>>;
|
|
69
72
|
readonly capability: CodeRuleCapability;
|
|
70
73
|
readonly capabilityStatus: string;
|
|
74
|
+
readonly contextV2Enabled: boolean;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
interface OwnerBehaviorExamplesInput {
|
|
78
|
+
readonly ownerDesiredOutcome: string;
|
|
79
|
+
readonly sourceNegativeToolCallId: number;
|
|
80
|
+
readonly positiveToolCallIds: readonly number[];
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
type OwnerBehaviorExamplesResult =
|
|
84
|
+
| { readonly ok: true; readonly value: OwnerBehaviorExamplesInput }
|
|
85
|
+
| { readonly ok: false; readonly reason: string };
|
|
86
|
+
|
|
87
|
+
function isRecord(value: unknown): value is Record<string, unknown> {
|
|
88
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
function readOwnerBehaviorExamples(filePath: string): OwnerBehaviorExamplesResult {
|
|
92
|
+
let parsed: unknown;
|
|
93
|
+
try {
|
|
94
|
+
parsed = JSON.parse(fs.readFileSync(filePath, 'utf8'));
|
|
95
|
+
} catch (error) {
|
|
96
|
+
return { ok: false, reason: `behavior_examples_unreadable: ${error instanceof Error ? error.message : String(error)}` };
|
|
97
|
+
}
|
|
98
|
+
if (!isRecord(parsed)) return { ok: false, reason: 'behavior_examples_invalid: root must be an object' };
|
|
99
|
+
if (typeof parsed.ownerDesiredOutcome !== 'string' || parsed.ownerDesiredOutcome.trim() === '') {
|
|
100
|
+
return { ok: false, reason: 'behavior_examples_invalid: ownerDesiredOutcome must be a non-empty string' };
|
|
101
|
+
}
|
|
102
|
+
if (!Number.isSafeInteger(parsed.sourceNegativeToolCallId) || Number(parsed.sourceNegativeToolCallId) <= 0) {
|
|
103
|
+
return { ok: false, reason: 'behavior_examples_invalid: sourceNegativeToolCallId must be a positive integer' };
|
|
104
|
+
}
|
|
105
|
+
if (!Array.isArray(parsed.positiveToolCallIds) || parsed.positiveToolCallIds.length === 0 || parsed.positiveToolCallIds.length > 3
|
|
106
|
+
|| parsed.positiveToolCallIds.some((id) => !Number.isSafeInteger(id) || Number(id) <= 0)) {
|
|
107
|
+
return { ok: false, reason: 'behavior_examples_invalid: positiveToolCallIds must contain 1 to 3 positive integers' };
|
|
108
|
+
}
|
|
109
|
+
return {
|
|
110
|
+
ok: true,
|
|
111
|
+
value: {
|
|
112
|
+
ownerDesiredOutcome: parsed.ownerDesiredOutcome,
|
|
113
|
+
sourceNegativeToolCallId: Number(parsed.sourceNegativeToolCallId),
|
|
114
|
+
positiveToolCallIds: parsed.positiveToolCallIds.map((id) => Number(id)),
|
|
115
|
+
},
|
|
116
|
+
};
|
|
71
117
|
}
|
|
72
118
|
|
|
73
119
|
function resolvePiAiAgentAdapter(
|
|
@@ -120,6 +166,8 @@ function resolveRunRuleHostRuntime(
|
|
|
120
166
|
}
|
|
121
167
|
|
|
122
168
|
const { effective } = configLoadResult;
|
|
169
|
+
const featureFlags = computeFeatureFlagsFromConfig(effective);
|
|
170
|
+
const contextV2Enabled = isFeatureEnabled(featureFlags, 'rulecode_context_v2');
|
|
123
171
|
const adapterOptions = { workspaceDir, timeoutMs };
|
|
124
172
|
const dreamer = resolvePiAiAgentAdapter(effective, 'dreamer', adapterOptions);
|
|
125
173
|
const philosopher = resolvePiAiAgentAdapter(effective, 'philosopher', adapterOptions);
|
|
@@ -135,15 +183,16 @@ function resolveRunRuleHostRuntime(
|
|
|
135
183
|
agentRuntimeProfiles,
|
|
136
184
|
capability: { enabled: false, disabledReason: readiness.reason },
|
|
137
185
|
capabilityStatus: `code_rule_capability: OFF (${readiness.reason})`,
|
|
186
|
+
contextV2Enabled,
|
|
138
187
|
};
|
|
139
188
|
}
|
|
140
|
-
const featureFlags = computeFeatureFlagsFromConfig(effective);
|
|
141
189
|
if (!isFeatureEnabled(featureFlags, 'code_rule_capability')) {
|
|
142
190
|
return {
|
|
143
191
|
agentAdapters: { dreamer: dreamer.adapter, philosopher: philosopher.adapter, scribe: scribe.adapter, evaluator: scribe.adapter },
|
|
144
192
|
agentRuntimeProfiles,
|
|
145
193
|
capability: { enabled: false, disabledReason: 'code_rule_capability feature flag is disabled' },
|
|
146
194
|
capabilityStatus: 'code_rule_capability: OFF (feature flag disabled)',
|
|
195
|
+
contextV2Enabled,
|
|
147
196
|
};
|
|
148
197
|
}
|
|
149
198
|
|
|
@@ -157,6 +206,7 @@ function resolveRunRuleHostRuntime(
|
|
|
157
206
|
agentRuntimeProfiles,
|
|
158
207
|
capability: { enabled: false, disabledReason: `artificer agent disabled: ${artificerBinding.reason}` },
|
|
159
208
|
capabilityStatus: `code_rule_capability: OFF (artificer disabled — ${artificerBinding.reason})`,
|
|
209
|
+
contextV2Enabled,
|
|
160
210
|
};
|
|
161
211
|
}
|
|
162
212
|
if (!evaluatorBinding.ok) {
|
|
@@ -165,6 +215,7 @@ function resolveRunRuleHostRuntime(
|
|
|
165
215
|
agentRuntimeProfiles,
|
|
166
216
|
capability: { enabled: false, disabledReason: `evaluator agent disabled: ${evaluatorBinding.reason}` },
|
|
167
217
|
capabilityStatus: `code_rule_capability: OFF (evaluator disabled — ${evaluatorBinding.reason})`,
|
|
218
|
+
contextV2Enabled,
|
|
168
219
|
};
|
|
169
220
|
}
|
|
170
221
|
|
|
@@ -177,6 +228,7 @@ function resolveRunRuleHostRuntime(
|
|
|
177
228
|
agentRuntimeProfiles,
|
|
178
229
|
capability: { enabled: false, disabledReason: `artificer runtime profile is not pi-ai (got '${artificerProfile.type}')` },
|
|
179
230
|
capabilityStatus: `code_rule_capability: OFF (artificer profile type='${artificerProfile.type}', expected pi-ai)`,
|
|
231
|
+
contextV2Enabled,
|
|
180
232
|
};
|
|
181
233
|
}
|
|
182
234
|
|
|
@@ -187,6 +239,7 @@ function resolveRunRuleHostRuntime(
|
|
|
187
239
|
agentRuntimeProfiles,
|
|
188
240
|
capability: { enabled: false, disabledReason: `artificer apiKeyEnv '${artificerProfile.apiKeyEnv}' is not set in environment` },
|
|
189
241
|
capabilityStatus: `code_rule_capability: OFF (artificer apiKeyEnv '${artificerProfile.apiKeyEnv}' not set)`,
|
|
242
|
+
contextV2Enabled,
|
|
190
243
|
};
|
|
191
244
|
}
|
|
192
245
|
|
|
@@ -209,6 +262,7 @@ function resolveRunRuleHostRuntime(
|
|
|
209
262
|
agentRuntimeProfiles,
|
|
210
263
|
capability: { enabled: true, artificerAdapter },
|
|
211
264
|
capabilityStatus: `code_rule_capability: ON (artificer profile='${artificerBinding.profileId}', evaluator profile='${evaluatorBinding.profileId}')`,
|
|
265
|
+
contextV2Enabled,
|
|
212
266
|
};
|
|
213
267
|
}
|
|
214
268
|
|
|
@@ -374,6 +428,91 @@ export async function handleRunRuleHost(opts: RunRuleHostOptions): Promise<void>
|
|
|
374
428
|
return;
|
|
375
429
|
}
|
|
376
430
|
|
|
431
|
+
let effectiveCapability = resolvedRuntime.capability;
|
|
432
|
+
let contextMode: 'v1' | 'v2' = 'v1';
|
|
433
|
+
let behaviorExamplePack: BehaviorExamplePack | undefined;
|
|
434
|
+
let behaviorExamplesReason: string | undefined;
|
|
435
|
+
const behaviorExamplesPath = opts.behaviorExamples
|
|
436
|
+
? path.resolve(workspaceDir, opts.behaviorExamples)
|
|
437
|
+
: undefined;
|
|
438
|
+
|
|
439
|
+
if (!resolvedRuntime.contextV2Enabled && behaviorExamplesPath) {
|
|
440
|
+
const reason = 'behavior_examples_not_allowed: rulecode_context_v2 is disabled';
|
|
441
|
+
if (opts.json) {
|
|
442
|
+
process.stdout.write(JSON.stringify({ status: 'failed', reason, nextAction: 'enable rulecode_context_v2 or remove --behavior-examples' }) + '\n');
|
|
443
|
+
} else {
|
|
444
|
+
console.error(`Error: ${reason}. Enable rulecode_context_v2 or remove --behavior-examples.`);
|
|
445
|
+
}
|
|
446
|
+
process.exitCode = 1;
|
|
447
|
+
return;
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
if (resolvedRuntime.contextV2Enabled) {
|
|
451
|
+
contextMode = 'v2';
|
|
452
|
+
if (!behaviorExamplesPath) {
|
|
453
|
+
behaviorExamplesReason = 'behavior_examples_missing';
|
|
454
|
+
} else {
|
|
455
|
+
const examplesResult = readOwnerBehaviorExamples(behaviorExamplesPath);
|
|
456
|
+
if (!examplesResult.ok) {
|
|
457
|
+
// P1 fix (CodeRabbit PR2 Comment 1): fail fast on parse failure instead
|
|
458
|
+
// of silently degrading to text_principle_only (rc-9-no-silent-fallback).
|
|
459
|
+
// examplesResult.reason already carries a stable prefix
|
|
460
|
+
// (behavior_examples_unreadable: | behavior_examples_invalid:).
|
|
461
|
+
const { reason } = examplesResult;
|
|
462
|
+
if (opts.json) {
|
|
463
|
+
process.stdout.write(JSON.stringify({
|
|
464
|
+
status: 'failed',
|
|
465
|
+
reason,
|
|
466
|
+
nextAction: 'fix the --behavior-examples JSON payload and retry',
|
|
467
|
+
}) + '\n');
|
|
468
|
+
} else {
|
|
469
|
+
console.error(`Error: ${reason}. Fix the --behavior-examples JSON payload and retry.`);
|
|
470
|
+
}
|
|
471
|
+
process.exitCode = 1;
|
|
472
|
+
return;
|
|
473
|
+
}
|
|
474
|
+
if (opts.confirm) {
|
|
475
|
+
// Lazy import: avoids loading `principles-disciple` at module init time.
|
|
476
|
+
// `pd --version` (and the create-principles-disciple smoke test) loads
|
|
477
|
+
// this file statically via index.ts. If we used a static import, the
|
|
478
|
+
// module would fail with MODULE_NOT_FOUND in bundled environments where
|
|
479
|
+
// `principles-disciple` is not resolvable from pd-cli's node_modules.
|
|
480
|
+
// The import only executes when `--confirm` is actually used.
|
|
481
|
+
const { BehaviorExamplePackAssembler, RuleHostEvidenceRegistry } = await import('principles-disciple/rulehost-evidence');
|
|
482
|
+
try {
|
|
483
|
+
const assembler = new BehaviorExamplePackAssembler({ workspaceDir, stateDir: path.join(workspaceDir, '.state') });
|
|
484
|
+
behaviorExamplePack = assembler.assemble({
|
|
485
|
+
sourcePainId: opts.painId,
|
|
486
|
+
ownerDesiredOutcome: examplesResult.value.ownerDesiredOutcome,
|
|
487
|
+
sourceNegativeToolCallId: examplesResult.value.sourceNegativeToolCallId,
|
|
488
|
+
positiveToolCallIds: examplesResult.value.positiveToolCallIds,
|
|
489
|
+
projectDir: workspaceDir,
|
|
490
|
+
});
|
|
491
|
+
} catch (error) {
|
|
492
|
+
// P1 fix (CodeRabbit PR2 Comment 1): fail fast on assembly failure
|
|
493
|
+
// instead of silently degrading to text_principle_only.
|
|
494
|
+
const reason = `behavior_examples_unreliable: ${error instanceof Error ? error.message : String(error)}`;
|
|
495
|
+
if (opts.json) {
|
|
496
|
+
process.stdout.write(JSON.stringify({
|
|
497
|
+
status: 'failed',
|
|
498
|
+
reason,
|
|
499
|
+
nextAction: 'verify pain lineage and tool call IDs reference existing trajectory rows; rerun pd pain record if needed',
|
|
500
|
+
}) + '\n');
|
|
501
|
+
} else {
|
|
502
|
+
console.error(`Error: ${reason}. Verify pain lineage and tool call IDs reference existing trajectory rows; rerun pd pain record if needed.`);
|
|
503
|
+
}
|
|
504
|
+
process.exitCode = 1;
|
|
505
|
+
return;
|
|
506
|
+
} finally {
|
|
507
|
+
RuleHostEvidenceRegistry.dispose(workspaceDir);
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
if (behaviorExamplesReason) {
|
|
512
|
+
effectiveCapability = { enabled: false, disabledReason: `${behaviorExamplesReason}; nextAction: provide reliable Owner-labelled tool call IDs with --behavior-examples` };
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
|
|
377
516
|
// ── Dry-run mode: report what would happen, don't run the pipeline ──
|
|
378
517
|
// Default is dry-run (CLI gate rule 4: mutating commands default to dry-run).
|
|
379
518
|
const isDryRun = opts.dryRun || !opts.confirm;
|
|
@@ -386,9 +525,15 @@ export async function handleRunRuleHost(opts: RunRuleHostOptions): Promise<void>
|
|
|
386
525
|
channel,
|
|
387
526
|
readiness,
|
|
388
527
|
readinessStatus: readiness.status,
|
|
389
|
-
capabilityStatus:
|
|
528
|
+
capabilityStatus: behaviorExamplesReason
|
|
529
|
+
? `code_rule_capability: OFF (${behaviorExamplesReason})`
|
|
530
|
+
: resolvedRuntime.capabilityStatus,
|
|
390
531
|
agentRuntimeProfiles: resolvedRuntime.agentRuntimeProfiles,
|
|
391
|
-
codeRuleCapability: { enabled:
|
|
532
|
+
codeRuleCapability: { enabled: effectiveCapability.enabled, disabledReason: effectiveCapability.disabledReason },
|
|
533
|
+
contextMode,
|
|
534
|
+
behaviorExamples: behaviorExamplesPath
|
|
535
|
+
? { path: behaviorExamplesPath, status: behaviorExamplesReason ? 'unreliable' : 'provided' }
|
|
536
|
+
: { status: resolvedRuntime.contextV2Enabled ? 'missing' : 'not_required' },
|
|
392
537
|
nextAction: readiness.status === 'ready'
|
|
393
538
|
? 'pass --confirm to run the full pipeline'
|
|
394
539
|
: readiness.status === 'text_principle_only'
|
|
@@ -396,7 +541,12 @@ export async function handleRunRuleHost(opts: RunRuleHostOptions): Promise<void>
|
|
|
396
541
|
: 'fix the readiness issues above before running the pipeline',
|
|
397
542
|
}) + '\n');
|
|
398
543
|
} else {
|
|
399
|
-
|
|
544
|
+
// P2 fix (CodeRabbit PR2 Comment 2): text branch must use the same v2-aware
|
|
545
|
+
// capabilityStatus source as the JSON branch (behaviorExamplesReason-aware).
|
|
546
|
+
const effectiveCapabilityStatus = behaviorExamplesReason
|
|
547
|
+
? `code_rule_capability: OFF (${behaviorExamplesReason})`
|
|
548
|
+
: resolvedRuntime.capabilityStatus;
|
|
549
|
+
process.stdout.write(formatDryRunOutput({ opts, capabilityStatus: effectiveCapabilityStatus, workspaceDir, readiness }) + '\n');
|
|
400
550
|
}
|
|
401
551
|
return;
|
|
402
552
|
}
|
|
@@ -409,7 +559,9 @@ export async function handleRunRuleHost(opts: RunRuleHostOptions): Promise<void>
|
|
|
409
559
|
painId: opts.painId,
|
|
410
560
|
runtimeAdapter: resolvedRuntime.agentAdapters.dreamer,
|
|
411
561
|
agentAdapters: resolvedRuntime.agentAdapters,
|
|
412
|
-
codeRuleCapability:
|
|
562
|
+
codeRuleCapability: effectiveCapability,
|
|
563
|
+
contextMode,
|
|
564
|
+
behaviorExamplePack,
|
|
413
565
|
channel: channel as RuleHostChannel,
|
|
414
566
|
maxRounds: opts.maxRounds,
|
|
415
567
|
timeoutMs: opts.timeoutMs,
|
|
@@ -465,10 +617,11 @@ export function registerRunRuleHostCommand(internalizationCmd: Command): Command
|
|
|
465
617
|
.option('--channel <channel>', 'Activation channel: code_tool_hook, prompt, defer_archive (default: code_tool_hook)', 'code_tool_hook')
|
|
466
618
|
.option('--max-rounds <n>', 'Max adversarial rounds (PRD cap = 2)', parseInt)
|
|
467
619
|
.option('--timeout-ms <ms>', 'Per-LLM-call timeout in milliseconds (default: 300000)', parseInt)
|
|
620
|
+
.option('--behavior-examples <json>', 'Owner-labelled negative/positive tool call IDs for RuleContext v2')
|
|
468
621
|
.option('--dry-run', 'Validate inputs + config, report capability status, do NOT run the pipeline (default)')
|
|
469
622
|
.option('--confirm', 'Actually run the pipeline (mutually exclusive with --dry-run)')
|
|
470
623
|
.option('--json', 'Output raw JSON')
|
|
471
624
|
.action(async (opts) => {
|
|
472
|
-
await handleRunRuleHost({ workspace: opts.workspace, painId: opts.painId, channel: opts.channel, maxRounds: opts.maxRounds, timeoutMs: opts.timeoutMs, dryRun: opts.dryRun, confirm: opts.confirm, json: opts.json });
|
|
625
|
+
await handleRunRuleHost({ workspace: opts.workspace, painId: opts.painId, channel: opts.channel, maxRounds: opts.maxRounds, timeoutMs: opts.timeoutMs, behaviorExamples: opts.behaviorExamples, dryRun: opts.dryRun, confirm: opts.confirm, json: opts.json });
|
|
473
626
|
});
|
|
474
627
|
}
|
|
@@ -18,6 +18,11 @@ vi.mock('child_process', () => ({
|
|
|
18
18
|
const { handleRuntimeUat } = await import('./runtime-uat.js');
|
|
19
19
|
const { guardUatWorkspace } = await import('../utils/production-workspace-guard.js');
|
|
20
20
|
|
|
21
|
+
// ─── Cross-platform production workspace path ─────────────────────────────────
|
|
22
|
+
// Mirrors the default in production-workspace-guard.ts: ~/.openclaw/workspace.
|
|
23
|
+
// Using this instead of hardcoded "D:\..." paths ensures tests work on Linux/macOS CI.
|
|
24
|
+
const PROD_WORKSPACE = path.join(os.homedir(), '.openclaw', 'workspace');
|
|
25
|
+
|
|
21
26
|
// ─── Test Setup ─────────────────────────────────────────────────────────────
|
|
22
27
|
const capturedStderr: string[] = [];
|
|
23
28
|
const capturedStdout: string[] = [];
|
|
@@ -53,23 +58,16 @@ beforeEach(() => {
|
|
|
53
58
|
|
|
54
59
|
// ─── Tests ──────────────────────────────────────────────────────────────────
|
|
55
60
|
describe('PRI-334: production workspace refusal', () => {
|
|
56
|
-
it('refuses
|
|
57
|
-
mockExecFileSync.mockClear();
|
|
58
|
-
await handleRuntimeUat({ workspace: 'D:\\.openclaw\\workspace', count: 1 });
|
|
59
|
-
expect(capturedExitCode).toBe(1);
|
|
60
|
-
expect(mockExecFileSync).not.toHaveBeenCalled();
|
|
61
|
-
});
|
|
62
|
-
|
|
63
|
-
it('refuses C: workspace with exit code 1', async () => {
|
|
61
|
+
it('refuses default production workspace with exit code 1', async () => {
|
|
64
62
|
mockExecFileSync.mockClear();
|
|
65
|
-
await handleRuntimeUat({ workspace:
|
|
63
|
+
await handleRuntimeUat({ workspace: PROD_WORKSPACE, count: 1 });
|
|
66
64
|
expect(capturedExitCode).toBe(1);
|
|
67
65
|
expect(mockExecFileSync).not.toHaveBeenCalled();
|
|
68
66
|
});
|
|
69
67
|
|
|
70
|
-
it('refuses production workspace subdirectory', async () => {
|
|
68
|
+
it('refuses production workspace subdirectory with exit code 1', async () => {
|
|
71
69
|
mockExecFileSync.mockClear();
|
|
72
|
-
await handleRuntimeUat({ workspace: '
|
|
70
|
+
await handleRuntimeUat({ workspace: path.join(PROD_WORKSPACE, 'sub', 'path'), count: 1 });
|
|
73
71
|
expect(capturedExitCode).toBe(1);
|
|
74
72
|
expect(mockExecFileSync).not.toHaveBeenCalled();
|
|
75
73
|
});
|
|
@@ -82,11 +80,11 @@ describe('PRI-334: allowed paths (guard level)', () => {
|
|
|
82
80
|
});
|
|
83
81
|
|
|
84
82
|
it('allows workspace-test sibling (ERR-030)', () => {
|
|
85
|
-
expect(guardUatWorkspace('
|
|
83
|
+
expect(guardUatWorkspace(path.join(os.homedir(), '.openclaw', 'workspace-test'), 'test').refused).toBe(false);
|
|
86
84
|
});
|
|
87
85
|
|
|
88
86
|
it('allows workspace-backup sibling (ERR-030)', () => {
|
|
89
|
-
expect(guardUatWorkspace('
|
|
87
|
+
expect(guardUatWorkspace(path.join(os.homedir(), '.openclaw', 'workspace-backup'), 'test').refused).toBe(false);
|
|
90
88
|
});
|
|
91
89
|
});
|
|
92
90
|
|
|
@@ -94,7 +92,7 @@ describe('PRI-334: JSON output (EP-04)', () => {
|
|
|
94
92
|
it('outputs single JSON object with reason and nextAction', async () => {
|
|
95
93
|
mockExecFileSync.mockClear();
|
|
96
94
|
capturedStdout.length = 0;
|
|
97
|
-
await handleRuntimeUat({ workspace:
|
|
95
|
+
await handleRuntimeUat({ workspace: PROD_WORKSPACE, count: 1, json: true });
|
|
98
96
|
expect(capturedExitCode).toBe(1);
|
|
99
97
|
expect(mockExecFileSync).not.toHaveBeenCalled();
|
|
100
98
|
|
|
@@ -115,7 +113,7 @@ describe('PRI-334: escape hatch', () => {
|
|
|
115
113
|
capturedStderr.length = 0;
|
|
116
114
|
capturedExitCode = null;
|
|
117
115
|
|
|
118
|
-
await handleRuntimeUat({ workspace:
|
|
116
|
+
await handleRuntimeUat({ workspace: PROD_WORKSPACE, count: 1, allowProductionWorkspaceForUat: true });
|
|
119
117
|
const stderrText = capturedStderr.join('\n');
|
|
120
118
|
expect(stderrText).toContain('WARNING');
|
|
121
119
|
expect(stderrText).toContain('--allow-production-workspace-for-uat');
|
|
@@ -125,7 +123,7 @@ describe('PRI-334: escape hatch', () => {
|
|
|
125
123
|
describe('PRI-334: mutation prevention', () => {
|
|
126
124
|
it('does not call execFileSync after guard refusal', async () => {
|
|
127
125
|
mockExecFileSync.mockClear();
|
|
128
|
-
await handleRuntimeUat({ workspace:
|
|
126
|
+
await handleRuntimeUat({ workspace: PROD_WORKSPACE, count: 1 });
|
|
129
127
|
expect(mockExecFileSync).not.toHaveBeenCalled();
|
|
130
128
|
});
|
|
131
129
|
});
|
|
@@ -144,11 +144,12 @@ function pd(args: string[], workspace: string, timeoutMs = 300_000): string {
|
|
|
144
144
|
stdio: ['pipe', 'pipe', 'pipe'],
|
|
145
145
|
});
|
|
146
146
|
} catch (err: unknown) {
|
|
147
|
-
if (err instanceof Error &&
|
|
147
|
+
if (err instanceof Error && // eslint-disable-next-line no-restricted-syntax -- 'in' required for Error subtype narrowing (err.code access)
|
|
148
|
+
'code' in err && (err as { code: string }).code === 'ENOENT') {
|
|
148
149
|
throw new Error(`pd CLI not found at ${cliPath} — run: npm run build --workspace=@principles/pd-cli`, { cause: err });
|
|
149
150
|
}
|
|
150
|
-
if (err && typeof err === 'object' && 'stdout'
|
|
151
|
-
return String((err).stdout);
|
|
151
|
+
if (err && typeof err === 'object' && Object.hasOwn(err, 'stdout')) {
|
|
152
|
+
return String((err as { stdout: unknown }).stdout);
|
|
152
153
|
}
|
|
153
154
|
throw err;
|
|
154
155
|
}
|
package/src/config-reader.ts
CHANGED
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
|
|
14
14
|
import * as fs from 'fs';
|
|
15
15
|
import * as path from 'path';
|
|
16
|
-
import yaml from 'js-yaml';
|
|
16
|
+
import * as yaml from 'js-yaml';
|
|
17
17
|
import { resolveOutputLanguage, DEFAULT_OUTPUT_LANGUAGE } from '@principles/core/runtime-v2';
|
|
18
18
|
import type { ResolvedOutputLanguage } from '@principles/core/runtime-v2';
|
|
19
19
|
|
package/src/index.ts
CHANGED
|
@@ -8,13 +8,13 @@
|
|
|
8
8
|
|
|
9
9
|
import { Command } from 'commander';
|
|
10
10
|
import { handlePainRecord } from './commands/pain-record.js';
|
|
11
|
-
import {
|
|
11
|
+
import { registerPainRetryCommand } from './commands/pain-retry.js';
|
|
12
12
|
import { handlePainEvidence } from './commands/pain-evidence.js';
|
|
13
13
|
import { handleSamplesList } from './commands/samples-list.js';
|
|
14
14
|
import { handleSamplesReview } from './commands/samples-review.js';
|
|
15
15
|
import { handleEvolutionTasksList } from './commands/evolution-tasks-list.js';
|
|
16
16
|
import { handleEvolutionTasksShow } from './commands/evolution-tasks-show.js';
|
|
17
|
-
import {
|
|
17
|
+
import { registerHealthCommand } from './commands/health.js';
|
|
18
18
|
import { handleTaskShow, registerTaskListCommand } from './commands/task.js';
|
|
19
19
|
import { handleRunList, handleRunShow } from './commands/run.js';
|
|
20
20
|
import { handleTrajectoryLocate } from './commands/trajectory.js';
|
|
@@ -42,11 +42,20 @@ import { handleRuntimePainFlood } from './commands/runtime-pain-flood-simulation
|
|
|
42
42
|
import { handleRuntimeInternalizationIntegrity } from './commands/runtime-internalization-integrity.js';
|
|
43
43
|
import { handleRuntimeInternalizationIntegrityRepair } from './commands/runtime-internalization-integrity-repair.js';
|
|
44
44
|
import { handleRuntimeInternalizationEnqueueSuccessors } from './commands/runtime-internalization-enqueue-successors.js';
|
|
45
|
+
import { handleRuntimeInternalizationContextTrace } from './commands/runtime-internalization-context-trace.js';
|
|
45
46
|
import { handleRuntimeDiagnosticsExport } from './commands/runtime-diagnostics-export.js';
|
|
46
47
|
import { handleRuntimeRecoverySweep } from './commands/runtime-recovery.js';
|
|
47
48
|
import { handleRuntimeRecoveryFailedTasks } from './commands/runtime-recovery-failed-tasks.js';
|
|
48
|
-
import {
|
|
49
|
-
|
|
49
|
+
import {
|
|
50
|
+
handleRuntimeActivationDeactivate,
|
|
51
|
+
handleRuntimeActivationList,
|
|
52
|
+
handleRuntimeActivationEdit,
|
|
53
|
+
registerRuntimeActivationPromoteCommand,
|
|
54
|
+
registerRuntimeActivationDeactivateCommand,
|
|
55
|
+
registerRuntimeActivationListCommand,
|
|
56
|
+
registerRuntimeActivationDispatchCommand,
|
|
57
|
+
registerRuntimeActivationApproveCommand,
|
|
58
|
+
} from './commands/runtime-activation.js';
|
|
50
59
|
import { handleProvenChannelBaseline } from './commands/proven-channel-baseline.js';
|
|
51
60
|
import { handleDemoStoryA } from './commands/demo-story-a.js';
|
|
52
61
|
import { handleRuntimeFeaturesStatus } from './commands/runtime-features.js';
|
|
@@ -54,6 +63,7 @@ import { handleConfigDoctor } from './commands/config-doctor.js';
|
|
|
54
63
|
import { registerMvpCommands } from './commands/mvp-smoke.js';
|
|
55
64
|
import { registerRulecodeCommand } from './commands/rulecode.js';
|
|
56
65
|
import { registerIntentCommand } from './commands/intent.js';
|
|
66
|
+
import { registerErrorsListCommand } from './commands/errors-list.js';
|
|
57
67
|
|
|
58
68
|
import { createRequire } from 'module';
|
|
59
69
|
const require = createRequire(import.meta.url);
|
|
@@ -85,30 +95,11 @@ painCmd
|
|
|
85
95
|
await handlePainRecord(opts);
|
|
86
96
|
});
|
|
87
97
|
|
|
88
|
-
painCmd
|
|
89
|
-
.command('retry')
|
|
90
|
-
.description('Retry a failed diagnosis by pain ID')
|
|
91
|
-
.requiredOption('-p, --pain-id <painId>', 'Pain ID to retry diagnosis for')
|
|
92
|
-
.option('-w, --workspace <path>', 'Workspace directory')
|
|
93
|
-
.option('-r, --runtime <kind>', "Runtime kind: 'openclaw-cli', 'test-double', 'pi-ai'")
|
|
94
|
-
.option('--openclaw-local', 'Use local OpenClaw (mutually exclusive with --openclaw-gateway)')
|
|
95
|
-
.option('--openclaw-gateway', 'Use gateway OpenClaw (mutually exclusive with --openclaw-local)')
|
|
96
|
-
.option('-a, --agent <agentId>', 'Agent ID to invoke')
|
|
97
|
-
.option('--provider <name>', 'LLM provider (e.g., openrouter) — for pi-ai, falls back to policy')
|
|
98
|
-
.option('--model <id>', 'Model ID (e.g., anthropic/claude-sonnet-4) — for pi-ai, falls back to policy')
|
|
99
|
-
.option('--apiKeyEnv <name>', 'Env var name for API key — for pi-ai, falls back to policy')
|
|
100
|
-
.option('--baseUrl <url>', 'Custom base URL — for pi-ai, falls back to policy')
|
|
101
|
-
.option('--maxRetries <n>', 'Max retry attempts for LLM failures — for pi-ai, falls back to policy', parseInt)
|
|
102
|
-
.option('--timeoutMs <ms>', 'Timeout in milliseconds — for pi-ai, falls back to policy', parseInt)
|
|
103
|
-
.option('--force', 'Allow retry of already-succeeded tasks')
|
|
104
|
-
.option('--json', 'Output raw JSON')
|
|
105
|
-
.action(async (opts) => {
|
|
106
|
-
await handlePainRetry(opts);
|
|
107
|
-
});
|
|
98
|
+
registerPainRetryCommand(painCmd);
|
|
108
99
|
|
|
109
100
|
painCmd
|
|
110
101
|
.command('evidence')
|
|
111
|
-
.description('Show recent pain admission
|
|
102
|
+
.description('Show recent TRIGGER_DECISION log entries — pain admission gate decisions only (PEAT-B2)')
|
|
112
103
|
.option('-w, --workspace <path>', 'Workspace directory')
|
|
113
104
|
.option('-l, --limit <number>', 'Max entries to show (default: 20)', parseInt)
|
|
114
105
|
.option('--json', 'Output raw JSON')
|
|
@@ -169,14 +160,7 @@ tasksCmd
|
|
|
169
160
|
await handleEvolutionTasksShow({ id });
|
|
170
161
|
});
|
|
171
162
|
|
|
172
|
-
program
|
|
173
|
-
.command('health')
|
|
174
|
-
.description('Show health diagnostics for all workspaces')
|
|
175
|
-
.option('-w, --workspace <path>', 'Workspace directory')
|
|
176
|
-
.option('--json', 'Output raw JSON')
|
|
177
|
-
.action(async (opts) => {
|
|
178
|
-
await handleHealth(opts);
|
|
179
|
-
});
|
|
163
|
+
registerHealthCommand(program);
|
|
180
164
|
|
|
181
165
|
// ── Runtime v2 task/run commands ──────────────────────────────────────────────鈹€鈹€鈹€鈹€鈹€鈹€
|
|
182
166
|
|
|
@@ -303,7 +287,7 @@ diagnoseCmd
|
|
|
303
287
|
.description('Execute diagnostician runner for a task')
|
|
304
288
|
.requiredOption('-t, --task-id <taskId>', 'Task ID to execute')
|
|
305
289
|
.option('-w, --workspace <path>', 'Workspace directory')
|
|
306
|
-
.option('-r, --runtime <kind>', "Runtime kind: 'openclaw-cli', 'test-double', 'pi-ai'")
|
|
290
|
+
.option('-r, --runtime <kind>', "Runtime kind: 'openclaw-cli', 'test-double', 'pi-ai'. If omitted, resolved from .pd/config.yaml; refuses if no binding (no test-double default).")
|
|
307
291
|
.option('--openclaw-local', 'Use local OpenClaw (mutually exclusive with --openclaw-gateway)')
|
|
308
292
|
.option('--openclaw-gateway', 'Use gateway OpenClaw (mutually exclusive with --openclaw-local)')
|
|
309
293
|
.option('-a, --agent <agentId>', 'Agent ID to invoke')
|
|
@@ -334,6 +318,28 @@ runtimeCmd
|
|
|
334
318
|
await handleRuntimeCanary({ workspace: opts.workspace, json: opts.json });
|
|
335
319
|
});
|
|
336
320
|
|
|
321
|
+
// pd runtime init — Initialize all PD SQLite databases for a workspace.
|
|
322
|
+
// Lazy import: avoids loading `principles-disciple` at module init time, which
|
|
323
|
+
// would crash `pd --version` in packaged installs where the plugin's transitive
|
|
324
|
+
// deps are not resolvable from pd-cli's node_modules. The import only executes
|
|
325
|
+
// when `pd runtime init` is actually invoked.
|
|
326
|
+
runtimeCmd
|
|
327
|
+
.command('init')
|
|
328
|
+
.description('Initialize all PD SQLite databases (state.db, trajectory.db, subagent_workflows.db)')
|
|
329
|
+
.option('-w, --workspace <path>', 'Workspace directory')
|
|
330
|
+
.option('--dry-run', 'Show what would be initialized without writing (default)')
|
|
331
|
+
.option('--confirm', 'Actually initialize the databases (required to write)')
|
|
332
|
+
.option('--json', 'Output raw JSON')
|
|
333
|
+
.action(async (opts) => {
|
|
334
|
+
const { handleRuntimeInit } = await import('./commands/runtime-init.js');
|
|
335
|
+
await handleRuntimeInit({
|
|
336
|
+
workspace: opts.workspace,
|
|
337
|
+
dryRun: opts.dryRun === true,
|
|
338
|
+
confirm: opts.confirm === true,
|
|
339
|
+
json: opts.json === true,
|
|
340
|
+
});
|
|
341
|
+
});
|
|
342
|
+
|
|
337
343
|
const synthCmd = runtimeCmd
|
|
338
344
|
.command('synthetic', { hidden: true })
|
|
339
345
|
.description('Synthetic workload baseline commands');
|
|
@@ -414,31 +420,15 @@ const activationTopCmd = program
|
|
|
414
420
|
.command('activation')
|
|
415
421
|
.description('Activation management — list active activations, deactivate (Story A\' Steps 5-6)');
|
|
416
422
|
|
|
417
|
-
activationTopCmd
|
|
418
|
-
.command('list')
|
|
419
|
-
.description('List all activations for a workspace')
|
|
420
|
-
.option('-w, --workspace <path>', 'Workspace directory')
|
|
421
|
-
.option('-c, --channel <channel>', 'Filter by channel (prompt|code_tool_hook)')
|
|
422
|
-
.option('--include-deactivated', 'Include deactivated records in output')
|
|
423
|
-
.option('--json', 'Output raw JSON')
|
|
424
|
-
.action(async (opts) => {
|
|
425
|
-
await handleRuntimeActivationList({
|
|
426
|
-
workspace: opts.workspace,
|
|
427
|
-
channel: opts.channel,
|
|
428
|
-
includeDeactivated: opts.includeDeactivated,
|
|
429
|
-
json: opts.json,
|
|
430
|
-
});
|
|
431
|
-
});
|
|
423
|
+
registerRuntimeActivationListCommand(activationTopCmd);
|
|
432
424
|
|
|
433
|
-
activationTopCmd
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
await handleRuntimeActivationDeactivate({ activationId: opts.activationId, workspace: opts.workspace, json: opts.json });
|
|
441
|
-
});
|
|
425
|
+
registerRuntimeActivationDeactivateCommand(activationTopCmd);
|
|
426
|
+
|
|
427
|
+
// Bug-M fix: CLI closed loop — approve a pending approval and dispatch its activation.
|
|
428
|
+
// Reuses the same ApprovalQueue + ApprovalCompletionService as the Console model.
|
|
429
|
+
registerRuntimeActivationApproveCommand(activationTopCmd);
|
|
430
|
+
|
|
431
|
+
registerRuntimeActivationPromoteCommand(activationTopCmd);
|
|
442
432
|
|
|
443
433
|
const configCmd = program
|
|
444
434
|
.command('config')
|
|
@@ -459,6 +449,7 @@ const demoCmd = program
|
|
|
459
449
|
|
|
460
450
|
demoCmd
|
|
461
451
|
.command('story-a')
|
|
452
|
+
.alias('first-principle')
|
|
462
453
|
.description('Run Story A\'s proven-channel demo (PRI-246) — full evidence→proposal→approval→activation→observation chain')
|
|
463
454
|
.option('-w, --workspace <path>', 'Workspace directory (default: temp workspace)')
|
|
464
455
|
.option('--json', 'Output raw JSON')
|
|
@@ -541,7 +532,7 @@ runtimeHealthCmd
|
|
|
541
532
|
});
|
|
542
533
|
|
|
543
534
|
const internalizationCmd = runtimeCmd
|
|
544
|
-
.command('internalization'
|
|
535
|
+
.command('internalization')
|
|
545
536
|
.description('Internalization Engine operator visibility');
|
|
546
537
|
|
|
547
538
|
internalizationCmd
|
|
@@ -610,29 +601,23 @@ internalizationCmd
|
|
|
610
601
|
await handleRuntimeInternalizationEnqueueSuccessors({ workspace: opts.workspace, dryRun: opts.dryRun, confirm: opts.confirm, json: opts.json });
|
|
611
602
|
});
|
|
612
603
|
|
|
604
|
+
// Layer 3 (design §6.7, PR 5): read-only context-trace command.
|
|
605
|
+
internalizationCmd
|
|
606
|
+
.command('context-trace')
|
|
607
|
+
.description('Trace the internalization context chain: summaries, three-segment diagnosis, truncations, degradations')
|
|
608
|
+
.requiredOption('-t, --task <taskId>', 'Task ID to trace')
|
|
609
|
+
.option('-a, --artifact <artifactId>', 'Specific artifact ID to start from')
|
|
610
|
+
.option('-w, --workspace <path>', 'Workspace directory')
|
|
611
|
+
.option('--json', 'Output raw JSON (default)')
|
|
612
|
+
.action(async (opts) => {
|
|
613
|
+
await handleRuntimeInternalizationContextTrace({ workspace: opts.workspace, task: opts.task, artifact: opts.artifact, json: opts.json });
|
|
614
|
+
});
|
|
615
|
+
|
|
613
616
|
const activationCmd = runtimeCmd
|
|
614
617
|
.command('activation', { hidden: true })
|
|
615
618
|
.description('Activation dispatch operations (hidden — use pd activation for list/deactivate)');
|
|
616
619
|
|
|
617
|
-
activationCmd
|
|
618
|
-
.command('dispatch')
|
|
619
|
-
.description('Dispatch an activation for a rollout-reviewed artifact')
|
|
620
|
-
.option('-a, --artifact-id <id>', 'PIArtifact ID to activate')
|
|
621
|
-
.option('-w, --workspace <path>', 'Workspace directory')
|
|
622
|
-
.option('-c, --channel <channel>', 'Activation channel (prompt|defer_archive)', 'prompt')
|
|
623
|
-
.option('--dry-run', 'Dry-run mode (default, no writes)')
|
|
624
|
-
.option('--confirm', 'Confirm and write activation record')
|
|
625
|
-
.option('--json', 'Output raw JSON')
|
|
626
|
-
.action(async (opts) => {
|
|
627
|
-
await handleRuntimeActivationDispatch({
|
|
628
|
-
workspace: opts.workspace,
|
|
629
|
-
artifactId: opts.artifactId,
|
|
630
|
-
channel: opts.channel,
|
|
631
|
-
dryRun: opts.dryRun,
|
|
632
|
-
confirm: opts.confirm,
|
|
633
|
-
json: opts.json,
|
|
634
|
-
});
|
|
635
|
-
});
|
|
620
|
+
registerRuntimeActivationDispatchCommand(activationCmd);
|
|
636
621
|
|
|
637
622
|
// PRI-408 Contract E: Owner-initiated rollback/deactivate of an activation.
|
|
638
623
|
// Idempotent — calling twice on the same ID is safe and returns ok=false with reason.
|
|
@@ -977,6 +962,12 @@ registerRulecodeCommand(program);
|
|
|
977
962
|
|
|
978
963
|
registerIntentCommand(program);
|
|
979
964
|
|
|
965
|
+
// ─── Errors List (Task 14: Feedback Pipeline Observability) ────────────────
|
|
966
|
+
// Operator diagnostic: aggregates SQLite failed/needs_human_review tasks +
|
|
967
|
+
// worker-status.json errors array. Read-only.
|
|
968
|
+
|
|
969
|
+
registerErrorsListCommand(program);
|
|
970
|
+
|
|
980
971
|
const consoleCmd = program
|
|
981
972
|
.command('console')
|
|
982
973
|
.description('Start the pd-console web UI for principle review (default: fallback launcher)')
|