@principles/pd-cli 1.152.12 → 1.152.13

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.
Files changed (296) hide show
  1. package/package.json +13 -7
  2. package/CHANGELOG.md +0 -23
  3. package/dist/commands/__tests__/intent-flag-wiring.test.d.ts +0 -9
  4. package/dist/commands/__tests__/intent-flag-wiring.test.d.ts.map +0 -1
  5. package/dist/commands/__tests__/intent-flag-wiring.test.js +0 -237
  6. package/dist/commands/__tests__/intent-flag-wiring.test.js.map +0 -1
  7. package/dist/commands/__tests__/legacy-cleanup.test.d.ts +0 -18
  8. package/dist/commands/__tests__/legacy-cleanup.test.d.ts.map +0 -1
  9. package/dist/commands/__tests__/legacy-cleanup.test.js +0 -467
  10. package/dist/commands/__tests__/legacy-cleanup.test.js.map +0 -1
  11. package/dist/commands/__tests__/mvp-smoke.test.d.ts +0 -15
  12. package/dist/commands/__tests__/mvp-smoke.test.d.ts.map +0 -1
  13. package/dist/commands/__tests__/mvp-smoke.test.js +0 -262
  14. package/dist/commands/__tests__/mvp-smoke.test.js.map +0 -1
  15. package/dist/commands/__tests__/pain-retry-maxTokens-flag.test.d.ts +0 -2
  16. package/dist/commands/__tests__/pain-retry-maxTokens-flag.test.d.ts.map +0 -1
  17. package/dist/commands/__tests__/pain-retry-maxTokens-flag.test.js +0 -60
  18. package/dist/commands/__tests__/pain-retry-maxTokens-flag.test.js.map +0 -1
  19. package/dist/commands/__tests__/rulecode-flag-wiring.test.d.ts +0 -21
  20. package/dist/commands/__tests__/rulecode-flag-wiring.test.d.ts.map +0 -1
  21. package/dist/commands/__tests__/rulecode-flag-wiring.test.js +0 -186
  22. package/dist/commands/__tests__/rulecode-flag-wiring.test.js.map +0 -1
  23. package/dist/commands/__tests__/rulecode-handler.test.d.ts +0 -16
  24. package/dist/commands/__tests__/rulecode-handler.test.d.ts.map +0 -1
  25. package/dist/commands/__tests__/rulecode-handler.test.js +0 -285
  26. package/dist/commands/__tests__/rulecode-handler.test.js.map +0 -1
  27. package/dist/commands/__tests__/run-rulehost-flag-wiring.test.d.ts +0 -24
  28. package/dist/commands/__tests__/run-rulehost-flag-wiring.test.d.ts.map +0 -1
  29. package/dist/commands/__tests__/run-rulehost-flag-wiring.test.js +0 -232
  30. package/dist/commands/__tests__/run-rulehost-flag-wiring.test.js.map +0 -1
  31. package/dist/commands/__tests__/runtime-activation-nextaction.test.d.ts +0 -15
  32. package/dist/commands/__tests__/runtime-activation-nextaction.test.d.ts.map +0 -1
  33. package/dist/commands/__tests__/runtime-activation-nextaction.test.js +0 -73
  34. package/dist/commands/__tests__/runtime-activation-nextaction.test.js.map +0 -1
  35. package/dist/commands/__tests__/runtime-probe-config.test.d.ts +0 -20
  36. package/dist/commands/__tests__/runtime-probe-config.test.d.ts.map +0 -1
  37. package/dist/commands/__tests__/runtime-probe-config.test.js +0 -389
  38. package/dist/commands/__tests__/runtime-probe-config.test.js.map +0 -1
  39. package/dist/commands/__tests__/telemetry-flag-wiring.test.d.ts +0 -9
  40. package/dist/commands/__tests__/telemetry-flag-wiring.test.d.ts.map +0 -1
  41. package/dist/commands/__tests__/telemetry-flag-wiring.test.js +0 -76
  42. package/dist/commands/__tests__/telemetry-flag-wiring.test.js.map +0 -1
  43. package/dist/commands/__tests__/version.test.d.ts +0 -2
  44. package/dist/commands/__tests__/version.test.d.ts.map +0 -1
  45. package/dist/commands/__tests__/version.test.js +0 -238
  46. package/dist/commands/__tests__/version.test.js.map +0 -1
  47. package/dist/commands/runtime-uat.guard.test.d.ts +0 -2
  48. package/dist/commands/runtime-uat.guard.test.d.ts.map +0 -1
  49. package/dist/commands/runtime-uat.guard.test.js +0 -153
  50. package/dist/commands/runtime-uat.guard.test.js.map +0 -1
  51. package/dist/services/__tests__/cli-output.test.d.ts +0 -18
  52. package/dist/services/__tests__/cli-output.test.d.ts.map +0 -1
  53. package/dist/services/__tests__/cli-output.test.js +0 -103
  54. package/dist/services/__tests__/cli-output.test.js.map +0 -1
  55. package/dist/services/__tests__/evaluator-runner-deps.test.d.ts +0 -2
  56. package/dist/services/__tests__/evaluator-runner-deps.test.d.ts.map +0 -1
  57. package/dist/services/__tests__/evaluator-runner-deps.test.js +0 -343
  58. package/dist/services/__tests__/evaluator-runner-deps.test.js.map +0 -1
  59. package/dist/services/__tests__/rulehost-readiness.test.d.ts +0 -2
  60. package/dist/services/__tests__/rulehost-readiness.test.d.ts.map +0 -1
  61. package/dist/services/__tests__/rulehost-readiness.test.js +0 -311
  62. package/dist/services/__tests__/rulehost-readiness.test.js.map +0 -1
  63. package/dist/services/__tests__/runtime-adapter-resolver.test.d.ts +0 -18
  64. package/dist/services/__tests__/runtime-adapter-resolver.test.d.ts.map +0 -1
  65. package/dist/services/__tests__/runtime-adapter-resolver.test.js +0 -673
  66. package/dist/services/__tests__/runtime-adapter-resolver.test.js.map +0 -1
  67. package/dist/utils/production-workspace-guard.test.d.ts +0 -2
  68. package/dist/utils/production-workspace-guard.test.d.ts.map +0 -1
  69. package/dist/utils/production-workspace-guard.test.js +0 -137
  70. package/dist/utils/production-workspace-guard.test.js.map +0 -1
  71. package/scripts/llm-dogfood.ts +0 -456
  72. package/scripts/migrate-illegal-expected-decision.ts +0 -252
  73. package/src/commands/__tests__/intent-flag-wiring.test.ts +0 -282
  74. package/src/commands/__tests__/legacy-cleanup.test.ts +0 -602
  75. package/src/commands/__tests__/mvp-smoke.test.ts +0 -300
  76. package/src/commands/__tests__/pain-retry-maxTokens-flag.test.ts +0 -73
  77. package/src/commands/__tests__/rulecode-flag-wiring.test.ts +0 -237
  78. package/src/commands/__tests__/rulecode-handler.test.ts +0 -369
  79. package/src/commands/__tests__/run-rulehost-flag-wiring.test.ts +0 -292
  80. package/src/commands/__tests__/runtime-activation-nextaction.test.ts +0 -81
  81. package/src/commands/__tests__/runtime-probe-config.test.ts +0 -432
  82. package/src/commands/__tests__/telemetry-flag-wiring.test.ts +0 -84
  83. package/src/commands/__tests__/version.test.ts +0 -251
  84. package/src/commands/admission-gate.ts +0 -30
  85. package/src/commands/artifact.ts +0 -82
  86. package/src/commands/build-trajectory-evidence.ts +0 -298
  87. package/src/commands/candidate.ts +0 -1250
  88. package/src/commands/codex-ingest-catchup.ts +0 -114
  89. package/src/commands/codex-ingest-quarantine.ts +0 -127
  90. package/src/commands/codex-reconcile.ts +0 -84
  91. package/src/commands/codex-setup.ts +0 -476
  92. package/src/commands/codex-worker.ts +0 -185
  93. package/src/commands/command-helpers.ts +0 -24
  94. package/src/commands/config-doctor.ts +0 -193
  95. package/src/commands/console.ts +0 -797
  96. package/src/commands/context.ts +0 -72
  97. package/src/commands/demo-story-a.ts +0 -241
  98. package/src/commands/diagnose.ts +0 -756
  99. package/src/commands/errors-list.ts +0 -441
  100. package/src/commands/evolution-tasks-list.ts +0 -48
  101. package/src/commands/evolution-tasks-show.ts +0 -62
  102. package/src/commands/flow.ts +0 -60
  103. package/src/commands/health-codex.ts +0 -576
  104. package/src/commands/health.ts +0 -315
  105. package/src/commands/history.ts +0 -63
  106. package/src/commands/intent.ts +0 -457
  107. package/src/commands/legacy-cleanup.ts +0 -531
  108. package/src/commands/legacy-import.ts +0 -104
  109. package/src/commands/mvp-smoke.ts +0 -160
  110. package/src/commands/pain-evidence.ts +0 -226
  111. package/src/commands/pain-list.ts +0 -239
  112. package/src/commands/pain-record.ts +0 -612
  113. package/src/commands/pain-retry.ts +0 -916
  114. package/src/commands/principles-stats.ts +0 -700
  115. package/src/commands/proven-channel-baseline.ts +0 -115
  116. package/src/commands/quality-scorecard.ts +0 -272
  117. package/src/commands/remediation-output.ts +0 -66
  118. package/src/commands/rulecode.ts +0 -465
  119. package/src/commands/run.ts +0 -89
  120. package/src/commands/runtime-activation.ts +0 -1629
  121. package/src/commands/runtime-artifact-repair.ts +0 -524
  122. package/src/commands/runtime-canary.ts +0 -395
  123. package/src/commands/runtime-compatibility-scan.ts +0 -105
  124. package/src/commands/runtime-diagnostics-export.ts +0 -229
  125. package/src/commands/runtime-features.ts +0 -153
  126. package/src/commands/runtime-gfi-snapshot.ts +0 -135
  127. package/src/commands/runtime-health-snapshot.ts +0 -108
  128. package/src/commands/runtime-init.ts +0 -429
  129. package/src/commands/runtime-internalization-enqueue-successors.ts +0 -530
  130. package/src/commands/runtime-internalization-integrity-repair.ts +0 -79
  131. package/src/commands/runtime-internalization-integrity.ts +0 -107
  132. package/src/commands/runtime-internalization-queue.ts +0 -135
  133. package/src/commands/runtime-internalization-retry.ts +0 -191
  134. package/src/commands/runtime-internalization-run-once.ts +0 -791
  135. package/src/commands/runtime-internalization-run-rulehost.ts +0 -749
  136. package/src/commands/runtime-internalization-wake-once.ts +0 -87
  137. package/src/commands/runtime-pain-flood-simulation.ts +0 -121
  138. package/src/commands/runtime-pruning.ts +0 -438
  139. package/src/commands/runtime-recovery-failed-tasks.ts +0 -258
  140. package/src/commands/runtime-recovery.ts +0 -109
  141. package/src/commands/runtime-synthetic-baseline.ts +0 -70
  142. package/src/commands/runtime-uat.guard.test.ts +0 -175
  143. package/src/commands/runtime-uat.ts +0 -380
  144. package/src/commands/runtime.ts +0 -473
  145. package/src/commands/samples-list.ts +0 -39
  146. package/src/commands/samples-review.ts +0 -36
  147. package/src/commands/task.ts +0 -271
  148. package/src/commands/telemetry.ts +0 -349
  149. package/src/commands/trace.ts +0 -174
  150. package/src/commands/trajectory-db-unavailable.ts +0 -19
  151. package/src/commands/trajectory.ts +0 -64
  152. package/src/commands/version.ts +0 -49
  153. package/src/config-reader.ts +0 -122
  154. package/src/index.ts +0 -1276
  155. package/src/legacy/legacy-import.ts +0 -179
  156. package/src/legacy/session-history-import.ts +0 -203
  157. package/src/resolve-workspace.ts +0 -106
  158. package/src/services/__tests__/cli-output.test.ts +0 -130
  159. package/src/services/__tests__/evaluator-runner-deps.test.ts +0 -382
  160. package/src/services/__tests__/rulehost-readiness.test.ts +0 -363
  161. package/src/services/__tests__/runtime-adapter-resolver.test.ts +0 -793
  162. package/src/services/cli-output.ts +0 -95
  163. package/src/services/config-doctor.ts +0 -697
  164. package/src/services/console-launcher.ts +0 -537
  165. package/src/services/demo-rule-compiler.ts +0 -40
  166. package/src/services/demo-story-a-runner.ts +0 -471
  167. package/src/services/mainline-snapshot-assembler.ts +0 -579
  168. package/src/services/pain-flood-simulation-runner.ts +0 -462
  169. package/src/services/pd-config-loader.ts +0 -433
  170. package/src/services/proven-channel-baseline-runner.ts +0 -157
  171. package/src/services/quality-scorecard/data-extractor.ts +0 -150
  172. package/src/services/quality-scorecard/local-evaluator.ts +0 -142
  173. package/src/services/quality-scorecard/strong-model-gate.ts +0 -202
  174. package/src/services/resolve-runtime-from-pd-config.ts +0 -230
  175. package/src/services/rulehost-pipeline-runner.ts +0 -1214
  176. package/src/services/rulehost-readiness.ts +0 -326
  177. package/src/services/runtime-adapter-resolver.ts +0 -364
  178. package/src/services/synthetic-baseline-runner.ts +0 -400
  179. package/src/services/version-report.ts +0 -253
  180. package/src/services/workspace-tool-semantics.ts +0 -26
  181. package/src/utils/path-security.ts +0 -96
  182. package/src/utils/production-workspace-guard.test.ts +0 -157
  183. package/src/utils/production-workspace-guard.ts +0 -210
  184. package/tests/bdd/cli-contract.steps.ts +0 -346
  185. package/tests/bdd/principles-stats.steps.ts +0 -211
  186. package/tests/bdd/support/gherkin-loader.ts +0 -147
  187. package/tests/bdd/support/repo-root.ts +0 -62
  188. package/tests/bdd/support/vitest-bdd.ts +0 -179
  189. package/tests/commands/admission-gate-coverage.test.ts +0 -79
  190. package/tests/commands/build-trajectory-evidence.test.ts +0 -508
  191. package/tests/commands/candidate-audit-repair.test.ts +0 -421
  192. package/tests/commands/candidate-intake.test.ts +0 -732
  193. package/tests/commands/candidate-internalization-backfill.test.ts +0 -548
  194. package/tests/commands/candidate-internalize-lineage.test.ts +0 -628
  195. package/tests/commands/candidate-internalize.test.ts +0 -299
  196. package/tests/commands/candidate-route.test.ts +0 -329
  197. package/tests/commands/candidate-show.test.ts +0 -95
  198. package/tests/commands/cli-command-tree.test.ts +0 -144
  199. package/tests/commands/cli-help-snapshot.test.ts +0 -155
  200. package/tests/commands/cli-skill-contract.test.ts +0 -121
  201. package/tests/commands/codex-consent-reversibility.steps.test.ts +0 -299
  202. package/tests/commands/codex-ingest-quarantine.test.ts +0 -136
  203. package/tests/commands/codex-setup.test.ts +0 -297
  204. package/tests/commands/codex-worker-daemon.test.ts +0 -95
  205. package/tests/commands/codex-worker-registration.test.ts +0 -207
  206. package/tests/commands/config-doctor.test.ts +0 -336
  207. package/tests/commands/console-launcher-edge-cases.test.ts +0 -388
  208. package/tests/commands/console-open.test.ts +0 -1381
  209. package/tests/commands/context.test.ts +0 -114
  210. package/tests/commands/demo-story-a.test.ts +0 -318
  211. package/tests/commands/diagnose.test.ts +0 -1803
  212. package/tests/commands/errors-list.test.ts +0 -679
  213. package/tests/commands/evolution-tasks-list.test.ts +0 -41
  214. package/tests/commands/evolution-tasks-show.test.ts +0 -46
  215. package/tests/commands/health-codex.test.ts +0 -349
  216. package/tests/commands/health-host-wiring.test.ts +0 -76
  217. package/tests/commands/health-reliability.test.ts +0 -99
  218. package/tests/commands/health.test.ts +0 -413
  219. package/tests/commands/intent.test.ts +0 -321
  220. package/tests/commands/legacy-cleanup.test.ts +0 -148
  221. package/tests/commands/pain-evidence.test.ts +0 -518
  222. package/tests/commands/pain-list.test.ts +0 -219
  223. package/tests/commands/pain-record-async.test.ts +0 -335
  224. package/tests/commands/pain-record-session-parser.test.ts +0 -228
  225. package/tests/commands/pain-record.test.ts +0 -851
  226. package/tests/commands/pain-retry.test.ts +0 -1121
  227. package/tests/commands/plugin-config-resolution-cutover.test.ts +0 -229
  228. package/tests/commands/pri-393-runtime-config-unification.test.ts +0 -443
  229. package/tests/commands/principles-stats-wiring.test.ts +0 -135
  230. package/tests/commands/principles-stats.test.ts +0 -274
  231. package/tests/commands/product-path-regression.test.ts +0 -86
  232. package/tests/commands/proven-channel-baseline.test.ts +0 -441
  233. package/tests/commands/rulecode.test.ts +0 -177
  234. package/tests/commands/run-rulehost-handler.test.ts +0 -908
  235. package/tests/commands/runtime-activation-approve-flag-wiring.test.ts +0 -227
  236. package/tests/commands/runtime-activation-deactivate-flag-wiring.test.ts +0 -167
  237. package/tests/commands/runtime-activation-dispatch-flag-wiring.test.ts +0 -262
  238. package/tests/commands/runtime-activation-governance-audit.test.ts +0 -95
  239. package/tests/commands/runtime-activation-list-flag-wiring.test.ts +0 -193
  240. package/tests/commands/runtime-activation-promote-flag-wiring.test.ts +0 -248
  241. package/tests/commands/runtime-activation-shadow-telemetry.test.ts +0 -130
  242. package/tests/commands/runtime-activation.test.ts +0 -2052
  243. package/tests/commands/runtime-artifact-repair-registration.test.ts +0 -74
  244. package/tests/commands/runtime-artifact-repair.test.ts +0 -404
  245. package/tests/commands/runtime-canary.test.ts +0 -430
  246. package/tests/commands/runtime-compatibility-scan.test.ts +0 -146
  247. package/tests/commands/runtime-diagnostics-export.test.ts +0 -175
  248. package/tests/commands/runtime-features.test.ts +0 -249
  249. package/tests/commands/runtime-health-snapshot.test.ts +0 -358
  250. package/tests/commands/runtime-init-empty-workspace.test.ts +0 -252
  251. package/tests/commands/runtime-init.test.ts +0 -420
  252. package/tests/commands/runtime-internalization-enqueue-successors.test.ts +0 -782
  253. package/tests/commands/runtime-internalization-integrity-repair.test.ts +0 -239
  254. package/tests/commands/runtime-internalization-integrity.test.ts +0 -140
  255. package/tests/commands/runtime-internalization-queue.test.ts +0 -380
  256. package/tests/commands/runtime-internalization-retry-owner-authority.test.ts +0 -431
  257. package/tests/commands/runtime-internalization-run-once-evaluator-parity.test.ts +0 -269
  258. package/tests/commands/runtime-internalization-run-once-language.test.ts +0 -303
  259. package/tests/commands/runtime-internalization-run-once-real-config.test.ts +0 -237
  260. package/tests/commands/runtime-internalization-run-once-rollout-parity.test.ts +0 -706
  261. package/tests/commands/runtime-internalization-run-once.test.ts +0 -1791
  262. package/tests/commands/runtime-internalization-wake-once.test.ts +0 -171
  263. package/tests/commands/runtime-internalization.test.ts +0 -53
  264. package/tests/commands/runtime-pain-flood-simulation.test.ts +0 -418
  265. package/tests/commands/runtime-pruning.test.ts +0 -694
  266. package/tests/commands/runtime-recovery-failed-tasks.test.ts +0 -328
  267. package/tests/commands/runtime-recovery.test.ts +0 -120
  268. package/tests/commands/runtime-synthetic-baseline.test.ts +0 -249
  269. package/tests/commands/runtime-uat.test.ts +0 -397
  270. package/tests/commands/runtime.test.ts +0 -392
  271. package/tests/commands/samples-list.test.ts +0 -43
  272. package/tests/commands/samples-review.test.ts +0 -41
  273. package/tests/commands/task.test.ts +0 -153
  274. package/tests/commands/telemetry.test.ts +0 -190
  275. package/tests/commands/trace.test.ts +0 -316
  276. package/tests/config-reader.test.ts +0 -143
  277. package/tests/e2e/candidate-intake-e2e.test.ts +0 -338
  278. package/tests/e2e/cli-full-flow.test.ts +0 -233
  279. package/tests/e2e/cross-package-acceptance.test.ts +0 -635
  280. package/tests/helpers/pd-cli-path.ts +0 -5
  281. package/tests/pd-cli-smoke.test.ts +0 -13
  282. package/tests/resolve-workspace.test.ts +0 -196
  283. package/tests/services/config-doctor-signal-health.test.ts +0 -109
  284. package/tests/services/console-launcher.test.ts +0 -114
  285. package/tests/services/demo-rule-compiler.test.ts +0 -242
  286. package/tests/services/mainline-snapshot-assembler.test.ts +0 -572
  287. package/tests/services/pd-config-loader.test.ts +0 -505
  288. package/tests/services/proven-channel-baseline-runner.test.ts +0 -30
  289. package/tests/services/quality-scorecard/strong-model-gate.test.ts +0 -133
  290. package/tests/services/resolve-runtime-from-pd-config.test.ts +0 -485
  291. package/tests/services/rulehost-pipeline-e2e.test.ts +0 -538
  292. package/tests/services/rulehost-pipeline-runner.test.ts +0 -1242
  293. package/tests/services/workspace-tool-semantics.test.ts +0 -76
  294. package/tests/utils/path-security.test.ts +0 -180
  295. package/tsconfig.json +0 -26
  296. package/vitest.config.ts +0 -10
package/src/index.ts DELETED
@@ -1,1276 +0,0 @@
1
- #!/usr/bin/env node
2
- /**
3
- * pd CLI — Principles Disciple command-line interface.
4
- *
5
- * Usage:
6
- * pd pain record --reason <text> [--score N] [--source manual]
7
- */
8
-
9
- import { Command } from 'commander';
10
- import { handlePainRecord } from './commands/pain-record.js';
11
- import { registerPainRetryCommand } from './commands/pain-retry.js';
12
- import { handlePainEvidence } from './commands/pain-evidence.js';
13
- import { handlePainList } from './commands/pain-list.js';
14
- import { handleSamplesList } from './commands/samples-list.js';
15
- import { handleSamplesReview } from './commands/samples-review.js';
16
- import { handleEvolutionTasksList } from './commands/evolution-tasks-list.js';
17
- import { handleEvolutionTasksShow } from './commands/evolution-tasks-show.js';
18
- import { registerHealthCommand } from './commands/health.js';
19
- import { registerVersionCommand } from './commands/version.js';
20
- import { buildVersionReport, formatShortVersion, VersionReportError } from './services/version-report.js';
21
- import { handleTaskShow, registerTaskListCommand } from './commands/task.js';
22
- import { handleRunList, handleRunShow } from './commands/run.js';
23
- import { handleTrajectoryLocate } from './commands/trajectory.js';
24
- import { handleHistoryQuery } from './commands/history.js';
25
- import { handleContextBuild } from './commands/context.js';
26
- import { handleLegacyImportOpenClaw } from './commands/legacy-import.js';
27
- import { handleLegacyCleanup } from './commands/legacy-cleanup.js';
28
- import { handleDiagnoseStatus, handleDiagnoseRun } from './commands/diagnose.js';
29
- import { registerRuntimeProbeCommand } from './commands/runtime.js';
30
- import { handleFlowShow } from './commands/flow.js';
31
- import { handleTraceShow } from './commands/trace.js';
32
- import { handlePruningReport, handlePruningExplain, handlePruningReview, handlePruningRollback, handlePruningOrphans } from './commands/runtime-pruning.js';
33
- import { handleRuntimeHealthSnapshot } from './commands/runtime-health-snapshot.js';
34
- import { handleRuntimeGfiSnapshot } from './commands/runtime-gfi-snapshot.js';
35
- import { handleRuntimeUat } from './commands/runtime-uat.js';
36
- import { handleRuntimeInternalizationQueue } from './commands/runtime-internalization-queue.js';
37
- import { handleRuntimeInternalizationWakeOnce } from './commands/runtime-internalization-wake-once.js';
38
- import { handleRuntimeInternalizationRunOnce } from './commands/runtime-internalization-run-once.js';
39
- import { handleRuntimeInternalizationRetry } from './commands/runtime-internalization-retry.js';
40
- import { registerRunRuleHostCommand } from './commands/runtime-internalization-run-rulehost.js';
41
- import { handleCandidateList, handleCandidateShow, handleCandidateIntake, handleCandidateAudit, handleCandidateRepair, handleCandidateRoute, handleCandidateInternalize, handleCandidateInternalizationBackfill } from './commands/candidate.js';
42
- import { handleArtifactShow } from './commands/artifact.js';
43
- import { handleRuntimeCanary } from './commands/runtime-canary.js';
44
- import { handleRuntimeSyntheticBaseline } from './commands/runtime-synthetic-baseline.js';
45
- import { handleRuntimePainFlood } from './commands/runtime-pain-flood-simulation.js';
46
- import { handleRuntimeInternalizationIntegrity } from './commands/runtime-internalization-integrity.js';
47
- import { handleRuntimeInternalizationIntegrityRepair } from './commands/runtime-internalization-integrity-repair.js';
48
- import { handleRuntimeInternalizationEnqueueSuccessors } from './commands/runtime-internalization-enqueue-successors.js';
49
- import { handleRuntimeDiagnosticsExport } from './commands/runtime-diagnostics-export.js';
50
- import { registerRuntimeCompatibilityScanCommand } from './commands/runtime-compatibility-scan.js';
51
- import { handleRuntimeRecoverySweep } from './commands/runtime-recovery.js';
52
- import { handleRuntimeRecoveryFailedTasks } from './commands/runtime-recovery-failed-tasks.js';
53
- import { handleRuntimeArtifactRepair } from './commands/runtime-artifact-repair.js';
54
- import {
55
- handleRuntimeActivationDeactivate,
56
- handleRuntimeActivationList,
57
- handleRuntimeActivationEdit,
58
- registerRuntimeActivationPromoteCommand,
59
- registerRuntimeActivationDeactivateCommand,
60
- registerRuntimeActivationListCommand,
61
- registerRuntimeActivationDispatchCommand,
62
- registerRuntimeActivationApproveCommand,
63
- } from './commands/runtime-activation.js';
64
- import { handleProvenChannelBaseline } from './commands/proven-channel-baseline.js';
65
- import { handleDemoStoryA } from './commands/demo-story-a.js';
66
- import { handleRuntimeFeaturesStatus } from './commands/runtime-features.js';
67
- import { handleConfigDoctor } from './commands/config-doctor.js';
68
- import { registerMvpCommands } from './commands/mvp-smoke.js';
69
- import { registerRulecodeCommand } from './commands/rulecode.js';
70
- import { registerIntentCommand } from './commands/intent.js';
71
- import { registerErrorsListCommand } from './commands/errors-list.js';
72
- import { registerPrinciplesCommand } from './commands/principles-stats.js';
73
- import { registerTelemetryCommand } from './commands/telemetry.js';
74
-
75
- import { createRequire } from 'module';
76
- const require = createRequire(import.meta.url);
77
- const pkg = require('../package.json') as { version: string };
78
-
79
- const program = new Command();
80
-
81
- // SPEC §12: `pd --version` prints the canonical product version when a
82
- // supported installation exists; a development checkout falls back to the
83
- // CLI package version with an explicit marker instead of impersonating an
84
- // installed release.
85
- function handleVersionFlag(args: readonly string[]): boolean {
86
- if (!args.includes('--version') && !args.includes('-V')) return false;
87
- try {
88
- console.log(formatShortVersion(buildVersionReport()));
89
- return true;
90
- } catch (error) {
91
- if (error instanceof VersionReportError && error.reason === 'not_installed') {
92
- console.log(`Principles Disciple ${pkg.version} (development-checkout)`);
93
- return true;
94
- }
95
- if (error instanceof VersionReportError) {
96
- console.error(error.message);
97
- console.error(`Next: ${error.nextAction}`);
98
- process.exitCode = 1;
99
- return true;
100
- }
101
- throw error;
102
- }
103
- }
104
-
105
- program
106
- .name('pd')
107
- .description('PD CLI — Pain recording, sample management, and evolution task history')
108
- .option('-V, --version', 'output the canonical PD product version')
109
- .enablePositionalOptions();
110
-
111
- registerVersionCommand(program);
112
-
113
- const painCmd = program
114
- .command('pain')
115
- .description('Pain signal management');
116
-
117
- painCmd
118
- .command('record')
119
- .description('Record a pain signal via Runtime v2 bridge')
120
- .option('-r, --reason <text>', 'Reason for the pain signal (required)')
121
- .option('-s, --score <number>', 'Pain score 0-100', parseInt)
122
- .option('-S, --source <text>', 'Source of the pain signal', 'manual')
123
- .option('-w, --workspace <path>', 'Workspace directory')
124
- .option('--session <id>', 'Session ID to bind (validated against this workspace\'s trajectory.db; without it the record is unbound: no trajectory evidence, candidates likely gated by the admission threshold)')
125
- .option('--host <kind>', 'PRI-743: explicit host attribution (openclaw | codex). openclaw = default attribution without the disclosure warning; codex requires the real Codex lineage (--rollout-id, --host-turn-id, and --session as the root session).', undefined)
126
- .option('--rollout-id <id>', 'PRI-743: Codex rollout identity — required by --host codex', undefined)
127
- .option('--host-turn-id <id>', 'PRI-743: Codex turn id — required by --host codex', undefined)
128
- .option('--logical-key <key>', 'PRI-743: Codex logical observation key override for --host codex (default: codex|<rollout-id>|<host-turn-id>|user)', undefined)
129
- .option('--wait', 'Wait for diagnosis to complete (sync mode, overrides async flag)')
130
- .option('--json', 'Output raw JSON')
131
- .action(async (opts) => {
132
- await handlePainRecord(opts);
133
- });
134
-
135
- registerPainRetryCommand(painCmd);
136
-
137
- painCmd
138
- .command('list')
139
- .description('List canonical pain events with host attribution (PRI-640)')
140
- .option('-w, --workspace <path>', 'Workspace directory')
141
- .option('-l, --limit <number>', 'Max entries to show (default: 20)', parseInt)
142
- .option('--host <kind>', 'Filter by host: openclaw | codex | unknown')
143
- .option('--json', 'Output raw JSON')
144
- .action(async (opts) => {
145
- await handlePainList(opts);
146
- });
147
-
148
- painCmd
149
- .command('evidence')
150
- .description('Show recent TRIGGER_DECISION log entries — pain admission gate decisions only (PEAT-B2)')
151
- .option('-w, --workspace <path>', 'Workspace directory')
152
- .option('-l, --limit <number>', 'Max entries to show (default: 20)', parseInt)
153
- .option('--json', 'Output raw JSON')
154
- .action(async (opts) => {
155
- await handlePainEvidence(opts);
156
- });
157
-
158
- const samplesCmd = program
159
- .command('samples', { hidden: true })
160
- .description('Correction sample management');
161
-
162
- samplesCmd
163
- .command('list')
164
- .description('List correction samples')
165
- .option('-s, --status <pending|approved|rejected>', 'Filter by review status', 'pending')
166
- .action(async (opts) => {
167
- await handleSamplesList(opts);
168
- });
169
-
170
- samplesCmd
171
- .command('review')
172
- .description('Review a correction sample')
173
- .argument('<sample-id>', 'The sample ID to review')
174
- .argument('<approve|reject>', 'Review decision')
175
- .argument('[note]', 'Optional review note')
176
- .action(async (sampleId, decision, note) => {
177
- if (decision !== 'approve' && decision !== 'reject') {
178
- console.error('Error: decision must be "approve" or "reject"');
179
- process.exit(1);
180
- }
181
- await handleSamplesReview({ sampleId, decision: decision === 'approve' ? 'approved' : 'rejected', note });
182
- });
183
-
184
- // ── Evolution task reader (hidden) ────────────────────────────────────────────
185
- // PRI-752 review: the worker is gone (flag retired to `gone`), but this
186
- // read-only surface stays for historical `evolution_tasks` rows in already-
187
- // provisioned workspaces — data-retention disposition is a separate Owner
188
- // decision (PRI-737 reality audit §7.3). Table schema + quality-scorecard
189
- // reader are retained accordingly.
190
- const evolutionCmd = program
191
- .command('evolution', { hidden: true })
192
- .description('Evolution task management (historical data reader)');
193
-
194
- const tasksCmd = evolutionCmd
195
- .command('tasks')
196
- .description('List and show evolution tasks');
197
-
198
- tasksCmd
199
- .command('list')
200
- .description('List evolution tasks')
201
- .option('-s, --status <status>', 'Filter by status (pending|in_progress|completed|all)', 'all')
202
- .option('-l, --limit <number>', 'Maximum tasks to return', parseInt, 50)
203
- .option('-f, --date-from <date>', 'Filter tasks created on or after this date')
204
- .option('-t, --date-to <date>', 'Filter tasks created on or before this date')
205
- .action(async (opts) => {
206
- await handleEvolutionTasksList(opts);
207
- });
208
-
209
- tasksCmd
210
- .command('show')
211
- .description('Show full details for an evolution task')
212
- .argument('<id>', 'Task ID (numeric or string taskId)')
213
- .action(async (id, _opts) => {
214
- await handleEvolutionTasksShow({ id });
215
- });
216
-
217
- registerHealthCommand(program);
218
-
219
- // ── Anonymous Product Telemetry v1 control plane (PRI-595~603) ────────────────
220
-
221
- registerTelemetryCommand(program);
222
-
223
- // ── Runtime v2 task/run commands ──────────────────────────────────────────────鈹€鈹€鈹€鈹€鈹€鈹€
224
-
225
- const rtTaskCmd = program
226
- .command('task')
227
- .description('Runtime v2 task inspection');
228
-
229
- registerTaskListCommand(rtTaskCmd);
230
-
231
- rtTaskCmd
232
- .command('show <taskId>')
233
- .description('Show detailed task information')
234
- .option('-w, --workspace <path>', 'Workspace directory')
235
- .option('--json', 'Output raw JSON')
236
- .action(async (taskId, opts) => {
237
- await handleTaskShow({ id: taskId, json: opts.json, workspace: opts.workspace });
238
- });
239
-
240
- const rtRunCmd = program
241
- .command('run', { hidden: true })
242
- .description('Runtime v2 run inspection');
243
-
244
- rtRunCmd
245
- .command('list <taskId>')
246
- .description('List all runs for a task')
247
- .action(async (taskId) => {
248
- await handleRunList({ taskId });
249
- });
250
-
251
- rtRunCmd
252
- .command('show <runId>')
253
- .description('Show detailed run information')
254
- .action(async (runId) => {
255
- await handleRunShow({ id: runId });
256
- });
257
-
258
- // ── Runtime v2 trajectory/history/context commands ────────────────────────────鈹€鈹€
259
-
260
- const trajectoryCmd = program
261
- .command('trajectory', { hidden: true })
262
- .description('Runtime v2 trajectory location');
263
-
264
- trajectoryCmd
265
- .command('locate')
266
- .description('Locate a trajectory by task ID, run ID, or time range')
267
- .option('-t, --task <taskId>', 'Locate by task ID')
268
- .option('-r, --run <runId>', 'Locate by run ID')
269
- .option('--from <date>', 'Start of time range (ISO string)')
270
- .option('--to <date>', 'End of time range (ISO string)')
271
- .option('-w, --workspace <path>', 'Workspace directory')
272
- .option('--json', 'Output raw JSON')
273
- .action(async (opts) => {
274
- await handleTrajectoryLocate(opts);
275
- });
276
-
277
- const historyCmd = program
278
- .command('history', { hidden: true })
279
- .description('Runtime v2 history query');
280
-
281
- historyCmd
282
- .command('query <taskId>')
283
- .description('Query run history for a task')
284
- .option('-l, --limit <number>', 'Limit number of entries', parseInt)
285
- .option('-c, --cursor <cursor>', 'Pagination cursor')
286
- .option('--from <date>', 'Start of time range (ISO string)')
287
- .option('--to <date>', 'End of time range (ISO string)')
288
- .option('-w, --workspace <path>', 'Workspace directory')
289
- .option('--json', 'Output raw JSON')
290
- .action(async (taskId, opts) => {
291
- await handleHistoryQuery(taskId, opts);
292
- });
293
-
294
- const contextCmd = program
295
- .command('context', { hidden: true })
296
- .description('Runtime v2 context assembly');
297
-
298
- contextCmd
299
- .command('build <taskId>')
300
- .description('Assemble diagnostician context for a task')
301
- .option('-w, --workspace <path>', 'Workspace directory')
302
- .option('--json', 'Output raw JSON')
303
- .action(async (taskId, opts) => {
304
- await handleContextBuild(taskId, opts);
305
- });
306
-
307
- // ── Legacy import command ──────────────────────────────────────────────────────鈹€鈹€鈹€鈹€鈹€鈹€鈹€
308
-
309
- const legacyCmd = program
310
- .command('legacy', { hidden: true })
311
- .description('Legacy data management (import and cleanup)');
312
-
313
- const importCmd = legacyCmd.command('import');
314
- importCmd
315
- .command('openclaw')
316
- .description(
317
- 'Import OpenClaw legacy data into PD Runtime v2 SQLite. ' +
318
- 'Run this once per workspace before using trajectory/history/context commands.',
319
- )
320
- .option('-w, --workspace <path>', 'Workspace directory (required)')
321
- .option('--json', 'Output raw JSON')
322
- .action(async (opts) => {
323
- await handleLegacyImportOpenClaw(opts);
324
- });
325
-
326
- // ── Diagnostician run/status commands ─────────────────────────────────────────鈹€鈹€鈹€鈹€
327
-
328
- const diagnoseCmd = program
329
- .command('diagnose')
330
- .description('Diagnostician execution and status inspection');
331
-
332
- diagnoseCmd
333
- .command('status')
334
- .description('Inspect diagnostician task status')
335
- .requiredOption('-t, --task-id <taskId>', 'Task ID to inspect')
336
- .option('-w, --workspace <path>', 'Workspace directory')
337
- .option('--stalled-threshold <seconds>', 'Age threshold in seconds for classifying task as stalled')
338
- .option('--json', 'Output raw JSON')
339
- .action(async (opts) => {
340
- await handleDiagnoseStatus(opts);
341
- });
342
-
343
- diagnoseCmd
344
- .command('run')
345
- .description('Execute diagnostician runner for a task')
346
- .requiredOption('-t, --task-id <taskId>', 'Task ID to execute')
347
- .option('-w, --workspace <path>', 'Workspace directory')
348
- .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).")
349
- .option('--openclaw-local', 'Use local OpenClaw (mutually exclusive with --openclaw-gateway)')
350
- .option('--openclaw-gateway', 'Use gateway OpenClaw (mutually exclusive with --openclaw-local)')
351
- .option('-a, --agent <agentId>', 'Agent ID to invoke')
352
- .option('--provider <name>', 'LLM provider (e.g., openrouter) — for pi-ai, falls back to policy')
353
- .option('--model <id>', 'Model ID (e.g., anthropic/claude-sonnet-4) — for pi-ai, falls back to policy')
354
- .option('--apiKeyEnv <name>', 'Env var name for API key — for pi-ai, falls back to policy')
355
- .option('--baseUrl <url>', 'Custom base URL — for pi-ai, falls back to policy')
356
- .option('--maxRetries <n>', 'Max retry attempts for LLM failures — for pi-ai, falls back to policy', parseInt)
357
- .option('--timeoutMs <ms>', 'Timeout in milliseconds — for pi-ai, falls back to policy', parseInt)
358
- .option('--no-intake', 'Skip candidate intake after successful diagnosis')
359
- .option('--json', 'Output raw JSON')
360
- .action(async (opts) => {
361
- await handleDiagnoseRun(opts);
362
- });
363
-
364
- // ── Runtime probe command (HG-01 HARD GATE) ───────────────────────────────────鈹€鈹€鈹€鈹€
365
-
366
- const runtimeCmd = program
367
- .command('runtime')
368
- .description('Runtime inspection and health checks');
369
-
370
- runtimeCmd
371
- .command('canary', { hidden: true })
372
- .description('One-shot control plane health canary')
373
- .option('-w, --workspace <path>', 'Workspace directory')
374
- .option('--json', 'Output raw JSON')
375
- .action(async (opts) => {
376
- await handleRuntimeCanary({ workspace: opts.workspace, json: opts.json });
377
- });
378
-
379
- // pd runtime init — Initialize all PD SQLite databases for a workspace.
380
- // Lazy import: avoids loading `principles-disciple` at module init time, which
381
- // would crash `pd --version` in packaged installs where the plugin's transitive
382
- // deps are not resolvable from pd-cli's node_modules. The import only executes
383
- // when `pd runtime init` is actually invoked.
384
- runtimeCmd
385
- .command('init')
386
- .description('Initialize all PD SQLite databases (state.db, trajectory.db)')
387
- .option('-w, --workspace <path>', 'Workspace directory')
388
- .option('--dry-run', 'Show what would be initialized without writing (default)')
389
- .option('--confirm', 'Actually initialize the databases (required to write)')
390
- .option('--json', 'Output raw JSON')
391
- .action(async (opts) => {
392
- const { handleRuntimeInit } = await import('./commands/runtime-init.js');
393
- await handleRuntimeInit({
394
- workspace: opts.workspace,
395
- dryRun: opts.dryRun === true,
396
- confirm: opts.confirm === true,
397
- json: opts.json === true,
398
- });
399
- });
400
-
401
- registerRuntimeCompatibilityScanCommand(runtimeCmd);
402
-
403
- const synthCmd = runtimeCmd
404
- .command('synthetic', { hidden: true })
405
- .description('Synthetic workload baseline commands');
406
-
407
- synthCmd
408
- .command('baseline')
409
- .description('Run synthetic PD workload baseline (PRI-206) — deterministic, no LLM required')
410
- .option('-w, --workspace <path>', 'Workspace directory (default: temp workspace)')
411
- .option('--json', 'Output raw JSON')
412
- .action(async (opts) => {
413
- await handleRuntimeSyntheticBaseline({ workspace: opts.workspace, json: opts.json });
414
- });
415
-
416
- synthCmd
417
- .command('flood')
418
- .description('Run pain flood simulation (PRI-208) — deterministic dedup/stress test, no LLM required')
419
- .option('-w, --workspace <path>', 'Workspace directory (default: temp workspace)')
420
- .option('--json', 'Output raw JSON')
421
- .option('--identical-count <n>', 'Number of identical pain signals (default: 10)', parseInt)
422
- .option('--similar-count <n>', 'Number of similar pain signals (default: 10)', parseInt)
423
- .option('--stress-count <n>', 'Number of stress test pain signals (default: 50)', parseInt)
424
- .action(async (opts) => {
425
- await handleRuntimePainFlood({
426
- workspace: opts.workspace,
427
- json: opts.json,
428
- identicalCount: opts.identicalCount,
429
- similarCount: opts.similarCount,
430
- stressCount: opts.stressCount,
431
- });
432
- });
433
-
434
- synthCmd
435
- .command('proven-channel')
436
- .description('Run MVP activation continuity baseline (PRI-240) — deterministic, no LLM required')
437
- .option('-w, --workspace <path>', 'Workspace directory (default: temp workspace)')
438
- .option('--json', 'Output raw JSON')
439
- .option('--channels <channels>', 'Comma-separated channel list (prompt,code_tool_hook,defer_archive)')
440
- .action(async (opts) => {
441
- await handleProvenChannelBaseline({
442
- workspace: opts.workspace,
443
- json: opts.json,
444
- channels: opts.channels,
445
- });
446
- });
447
-
448
- runtimeCmd
449
- .command('features')
450
- .description('Show feature flag status (PRI-239)')
451
- .option('-w, --workspace <path>', 'Workspace directory')
452
- .option('--json', 'Output raw JSON')
453
- .action(async (opts) => {
454
- await handleRuntimeFeaturesStatus({
455
- workspace: opts.workspace,
456
- json: opts.json,
457
- });
458
- });
459
-
460
- // ── PRI-455: Promoted owner commands (trace + activation) ────────────────────
461
- // These are promoted from runtime subcommands to top-level for discoverability.
462
- // The old paths (pd runtime trace show, pd runtime activation list) remain as
463
- // hidden aliases — they still work but are not shown in --help.
464
-
465
- const traceTopCmd = program
466
- .command('trace')
467
- .description('Trace full pain-to-ledger chain (Story A\' Step 6: Observe)');
468
-
469
- traceTopCmd
470
- .command('show')
471
- .description('Show full trace for a pain ID')
472
- .requiredOption('--pain-id <id>', 'Pain ID to trace')
473
- .option('-w, --workspace <path>', 'Workspace directory')
474
- .option('--json', 'Output raw JSON')
475
- .action(async (opts) => {
476
- await handleTraceShow({ painId: opts.painId, workspace: opts.workspace, json: opts.json });
477
- });
478
-
479
- const activationTopCmd = program
480
- .command('activation')
481
- .description('Activation management — list active activations, deactivate (Story A\' Steps 5-6)');
482
-
483
- registerRuntimeActivationListCommand(activationTopCmd);
484
-
485
- registerRuntimeActivationDeactivateCommand(activationTopCmd);
486
-
487
- // Bug-M fix: CLI closed loop — approve a pending approval and dispatch its activation.
488
- // Reuses the same ApprovalQueue + ApprovalCompletionService as the Console model.
489
- registerRuntimeActivationApproveCommand(activationTopCmd);
490
-
491
- registerRuntimeActivationPromoteCommand(activationTopCmd);
492
-
493
- const configCmd = program
494
- .command('config')
495
- .description('PD configuration discovery and diagnosis');
496
-
497
- configCmd
498
- .command('doctor')
499
- .description('Show PD + OpenClaw config locations, feature flags, and provider connectivity (PRI-299)')
500
- .option('-w, --workspace <path>', 'Workspace directory')
501
- .option('--json', 'Output raw JSON')
502
- .action(async (opts) => {
503
- await handleConfigDoctor({ workspace: opts.workspace, json: opts.json });
504
- });
505
-
506
- const demoCmd = program
507
- .command('demo', { hidden: true })
508
- .description('Demo scenarios for MVP validation');
509
-
510
- demoCmd
511
- .command('story-a')
512
- .alias('first-principle')
513
- .description('Run Story A\'s proven-channel demo (PRI-246) — full evidence→proposal→approval→activation→observation chain')
514
- .option('-w, --workspace <path>', 'Workspace directory (default: temp workspace)')
515
- .option('--json', 'Output raw JSON')
516
- .option('--channels <channels>', 'Comma-separated channel list (prompt,code_tool_hook,defer_archive)')
517
- .option('--allow-demo-write-to-existing-workspace', 'Developer override: permit writing demo artifacts into a workspace that already contains PD state (demo isolation guard)')
518
- .action(async (opts) => {
519
- await handleDemoStoryA({
520
- workspace: opts.workspace,
521
- json: opts.json,
522
- channels: opts.channels,
523
- allowDemoWriteToExistingWorkspace: opts.allowDemoWriteToExistingWorkspace === true,
524
- });
525
- });
526
-
527
- registerRuntimeProbeCommand(runtimeCmd);
528
-
529
- const flowCmd = runtimeCmd
530
- .command('flow', { hidden: true })
531
- .description('Workflow funnel inspection');
532
-
533
- flowCmd
534
- .command('show')
535
- .description('Show all workflow funnel definitions from workflows.yaml')
536
- .option('-w, --workspace <path>', 'Workspace directory')
537
- .option('--json', 'Output raw JSON')
538
- .action(async (opts) => {
539
- await handleFlowShow(opts);
540
- });
541
-
542
- const traceCmd = runtimeCmd
543
- .command('trace', { hidden: true })
544
- .description('Trace full pain-to-ledger chain (hidden alias — use pd trace show)');
545
-
546
- traceCmd
547
- .command('show')
548
- .description('Show full trace for a pain ID')
549
- .requiredOption('--pain-id <id>', 'Pain ID to trace')
550
- .option('-w, --workspace <path>', 'Workspace directory')
551
- .option('--json', 'Output raw JSON')
552
- .action(async (opts) => {
553
- await handleTraceShow({ painId: opts.painId, workspace: opts.workspace, json: opts.json });
554
- });
555
-
556
- runtimeCmd
557
- .command('uat', { hidden: true })
558
- .description('Runtime V2 chain UAT baseline runner')
559
- .option('-w, --workspace <path>', 'Workspace directory')
560
- .option('--count <n>', 'Number of iterations (default: 5, max: 50)', parseInt)
561
- .option('--min-success-rate <rate>', 'Minimum success rate threshold (default: 1.0)', parseFloat)
562
- .option('--json', 'Output machine-readable JSON summary')
563
- .option('--allow-production-workspace-for-uat', 'DANGEROUS: Allow UAT to write to production workspace (NOT RECOMMENDED)')
564
- .action(async (opts) => {
565
- await handleRuntimeUat({
566
- workspace: opts.workspace,
567
- count: opts.count,
568
- minSuccessRate: opts.minSuccessRate,
569
- json: opts.json,
570
- allowProductionWorkspaceForUat: opts.allowProductionWorkspaceForUat,
571
- });
572
- });
573
-
574
- const runtimeHealthCmd = runtimeCmd
575
- .command('health', { hidden: true })
576
- .description('Runtime V2 health inspection');
577
-
578
- runtimeHealthCmd
579
- .command('snapshot')
580
- .description('Operator health snapshot combining chain, ledger, and pruning status')
581
- .option('-w, --workspace <path>', 'Workspace directory')
582
- .option('--json', 'Output raw JSON')
583
- .action(async (opts) => {
584
- await handleRuntimeHealthSnapshot({ workspace: opts.workspace, json: opts.json });
585
- });
586
-
587
- // ── pd codex reconcile — Codex governance continuation recovery ───────────────
588
- // Codex Governance Closure Slice B (PRI-623, SPEC §13/§20): runs the idempotent
589
- // cross-store reconciliation pass (admitted pain → missing Diagnostician task,
590
- // task-before-link, pending promotion tails) exposed for the CLI now and the
591
- // Slice C Companion worker later.
592
- const codexCmd = program
593
- .command('codex')
594
- .description('Codex host governance operations');
595
-
596
- // ── pd codex setup — consent UX for conversation ingestion (Slice D) ─────────
597
- // PRI-625, SPEC rev 2 §17 + G2A frozen disclosure: the ONE authority that can
598
- // enable codex_conversation_ingestion — presents the frozen disclosure and
599
- // records the explicit Owner decision BEFORE flipping the flag. Declining
600
- // leaves all existing governance unchanged and reads no transcript.
601
- codexCmd
602
- .command('setup')
603
- .description('Present the frozen ingestion disclosure and record the explicit consent decision (accept enables codex_conversation_ingestion; decline keeps everything off)')
604
- .option('-w, --workspace <path>', 'Workspace directory')
605
- .option('--accept', 'Explicitly accept after the disclosure has been presented (non-interactive)')
606
- .option('--decline', 'Explicitly decline; the ingestion flag stays off and no transcript is ever read')
607
- .option('--show-disclosure', 'Print the frozen disclosure text (zh default, --lang en) and exit without mutating anything')
608
- .option('--lang <zh|en>', 'Disclosure language for presentation', undefined)
609
- .option('--json', 'Output raw JSON (decision must be explicit: --accept or --decline)')
610
- .action(async (opts) => {
611
- const { handleCodexSetup } = await import('./commands/codex-setup.js');
612
- await handleCodexSetup({
613
- workspace: opts.workspace,
614
- json: opts.json === true,
615
- accept: opts.accept === true,
616
- decline: opts.decline === true,
617
- showDisclosure: opts.showDisclosure === true,
618
- ...(typeof opts.lang === 'string' ? { lang: opts.lang } : {}),
619
- });
620
- });
621
-
622
- codexCmd
623
- .command('reconcile')
624
- .description('Reconcile admitted Codex pains with Diagnostician tasks and promotion tails (idempotent)')
625
- .option('-w, --workspace <path>', 'Workspace directory')
626
- .option('--limit <n>', 'Maximum admitted pains to reconcile per pass (1-200, default 50)')
627
- .option('--json', 'Output raw JSON')
628
- .action(async (opts) => {
629
- const { handleCodexReconcile } = await import('./commands/codex-reconcile.js');
630
- const limit = typeof opts.limit === 'string' ? Number.parseInt(opts.limit, 10) : undefined;
631
- await handleCodexReconcile({
632
- workspace: opts.workspace,
633
- json: opts.json === true,
634
- ...(limit !== undefined && Number.isInteger(limit) ? { limit } : {}),
635
- });
636
- });
637
-
638
- // ── pd codex ingest catch-up — bounded manual transcript lag recovery ────────
639
- // Codex Governance Closure Slice C (PRI-624, SPEC §15): the manual-mode
640
- // counterpart of the Companion worker's catch-up step. Zero transcript I/O
641
- // when codex_conversation_ingestion is disabled.
642
- const codexIngestCmd = codexCmd
643
- .command('ingest')
644
- .description('Codex conversation-ingestion operations');
645
-
646
- codexIngestCmd
647
- .command('catch-up')
648
- .description('Catch up transcript lag from durable checkpoints (bounded, non-destructive, no LLM)')
649
- .option('-w, --workspace <path>', 'Workspace directory')
650
- .option('--max-rollouts <n>', 'Maximum rollouts to catch up per pass (1-32, default 8)')
651
- .option('--json', 'Output raw JSON')
652
- .action(async (opts) => {
653
- const { handleCodexIngestCatchUp } = await import('./commands/codex-ingest-catchup.js');
654
- const maxRollouts = typeof opts.maxRollouts === 'string' ? Number.parseInt(opts.maxRollouts, 10) : undefined;
655
- await handleCodexIngestCatchUp({
656
- workspace: opts.workspace,
657
- json: opts.json === true,
658
- ...(maxRollouts !== undefined && Number.isInteger(maxRollouts) ? { maxRollouts } : {}),
659
- });
660
- });
661
-
662
- // ── pd codex ingest quarantine — audited recovery for invalid records ────────
663
- // Codex Governance Closure Slice D (PRI-625, SPEC §15): dry-run by default,
664
- // --confirm required to mutate; records digest/reason/operator/timestamp/gap;
665
- // never edits the Codex transcript; promoted evidence is refused.
666
- codexIngestCmd
667
- .command('quarantine')
668
- .description('Quarantine a permanently invalid governance observation (dry-run by default; --confirm to apply; never touches the transcript)')
669
- .option('-w, --workspace <path>', 'Workspace directory')
670
- .option('--rollout <id>', 'Rollout identity that owns the record (required)')
671
- .option('--record <id>', 'Numeric governance_observations.id to quarantine (required)')
672
- .option('--reason <text>', 'Why the record is permanently invalid, 1-200 chars (required)')
673
- .option('--operator <id>', 'Operator identity recorded in the audit metadata (default: current OS user)')
674
- .option('--confirm', 'Apply the quarantine; without this flag the command is a dry run')
675
- .option('--json', 'Output raw JSON')
676
- .action(async (opts) => {
677
- const { handleCodexIngestQuarantine } = await import('./commands/codex-ingest-quarantine.js');
678
- await handleCodexIngestQuarantine({
679
- workspace: opts.workspace,
680
- rollout: opts.rollout,
681
- record: opts.record,
682
- reason: opts.reason,
683
- ...(typeof opts.operator === 'string' ? { operator: opts.operator } : {}),
684
- confirm: opts.confirm === true,
685
- json: opts.json === true,
686
- });
687
- });
688
-
689
- // ── pd codex worker — Workspace-scoped governance worker ─────────────────────
690
- // Codex Governance Closure Slice C (PRI-624, SPEC §13; ADR-0020 §11.1): the
691
- // one Owner-approved background worker (catch-up → reconciliation → one
692
- // Diagnostician execution → one bounded downstream consumer cycle). The
693
- // Companion spawns this per registered workspace; --once is the manual and
694
- // supervised-restart form.
695
- codexCmd
696
- .command('worker')
697
- .description('Run the Codex workspace governance worker (catch-up, reconciliation, diagnostician, downstream)')
698
- .option('-w, --workspace <path>', 'Workspace directory')
699
- .option('--once', 'Run exactly one bounded cycle and exit')
700
- .option('--interval <ms>', 'Cycle interval for continuous mode (default 120000, minimum 1000)')
701
- .option('--status', 'Report the SPEC §15 worker mode without executing anything')
702
- .option('--json', 'Output raw JSON')
703
- .action(async (opts) => {
704
- const { handleCodexWorker } = await import('./commands/codex-worker.js');
705
- const intervalMs = typeof opts.interval === 'string' ? Number.parseInt(opts.interval, 10) : undefined;
706
- await handleCodexWorker({
707
- workspace: opts.workspace,
708
- json: opts.json === true,
709
- once: opts.once === true,
710
- status: opts.status === true,
711
- ...(intervalMs !== undefined && Number.isInteger(intervalMs) ? { intervalMs } : {}),
712
- });
713
- });
714
-
715
- runtimeHealthCmd
716
- .command('gfi')
717
- .description('GFI workspace snapshot — active vs stale session breakdown')
718
- .option('-w, --workspace <path>', 'Workspace directory')
719
- .option('--json', 'Output raw JSON')
720
- .action(async (opts) => {
721
- await handleRuntimeGfiSnapshot({ workspace: opts.workspace, json: opts.json });
722
- });
723
-
724
- const internalizationCmd = runtimeCmd
725
- .command('internalization')
726
- .description('Internalization Engine operator visibility');
727
-
728
- internalizationCmd
729
- .command('queue')
730
- .description('Show PI task queue health snapshot')
731
- .option('-w, --workspace <path>', 'Workspace directory')
732
- .option('--json', 'Output raw JSON')
733
- .action(async (opts) => {
734
- await handleRuntimeInternalizationQueue({ workspace: opts.workspace, json: opts.json });
735
- });
736
-
737
- internalizationCmd
738
- .command('wake-once')
739
- .description('Dry-run lease evaluation for the next leasable PI task')
740
- .option('-w, --workspace <path>', 'Workspace directory')
741
- .option('--dry-run', 'Evaluate lease without acquiring (required)', false)
742
- .option('--json', 'Output raw JSON')
743
- .action(async (opts) => {
744
- await handleRuntimeInternalizationWakeOnce({ workspace: opts.workspace, dryRun: opts.dryRun, json: opts.json });
745
- });
746
-
747
- internalizationCmd
748
- .command('retry')
749
- .description('Requeue a needs_human_review task (owner attention queue out-edge)')
750
- .option('-w, --workspace <path>', 'Workspace directory')
751
- .requiredOption('--task <taskId>', 'Task id to requeue')
752
- .option('--confirm', 'Actually requeue (default is dry-run)')
753
- .option('--json', 'Output as JSON')
754
- .action(async (opts) => {
755
- await handleRuntimeInternalizationRetry({ workspace: opts.workspace, taskId: opts.task, confirm: opts.confirm, json: opts.json });
756
- });
757
-
758
- internalizationCmd
759
- .command('run-once')
760
- .description('Wake-and-run: lease the next PI task and execute it')
761
- .option('-w, --workspace <path>', 'Workspace directory')
762
- .option('--runner <kind>', 'Runner kind to execute (default: dreamer)', 'dreamer')
763
- .option('--runtime <kind>', 'Runtime adapter kind: config (from workflows.yaml), pi-ai, openclaw-cli, test-double (default: config)', 'config')
764
- .option('--allow-test-double', 'Acknowledge that test-double runtime will mutate real queue state')
765
- .option('--no-enqueue-next', 'Skip successor enqueue after successful runner (default: auto-enqueue)')
766
- .option('--timeout-ms <ms>', 'Runner timeout in milliseconds (default: 300000, overrides workflows.yaml)', parseInt)
767
- .option('--json', 'Output raw JSON')
768
- .action(async (opts) => {
769
- await handleRuntimeInternalizationRunOnce({ workspace: opts.workspace, json: opts.json, runtime: opts.runtime, runner: opts.runner, allowTestDouble: opts.allowTestDouble, enqueueNext: opts.enqueueNext, timeoutMs: opts.timeoutMs });
770
- });
771
-
772
- registerRunRuleHostCommand(internalizationCmd);
773
-
774
- internalizationCmd
775
- .command('integrity')
776
- .description('Check internalization chain integrity')
777
- .option('-w, --workspace <path>', 'Workspace directory')
778
- .option('--json', 'Output raw JSON')
779
- .action(async (opts) => {
780
- await handleRuntimeInternalizationIntegrity({ workspace: opts.workspace, json: opts.json });
781
- });
782
-
783
- internalizationCmd
784
- .command('integrity-repair')
785
- .description('Repair broken internalization chain links (operator repair path)')
786
- .option('-w, --workspace <path>', 'Workspace directory')
787
- .option('--dry-run', 'Report only, no modifications')
788
- .option('--confirm', 'Actually repair broken links')
789
- .option('--json', 'Output raw JSON')
790
- .action(async (opts) => {
791
- await handleRuntimeInternalizationIntegrityRepair({ workspace: opts.workspace, confirm: opts.confirm, dryRun: opts.dryRun, json: opts.json });
792
- });
793
-
794
- internalizationCmd
795
- .command('enqueue-successors')
796
- .description('Enqueue successor tasks for succeeded internalization tasks missing successors')
797
- .option('-w, --workspace <path>', 'Workspace directory')
798
- .option('--dry-run', 'Report only, no modifications (default)')
799
- .option('--confirm', 'Actually create successor tasks')
800
- .option('--json', 'Output raw JSON')
801
- .action(async (opts) => {
802
- await handleRuntimeInternalizationEnqueueSuccessors({ workspace: opts.workspace, dryRun: opts.dryRun, confirm: opts.confirm, json: opts.json });
803
- });
804
-
805
- const activationCmd = runtimeCmd
806
- .command('activation', { hidden: true })
807
- .description('Activation dispatch operations (hidden — use pd activation for list/deactivate)');
808
-
809
- registerRuntimeActivationDispatchCommand(activationCmd);
810
-
811
- // PRI-408 Contract E: Owner-initiated rollback/deactivate of an activation.
812
- // Idempotent — calling twice on the same ID is safe and returns ok=false with reason.
813
- activationCmd
814
- .command('deactivate')
815
- .description('Deactivate (rollback) an active activation — idempotent (PRI-408 Contract E)')
816
- .option('-a, --activation-id <id>', 'Activation ID to deactivate')
817
- .option('-w, --workspace <path>', 'Workspace directory')
818
- .option('--json', 'Output raw JSON')
819
- .action(async (opts) => {
820
- await handleRuntimeActivationDeactivate({
821
- workspace: opts.workspace,
822
- activationId: opts.activationId,
823
- json: opts.json,
824
- });
825
- });
826
-
827
- // PRI-408 Contract D: Owner observability — list current activations.
828
- activationCmd
829
- .command('list')
830
- .description('List activations (default: active only) — PRI-408 Contract D observability')
831
- .option('-w, --workspace <path>', 'Workspace directory')
832
- .option('-c, --channel <channel>', 'Filter by channel (prompt|code_tool_hook)')
833
- .option('--include-deactivated', 'Include deactivated records in output')
834
- .option('--json', 'Output raw JSON')
835
- .action(async (opts) => {
836
- await handleRuntimeActivationList({
837
- workspace: opts.workspace,
838
- channel: opts.channel,
839
- includeDeactivated: opts.includeDeactivated,
840
- json: opts.json,
841
- });
842
- });
843
-
844
- // P1 #2 fix: Owner edit entry point — swap a pending approval's artifact.
845
- // Required because ApprovalQueue.edit() was dead code with no CLI/OpenClaw entry.
846
- // P2 #5: use .option() instead of .requiredOption() so missing-flag errors
847
- // produce structured JSON output via the handler, not Commander's pre-handler exit.
848
- activationCmd
849
- .command('edit')
850
- .description('Edit a pending approval to swap its artifact — P1 #2 owner edit entry point')
851
- .option('-a, --approval-id <id>', 'Approval ID to edit (must be pending)')
852
- .option('-n, --new-artifact-id <id>', 'New PIArtifact ID to swap to')
853
- .option('-r, --edit-reason <text>', 'Reason for the edit')
854
- .option('-w, --workspace <path>', 'Workspace directory')
855
- .option('--json', 'Output raw JSON')
856
- .action(async (opts) => {
857
- await handleRuntimeActivationEdit({
858
- workspace: opts.workspace,
859
- approvalId: opts.approvalId,
860
- newArtifactId: opts.newArtifactId,
861
- editReason: opts.editReason,
862
- json: opts.json,
863
- });
864
- });
865
-
866
- const diagnosticsCmd = runtimeCmd
867
- .command('diagnostics', { hidden: true })
868
- .description('Control plane diagnostic bundle operations');
869
-
870
- // PRI-674: visible (was hidden) — the only recovery re-entry point for an
871
- // Owner without Console access; hidden-ness left failed diagnostician tasks
872
- // undiscoverable.
873
- const recoveryCmd = runtimeCmd
874
- .command('recovery')
875
- .description('Runtime V2 recovery operations (expired-lease sweep, failed-task recovery)');
876
-
877
- // PRI-555 phase 1: dry-run-only artifact identity drift repair planner.
878
- runtimeCmd
879
- .command('artifact-repair')
880
- .description('Plan repairs for unreachable scribe artifacts (dry-run only; writes migration-plan.json, never modifies state.db)')
881
- .option('-w, --workspace <path>', 'Workspace directory')
882
- .option('--dry-run', 'Build migration-plan.json only (default)')
883
- .option('--confirm', 'Not implemented in this phase — refused')
884
- .option('--out <path>', 'Output path for migration-plan.json (default: ./migration-plan.json)')
885
- .option('--json', 'Output raw JSON')
886
- .action(async (opts) => {
887
- await handleRuntimeArtifactRepair({
888
- workspace: opts.workspace,
889
- dryRun: opts.dryRun,
890
- confirm: opts.confirm,
891
- out: opts.out,
892
- json: opts.json,
893
- });
894
- });
895
-
896
-
897
- recoveryCmd
898
- .command('sweep')
899
- .description('Detect and optionally recover expired leases')
900
- .option('-w, --workspace <path>', 'Workspace directory')
901
- .option('--dry-run', 'Report only, no modifications (default)')
902
- .option('--confirm', 'Actually recover expired leases')
903
- .option('--json', 'Output raw JSON')
904
- .action(async (opts) => {
905
- await handleRuntimeRecoverySweep({ workspace: opts.workspace, dryRun: opts.dryRun, confirm: opts.confirm, json: opts.json });
906
- });
907
-
908
- recoveryCmd
909
- .command('failed-tasks')
910
- .description('Recover failed internalization and diagnostician tasks')
911
- .option('-w, --workspace <path>', 'Workspace directory')
912
- .option('--dry-run', 'Report only, no modifications (default)')
913
- .option('--confirm', 'Actually recover failed tasks')
914
- .option('--force', 'Force recovery of tasks that exhausted max attempts')
915
- .option('--json', 'Output raw JSON')
916
- .action(async (opts) => {
917
- await handleRuntimeRecoveryFailedTasks({
918
- workspace: opts.workspace,
919
- dryRun: opts.dryRun,
920
- confirm: opts.confirm,
921
- force: opts.force,
922
- json: opts.json,
923
- });
924
- });
925
-
926
- diagnosticsCmd
927
- .command('export')
928
- .description('Export diagnostic bundle for AI assistant analysis')
929
- .option('-w, --workspace <path>', 'Workspace directory')
930
- .option('--out <dir>', 'Output directory (must be within workspace)')
931
- .option('--json', 'Output raw JSON')
932
- .action(async (opts) => {
933
- await handleRuntimeDiagnosticsExport({ workspace: opts.workspace, out: opts.out, json: opts.json });
934
- });
935
-
936
- const pruningCmd = runtimeCmd
937
- .command('pruning', { hidden: true })
938
- .description('Non-destructive pruning metrics and health signals');
939
-
940
- pruningCmd
941
- .command('report')
942
- .description('Show pruning health report — watch/review principle signals')
943
- .option('-w, --workspace <path>', 'Workspace directory')
944
- .option('--json', 'Output raw JSON')
945
- .action((opts) => {
946
- handlePruningReport({ workspace: opts.workspace, json: opts.json });
947
- });
948
-
949
- pruningCmd
950
- .command('explain')
951
- .description('Explain why a specific principle was flagged')
952
- .requiredOption('--principle-id <id>', 'Principle ID to explain')
953
- .option('-w, --workspace <path>', 'Workspace directory')
954
- .option('--json', 'Output raw JSON')
955
- .action((opts) => {
956
- handlePruningExplain({ principleId: opts.principleId, workspace: opts.workspace, json: opts.json });
957
- });
958
-
959
- pruningCmd
960
- .command('review')
961
- .description('Record a human pruning decision for a flagged principle')
962
- .requiredOption('--principle-id <id>', 'Principle ID to review')
963
- .requiredOption('--decision <decision>', "Decision: keep, defer, or archive-candidate")
964
- .option('--note <text>', 'Review note (required for archive-candidate)')
965
- .option('--reviewer <name>', 'Reviewer name', 'operator')
966
- .option('-w, --workspace <path>', 'Workspace directory')
967
- .option('--json', 'Output raw JSON')
968
- .action((opts) => {
969
- handlePruningReview({
970
- principleId: opts.principleId,
971
- decision: opts.decision,
972
- note: opts.note,
973
- reviewer: opts.reviewer,
974
- workspace: opts.workspace,
975
- json: opts.json,
976
- });
977
- });
978
-
979
- pruningCmd
980
- .command('rollback')
981
- .description('Restore a masked principle to injection by overriding archive-candidate')
982
- .requiredOption('--principle-id <id>', 'Principle ID to restore')
983
- .option('--note <text>', 'Reason for rollback')
984
- .option('--reviewer <name>', 'Reviewer name', 'operator')
985
- .option('-w, --workspace <path>', 'Workspace directory')
986
- .option('--json', 'Output raw JSON')
987
- .action((opts) => {
988
- handlePruningRollback({
989
- principleId: opts.principleId,
990
- note: opts.note,
991
- reviewer: opts.reviewer,
992
- workspace: opts.workspace,
993
- json: opts.json,
994
- });
995
- });
996
-
997
- pruningCmd
998
- .command('orphans')
999
- .description('List orphan derived candidates not found in state.db')
1000
- .option('-w, --workspace <path>', 'Workspace directory')
1001
- .option('--dry-run', 'Report only, no modifications (default)')
1002
- .option('--confirm', 'Actually remove orphan references from ledger')
1003
- .option('--json', 'Output raw JSON')
1004
- .action((opts) => {
1005
- handlePruningOrphans({
1006
- workspace: opts.workspace,
1007
- dryRun: opts.dryRun,
1008
- confirm: opts.confirm,
1009
- json: opts.json,
1010
- });
1011
- });
1012
-
1013
- // ── Candidate inspection commands ─────────────────────────────────────────────
1014
-
1015
- const candidateCmd = program
1016
- .command('candidate')
1017
- .description('Principle candidate inspection');
1018
-
1019
- candidateCmd
1020
- .command('list')
1021
- .description('List principle candidates for a task')
1022
- .requiredOption('-t, --task-id <taskId>', 'Task ID to query')
1023
- .option('-w, --workspace <path>', 'Workspace directory')
1024
- .option('--json', 'Output raw JSON')
1025
- .action(async (opts) => {
1026
- await handleCandidateList(opts);
1027
- });
1028
-
1029
- candidateCmd
1030
- .command('show [candidateId]')
1031
- .description('Show detail for a single principle candidate')
1032
- .requiredOption('-w, --workspace <path>', 'Workspace directory')
1033
- .option('--candidate-id <id>', 'Candidate ID (alternative to positional arg)')
1034
- .option('--json', 'Output raw JSON')
1035
- .action(async (candidateId, opts) => {
1036
- const resolvedId = opts.candidateId ?? candidateId;
1037
- if (!resolvedId) {
1038
- console.error('Error: candidate ID is required (positional or --candidate-id)');
1039
- process.exitCode = 1;
1040
- return;
1041
- }
1042
- if (candidateId && opts.candidateId && candidateId !== opts.candidateId) {
1043
- console.error(`Error: conflicting candidate IDs: positional="${candidateId}", --candidate-id="${opts.candidateId}"`);
1044
- process.exitCode = 1;
1045
- return;
1046
- }
1047
- await handleCandidateShow({ candidateId: resolvedId, ...opts });
1048
- });
1049
-
1050
- candidateCmd
1051
- .command('intake')
1052
- .description('Intake a principle candidate into the ledger')
1053
- .requiredOption('--candidate-id <id>', 'Candidate ID to intake')
1054
- .option('-w, --workspace <path>', 'Workspace directory')
1055
- .option('--json', 'Output as JSON')
1056
- .option('--dry-run', 'Show what would be written without writing')
1057
- .action(async (opts) => {
1058
- await handleCandidateIntake(opts);
1059
- });
1060
-
1061
- candidateCmd
1062
- .command('audit')
1063
- .description('Audit candidate/ledger consistency for Runtime v2')
1064
- .option('-w, --workspace <path>', 'Workspace directory')
1065
- .option('--json', 'Output as JSON')
1066
- .action(async (opts) => {
1067
- await handleCandidateAudit(opts);
1068
- });
1069
-
1070
- candidateCmd
1071
- .command('repair')
1072
- .description('Repair consumed candidate with missing ledger entry')
1073
- .requiredOption('--candidate-id <id>', 'Candidate ID to repair')
1074
- .option('-w, --workspace <path>', 'Workspace directory')
1075
- .option('--json', 'Output as JSON')
1076
- .action(async (opts) => {
1077
- await handleCandidateRepair(opts);
1078
- });
1079
-
1080
- candidateCmd
1081
- .command('route')
1082
- .description('Show internalization route decision for a candidate')
1083
- .requiredOption('--candidate-id <id>', 'Candidate ID to inspect')
1084
- .option('-w, --workspace <path>', 'Workspace directory')
1085
- .option('--json', 'Output as JSON')
1086
- .action(async (opts) => {
1087
- await handleCandidateRoute(opts);
1088
- });
1089
-
1090
- candidateCmd
1091
- .command('internalize')
1092
- .description('Seed internalization Dreamer task from a candidate')
1093
- .requiredOption('--candidate-id <id>', 'Candidate ID to internalize')
1094
- .option('-w, --workspace <path>', 'Workspace directory')
1095
- .option('--json', 'Output as JSON')
1096
- .option('--dry-run', 'Preview without writing to database')
1097
- .action(async (opts) => {
1098
- await handleCandidateInternalize(opts);
1099
- });
1100
-
1101
- const candidateInternalizationCmd = candidateCmd
1102
- .command('internalization')
1103
- .description('Internalization pipeline operations for candidates');
1104
-
1105
- candidateInternalizationCmd
1106
- .command('backfill')
1107
- .description('Backfill dreamer tasks for consumed candidates created before Internalization Engine')
1108
- .option('-w, --workspace <path>', 'Workspace directory')
1109
- .option('--dry-run', 'Report only, no modifications (default)')
1110
- .option('--confirm', 'Actually create missing dreamer tasks')
1111
- .option('--include-pending', 'Include pending candidates (intake first, then seed dreamer)')
1112
- .option('--json', 'Output as JSON')
1113
- .action(async (opts) => {
1114
- await handleCandidateInternalizationBackfill({ workspace: opts.workspace, dryRun: opts.dryRun, confirm: opts.confirm, includePending: opts.includePending, json: opts.json });
1115
- });
1116
-
1117
- // ── Artifact inspection commands ──────────────────────────────────────────────
1118
-
1119
- const artifactCmd = program
1120
- .command('artifact', { hidden: true })
1121
- .description('Artifact registry inspection');
1122
-
1123
- artifactCmd
1124
- .command('show <artifactId>')
1125
- .description('Show artifact content and its associated candidates')
1126
- .requiredOption('-w, --workspace <path>', 'Workspace directory')
1127
- .option('--json', 'Output raw JSON')
1128
- .action(async (artifactId, opts) => {
1129
- await handleArtifactShow({ artifactId, ...opts });
1130
- });
1131
-
1132
- const _legacyCleanupCmd = legacyCmd
1133
- .command('cleanup')
1134
- .description('Clean legacy empathy/diagnostician artifacts and V1 Artificer artifacts from workspace')
1135
- .requiredOption('-w, --workspace <path>', 'Workspace directory')
1136
- .option('--dry-run', 'Show what would be cleaned without applying (default)')
1137
- .option('--apply', 'Actually apply the cleanup')
1138
- .option('--json', 'Output raw JSON')
1139
- .action(async (opts) => {
1140
- // CLI gate rule 4: --dry-run and --apply are mutually exclusive
1141
- if (opts.dryRun && opts.apply) {
1142
- const msg = 'Error: --dry-run and --apply are mutually exclusive';
1143
- if (opts.json) {
1144
- console.log(JSON.stringify({ status: 'failed', reason: msg, nextAction: 'Specify either --dry-run or --apply, not both' }, null, 2));
1145
- } else {
1146
- console.error(msg);
1147
- }
1148
- process.exitCode = 1;
1149
- return;
1150
- }
1151
- // Default to dry-run if neither flag is set (CLI gate rule 4).
1152
- // Pass undefined through — the handler's logic
1153
- // (opts.apply === true ? false : opts.dryRun !== false) correctly
1154
- // defaults to dry-run when both are undefined.
1155
- await handleLegacyCleanup({
1156
- workspacePath: opts.workspace,
1157
- dryRun: opts.dryRun,
1158
- apply: opts.apply,
1159
- json: opts.json ?? false,
1160
- });
1161
- });
1162
-
1163
- // ─── MVP Smoke (PRI-397) ────────────────────────────────────────────────────
1164
-
1165
- registerMvpCommands(program);
1166
-
1167
- // ─── RuleCode CLI (PRI-439 Phase 5) ─────────────────────────────────────────
1168
- // Read-only commands: spec, validate, replay. No DB mutation, no artifact writes.
1169
-
1170
- registerRulecodeCommand(program);
1171
-
1172
- // ─── Intent Engineering (PRI-466) ───────────────────────────────────────────
1173
- // Owner-authored INTENT.md management: init (create), show (read-only summary).
1174
-
1175
- registerIntentCommand(program);
1176
-
1177
- // ─── Errors List (Task 14: Feedback Pipeline Observability) ────────────────
1178
- // Operator diagnostic: aggregates SQLite failed/needs_human_review tasks +
1179
- // worker-status.json errors array. Read-only.
1180
-
1181
- registerErrorsListCommand(program);
1182
-
1183
- // ─── Principles Stats (PRI-562 Phase 0) ─────────────────────────────────────
1184
- // Owner-facing observability: principle injection volume/cost/duplicates/
1185
- // application evidence. Read-only aggregation over event logs + receipt ledger.
1186
-
1187
- registerPrinciplesCommand(program);
1188
-
1189
- const consoleCmd = program
1190
- .command('console')
1191
- .description('Start the pd-console web UI for principle review (default: fallback launcher)')
1192
- .passThroughOptions()
1193
- .option('-w, --workspace <path>', 'Workspace directory')
1194
- .option('-p, --port <port>', 'Port to listen on', '3100')
1195
- .option('--no-auth', 'Disable authentication (local dev only)')
1196
- .option('--json', 'Output JSON status', false);
1197
-
1198
- consoleCmd
1199
- .command('start')
1200
- .description('Legacy launcher — start the pd-console on the requested port (no reuse, no browser open)')
1201
- .option('-w, --workspace <path>', 'Workspace directory')
1202
- .option('-p, --port <port>', 'Port to listen on', '3100')
1203
- .option('--no-auth', 'Disable authentication (local dev only)')
1204
- .option('--json', 'Output JSON status', false)
1205
- .action(async (opts) => {
1206
- const { handleConsole } = await import('./commands/console.js');
1207
- await handleConsole({
1208
- workspace: opts.workspace,
1209
- port: opts.port,
1210
- noAuth: opts.auth === false,
1211
- json: opts.json,
1212
- });
1213
- });
1214
-
1215
- // PRI-300: seed-friendly Console launcher with reuse + auto-port + browser open
1216
- consoleCmd
1217
- .command('open')
1218
- .description('Open the pd-console in your browser (PRI-300) — auto-port, reuses running console, loopback-only')
1219
- .option('-w, --workspace <path>', 'Workspace directory')
1220
- .option('-p, --port <port>', 'Preferred port (default 3100; auto-falls back to next free port)')
1221
- .option('--host <host>', 'Loopback host (default 127.0.0.1; non-loopback refused)')
1222
- .option('--no-auth', 'Disable authentication (local dev only)')
1223
- .option('--token <token>', 'Auth token for the Console (or set PD_CONSOLE_TOKEN env var)')
1224
- .option('--no-browser', 'Do not open the system browser on success')
1225
- .option('--json', 'Output JSON status (suppresses browser open)', false)
1226
- .action(async (opts) => {
1227
- const { handleConsoleOpen } = await import('./commands/console.js');
1228
- await handleConsoleOpen({
1229
- workspace: opts.workspace,
1230
- port: opts.port,
1231
- host: opts.host,
1232
- noAuth: opts.auth === false,
1233
- token: opts.token,
1234
- noBrowser: opts.browser === false,
1235
- json: opts.json,
1236
- });
1237
- });
1238
-
1239
- // Default `pd console` → legacy launcher (backward compat)
1240
- consoleCmd.action(async (opts) => {
1241
- const { handleConsole } = await import('./commands/console.js');
1242
- await handleConsole({
1243
- workspace: opts.workspace,
1244
- port: opts.port,
1245
- noAuth: opts.auth === false,
1246
- json: opts.json,
1247
- });
1248
- });
1249
-
1250
- // ─── Quality Scorecard (PRI-361) ──────────────────────────────────
1251
-
1252
- const qualityCmd = program
1253
- .command('quality', { hidden: true })
1254
- .description('Quality scoring and evaluation');
1255
-
1256
- qualityCmd
1257
- .command('scorecard')
1258
- .description('Generate quality scorecard report for PD pain→diagnosis→principle chain')
1259
- .option('-w, --workspace <path>', 'Workspace directory')
1260
- .option('--local-model <id>', 'LM Studio model ID', 'qwen3.6-27b-mtp')
1261
- .option('--local-url <url>', 'LM Studio base URL', 'http://localhost:12341/v1')
1262
- .option('--strong-model <id>', 'Strong model for adjudication (provider/model)')
1263
- .option('--skip-strong-model', 'Skip strong model adjudication', false)
1264
- .option('--min-score <n>', 'Minimum pain score to evaluate', '50')
1265
- .option('--limit <n>', 'Max episodes to evaluate (0=all)', '0')
1266
- .option('--format <fmt>', 'Output format: json, markdown, html', 'markdown')
1267
- .option('--output <path>', 'Output file path')
1268
- .option('--json', 'Output as JSON', false)
1269
- .action(async (opts) => {
1270
- const { handleQualityScorecard } = await import('./commands/quality-scorecard.js');
1271
- await handleQualityScorecard(opts);
1272
- });
1273
-
1274
- if (!handleVersionFlag(process.argv.slice(2))) {
1275
- program.parse();
1276
- }