create-principles-disciple 1.79.0 → 1.81.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.
Files changed (196) hide show
  1. package/console/package.json +1 -0
  2. package/core/dist/runtime-v2/__tests__/admission-gate.test.js +6 -6
  3. package/core/dist/runtime-v2/__tests__/admission-gate.test.js.map +1 -1
  4. package/core/dist/runtime-v2/__tests__/architecture-regression.test.js +39 -0
  5. package/core/dist/runtime-v2/__tests__/architecture-regression.test.js.map +1 -1
  6. package/core/dist/runtime-v2/__tests__/artificer-runner-vslice.test.js +52 -0
  7. package/core/dist/runtime-v2/__tests__/artificer-runner-vslice.test.js.map +1 -1
  8. package/core/dist/runtime-v2/__tests__/evaluator-runner-vslice.test.js +245 -1
  9. package/core/dist/runtime-v2/__tests__/evaluator-runner-vslice.test.js.map +1 -1
  10. package/core/dist/runtime-v2/__tests__/feedback/redact-sensitive.test.js +131 -1
  11. package/core/dist/runtime-v2/__tests__/feedback/redact-sensitive.test.js.map +1 -1
  12. package/core/dist/runtime-v2/__tests__/fixtures/llm-e2e-config.d.ts.map +1 -1
  13. package/core/dist/runtime-v2/__tests__/fixtures/llm-e2e-config.js +4 -2
  14. package/core/dist/runtime-v2/__tests__/fixtures/llm-e2e-config.js.map +1 -1
  15. package/core/dist/runtime-v2/__tests__/scribe-runner-vslice.test.js +425 -2
  16. package/core/dist/runtime-v2/__tests__/scribe-runner-vslice.test.js.map +1 -1
  17. package/core/dist/runtime-v2/__tests__/telemetry-event.test.d.ts +2 -0
  18. package/core/dist/runtime-v2/__tests__/telemetry-event.test.d.ts.map +1 -0
  19. package/core/dist/runtime-v2/__tests__/telemetry-event.test.js +69 -0
  20. package/core/dist/runtime-v2/__tests__/telemetry-event.test.js.map +1 -0
  21. package/core/dist/runtime-v2/admission-gate.d.ts.map +1 -1
  22. package/core/dist/runtime-v2/admission-gate.js +0 -8
  23. package/core/dist/runtime-v2/admission-gate.js.map +1 -1
  24. package/core/dist/runtime-v2/config/__tests__/pd-config-contract.test.d.ts +15 -0
  25. package/core/dist/runtime-v2/config/__tests__/pd-config-contract.test.d.ts.map +1 -0
  26. package/core/dist/runtime-v2/config/__tests__/pd-config-contract.test.js +685 -0
  27. package/core/dist/runtime-v2/config/__tests__/pd-config-contract.test.js.map +1 -0
  28. package/core/dist/runtime-v2/config/index.d.ts +14 -0
  29. package/core/dist/runtime-v2/config/index.d.ts.map +1 -0
  30. package/core/dist/runtime-v2/config/index.js +16 -0
  31. package/core/dist/runtime-v2/config/index.js.map +1 -0
  32. package/core/dist/runtime-v2/config/pd-config-defaults.d.ts +14 -0
  33. package/core/dist/runtime-v2/config/pd-config-defaults.d.ts.map +1 -0
  34. package/core/dist/runtime-v2/config/pd-config-defaults.js +74 -0
  35. package/core/dist/runtime-v2/config/pd-config-defaults.js.map +1 -0
  36. package/core/dist/runtime-v2/config/pd-config-effective.d.ts +14 -0
  37. package/core/dist/runtime-v2/config/pd-config-effective.d.ts.map +1 -0
  38. package/core/dist/runtime-v2/config/pd-config-effective.js +118 -0
  39. package/core/dist/runtime-v2/config/pd-config-effective.js.map +1 -0
  40. package/core/dist/runtime-v2/config/pd-config-feature-flags.d.ts +35 -0
  41. package/core/dist/runtime-v2/config/pd-config-feature-flags.d.ts.map +1 -0
  42. package/core/dist/runtime-v2/config/pd-config-feature-flags.js +99 -0
  43. package/core/dist/runtime-v2/config/pd-config-feature-flags.js.map +1 -0
  44. package/core/dist/runtime-v2/config/pd-config-redaction.d.ts +22 -0
  45. package/core/dist/runtime-v2/config/pd-config-redaction.d.ts.map +1 -0
  46. package/core/dist/runtime-v2/config/pd-config-redaction.js +179 -0
  47. package/core/dist/runtime-v2/config/pd-config-redaction.js.map +1 -0
  48. package/core/dist/runtime-v2/config/pd-config-types.d.ts +124 -0
  49. package/core/dist/runtime-v2/config/pd-config-types.d.ts.map +1 -0
  50. package/core/dist/runtime-v2/config/pd-config-types.js +35 -0
  51. package/core/dist/runtime-v2/config/pd-config-types.js.map +1 -0
  52. package/core/dist/runtime-v2/config/pd-config-validate.d.ts +16 -0
  53. package/core/dist/runtime-v2/config/pd-config-validate.d.ts.map +1 -0
  54. package/core/dist/runtime-v2/config/pd-config-validate.js +443 -0
  55. package/core/dist/runtime-v2/config/pd-config-validate.js.map +1 -0
  56. package/core/dist/runtime-v2/feature-flags/plugin-surface-registry.js +10 -10
  57. package/core/dist/runtime-v2/feature-flags/plugin-surface-registry.js.map +1 -1
  58. package/core/dist/runtime-v2/feedback/index.d.ts +1 -1
  59. package/core/dist/runtime-v2/feedback/index.d.ts.map +1 -1
  60. package/core/dist/runtime-v2/feedback/index.js +1 -1
  61. package/core/dist/runtime-v2/feedback/index.js.map +1 -1
  62. package/core/dist/runtime-v2/feedback/redact-sensitive.d.ts +2 -0
  63. package/core/dist/runtime-v2/feedback/redact-sensitive.d.ts.map +1 -1
  64. package/core/dist/runtime-v2/feedback/redact-sensitive.js +32 -3
  65. package/core/dist/runtime-v2/feedback/redact-sensitive.js.map +1 -1
  66. package/core/dist/runtime-v2/index.d.ts +5 -1
  67. package/core/dist/runtime-v2/index.d.ts.map +1 -1
  68. package/core/dist/runtime-v2/index.js +9 -1
  69. package/core/dist/runtime-v2/index.js.map +1 -1
  70. package/core/dist/runtime-v2/internalization/__tests__/peer-runner-lineage-injection.test.d.ts +2 -0
  71. package/core/dist/runtime-v2/internalization/__tests__/peer-runner-lineage-injection.test.d.ts.map +1 -0
  72. package/core/dist/runtime-v2/internalization/__tests__/peer-runner-lineage-injection.test.js +95 -0
  73. package/core/dist/runtime-v2/internalization/__tests__/peer-runner-lineage-injection.test.js.map +1 -0
  74. package/core/dist/runtime-v2/internalization/__tests__/philosopher-runner-trust-boundary.test.d.ts +2 -0
  75. package/core/dist/runtime-v2/internalization/__tests__/philosopher-runner-trust-boundary.test.d.ts.map +1 -0
  76. package/core/dist/runtime-v2/internalization/__tests__/philosopher-runner-trust-boundary.test.js +398 -0
  77. package/core/dist/runtime-v2/internalization/__tests__/philosopher-runner-trust-boundary.test.js.map +1 -0
  78. package/core/dist/runtime-v2/internalization/artificer-output.d.ts +3 -2
  79. package/core/dist/runtime-v2/internalization/artificer-output.d.ts.map +1 -1
  80. package/core/dist/runtime-v2/internalization/artificer-output.js +40 -31
  81. package/core/dist/runtime-v2/internalization/artificer-output.js.map +1 -1
  82. package/core/dist/runtime-v2/internalization/artificer-runner.d.ts +59 -38
  83. package/core/dist/runtime-v2/internalization/artificer-runner.d.ts.map +1 -1
  84. package/core/dist/runtime-v2/internalization/artificer-runner.js +122 -394
  85. package/core/dist/runtime-v2/internalization/artificer-runner.js.map +1 -1
  86. package/core/dist/runtime-v2/internalization/dreamer-output.d.ts +4 -3
  87. package/core/dist/runtime-v2/internalization/dreamer-output.d.ts.map +1 -1
  88. package/core/dist/runtime-v2/internalization/dreamer-output.js +11 -9
  89. package/core/dist/runtime-v2/internalization/dreamer-output.js.map +1 -1
  90. package/core/dist/runtime-v2/internalization/dreamer-runner.d.ts +31 -92
  91. package/core/dist/runtime-v2/internalization/dreamer-runner.d.ts.map +1 -1
  92. package/core/dist/runtime-v2/internalization/dreamer-runner.js +80 -492
  93. package/core/dist/runtime-v2/internalization/dreamer-runner.js.map +1 -1
  94. package/core/dist/runtime-v2/internalization/evaluator-output.d.ts +2 -2
  95. package/core/dist/runtime-v2/internalization/evaluator-output.d.ts.map +1 -1
  96. package/core/dist/runtime-v2/internalization/evaluator-output.js +29 -23
  97. package/core/dist/runtime-v2/internalization/evaluator-output.js.map +1 -1
  98. package/core/dist/runtime-v2/internalization/evaluator-runner.d.ts +74 -48
  99. package/core/dist/runtime-v2/internalization/evaluator-runner.d.ts.map +1 -1
  100. package/core/dist/runtime-v2/internalization/evaluator-runner.js +165 -443
  101. package/core/dist/runtime-v2/internalization/evaluator-runner.js.map +1 -1
  102. package/core/dist/runtime-v2/internalization/peer-runner-contracts.d.ts +14 -0
  103. package/core/dist/runtime-v2/internalization/peer-runner-contracts.d.ts.map +1 -1
  104. package/core/dist/runtime-v2/internalization/peer-runner-contracts.js +21 -0
  105. package/core/dist/runtime-v2/internalization/peer-runner-contracts.js.map +1 -1
  106. package/core/dist/runtime-v2/internalization/philosopher-output.d.ts +8 -2
  107. package/core/dist/runtime-v2/internalization/philosopher-output.d.ts.map +1 -1
  108. package/core/dist/runtime-v2/internalization/philosopher-output.js +16 -11
  109. package/core/dist/runtime-v2/internalization/philosopher-output.js.map +1 -1
  110. package/core/dist/runtime-v2/internalization/philosopher-runner.d.ts +36 -55
  111. package/core/dist/runtime-v2/internalization/philosopher-runner.d.ts.map +1 -1
  112. package/core/dist/runtime-v2/internalization/philosopher-runner.js +118 -400
  113. package/core/dist/runtime-v2/internalization/philosopher-runner.js.map +1 -1
  114. package/core/dist/runtime-v2/internalization/rollout-reviewer-runner.d.ts.map +1 -1
  115. package/core/dist/runtime-v2/internalization/rollout-reviewer-runner.js +3 -1
  116. package/core/dist/runtime-v2/internalization/rollout-reviewer-runner.js.map +1 -1
  117. package/core/dist/runtime-v2/internalization/scribe-output.d.ts +8 -2
  118. package/core/dist/runtime-v2/internalization/scribe-output.d.ts.map +1 -1
  119. package/core/dist/runtime-v2/internalization/scribe-output.js +33 -17
  120. package/core/dist/runtime-v2/internalization/scribe-output.js.map +1 -1
  121. package/core/dist/runtime-v2/internalization/scribe-runner.d.ts +56 -49
  122. package/core/dist/runtime-v2/internalization/scribe-runner.d.ts.map +1 -1
  123. package/core/dist/runtime-v2/internalization/scribe-runner.js +117 -397
  124. package/core/dist/runtime-v2/internalization/scribe-runner.js.map +1 -1
  125. package/core/dist/runtime-v2/internalization/trainer-runner.d.ts.map +1 -1
  126. package/core/dist/runtime-v2/internalization/trainer-runner.js +3 -1
  127. package/core/dist/runtime-v2/internalization/trainer-runner.js.map +1 -1
  128. package/core/dist/runtime-v2/runner/__tests__/base-peer-runner-trust-boundary.test.d.ts +2 -0
  129. package/core/dist/runtime-v2/runner/__tests__/base-peer-runner-trust-boundary.test.d.ts.map +1 -0
  130. package/core/dist/runtime-v2/runner/__tests__/base-peer-runner-trust-boundary.test.js +379 -0
  131. package/core/dist/runtime-v2/runner/__tests__/base-peer-runner-trust-boundary.test.js.map +1 -0
  132. package/core/dist/runtime-v2/runner/base-peer-runner.d.ts +122 -0
  133. package/core/dist/runtime-v2/runner/base-peer-runner.d.ts.map +1 -0
  134. package/core/dist/runtime-v2/runner/base-peer-runner.js +528 -0
  135. package/core/dist/runtime-v2/runner/base-peer-runner.js.map +1 -0
  136. package/core/dist/runtime-v2/runner/peer-runner-types.d.ts +107 -0
  137. package/core/dist/runtime-v2/runner/peer-runner-types.d.ts.map +1 -0
  138. package/core/dist/runtime-v2/runner/peer-runner-types.js +13 -0
  139. package/core/dist/runtime-v2/runner/peer-runner-types.js.map +1 -0
  140. package/core/dist/telemetry-event.d.ts +2 -2
  141. package/core/dist/telemetry-event.d.ts.map +1 -1
  142. package/core/dist/telemetry-event.js +89 -0
  143. package/core/dist/telemetry-event.js.map +1 -1
  144. package/dist/installer.d.ts +1 -1
  145. package/dist/installer.d.ts.map +1 -1
  146. package/dist/installer.js +39 -10
  147. package/dist/installer.js.map +1 -1
  148. package/dist/mvp-config.d.ts +33 -0
  149. package/dist/mvp-config.d.ts.map +1 -1
  150. package/dist/mvp-config.js +174 -0
  151. package/dist/mvp-config.js.map +1 -1
  152. package/package.json +3 -3
  153. package/pd-cli/dist/commands/config-doctor.d.ts +17 -0
  154. package/pd-cli/dist/commands/config-doctor.d.ts.map +1 -0
  155. package/pd-cli/dist/commands/config-doctor.js +143 -0
  156. package/pd-cli/dist/commands/config-doctor.js.map +1 -0
  157. package/pd-cli/dist/commands/console.d.ts +18 -0
  158. package/pd-cli/dist/commands/console.d.ts.map +1 -1
  159. package/pd-cli/dist/commands/console.js +439 -0
  160. package/pd-cli/dist/commands/console.js.map +1 -1
  161. package/pd-cli/dist/commands/runtime-features.d.ts +23 -8
  162. package/pd-cli/dist/commands/runtime-features.d.ts.map +1 -1
  163. package/pd-cli/dist/commands/runtime-features.js +72 -31
  164. package/pd-cli/dist/commands/runtime-features.js.map +1 -1
  165. package/pd-cli/dist/index.d.ts +1 -1
  166. package/pd-cli/dist/index.js +83 -31
  167. package/pd-cli/dist/index.js.map +1 -1
  168. package/pd-cli/dist/services/config-doctor.d.ts +102 -0
  169. package/pd-cli/dist/services/config-doctor.d.ts.map +1 -0
  170. package/pd-cli/dist/services/config-doctor.js +426 -0
  171. package/pd-cli/dist/services/config-doctor.js.map +1 -0
  172. package/pd-cli/dist/services/console-launcher.d.ts +110 -0
  173. package/pd-cli/dist/services/console-launcher.d.ts.map +1 -0
  174. package/pd-cli/dist/services/console-launcher.js +282 -0
  175. package/pd-cli/dist/services/console-launcher.js.map +1 -0
  176. package/pd-cli/dist/services/pd-config-loader.d.ts +64 -0
  177. package/pd-cli/dist/services/pd-config-loader.d.ts.map +1 -0
  178. package/pd-cli/dist/services/pd-config-loader.js +156 -0
  179. package/pd-cli/dist/services/pd-config-loader.js.map +1 -0
  180. package/pd-cli/package.json +3 -1
  181. package/plugin/dist/core/event-log.d.ts +10 -0
  182. package/plugin/dist/core/event-log.js +85 -1
  183. package/plugin/dist/core/pd-config-loader.d.ts +96 -0
  184. package/plugin/dist/core/pd-config-loader.js +307 -0
  185. package/plugin/dist/core/runtime-v2-prompt-activation-reader.d.ts +4 -0
  186. package/plugin/dist/core/runtime-v2-prompt-activation-reader.js +12 -56
  187. package/plugin/dist/core/surface-guard.d.ts +12 -8
  188. package/plugin/dist/core/surface-guard.js +51 -2
  189. package/plugin/dist/hooks/gate.js +3 -0
  190. package/plugin/dist/hooks/prompt.js +4 -5
  191. package/plugin/dist/index.d.ts +4 -0
  192. package/plugin/dist/index.js +70 -94
  193. package/plugin/dist/service/correction-observer-service.d.ts +8 -0
  194. package/plugin/dist/service/correction-observer-service.js +48 -29
  195. package/plugin/dist/utils/workspace-resolver.d.ts +33 -1
  196. package/plugin/dist/utils/workspace-resolver.js +182 -3
@@ -1,14 +1,15 @@
1
1
  import { PDRuntimeError } from '../error-categories.js';
2
2
  import { hydratePITaskRecord } from './pitask-metadata.js';
3
- import { RunnerPhase } from '../runner/runner-phase.js';
4
3
  import { DreamerPromptBuilder } from './dreamer-prompt-builder.js';
5
- const DEFAULT_DREAMER_RUNNER_OPTIONS = {
4
+ import { injectRunnerLineageIfAbsent } from './peer-runner-contracts.js';
5
+ import { BasePeerRunner } from '../runner/base-peer-runner.js';
6
+ export const DEFAULT_DREAMER_RUNNER_OPTIONS = {
6
7
  pollIntervalMs: 5_000,
7
8
  timeoutMs: 300_000,
8
9
  defaultMaxAttempts: 3,
9
10
  agentId: 'dreamer',
10
11
  };
11
- function resolveDreamerRunnerOptions(options) {
12
+ export function resolveDreamerRunnerOptions(options) {
12
13
  return {
13
14
  pollIntervalMs: options.pollIntervalMs ?? DEFAULT_DREAMER_RUNNER_OPTIONS.pollIntervalMs,
14
15
  timeoutMs: options.timeoutMs ?? DEFAULT_DREAMER_RUNNER_OPTIONS.timeoutMs,
@@ -18,148 +19,23 @@ function resolveDreamerRunnerOptions(options) {
18
19
  agentId: options.agentId ?? DEFAULT_DREAMER_RUNNER_OPTIONS.agentId,
19
20
  };
20
21
  }
21
- // ── DreamerRunner ─────────────────────────────────────────────────────────────
22
- export class DreamerRunner {
23
- phase = RunnerPhase.Idle;
24
- resolvedOptions;
25
- stateManager;
26
- runtimeAdapter;
27
- eventEmitter;
22
+ // ── DreamerRunner ────────────────────────────────────────────────────────────
23
+ export class DreamerRunner extends BasePeerRunner {
28
24
  validator;
29
- artifactStore;
30
25
  constructor(deps, options) {
31
- this.stateManager = deps.stateManager;
32
- this.runtimeAdapter = deps.runtimeAdapter;
33
- this.eventEmitter = deps.eventEmitter;
34
- this.validator = deps.validator;
35
- this.artifactStore = deps.artifactStore;
36
- this.resolvedOptions = resolveDreamerRunnerOptions(options);
37
- }
38
- /** Get the current internal phase. For testing/observability only. */
39
- get currentPhase() {
40
- return this.phase;
41
- }
42
- emitDreamerEvent(eventType, taskId, payload) {
43
- this.eventEmitter.emitTelemetry({
44
- eventType: eventType,
45
- traceId: taskId,
46
- timestamp: new Date().toISOString(),
47
- sessionId: this.resolvedOptions.owner,
48
- agentId: this.resolvedOptions.agentId,
49
- payload,
26
+ super(deps, options, {
27
+ runnerName: 'dreamer',
28
+ expectedTaskKind: 'dreamer',
29
+ defaultAgentId: 'dreamer',
30
+ resultRefPrefix: 'dreamer',
50
31
  });
32
+ this.validator = deps.validator;
51
33
  }
52
- /**
53
- * Execute the full Dreamer lifecycle for a task.
54
- *
55
- * The runner does NOT hold mutable state between run() calls.
56
- * Each invocation is independent.
57
- */
58
- async run(taskId) {
59
- this.phase = RunnerPhase.Idle;
60
- // 1. Acquire lease — isolated try/catch so lease_conflict never uses synthetic TaskRecord
61
- // eslint-disable-next-line @typescript-eslint/init-declarations
62
- let leasedTask;
63
- try {
64
- leasedTask = await this.stateManager.acquireLease({
65
- taskId,
66
- owner: this.resolvedOptions.owner,
67
- runtimeKind: this.resolvedOptions.runtimeKind,
68
- });
69
- }
70
- catch (error) {
71
- return await this.handleLeaseOrPhaseError(taskId, error);
72
- }
73
- this.emitDreamerEvent('dreamer_task_leased', taskId, {
74
- taskKind: 'dreamer',
75
- attemptCount: leasedTask.attemptCount,
76
- });
77
- if (leasedTask.taskKind !== 'dreamer') {
78
- this.emitDreamerEvent('dreamer_wrong_task_kind', taskId, {
79
- expectedKind: 'dreamer',
80
- actualKind: leasedTask.taskKind,
81
- });
82
- await this.stateManager.markTaskFailed(taskId, 'input_invalid');
83
- return {
84
- status: 'failed',
85
- taskId,
86
- errorCategory: 'input_invalid',
87
- failureReason: `Task kind must be 'dreamer', got '${leasedTask.taskKind}'`,
88
- attemptCount: leasedTask.attemptCount,
89
- };
90
- }
91
- // All subsequent errors use the real leasedTask — no synthetic TaskRecord allowed
92
- try {
93
- // acquireLease creates a RunRecord; resolve its runId for store operations
94
- const storeRunId = await this.resolveStoreRunId(taskId);
95
- // 2. Build context from predecessor task outputs (no ContextAssembler)
96
- this.phase = RunnerPhase.BuildingContext;
97
- const { contextHash, contextRefs, predecessorOutput } = await this.buildContext(taskId);
98
- this.emitDreamerEvent('dreamer_context_built', taskId, { contextHash });
99
- // 3. Invoke runtime
100
- this.phase = RunnerPhase.Invoking;
101
- const runHandle = await this.invokeRuntime({ taskId, contextHash, contextRefs, predecessorOutput });
102
- this.emitDreamerEvent('dreamer_run_started', taskId, {
103
- runtimeKind: this.resolvedOptions.runtimeKind,
104
- });
105
- // 4. Poll until terminal
106
- this.phase = RunnerPhase.Polling;
107
- const finalStatus = await this.pollUntilTerminal(runHandle);
108
- // 5. Handle non-success terminal states
109
- if (finalStatus.status !== 'succeeded') {
110
- return await this.handleRuntimeFailure(taskId, leasedTask, finalStatus);
111
- }
112
- // 6. Fetch output
113
- this.phase = RunnerPhase.FetchingOutput;
114
- const output = await this.fetchAndParseOutput(runHandle.runId, taskId);
115
- // 7. Validate
116
- this.phase = RunnerPhase.Validating;
117
- const validationResult = await this.validator.validate(output, taskId);
118
- if (!validationResult.valid) {
119
- return await this.handleValidationError({
120
- taskId,
121
- task: leasedTask,
122
- errors: validationResult.errors,
123
- errorCategory: validationResult.errorCategory,
124
- });
125
- }
126
- this.emitDreamerEvent('dreamer_output_validated', taskId, {
127
- candidateCount: output.candidates.length,
128
- });
129
- // 8. Succeed task
130
- return await this.succeedTask({
131
- taskId,
132
- runId: storeRunId,
133
- output,
134
- task: leasedTask,
135
- contextHash,
136
- });
137
- }
138
- catch (error) {
139
- // handleLeaseOrPhaseError is only for lease errors (before lease).
140
- // Post-lease errors use retryOrFail with the real leasedTask.
141
- return await this.handlePostLeaseError(taskId, leasedTask, error);
142
- }
34
+ // ── Abstract implementations ───────────────────────────────────────────────
35
+ // eslint-disable-next-line @typescript-eslint/class-methods-use-this
36
+ get permanentErrorCategories() {
37
+ return new Set(['storage_unavailable', 'workspace_invalid', 'capability_missing', 'cancelled', 'input_invalid']);
143
38
  }
144
- // ── Phase methods ─────────────────────────────────────────────────────────
145
- /**
146
- * Build context from predecessor task outputs.
147
- *
148
- * Dreamer doesn't use ContextAssembler — it resolves predecessor context
149
- * from dependencyTaskIds via stateManager.getTask(). The predecessor's
150
- * resultRef/outputArtifactRefs become the Dreamer's input context.
151
- *
152
- * Degradation semantics (intentional partial failure):
153
- * - If ALL dependencies fail → builds empty context (continues, not fail-closed)
154
- * - If SOME dependencies fail → builds partial context + emits dreamer_context_partial
155
- * - Only fulfilled results contribute contextRefs
156
- *
157
- * This is a deliberate design choice: Dreamer can produce output with partial
158
- * context, whereas the host layer's task-ready validation is fail-closed.
159
- * Partial context is reported via telemetry.
160
- *
161
- * @see hydratePITaskRecord (PRI-65) for fail-closed PI metadata access
162
- */
163
39
  async buildContext(taskId) {
164
40
  const task = await this.stateManager.getTask(taskId);
165
41
  if (!task) {
@@ -203,434 +79,146 @@ export class DreamerRunner {
203
79
  }
204
80
  }
205
81
  if (rejectedDeps.length > 0) {
206
- this.emitDreamerEvent('dreamer_context_partial', taskId, {
82
+ this.emitEvent('context_partial', taskId, {
207
83
  rejectedCount: rejectedDeps.length,
208
84
  rejectedDeps,
209
85
  });
210
86
  }
211
- const contextHash = DreamerRunner.hashContextRefs(contextRefs);
87
+ const contextHash = BasePeerRunner.hashContextRefs(contextRefs);
212
88
  return { contextHash, contextRefs, predecessorOutput };
213
89
  }
214
- /**
215
- * Compute a deterministic hash from context references.
216
- * Used for telemetry and result tracking, not for caching.
217
- */
218
- static hashContextRefs(refs) {
219
- if (refs.length === 0)
220
- return 'empty';
221
- // Simple deterministic hash via DJB2-style accumulator
222
- // Not cryptographic — only used for observability
223
- const str = refs.join('|');
224
- let hash = 0;
225
- for (let i = 0; i < str.length; i++) {
226
- hash = (Math.imul(31, hash) + str.charCodeAt(i)) | 0;
227
- }
228
- return `ctx-${Math.abs(hash).toString(16)}`;
229
- }
230
- async resolveStoreRunId(taskId) {
231
- const runs = await this.stateManager.getRunsByTask(taskId);
232
- const latestRun = runs[runs.length - 1];
233
- if (!latestRun) {
234
- throw new PDRuntimeError('execution_failed', `No run records found for task ${taskId} after lease acquisition`);
235
- }
236
- return latestRun.runId;
237
- }
238
- async resolveLineageArtifactIds(taskId) {
239
- const task = await this.stateManager.getTask(taskId);
240
- if (!task)
241
- return { ids: [], hasRejected: false };
242
- const piTask = hydratePITaskRecord(task);
243
- const deps = piTask?.dependencyTaskIds ?? [];
244
- if (deps.length === 0)
245
- return { ids: [], hasRejected: false };
246
- const lineageIds = [];
247
- let hasRejected = false;
248
- const results = await Promise.allSettled(deps.map((depId) => this.artifactStore.listBySourceTaskId(depId)));
249
- for (const result of results) {
250
- if (result.status === 'fulfilled') {
251
- for (const artifact of result.value) {
252
- lineageIds.push(artifact.artifactId);
253
- }
254
- }
255
- else {
256
- hasRejected = true;
257
- }
258
- }
259
- return { ids: lineageIds, hasRejected };
260
- }
261
- async invokeRuntime(params) {
90
+ async invokeRuntime(taskId, context) {
262
91
  const builder = new DreamerPromptBuilder();
263
92
  const { message } = builder.buildPrompt({
264
- taskId: params.taskId,
265
- contextHash: params.contextHash,
266
- contextRefs: params.contextRefs,
267
- predecessorOutput: params.predecessorOutput,
93
+ taskId,
94
+ contextHash: context.contextHash,
95
+ contextRefs: context.contextRefs,
96
+ predecessorOutput: context.predecessorOutput,
268
97
  });
269
- const startInput = {
98
+ return this.runtimeAdapter.startRun({
270
99
  agentSpec: { agentId: this.resolvedOptions.agentId, schemaVersion: 'v1' },
271
- taskRef: { taskId: params.taskId },
100
+ taskRef: { taskId },
272
101
  inputPayload: message,
273
102
  contextItems: [],
274
103
  outputSchemaRef: 'dreamer-output-v1',
275
104
  timeoutMs: this.resolvedOptions.timeoutMs,
276
- };
277
- return this.runtimeAdapter.startRun(startInput);
278
- }
279
- async pollUntilTerminal(runHandle) {
280
- const deadline = Date.now() + this.resolvedOptions.timeoutMs;
281
- const terminalStatuses = ['succeeded', 'failed', 'timed_out', 'cancelled'];
282
- while (Date.now() < deadline) {
283
- const status = await this.runtimeAdapter.pollRun(runHandle.runId);
284
- if (terminalStatuses.includes(status.status)) {
285
- return status;
286
- }
287
- await this.sleep(this.resolvedOptions.pollIntervalMs);
288
- }
289
- // Timeout — cancel gracefully, preserve timeout error with cancel status
290
- let cancelFailed = false;
291
- try {
292
- await this.runtimeAdapter.cancelRun(runHandle.runId);
293
- }
294
- catch (cancelErr) {
295
- cancelFailed = true;
296
- this.emitDreamerEvent('dreamer_cancel_run_failed', runHandle.runId, {
297
- runId: runHandle.runId,
298
- errorMessage: cancelErr instanceof Error ? cancelErr.message : String(cancelErr),
299
- });
300
- }
301
- const cancelNote = cancelFailed ? ' (cancelRun also failed)' : '';
302
- throw new PDRuntimeError('timeout', `Run ${runHandle.runId} timed out after ${this.resolvedOptions.timeoutMs}ms${cancelNote}`);
303
- }
304
- async fetchAndParseOutput(runId, taskId) {
305
- const result = await this.fetchOutputWithTelemetry(runId, taskId);
306
- if (!result || !result.payload) {
307
- this.emitDreamerEvent('dreamer_output_extraction_failed', taskId, {
308
- runId,
309
- stage: 'payload_missing',
310
- errorMessage: `No output available for run ${runId}`,
311
- });
312
- throw new PDRuntimeError('output_invalid', `No output available for run ${runId}`);
313
- }
314
- const payload = result.payload;
315
- if (typeof payload !== 'object' || payload === null) {
316
- this.emitDreamerEvent('dreamer_output_extraction_failed', taskId, {
317
- runId,
318
- stage: 'payload_not_object',
319
- errorMessage: `Output payload is not an object for run ${runId}`,
320
- });
321
- throw new PDRuntimeError('output_invalid', `Output payload is not an object for run ${runId}`);
322
- }
323
- return result.payload;
105
+ });
324
106
  }
325
- async fetchOutputWithTelemetry(runId, taskId) {
326
- try {
327
- return await this.runtimeAdapter.fetchOutput(runId);
328
- }
329
- catch (fetchErr) {
330
- this.emitDreamerEvent('dreamer_output_extraction_failed', taskId, {
331
- runId,
332
- stage: 'fetchOutput',
333
- errorMessage: fetchErr instanceof Error ? fetchErr.message : String(fetchErr),
334
- });
335
- throw fetchErr;
336
- }
107
+ async validateOutput(output, taskId) {
108
+ const result = await this.validator.validate(output, taskId);
109
+ return {
110
+ valid: result.valid,
111
+ errors: result.errors,
112
+ errorCategory: result.errorCategory,
113
+ };
337
114
  }
338
- async succeedTask(ctx) {
339
- // Store output before marking succeeded so run record reflects output
115
+ // eslint-disable-next-line @typescript-eslint/max-params
116
+ async succeedTask(taskId, runId, output, task, contextHash, _context) {
117
+ // Store output before marking succeeded
340
118
  try {
341
- await this.stateManager.updateRunOutput(ctx.runId, JSON.stringify(ctx.output));
119
+ await this.stateManager.updateRunOutput(runId, JSON.stringify(output));
342
120
  }
343
121
  catch (updateErr) {
344
- this.emitDreamerEvent('dreamer_update_output_failed', ctx.taskId, {
345
- runId: ctx.runId,
122
+ this.emitEvent('update_output_failed', taskId, {
123
+ runId,
346
124
  errorMessage: updateErr instanceof Error ? updateErr.message : String(updateErr),
347
125
  });
348
126
  throw updateErr;
349
127
  }
350
- // Emit per-candidate telemetry
351
- for (const candidate of ctx.output.candidates) {
352
- this.emitDreamerEvent('dreamer_candidate_generated', ctx.taskId, {
353
- candidateIndex: candidate.candidateIndex,
354
- confidence: candidate.confidence,
355
- riskLevel: candidate.riskLevel,
356
- });
357
- }
358
128
  // Write PIArtifact via artifactStore (idempotent upsert)
359
- // PIArtifact is the core durable output of DreamerRunner.
360
- // If artifact write fails, the task must NOT be marked succeeded —
361
- // downstream runners (Philosopher/Scribe) require durable artifact input.
362
129
  let lineageArtifactIds = [];
363
130
  let lineageHasRejected = false;
364
131
  try {
365
- const lineageResult = await this.resolveLineageArtifactIds(ctx.taskId);
132
+ const lineageResult = await this.resolveLineageArtifactIds(taskId);
366
133
  lineageArtifactIds = lineageResult.ids;
367
134
  lineageHasRejected = lineageResult.hasRejected;
368
135
  }
369
136
  catch (lineageErr) {
370
- this.emitDreamerEvent('dreamer_lineage_resolve_failed', ctx.taskId, {
371
- runId: ctx.runId,
137
+ this.emitEvent('lineage_resolve_failed', taskId, {
138
+ runId,
372
139
  errorMessage: lineageErr instanceof Error ? lineageErr.message : String(lineageErr),
373
140
  });
374
141
  }
375
142
  if (lineageHasRejected) {
376
- this.emitDreamerEvent('dreamer_lineage_partial', ctx.taskId, {
377
- runId: ctx.runId,
143
+ this.emitEvent('lineage_partial', taskId, {
144
+ runId,
378
145
  resolvedCount: lineageArtifactIds.length,
379
146
  warning: 'Some dependency artifact queries were rejected; lineage may be incomplete',
380
147
  });
381
148
  }
382
- const artifactId = `pi-art-${ctx.taskId}-${ctx.runId}`;
149
+ const artifactId = `pi-art-${taskId}-${runId}`;
383
150
  const now = new Date().toISOString();
384
151
  try {
385
152
  await this.artifactStore.upsertArtifact({
386
153
  artifactId,
387
154
  artifactKind: 'principle',
388
- sourceTaskId: ctx.taskId,
155
+ sourceTaskId: taskId,
389
156
  lineageArtifactIds,
390
157
  validationStatus: 'pending',
391
- contentJson: JSON.stringify(ctx.output),
158
+ contentJson: JSON.stringify(output),
392
159
  createdAt: now,
393
160
  updatedAt: now,
394
161
  });
395
162
  }
396
163
  catch (artifactErr) {
397
- this.emitDreamerEvent('dreamer_artifact_write_failed', ctx.taskId, {
398
- runId: ctx.runId,
164
+ this.emitEvent('artifact_write_failed', taskId, {
165
+ runId,
399
166
  errorMessage: artifactErr instanceof Error ? artifactErr.message : String(artifactErr),
400
167
  });
401
168
  return this.retryOrFail({
402
- taskId: ctx.taskId,
403
- task: ctx.task,
169
+ taskId,
170
+ task,
404
171
  errorCategory: 'artifact_commit_failed',
405
172
  failureReason: `PIArtifact write failed: ${artifactErr instanceof Error ? artifactErr.message : String(artifactErr)}`,
406
173
  });
407
174
  }
408
- // Mark task succeeded with dreamer:// resultRef
409
- const resultRef = `dreamer://${ctx.runId}`;
175
+ // Mark task succeeded
176
+ const resultRef = `${this.config.resultRefPrefix}://${runId}`;
410
177
  try {
411
- await this.stateManager.markTaskSucceeded(ctx.taskId, resultRef);
178
+ await this.stateManager.markTaskSucceeded(taskId, resultRef);
412
179
  }
413
180
  catch (stateErr) {
414
- this.emitDreamerEvent('dreamer_mark_succeeded_failed', ctx.taskId, {
415
- taskId: ctx.taskId,
416
- runId: ctx.runId,
181
+ this.emitEvent('mark_succeeded_failed', taskId, {
182
+ taskId,
183
+ runId,
417
184
  errorMessage: stateErr instanceof Error ? stateErr.message : String(stateErr),
418
185
  });
419
186
  throw stateErr;
420
187
  }
421
- this.emitDreamerEvent('dreamer_task_succeeded', ctx.taskId, {
422
- attemptCount: ctx.task.attemptCount,
188
+ this.emitEvent('task_succeeded', taskId, {
189
+ attemptCount: task.attemptCount,
423
190
  resultRef,
424
- candidateCount: ctx.output.candidates.length,
191
+ candidateCount: output.candidates.length,
425
192
  });
426
- this.phase = RunnerPhase.Completed;
427
193
  return {
428
194
  status: 'succeeded',
429
- taskId: ctx.taskId,
430
- runId: ctx.runId,
195
+ taskId,
196
+ runId,
431
197
  artifactId,
432
198
  resultRef,
433
- contextHash: ctx.contextHash,
434
- output: ctx.output,
435
- attemptCount: ctx.task.attemptCount,
436
- };
437
- }
438
- async handleRuntimeFailure(taskId, task, runStatus) {
439
- const errorCategory = this.mapRunStatusToErrorCategory(runStatus.status, runStatus.reason);
440
- this.emitDreamerEvent('dreamer_run_failed', taskId, {
441
- runStatus: runStatus.status,
442
- errorCategory,
443
- });
444
- return this.retryOrFail({
445
- taskId,
446
- task,
447
- errorCategory,
448
- failureReason: `Runtime execution ended with status: ${runStatus.status}`,
449
- });
450
- }
451
- async handleValidationError(ctx) {
452
- const category = ctx.errorCategory ?? 'output_invalid';
453
- this.emitDreamerEvent('dreamer_output_invalid', ctx.taskId, {
454
- errorCount: ctx.errors.length,
455
- errorCategory: category,
456
- });
457
- return this.retryOrFail({
458
- taskId: ctx.taskId,
459
- task: ctx.task,
460
- errorCategory: category,
461
- failureReason: `Validation failed: ${ctx.errors.join('; ')}`,
462
- });
463
- }
464
- async handleLeaseOrPhaseError(taskId, error) {
465
- const classified = this.classifyError(error);
466
- // lease_conflict is concurrent-access conflict, not a state change.
467
- // No mutation methods (markTaskFailed/markTaskRetryWait) are called.
468
- if (classified.category === 'lease_conflict') {
469
- this.emitDreamerEvent('dreamer_run_failed', taskId, {
470
- errorCategory: 'lease_conflict',
471
- errorMessage: classified.message,
472
- });
473
- return {
474
- status: 'failed',
475
- taskId,
476
- errorCategory: 'lease_conflict',
477
- failureReason: classified.message,
478
- attemptCount: 1,
479
- };
480
- }
481
- // Non-lease errors (e.g., storage_unavailable before lease) must not
482
- // use synthetic TaskRecord. Build one with real defaults from options.
483
- this.emitDreamerEvent('dreamer_run_failed', taskId, {
484
- errorCategory: classified.category,
485
- errorMessage: classified.message,
486
- });
487
- const task = {
488
- taskId,
489
- taskKind: 'dreamer',
490
- status: 'leased',
491
- createdAt: new Date().toISOString(),
492
- updatedAt: new Date().toISOString(),
493
- attemptCount: 1,
494
- maxAttempts: this.resolvedOptions.defaultMaxAttempts,
495
- };
496
- return this.retryOrFail({ taskId, task, errorCategory: classified.category, failureReason: classified.message });
497
- }
498
- async handlePostLeaseError(taskId, task, error) {
499
- const classified = this.classifyError(error);
500
- this.emitDreamerEvent('dreamer_run_failed', taskId, {
501
- errorCategory: classified.category,
502
- errorMessage: classified.message,
503
- });
504
- return this.retryOrFail({ taskId, task, errorCategory: classified.category, failureReason: classified.message });
505
- }
506
- async retryOrFail(ctx) {
507
- // Check if error is permanent (never retry)
508
- if (this.isPermanentError(ctx.errorCategory)) {
509
- try {
510
- await this.stateManager.markTaskFailed(ctx.taskId, ctx.errorCategory);
511
- }
512
- catch (stateErr) {
513
- this.emitDreamerEvent('dreamer_mark_failed_error', ctx.taskId, {
514
- errorCategory: 'storage_unavailable',
515
- attemptCount: ctx.task.attemptCount,
516
- errorMessage: stateErr instanceof Error ? stateErr.message : String(stateErr),
517
- });
518
- return {
519
- status: 'failed',
520
- taskId: ctx.taskId,
521
- errorCategory: 'storage_unavailable',
522
- failureReason: `State manager error: ${ctx.failureReason}`,
523
- attemptCount: ctx.task.attemptCount,
524
- };
525
- }
526
- this.emitDreamerEvent('dreamer_task_failed', ctx.taskId, {
527
- errorCategory: ctx.errorCategory,
528
- attemptCount: ctx.task.attemptCount,
529
- failureReason: ctx.failureReason,
530
- });
531
- this.phase = RunnerPhase.Failed;
532
- return {
533
- status: 'failed',
534
- taskId: ctx.taskId,
535
- errorCategory: ctx.errorCategory,
536
- failureReason: ctx.failureReason,
537
- attemptCount: ctx.task.attemptCount,
538
- };
539
- }
540
- // Check retry policy
541
- const shouldRetry = this.stateManager.getRetryPolicy().shouldRetry(ctx.task);
542
- if (shouldRetry) {
543
- try {
544
- await this.stateManager.markTaskRetryWait(ctx.taskId, ctx.errorCategory);
545
- }
546
- catch (stateErr) {
547
- this.emitDreamerEvent('dreamer_mark_retry_error', ctx.taskId, {
548
- errorCategory: 'storage_unavailable',
549
- attemptCount: ctx.task.attemptCount,
550
- errorMessage: stateErr instanceof Error ? stateErr.message : String(stateErr),
551
- });
552
- return {
553
- status: 'failed',
554
- taskId: ctx.taskId,
555
- errorCategory: 'storage_unavailable',
556
- failureReason: `State manager error: ${ctx.failureReason}`,
557
- attemptCount: ctx.task.attemptCount,
558
- };
559
- }
560
- this.emitDreamerEvent('dreamer_task_retried', ctx.taskId, {
561
- errorCategory: ctx.errorCategory,
562
- attemptCount: ctx.task.attemptCount,
563
- });
564
- this.phase = RunnerPhase.RetryWaiting;
565
- return {
566
- status: 'retried',
567
- taskId: ctx.taskId,
568
- errorCategory: ctx.errorCategory,
569
- failureReason: ctx.failureReason,
570
- attemptCount: ctx.task.attemptCount,
571
- };
572
- }
573
- // Max attempts exceeded
574
- try {
575
- await this.stateManager.markTaskFailed(ctx.taskId, 'max_attempts_exceeded');
576
- }
577
- catch (stateErr) {
578
- this.emitDreamerEvent('dreamer_mark_failed_error', ctx.taskId, {
579
- errorCategory: 'storage_unavailable',
580
- attemptCount: ctx.task.attemptCount,
581
- errorMessage: stateErr instanceof Error ? stateErr.message : String(stateErr),
582
- });
583
- return {
584
- status: 'failed',
585
- taskId: ctx.taskId,
586
- errorCategory: 'storage_unavailable',
587
- failureReason: `State manager error: ${ctx.failureReason}`,
588
- attemptCount: ctx.task.attemptCount,
589
- };
590
- }
591
- this.emitDreamerEvent('dreamer_task_failed', ctx.taskId, {
592
- errorCategory: 'max_attempts_exceeded',
593
- attemptCount: ctx.task.attemptCount,
594
- failureReason: `Max attempts exceeded: ${ctx.failureReason}`,
595
- });
596
- this.phase = RunnerPhase.Failed;
597
- return {
598
- status: 'failed',
599
- taskId: ctx.taskId,
600
- errorCategory: 'max_attempts_exceeded',
601
- failureReason: `Max attempts exceeded: ${ctx.failureReason}`,
602
- attemptCount: ctx.task.attemptCount,
199
+ contextHash,
200
+ output,
201
+ attemptCount: task.attemptCount,
603
202
  };
604
203
  }
605
- // ── Error classification ──────────────────────────────────────────────────
606
- PERMANENT_ERROR_CATEGORIES = new Set(Object.freeze(['storage_unavailable', 'workspace_invalid', 'capability_missing', 'cancelled', 'input_invalid']));
607
- isPermanentError(category) {
608
- return this.PERMANENT_ERROR_CATEGORIES.has(category);
609
- }
204
+ // ── Optional hooks ─────────────────────────────────────────────────────────
205
+ /**
206
+ * Re-inject taskId if stripped by stripLineageFields (PRI-272 / ERR-008).
207
+ * Only fill when absent via Object.hasOwn — present-but-falsy values
208
+ * must reach validation and fail loud (Runtime Contract Rule 3).
209
+ */
610
210
  // eslint-disable-next-line @typescript-eslint/class-methods-use-this
611
- classifyError(error) {
612
- if (error instanceof PDRuntimeError) {
613
- return { category: error.category, message: error.message };
614
- }
615
- if (error instanceof Error) {
616
- return { category: 'execution_failed', message: error.message };
617
- }
618
- return { category: 'execution_failed', message: String(error) };
211
+ postFetchTransform(taskId, untrustedOutput) {
212
+ injectRunnerLineageIfAbsent(untrustedOutput, 'taskId', taskId);
619
213
  }
620
- // eslint-disable-next-line @typescript-eslint/class-methods-use-this
621
- mapRunStatusToErrorCategory(status, _reason) {
622
- switch (status) {
623
- case 'failed': return 'execution_failed';
624
- case 'timed_out': return 'timeout';
625
- case 'cancelled': return 'cancelled';
626
- default: return 'execution_failed';
214
+ emitSuccessTelemetry(taskId, output) {
215
+ for (const candidate of output.candidates) {
216
+ this.emitEvent('candidate_generated', taskId, {
217
+ candidateIndex: candidate.candidateIndex,
218
+ confidence: candidate.confidence,
219
+ riskLevel: candidate.riskLevel,
220
+ });
627
221
  }
628
222
  }
629
- // eslint-disable-next-line @typescript-eslint/class-methods-use-this
630
- sleep(ms) {
631
- return new Promise((resolve) => setTimeout(resolve, ms));
632
- }
633
223
  }
634
- // ── Exports ───────────────────────────────────────────────────────────────────
635
- export { resolveDreamerRunnerOptions, DEFAULT_DREAMER_RUNNER_OPTIONS };
636
224
  //# sourceMappingURL=dreamer-runner.js.map