@telora/factory 0.4.5

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 (301) hide show
  1. package/dist/audit.d.ts +69 -0
  2. package/dist/audit.d.ts.map +1 -0
  3. package/dist/audit.js +376 -0
  4. package/dist/audit.js.map +1 -0
  5. package/dist/builder-completion.d.ts +35 -0
  6. package/dist/builder-completion.d.ts.map +1 -0
  7. package/dist/builder-completion.js +375 -0
  8. package/dist/builder-completion.js.map +1 -0
  9. package/dist/builder-spawner.d.ts +40 -0
  10. package/dist/builder-spawner.d.ts.map +1 -0
  11. package/dist/builder-spawner.js +493 -0
  12. package/dist/builder-spawner.js.map +1 -0
  13. package/dist/completion-gate.d.ts +52 -0
  14. package/dist/completion-gate.d.ts.map +1 -0
  15. package/dist/completion-gate.js +336 -0
  16. package/dist/completion-gate.js.map +1 -0
  17. package/dist/completion-report.d.ts +36 -0
  18. package/dist/completion-report.d.ts.map +1 -0
  19. package/dist/completion-report.js +348 -0
  20. package/dist/completion-report.js.map +1 -0
  21. package/dist/completion.d.ts +58 -0
  22. package/dist/completion.d.ts.map +1 -0
  23. package/dist/completion.js +287 -0
  24. package/dist/completion.js.map +1 -0
  25. package/dist/config.d.ts +16 -0
  26. package/dist/config.d.ts.map +1 -0
  27. package/dist/config.js +57 -0
  28. package/dist/config.js.map +1 -0
  29. package/dist/context-manager.d.ts +152 -0
  30. package/dist/context-manager.d.ts.map +1 -0
  31. package/dist/context-manager.js +421 -0
  32. package/dist/context-manager.js.map +1 -0
  33. package/dist/crash-detection.d.ts +70 -0
  34. package/dist/crash-detection.d.ts.map +1 -0
  35. package/dist/crash-detection.js +123 -0
  36. package/dist/crash-detection.js.map +1 -0
  37. package/dist/crash-recovery.d.ts +83 -0
  38. package/dist/crash-recovery.d.ts.map +1 -0
  39. package/dist/crash-recovery.js +522 -0
  40. package/dist/crash-recovery.js.map +1 -0
  41. package/dist/crash-resolution.d.ts +34 -0
  42. package/dist/crash-resolution.d.ts.map +1 -0
  43. package/dist/crash-resolution.js +382 -0
  44. package/dist/crash-resolution.js.map +1 -0
  45. package/dist/escalation.d.ts +150 -0
  46. package/dist/escalation.d.ts.map +1 -0
  47. package/dist/escalation.js +352 -0
  48. package/dist/escalation.js.map +1 -0
  49. package/dist/execution-target.d.ts +31 -0
  50. package/dist/execution-target.d.ts.map +1 -0
  51. package/dist/execution-target.js +71 -0
  52. package/dist/execution-target.js.map +1 -0
  53. package/dist/execution-unit-init.d.ts +28 -0
  54. package/dist/execution-unit-init.d.ts.map +1 -0
  55. package/dist/execution-unit-init.js +115 -0
  56. package/dist/execution-unit-init.js.map +1 -0
  57. package/dist/execution.d.ts +17 -0
  58. package/dist/execution.d.ts.map +1 -0
  59. package/dist/execution.js +20 -0
  60. package/dist/execution.js.map +1 -0
  61. package/dist/factory-engine.d.ts +100 -0
  62. package/dist/factory-engine.d.ts.map +1 -0
  63. package/dist/factory-engine.js +243 -0
  64. package/dist/factory-engine.js.map +1 -0
  65. package/dist/gap-detection.d.ts +43 -0
  66. package/dist/gap-detection.d.ts.map +1 -0
  67. package/dist/gap-detection.js +149 -0
  68. package/dist/gap-detection.js.map +1 -0
  69. package/dist/gate-context.d.ts +23 -0
  70. package/dist/gate-context.d.ts.map +1 -0
  71. package/dist/gate-context.js +63 -0
  72. package/dist/gate-context.js.map +1 -0
  73. package/dist/gate-engine.d.ts +55 -0
  74. package/dist/gate-engine.d.ts.map +1 -0
  75. package/dist/gate-engine.js +191 -0
  76. package/dist/gate-engine.js.map +1 -0
  77. package/dist/gates/adversarial.d.ts +59 -0
  78. package/dist/gates/adversarial.d.ts.map +1 -0
  79. package/dist/gates/adversarial.js +426 -0
  80. package/dist/gates/adversarial.js.map +1 -0
  81. package/dist/gates/adversary-spawner.d.ts +35 -0
  82. package/dist/gates/adversary-spawner.d.ts.map +1 -0
  83. package/dist/gates/adversary-spawner.js +286 -0
  84. package/dist/gates/adversary-spawner.js.map +1 -0
  85. package/dist/gates/adversary-test-dir.d.ts +41 -0
  86. package/dist/gates/adversary-test-dir.d.ts.map +1 -0
  87. package/dist/gates/adversary-test-dir.js +150 -0
  88. package/dist/gates/adversary-test-dir.js.map +1 -0
  89. package/dist/gates/behavioral-parser.d.ts +32 -0
  90. package/dist/gates/behavioral-parser.d.ts.map +1 -0
  91. package/dist/gates/behavioral-parser.js +190 -0
  92. package/dist/gates/behavioral-parser.js.map +1 -0
  93. package/dist/gates/behavioral-runner.d.ts +36 -0
  94. package/dist/gates/behavioral-runner.d.ts.map +1 -0
  95. package/dist/gates/behavioral-runner.js +306 -0
  96. package/dist/gates/behavioral-runner.js.map +1 -0
  97. package/dist/gates/behavioral.d.ts +37 -0
  98. package/dist/gates/behavioral.d.ts.map +1 -0
  99. package/dist/gates/behavioral.js +485 -0
  100. package/dist/gates/behavioral.js.map +1 -0
  101. package/dist/gates/deterministic.d.ts +24 -0
  102. package/dist/gates/deterministic.d.ts.map +1 -0
  103. package/dist/gates/deterministic.js +186 -0
  104. package/dist/gates/deterministic.js.map +1 -0
  105. package/dist/git-factory.d.ts +59 -0
  106. package/dist/git-factory.d.ts.map +1 -0
  107. package/dist/git-factory.js +102 -0
  108. package/dist/git-factory.js.map +1 -0
  109. package/dist/guard-evaluation.d.ts +48 -0
  110. package/dist/guard-evaluation.d.ts.map +1 -0
  111. package/dist/guard-evaluation.js +416 -0
  112. package/dist/guard-evaluation.js.map +1 -0
  113. package/dist/index.d.ts +30 -0
  114. package/dist/index.d.ts.map +1 -0
  115. package/dist/index.js +39 -0
  116. package/dist/index.js.map +1 -0
  117. package/dist/instance-completion.d.ts +34 -0
  118. package/dist/instance-completion.d.ts.map +1 -0
  119. package/dist/instance-completion.js +366 -0
  120. package/dist/instance-completion.js.map +1 -0
  121. package/dist/instance-lifecycle.d.ts +15 -0
  122. package/dist/instance-lifecycle.d.ts.map +1 -0
  123. package/dist/instance-lifecycle.js +18 -0
  124. package/dist/instance-lifecycle.js.map +1 -0
  125. package/dist/instance-phase-dispatch.d.ts +75 -0
  126. package/dist/instance-phase-dispatch.d.ts.map +1 -0
  127. package/dist/instance-phase-dispatch.js +674 -0
  128. package/dist/instance-phase-dispatch.js.map +1 -0
  129. package/dist/instance-poll-loop.d.ts +43 -0
  130. package/dist/instance-poll-loop.d.ts.map +1 -0
  131. package/dist/instance-poll-loop.js +360 -0
  132. package/dist/instance-poll-loop.js.map +1 -0
  133. package/dist/instance-state-machine.d.ts +52 -0
  134. package/dist/instance-state-machine.d.ts.map +1 -0
  135. package/dist/instance-state-machine.js +235 -0
  136. package/dist/instance-state-machine.js.map +1 -0
  137. package/dist/log-manager.d.ts +28 -0
  138. package/dist/log-manager.d.ts.map +1 -0
  139. package/dist/log-manager.js +71 -0
  140. package/dist/log-manager.js.map +1 -0
  141. package/dist/pipeline-evaluator.d.ts +61 -0
  142. package/dist/pipeline-evaluator.d.ts.map +1 -0
  143. package/dist/pipeline-evaluator.js +107 -0
  144. package/dist/pipeline-evaluator.js.map +1 -0
  145. package/dist/pipeline-metrics.d.ts +52 -0
  146. package/dist/pipeline-metrics.d.ts.map +1 -0
  147. package/dist/pipeline-metrics.js +40 -0
  148. package/dist/pipeline-metrics.js.map +1 -0
  149. package/dist/pipeline-traversal.d.ts +43 -0
  150. package/dist/pipeline-traversal.d.ts.map +1 -0
  151. package/dist/pipeline-traversal.js +68 -0
  152. package/dist/pipeline-traversal.js.map +1 -0
  153. package/dist/plan-parser.d.ts +76 -0
  154. package/dist/plan-parser.d.ts.map +1 -0
  155. package/dist/plan-parser.js +223 -0
  156. package/dist/plan-parser.js.map +1 -0
  157. package/dist/planning-phase.d.ts +52 -0
  158. package/dist/planning-phase.d.ts.map +1 -0
  159. package/dist/planning-phase.js +444 -0
  160. package/dist/planning-phase.js.map +1 -0
  161. package/dist/planning-prompt.d.ts +64 -0
  162. package/dist/planning-prompt.d.ts.map +1 -0
  163. package/dist/planning-prompt.js +251 -0
  164. package/dist/planning-prompt.js.map +1 -0
  165. package/dist/planning.d.ts +16 -0
  166. package/dist/planning.d.ts.map +1 -0
  167. package/dist/planning.js +17 -0
  168. package/dist/planning.js.map +1 -0
  169. package/dist/process-runner.d.ts +41 -0
  170. package/dist/process-runner.d.ts.map +1 -0
  171. package/dist/process-runner.js +81 -0
  172. package/dist/process-runner.js.map +1 -0
  173. package/dist/product-config.d.ts +34 -0
  174. package/dist/product-config.d.ts.map +1 -0
  175. package/dist/product-config.js +43 -0
  176. package/dist/product-config.js.map +1 -0
  177. package/dist/queries/cycle-evaluations.d.ts +23 -0
  178. package/dist/queries/cycle-evaluations.d.ts.map +1 -0
  179. package/dist/queries/cycle-evaluations.js +37 -0
  180. package/dist/queries/cycle-evaluations.js.map +1 -0
  181. package/dist/queries/escalations.d.ts +30 -0
  182. package/dist/queries/escalations.d.ts.map +1 -0
  183. package/dist/queries/escalations.js +42 -0
  184. package/dist/queries/escalations.js.map +1 -0
  185. package/dist/queries/execution-units.d.ts +76 -0
  186. package/dist/queries/execution-units.d.ts.map +1 -0
  187. package/dist/queries/execution-units.js +109 -0
  188. package/dist/queries/execution-units.js.map +1 -0
  189. package/dist/queries/gate-results.d.ts +32 -0
  190. package/dist/queries/gate-results.d.ts.map +1 -0
  191. package/dist/queries/gate-results.js +44 -0
  192. package/dist/queries/gate-results.js.map +1 -0
  193. package/dist/queries/instances.d.ts +51 -0
  194. package/dist/queries/instances.d.ts.map +1 -0
  195. package/dist/queries/instances.js +77 -0
  196. package/dist/queries/instances.js.map +1 -0
  197. package/dist/queries/sessions.d.ts +50 -0
  198. package/dist/queries/sessions.d.ts.map +1 -0
  199. package/dist/queries/sessions.js +81 -0
  200. package/dist/queries/sessions.js.map +1 -0
  201. package/dist/queries/shared.d.ts +38 -0
  202. package/dist/queries/shared.d.ts.map +1 -0
  203. package/dist/queries/shared.js +119 -0
  204. package/dist/queries/shared.js.map +1 -0
  205. package/dist/queries/specs.d.ts +12 -0
  206. package/dist/queries/specs.d.ts.map +1 -0
  207. package/dist/queries/specs.js +21 -0
  208. package/dist/queries/specs.js.map +1 -0
  209. package/dist/queries/strategies.d.ts +14 -0
  210. package/dist/queries/strategies.d.ts.map +1 -0
  211. package/dist/queries/strategies.js +18 -0
  212. package/dist/queries/strategies.js.map +1 -0
  213. package/dist/queries/work-units.d.ts +42 -0
  214. package/dist/queries/work-units.d.ts.map +1 -0
  215. package/dist/queries/work-units.js +57 -0
  216. package/dist/queries/work-units.js.map +1 -0
  217. package/dist/queries/workflows.d.ts +29 -0
  218. package/dist/queries/workflows.d.ts.map +1 -0
  219. package/dist/queries/workflows.js +103 -0
  220. package/dist/queries/workflows.js.map +1 -0
  221. package/dist/remediation-units.d.ts +40 -0
  222. package/dist/remediation-units.d.ts.map +1 -0
  223. package/dist/remediation-units.js +263 -0
  224. package/dist/remediation-units.js.map +1 -0
  225. package/dist/replanning.d.ts +72 -0
  226. package/dist/replanning.d.ts.map +1 -0
  227. package/dist/replanning.js +403 -0
  228. package/dist/replanning.js.map +1 -0
  229. package/dist/resource-limits.d.ts +62 -0
  230. package/dist/resource-limits.d.ts.map +1 -0
  231. package/dist/resource-limits.js +322 -0
  232. package/dist/resource-limits.js.map +1 -0
  233. package/dist/scheduler.d.ts +98 -0
  234. package/dist/scheduler.d.ts.map +1 -0
  235. package/dist/scheduler.js +203 -0
  236. package/dist/scheduler.js.map +1 -0
  237. package/dist/session-adapter.d.ts +89 -0
  238. package/dist/session-adapter.d.ts.map +1 -0
  239. package/dist/session-adapter.js +108 -0
  240. package/dist/session-adapter.js.map +1 -0
  241. package/dist/sop-generator.d.ts +29 -0
  242. package/dist/sop-generator.d.ts.map +1 -0
  243. package/dist/sop-generator.js +235 -0
  244. package/dist/sop-generator.js.map +1 -0
  245. package/dist/spec-profiles.d.ts +41 -0
  246. package/dist/spec-profiles.d.ts.map +1 -0
  247. package/dist/spec-profiles.js +131 -0
  248. package/dist/spec-profiles.js.map +1 -0
  249. package/dist/strategy-design-graph.d.ts +23 -0
  250. package/dist/strategy-design-graph.d.ts.map +1 -0
  251. package/dist/strategy-design-graph.js +205 -0
  252. package/dist/strategy-design-graph.js.map +1 -0
  253. package/dist/strategy-design-prompt.d.ts +28 -0
  254. package/dist/strategy-design-prompt.d.ts.map +1 -0
  255. package/dist/strategy-design-prompt.js +108 -0
  256. package/dist/strategy-design-prompt.js.map +1 -0
  257. package/dist/strategy-design-schema.d.ts +767 -0
  258. package/dist/strategy-design-schema.d.ts.map +1 -0
  259. package/dist/strategy-design-schema.js +126 -0
  260. package/dist/strategy-design-schema.js.map +1 -0
  261. package/dist/strategy-design.d.ts +69 -0
  262. package/dist/strategy-design.d.ts.map +1 -0
  263. package/dist/strategy-design.js +411 -0
  264. package/dist/strategy-design.js.map +1 -0
  265. package/dist/strategy-gating.d.ts +31 -0
  266. package/dist/strategy-gating.d.ts.map +1 -0
  267. package/dist/strategy-gating.js +276 -0
  268. package/dist/strategy-gating.js.map +1 -0
  269. package/dist/team-prompt-builder.d.ts +47 -0
  270. package/dist/team-prompt-builder.d.ts.map +1 -0
  271. package/dist/team-prompt-builder.js +362 -0
  272. package/dist/team-prompt-builder.js.map +1 -0
  273. package/dist/trace-engine.d.ts +40 -0
  274. package/dist/trace-engine.d.ts.map +1 -0
  275. package/dist/trace-engine.js +344 -0
  276. package/dist/trace-engine.js.map +1 -0
  277. package/dist/types.d.ts +612 -0
  278. package/dist/types.d.ts.map +1 -0
  279. package/dist/types.js +9 -0
  280. package/dist/types.js.map +1 -0
  281. package/dist/unit-session-lifecycle.d.ts +78 -0
  282. package/dist/unit-session-lifecycle.d.ts.map +1 -0
  283. package/dist/unit-session-lifecycle.js +141 -0
  284. package/dist/unit-session-lifecycle.js.map +1 -0
  285. package/dist/unit-session.d.ts +30 -0
  286. package/dist/unit-session.d.ts.map +1 -0
  287. package/dist/unit-session.js +370 -0
  288. package/dist/unit-session.js.map +1 -0
  289. package/dist/watchdogs.d.ts +33 -0
  290. package/dist/watchdogs.d.ts.map +1 -0
  291. package/dist/watchdogs.js +170 -0
  292. package/dist/watchdogs.js.map +1 -0
  293. package/dist/work-unit-scheduler.d.ts +34 -0
  294. package/dist/work-unit-scheduler.d.ts.map +1 -0
  295. package/dist/work-unit-scheduler.js +91 -0
  296. package/dist/work-unit-scheduler.js.map +1 -0
  297. package/dist/workflow-transition.d.ts +90 -0
  298. package/dist/workflow-transition.d.ts.map +1 -0
  299. package/dist/workflow-transition.js +340 -0
  300. package/dist/workflow-transition.js.map +1 -0
  301. package/package.json +65 -0
@@ -0,0 +1,352 @@
1
+ /**
2
+ * Factory instance escalation and stuck detection.
3
+ *
4
+ * Handles escalation when resource limits are hit or the factory gets stuck.
5
+ * Pauses the instance and signals the human via the agent_escalations table.
6
+ *
7
+ * Stuck detection identifies when the same gate is failing N consecutive
8
+ * times with the same error pattern, indicating the builder is unable to
9
+ * make progress.
10
+ *
11
+ * Resume support: when a human resolves the escalation, the instance can
12
+ * transition from 'paused' back to 'building' via resumeInstance().
13
+ */
14
+ import { updateInstanceStatus, updateInstanceWorkflowStage } from './queries/instances.js';
15
+ import { createFactoryEscalation } from './queries/escalations.js';
16
+ import { getGateResultsByInstance } from './queries/gate-results.js';
17
+ import { getOrResolveWorkflow, attemptTransition } from './workflow-transition.js';
18
+ // ============================================================================
19
+ // Escalation trigger constants
20
+ // ============================================================================
21
+ /** Trigger fired when resource limits (token budget, wall clock, etc.) are exceeded. */
22
+ export const TRIGGER_RESOURCE_LIMIT_EXCEEDED = 'resource_limit_exceeded';
23
+ /** Trigger fired when a builder appears stuck (same gate failure repeated). */
24
+ export const TRIGGER_BUILDER_STUCK = 'builder_stuck';
25
+ /** Trigger fired when a work unit exhausts all gate retry iterations. */
26
+ export const TRIGGER_GATE_FAILURE_EXHAUSTED = 'gate_failure_exhausted';
27
+ /** Trigger fired when strategy-level gate evaluation fails. */
28
+ export const TRIGGER_STRATEGY_GATE_FAILED = 'strategy_gate_failed';
29
+ // ============================================================================
30
+ // Constants
31
+ // ============================================================================
32
+ /** Default number of consecutive same-pattern failures before stuck detection triggers. */
33
+ const DEFAULT_STUCK_THRESHOLD = 3;
34
+ /** Maximum length of error pattern to compare for stuck detection. */
35
+ const ERROR_PATTERN_MAX_LENGTH = 500;
36
+ /** Log prefix for all escalation messages. */
37
+ const LOG_PREFIX = '[escalation]';
38
+ // ============================================================================
39
+ // Escalation entry point
40
+ // ============================================================================
41
+ /**
42
+ * Escalate a factory instance.
43
+ *
44
+ * Sets the instance status to 'paused', records the escalation reason
45
+ * and message on the instance record, and creates an escalation entry
46
+ * in the agent_escalations table to signal the human.
47
+ *
48
+ * @param instanceId - The factory instance UUID.
49
+ * @param reason - Short reason for the escalation (e.g. "token_budget_exceeded").
50
+ * @param message - Detailed human-readable message describing the situation.
51
+ * @param config - Optional escalation configuration overrides.
52
+ * @param sessionId - Optional session ID to link the escalation to.
53
+ */
54
+ export async function escalateInstance(instanceId, reason, message, config, sessionId) {
55
+ // config is available for future use (e.g., escalation routing rules)
56
+ void config;
57
+ const now = new Date().toISOString();
58
+ console.log(`${LOG_PREFIX} Escalating instance ${instanceId}: ${reason}`);
59
+ // Step 1: Update instance status to paused with escalation fields
60
+ await updateInstanceStatus(instanceId, 'paused', {
61
+ escalationReason: reason,
62
+ escalationMessage: message,
63
+ escalatedAt: now,
64
+ });
65
+ // Step 2: Create an escalation record for the human to review
66
+ await createFactoryEscalation(instanceId, reason, message, undefined, sessionId);
67
+ console.log(`${LOG_PREFIX} Instance ${instanceId} paused and escalation created. ` +
68
+ `Reason: ${reason}`);
69
+ }
70
+ /**
71
+ * Escalate a factory instance using its in-memory state.
72
+ *
73
+ * Attempts a workflow-governed transition from the current status to
74
+ * 'paused'. If the workflow allows it (or no workflow exists), updates
75
+ * in-memory state and persists the escalation.
76
+ */
77
+ export async function escalateInstanceState(state, reason, message, config, sessionId) {
78
+ // Attempt workflow-governed transition to paused
79
+ const workflow = await getOrResolveWorkflow('factory_instance');
80
+ const ctx = buildEscalationEvalContext(state);
81
+ const transResult = await attemptTransition(workflow, state.status, 'paused', state.productId, 'factory_instance', state.instanceId, ctx);
82
+ if (!transResult.allowed) {
83
+ console.log(`${LOG_PREFIX} Instance ${state.instanceId} transition ${state.status} -> paused ` +
84
+ `blocked by workflow guards -- skipping escalation`);
85
+ return;
86
+ }
87
+ state.status = 'paused';
88
+ state.escalatedAt = new Date().toISOString();
89
+ if (transResult.newStageId) {
90
+ state.currentWorkflowStageId = transResult.newStageId;
91
+ await updateInstanceWorkflowStage(state.instanceId, transResult.newStageId, 'paused');
92
+ }
93
+ await escalateInstance(state.instanceId, reason, message, config, sessionId);
94
+ }
95
+ // ============================================================================
96
+ // Resume support
97
+ // ============================================================================
98
+ /**
99
+ * Resume a paused factory instance.
100
+ *
101
+ * Attempts a workflow-governed transition from 'paused' back to 'building'
102
+ * and clears the escalation fields. This is called when a human resolves
103
+ * the escalation and wants the factory to continue.
104
+ *
105
+ * @param instanceId - The factory instance UUID.
106
+ * @param state - The in-memory instance state (if available).
107
+ */
108
+ export async function resumeInstance(instanceId, state) {
109
+ console.log(`${LOG_PREFIX} Resuming instance ${instanceId} from paused state`);
110
+ // Attempt workflow-governed transition: paused -> building
111
+ if (state) {
112
+ const workflow = await getOrResolveWorkflow('factory_instance');
113
+ const ctx = buildEscalationEvalContext(state);
114
+ const transResult = await attemptTransition(workflow, 'paused', 'building', state.productId, 'factory_instance', instanceId, ctx);
115
+ if (!transResult.allowed) {
116
+ console.log(`${LOG_PREFIX} Instance ${instanceId} transition paused -> building ` +
117
+ `blocked by workflow guards`);
118
+ return;
119
+ }
120
+ if (transResult.newStageId) {
121
+ state.currentWorkflowStageId = transResult.newStageId;
122
+ await updateInstanceWorkflowStage(instanceId, transResult.newStageId, 'building');
123
+ }
124
+ }
125
+ await updateInstanceStatus(instanceId, 'building', {
126
+ escalationReason: null,
127
+ escalationMessage: null,
128
+ escalatedAt: null,
129
+ });
130
+ // Update in-memory state if provided
131
+ if (state) {
132
+ state.status = 'building';
133
+ }
134
+ console.log(`${LOG_PREFIX} Instance ${instanceId} resumed: paused -> building`);
135
+ }
136
+ /**
137
+ * Build a minimal EvaluationContext for escalation transitions.
138
+ */
139
+ function buildEscalationEvalContext(state) {
140
+ const elapsedSeconds = Math.floor((Date.now() - state.startedAt.getTime()) / 1000);
141
+ return {
142
+ deliveryId: '',
143
+ openIssueCount: 0,
144
+ totalIssueCount: 0,
145
+ issuesByStatus: {},
146
+ issuesByPriority: {},
147
+ lastExitCode: 0,
148
+ sessionCount: state.activeBuilderSessions.size,
149
+ tokensUsed: state.tokensUsed,
150
+ tokenBudget: state.blueprint.maxTokenBudget,
151
+ cycleCount: state.completionGateIterations,
152
+ wallClockSeconds: elapsedSeconds,
153
+ wallClockLimitSeconds: state.blueprint.maxWallClockHours
154
+ ? state.blueprint.maxWallClockHours * 3600
155
+ : null,
156
+ };
157
+ }
158
+ // ============================================================================
159
+ // Escalation trigger routing
160
+ // ============================================================================
161
+ /**
162
+ * Check whether a given trigger name is configured in the blueprint's
163
+ * escalation triggers list.
164
+ *
165
+ * If the trigger is in the list, the scenario should cause a pause+escalate.
166
+ * If not, the scenario should cause an immediate failure.
167
+ *
168
+ * @param blueprint - The factory blueprint with escalationTriggers config.
169
+ * @param triggerName - The trigger name to check (e.g. TRIGGER_RESOURCE_LIMIT_EXCEEDED).
170
+ * @returns true if the trigger should cause an escalation.
171
+ */
172
+ export function shouldEscalate(blueprint, triggerName) {
173
+ return blueprint.escalationTriggers.includes(triggerName);
174
+ }
175
+ /**
176
+ * Route an escalation-worthy event to either pause+escalate or immediate failure.
177
+ *
178
+ * If the trigger name is in the blueprint's escalationTriggers list, pauses
179
+ * the instance and creates an escalation. Otherwise, calls the onFail callback
180
+ * to fail the instance immediately.
181
+ *
182
+ * @param state - The in-memory instance state.
183
+ * @param triggerName - The trigger category (e.g. TRIGGER_RESOURCE_LIMIT_EXCEEDED).
184
+ * @param reason - Short reason for the escalation.
185
+ * @param message - Detailed human-readable message.
186
+ * @param onFail - Callback invoked when the trigger is not configured for escalation.
187
+ * @param config - Optional escalation configuration overrides.
188
+ */
189
+ export async function escalateOrFail(state, triggerName, reason, message, onFail, config, sessionId) {
190
+ if (shouldEscalate(state.blueprint, triggerName)) {
191
+ await escalateInstanceState(state, reason, message, config, sessionId);
192
+ }
193
+ else {
194
+ console.log(`${LOG_PREFIX} Trigger "${triggerName}" not in escalationTriggers -- failing instead of escalating`);
195
+ await onFail();
196
+ }
197
+ }
198
+ // ============================================================================
199
+ // Stuck detection
200
+ // ============================================================================
201
+ /**
202
+ * Detect whether any strategies in an instance appear to be stuck.
203
+ *
204
+ * A strategy is considered "stuck" when the same gate has failed N
205
+ * consecutive times (where N is the stuckThreshold) with the same
206
+ * error pattern. This indicates the builder is unable to make progress
207
+ * despite retries.
208
+ *
209
+ * Gate results are grouped by strategy_id and analyzed per-strategy.
210
+ *
211
+ * @param instanceState - The in-memory state of the factory instance.
212
+ * @param config - Optional escalation configuration overrides.
213
+ * @returns Array of stuck detection results (one per stuck strategy).
214
+ */
215
+ export async function detectStuckStrategies(instanceState, config) {
216
+ const threshold = config?.stuckThreshold ?? DEFAULT_STUCK_THRESHOLD;
217
+ const allGateResults = await getGateResultsByInstance(instanceState.instanceId);
218
+ const results = [];
219
+ // Group gate results by strategy
220
+ const byStrategy = new Map();
221
+ for (const gr of allGateResults) {
222
+ if (!gr.strategyId)
223
+ continue;
224
+ const existing = byStrategy.get(gr.strategyId);
225
+ if (existing) {
226
+ existing.push(gr);
227
+ }
228
+ else {
229
+ byStrategy.set(gr.strategyId, [gr]);
230
+ }
231
+ }
232
+ for (const [strategyId, gateResults] of byStrategy) {
233
+ const stuckResult = analyzeGateResultsForStuck(strategyId, gateResults, threshold);
234
+ if (stuckResult.isStuck) {
235
+ results.push(stuckResult);
236
+ }
237
+ }
238
+ return results;
239
+ }
240
+ /**
241
+ * Check stuck detection and escalate or fail based on blueprint triggers.
242
+ *
243
+ * Convenience function that combines detectStuckStrategies() with
244
+ * escalateOrFail(). Returns true if the instance was escalated or failed.
245
+ *
246
+ * @param onFail - Callback invoked when TRIGGER_BUILDER_STUCK is not in
247
+ * escalationTriggers and the instance should fail instead.
248
+ */
249
+ export async function checkAndEscalateIfStuck(state, onFail, config) {
250
+ const stuckStrategies = await detectStuckStrategies(state, config);
251
+ if (stuckStrategies.length === 0) {
252
+ return false;
253
+ }
254
+ // Build a detailed message from all stuck strategies
255
+ const details = stuckStrategies.map((s) => {
256
+ const pattern = s.errorPattern
257
+ ? `: "${s.errorPattern.slice(0, 200)}${s.errorPattern.length > 200 ? '...' : ''}"`
258
+ : '';
259
+ return (`Strategy ${s.strategyId} stuck at ${s.gateType ?? 'unknown'} gate ` +
260
+ `(${s.consecutiveFailures} consecutive failures with same error pattern${pattern})`);
261
+ });
262
+ const reason = 'stuck_detected';
263
+ const message = `Factory instance is stuck. ${stuckStrategies.length} strategy(ies) are failing ` +
264
+ `repeatedly with the same error:\n\n${details.join('\n')}`;
265
+ await escalateOrFail(state, TRIGGER_BUILDER_STUCK, reason, message, onFail, config);
266
+ return true;
267
+ }
268
+ // ============================================================================
269
+ // Pure analysis helpers
270
+ // ============================================================================
271
+ /**
272
+ * Analyze gate results for a single strategy to detect stuck patterns.
273
+ *
274
+ * Looks at the most recent gate results in reverse chronological order.
275
+ * If N consecutive failed results have the same gate type and normalized
276
+ * error output, the strategy is considered stuck.
277
+ */
278
+ export function analyzeGateResultsForStuck(strategyId, gateResults, threshold) {
279
+ const notStuck = {
280
+ isStuck: false,
281
+ strategyId,
282
+ gateType: null,
283
+ errorPattern: null,
284
+ consecutiveFailures: 0,
285
+ };
286
+ if (gateResults.length < threshold) {
287
+ return notStuck;
288
+ }
289
+ // Sort by creation time descending (most recent first)
290
+ const sorted = [...gateResults].sort((a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime());
291
+ // Get the most recent failed results
292
+ const recentFailed = [];
293
+ for (const result of sorted) {
294
+ if (!result.passed) {
295
+ recentFailed.push(result);
296
+ }
297
+ else {
298
+ // Stop at the first passing result -- the streak is broken
299
+ break;
300
+ }
301
+ }
302
+ if (recentFailed.length < threshold) {
303
+ return notStuck;
304
+ }
305
+ // Check if the N most recent failures share the same gate type and error pattern
306
+ const referenceResult = recentFailed[0];
307
+ const referencePattern = normalizeErrorPattern(referenceResult.output);
308
+ const referenceGateType = referenceResult.gateType;
309
+ let consecutiveCount = 0;
310
+ for (const result of recentFailed) {
311
+ if (result.gateType !== referenceGateType) {
312
+ break;
313
+ }
314
+ const pattern = normalizeErrorPattern(result.output);
315
+ if (pattern !== referencePattern) {
316
+ break;
317
+ }
318
+ consecutiveCount++;
319
+ }
320
+ if (consecutiveCount >= threshold) {
321
+ return {
322
+ isStuck: true,
323
+ strategyId,
324
+ gateType: referenceGateType,
325
+ errorPattern: referencePattern,
326
+ consecutiveFailures: consecutiveCount,
327
+ };
328
+ }
329
+ return notStuck;
330
+ }
331
+ /**
332
+ * Normalize an error output string for pattern comparison.
333
+ *
334
+ * Applies the following normalizations:
335
+ * - Trims whitespace
336
+ * - Collapses multiple whitespace to single space
337
+ * - Truncates to ERROR_PATTERN_MAX_LENGTH characters
338
+ * - Returns empty string for null/undefined input
339
+ *
340
+ * This allows comparing error outputs that differ only in timestamps,
341
+ * line numbers, or minor formatting variations.
342
+ */
343
+ export function normalizeErrorPattern(output) {
344
+ if (!output) {
345
+ return '';
346
+ }
347
+ return output
348
+ .trim()
349
+ .replace(/\s+/g, ' ')
350
+ .slice(0, ERROR_PATTERN_MAX_LENGTH);
351
+ }
352
+ //# sourceMappingURL=escalation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"escalation.js","sourceRoot":"","sources":["../src/escalation.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Builder execution target -- bridges TriggerExecutionTarget to a running builder.
3
+ *
4
+ * The BuilderExecutionTarget wraps a BuilderState (with its stdin handle) and
5
+ * implements TriggerExecutionTarget for sending stream-json messages to the
6
+ * builder process.
7
+ *
8
+ * Extracted from execution.ts for focused module boundaries.
9
+ */
10
+ import type { BuilderState, FactoryInstanceState, TriggerExecutionTarget, ContextDirective } from './types.js';
11
+ /**
12
+ * Wraps a BuilderState (with its stdin handle) as a TriggerExecutionTarget.
13
+ *
14
+ * Writes stream-json messages to the builder's stdin pipe.
15
+ * Handles edge cases: stdin already closed, write errors.
16
+ */
17
+ export declare class BuilderExecutionTarget implements TriggerExecutionTarget {
18
+ private readonly builder;
19
+ constructor(builder: BuilderState);
20
+ injectPrompt(prompt: string): Promise<void>;
21
+ manageContext(directive: ContextDirective): Promise<void>;
22
+ setField(fieldName: string, fieldValue: unknown): Promise<void>;
23
+ notify(recipients: string[], message: string): Promise<void>;
24
+ private sendMessage;
25
+ }
26
+ /**
27
+ * Look up the active builder for a work unit and return it as a TriggerExecutionTarget.
28
+ * Returns null if no active builder exists for the given work unit.
29
+ */
30
+ export declare function getBuilderTarget(state: FactoryInstanceState, workUnitId: string): TriggerExecutionTarget | null;
31
+ //# sourceMappingURL=execution-target.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"execution-target.d.ts","sourceRoot":"","sources":["../src/execution-target.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EACV,YAAY,EACZ,oBAAoB,EACpB,sBAAsB,EACtB,gBAAgB,EACjB,MAAM,YAAY,CAAC;AAWpB;;;;;GAKG;AACH,qBAAa,sBAAuB,YAAW,sBAAsB;IACvD,OAAO,CAAC,QAAQ,CAAC,OAAO;gBAAP,OAAO,EAAE,YAAY;IAE5C,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAI3C,aAAa,CAAC,SAAS,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC;IASzD,QAAQ,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAI/D,MAAM,CAAC,UAAU,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIlE,OAAO,CAAC,WAAW;CAcpB;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,oBAAoB,EAC3B,UAAU,EAAE,MAAM,GACjB,sBAAsB,GAAG,IAAI,CAM/B"}
@@ -0,0 +1,71 @@
1
+ /**
2
+ * Builder execution target -- bridges TriggerExecutionTarget to a running builder.
3
+ *
4
+ * The BuilderExecutionTarget wraps a BuilderState (with its stdin handle) and
5
+ * implements TriggerExecutionTarget for sending stream-json messages to the
6
+ * builder process.
7
+ *
8
+ * Extracted from execution.ts for focused module boundaries.
9
+ */
10
+ import { executeDirective } from './context-manager.js';
11
+ /** Log prefix for execution-target messages. */
12
+ const LOG_PREFIX = '[execution]';
13
+ // ============================================================================
14
+ // Builder execution target
15
+ // ============================================================================
16
+ /**
17
+ * Wraps a BuilderState (with its stdin handle) as a TriggerExecutionTarget.
18
+ *
19
+ * Writes stream-json messages to the builder's stdin pipe.
20
+ * Handles edge cases: stdin already closed, write errors.
21
+ */
22
+ export class BuilderExecutionTarget {
23
+ builder;
24
+ constructor(builder) {
25
+ this.builder = builder;
26
+ }
27
+ async injectPrompt(prompt) {
28
+ this.sendMessage(prompt, 'inject_prompt');
29
+ }
30
+ async manageContext(directive) {
31
+ const message = executeDirective(directive);
32
+ if (message) {
33
+ this.sendMessage(message, 'manage_context');
34
+ }
35
+ else {
36
+ console.log(`${LOG_PREFIX} manageContext directive '${directive.type}' produced no payload (handled externally or skipped)`);
37
+ }
38
+ }
39
+ async setField(fieldName, fieldValue) {
40
+ console.log(`${LOG_PREFIX} setField("${fieldName}", ${JSON.stringify(fieldValue)}) on builder ${this.builder.sessionId} -- no-op for builder sessions`);
41
+ }
42
+ async notify(recipients, message) {
43
+ console.log(`${LOG_PREFIX} notify(${JSON.stringify(recipients)}, "${message}") on builder ${this.builder.sessionId}`);
44
+ }
45
+ sendMessage(content, action) {
46
+ const { stdin } = this.builder;
47
+ if (!stdin || stdin.destroyed) {
48
+ console.warn(`${LOG_PREFIX} Cannot send ${action} to builder ${this.builder.sessionId} -- stdin closed`);
49
+ return;
50
+ }
51
+ try {
52
+ const payload = JSON.stringify({ type: 'user', content });
53
+ stdin.write(payload + '\n');
54
+ }
55
+ catch (err) {
56
+ console.warn(`${LOG_PREFIX} Failed to write ${action} to builder ${this.builder.sessionId}: ${err.message}`);
57
+ }
58
+ }
59
+ }
60
+ /**
61
+ * Look up the active builder for a work unit and return it as a TriggerExecutionTarget.
62
+ * Returns null if no active builder exists for the given work unit.
63
+ */
64
+ export function getBuilderTarget(state, workUnitId) {
65
+ const builder = state.activeBuilderSessions.get(workUnitId);
66
+ if (!builder || !builder.stdin || builder.stdin.destroyed) {
67
+ return null;
68
+ }
69
+ return new BuilderExecutionTarget(builder);
70
+ }
71
+ //# sourceMappingURL=execution-target.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"execution-target.js","sourceRoot":"","sources":["../src/execution-target.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AASH,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAExD,gDAAgD;AAChD,MAAM,UAAU,GAAG,aAAa,CAAC;AAEjC,+EAA+E;AAC/E,2BAA2B;AAC3B,+EAA+E;AAE/E;;;;;GAKG;AACH,MAAM,OAAO,sBAAsB;IACJ;IAA7B,YAA6B,OAAqB;QAArB,YAAO,GAAP,OAAO,CAAc;IAAG,CAAC;IAEtD,KAAK,CAAC,YAAY,CAAC,MAAc;QAC/B,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IAC5C,CAAC;IAED,KAAK,CAAC,aAAa,CAAC,SAA2B;QAC7C,MAAM,OAAO,GAAG,gBAAgB,CAAC,SAAS,CAAC,CAAC;QAC5C,IAAI,OAAO,EAAE,CAAC;YACZ,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE,gBAAgB,CAAC,CAAC;QAC9C,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,GAAG,CAAC,GAAG,UAAU,6BAA6B,SAAS,CAAC,IAAI,uDAAuD,CAAC,CAAC;QAC/H,CAAC;IACH,CAAC;IAED,KAAK,CAAC,QAAQ,CAAC,SAAiB,EAAE,UAAmB;QACnD,OAAO,CAAC,GAAG,CAAC,GAAG,UAAU,cAAc,SAAS,MAAM,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,gBAAgB,IAAI,CAAC,OAAO,CAAC,SAAS,gCAAgC,CAAC,CAAC;IAC1J,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,UAAoB,EAAE,OAAe;QAChD,OAAO,CAAC,GAAG,CAAC,GAAG,UAAU,WAAW,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,MAAM,OAAO,iBAAiB,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC;IACxH,CAAC;IAEO,WAAW,CAAC,OAAe,EAAE,MAAc;QACjD,MAAM,EAAE,KAAK,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC;QAC/B,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,SAAS,EAAE,CAAC;YAC9B,OAAO,CAAC,IAAI,CAAC,GAAG,UAAU,gBAAgB,MAAM,eAAe,IAAI,CAAC,OAAO,CAAC,SAAS,kBAAkB,CAAC,CAAC;YACzG,OAAO;QACT,CAAC;QAED,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,CAAC;YAC1D,KAAK,CAAC,KAAK,CAAC,OAAO,GAAG,IAAI,CAAC,CAAC;QAC9B,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,IAAI,CAAC,GAAG,UAAU,oBAAoB,MAAM,eAAe,IAAI,CAAC,OAAO,CAAC,SAAS,KAAM,GAAa,CAAC,OAAO,EAAE,CAAC,CAAC;QAC1H,CAAC;IACH,CAAC;CACF;AAED;;;GAGG;AACH,MAAM,UAAU,gBAAgB,CAC9B,KAA2B,EAC3B,UAAkB;IAElB,MAAM,OAAO,GAAG,KAAK,CAAC,qBAAqB,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;IAC5D,IAAI,CAAC,OAAO,IAAI,CAAC,OAAO,CAAC,KAAK,IAAI,OAAO,CAAC,KAAK,CAAC,SAAS,EAAE,CAAC;QAC1D,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,IAAI,sBAAsB,CAAC,OAAO,CAAC,CAAC;AAC7C,CAAC"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Execution unit initialization.
3
+ *
4
+ * Creates execution unit rows in the DB when a factory instance transitions
5
+ * to building. Each unit starts as 'idle', ready for strategy assignment
6
+ * by the scheduler.
7
+ */
8
+ import type { FactoryInstanceState } from './types.js';
9
+ /**
10
+ * Initialize execution units for a factory instance entering the building phase.
11
+ *
12
+ * Creates N execution unit rows in the DB (N = blueprint.executionUnitCount)
13
+ * and populates the in-memory executionUnits map on the instance state.
14
+ * Each unit gets a sequential slot_index (0..N-1), starts as 'idle',
15
+ * and inherits the model from the blueprint's execution unit config.
16
+ *
17
+ * Called once when an instance transitions from planning to building.
18
+ */
19
+ export declare function initializeExecutionUnits(state: FactoryInstanceState): Promise<void>;
20
+ /**
21
+ * Restore execution units from DB into in-memory state.
22
+ *
23
+ * Used during daemon restart (adoptActiveInstance) to rebuild the
24
+ * executionUnits map from existing DB rows. Units that were 'running'
25
+ * are reset to 'idle' since their sessions are gone.
26
+ */
27
+ export declare function restoreExecutionUnits(state: FactoryInstanceState): Promise<void>;
28
+ //# sourceMappingURL=execution-unit-init.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"execution-unit-init.d.ts","sourceRoot":"","sources":["../src/execution-unit-init.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EACV,oBAAoB,EAErB,MAAM,YAAY,CAAC;AAKpB;;;;;;;;;GASG;AACH,wBAAsB,wBAAwB,CAC5C,KAAK,EAAE,oBAAoB,GAC1B,OAAO,CAAC,IAAI,CAAC,CA6Cf;AAED;;;;;;GAMG;AACH,wBAAsB,qBAAqB,CACzC,KAAK,EAAE,oBAAoB,GAC1B,OAAO,CAAC,IAAI,CAAC,CAyDf"}
@@ -0,0 +1,115 @@
1
+ /**
2
+ * Execution unit initialization.
3
+ *
4
+ * Creates execution unit rows in the DB when a factory instance transitions
5
+ * to building. Each unit starts as 'idle', ready for strategy assignment
6
+ * by the scheduler.
7
+ */
8
+ import { createExecutionUnit, getExecutionUnitsByInstance, updateExecutionUnit } from './queries/execution-units.js';
9
+ const LOG_PREFIX = '[factory-init]';
10
+ /**
11
+ * Initialize execution units for a factory instance entering the building phase.
12
+ *
13
+ * Creates N execution unit rows in the DB (N = blueprint.executionUnitCount)
14
+ * and populates the in-memory executionUnits map on the instance state.
15
+ * Each unit gets a sequential slot_index (0..N-1), starts as 'idle',
16
+ * and inherits the model from the blueprint's execution unit config.
17
+ *
18
+ * Called once when an instance transitions from planning to building.
19
+ */
20
+ export async function initializeExecutionUnits(state) {
21
+ const { blueprint } = state;
22
+ const count = blueprint.executionUnitCount;
23
+ const unitConfig = blueprint.executionUnitConfig;
24
+ const defaultModel = unitConfig?.defaultModel ?? null;
25
+ console.log(`${LOG_PREFIX} Initializing ${count} execution unit(s) for instance ${state.instanceId} ` +
26
+ `(model: ${defaultModel ?? 'default'})`);
27
+ for (let i = 0; i < count; i++) {
28
+ const unit = await createExecutionUnit({
29
+ instanceId: state.instanceId,
30
+ slotIndex: i,
31
+ model: defaultModel,
32
+ config: unitConfig,
33
+ });
34
+ state.executionUnits.set(unit.id, {
35
+ unitId: unit.id,
36
+ instanceId: state.instanceId,
37
+ slotIndex: i,
38
+ status: 'idle',
39
+ pid: null,
40
+ stdin: null,
41
+ streamParser: null,
42
+ claudeSessionId: null,
43
+ assignedStrategyId: null,
44
+ assignedAt: null,
45
+ previousStrategyId: null,
46
+ activityTracker: null,
47
+ adapter: null,
48
+ startedAt: null,
49
+ dispatchedAt: null,
50
+ dispatchedWorkUnitIds: new Set(),
51
+ lastActivityAt: null,
52
+ tokensUsed: 0,
53
+ costUsed: 0,
54
+ });
55
+ }
56
+ console.log(`${LOG_PREFIX} Created ${count} execution unit(s) for instance ${state.instanceId}`);
57
+ }
58
+ /**
59
+ * Restore execution units from DB into in-memory state.
60
+ *
61
+ * Used during daemon restart (adoptActiveInstance) to rebuild the
62
+ * executionUnits map from existing DB rows. Units that were 'running'
63
+ * are reset to 'idle' since their sessions are gone.
64
+ */
65
+ export async function restoreExecutionUnits(state) {
66
+ const units = await getExecutionUnitsByInstance(state.instanceId);
67
+ if (units.length === 0) {
68
+ return;
69
+ }
70
+ for (const unit of units) {
71
+ // If the unit was running or assigned when the daemon died, reset to idle.
72
+ // After a crash, sessions for assigned/running units are gone -- the
73
+ // scheduler will reassign them on the next cycle.
74
+ const needsReset = unit.status === 'running' || unit.status === 'assigned';
75
+ const status = needsReset ? 'idle' : unit.status;
76
+ // Also persist the reset to DB so the scheduler sees clean state
77
+ if (needsReset) {
78
+ try {
79
+ await updateExecutionUnit(unit.id, {
80
+ status: 'idle',
81
+ assignedStrategyId: null,
82
+ assignedAt: null,
83
+ claudeSessionId: null,
84
+ });
85
+ }
86
+ catch (err) {
87
+ console.warn(`${LOG_PREFIX} Failed to reset unit ${unit.id} in DB during restore: ` +
88
+ `${err instanceof Error ? err.message : String(err)}`);
89
+ }
90
+ }
91
+ state.executionUnits.set(unit.id, {
92
+ unitId: unit.id,
93
+ instanceId: state.instanceId,
94
+ slotIndex: unit.slotIndex,
95
+ status,
96
+ pid: null,
97
+ stdin: null,
98
+ streamParser: null,
99
+ claudeSessionId: needsReset ? null : unit.claudeSessionId,
100
+ assignedStrategyId: needsReset ? null : unit.assignedStrategyId,
101
+ assignedAt: null,
102
+ previousStrategyId: null,
103
+ activityTracker: null,
104
+ adapter: null,
105
+ startedAt: null,
106
+ dispatchedAt: null,
107
+ dispatchedWorkUnitIds: new Set(),
108
+ lastActivityAt: null,
109
+ tokensUsed: 0,
110
+ costUsed: 0,
111
+ });
112
+ }
113
+ console.log(`${LOG_PREFIX} Restored ${units.length} execution unit(s) for instance ${state.instanceId}`);
114
+ }
115
+ //# sourceMappingURL=execution-unit-init.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"execution-unit-init.js","sourceRoot":"","sources":["../src/execution-unit-init.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Factory execution -- barrel re-export.
3
+ *
4
+ * The implementation has been split into focused modules:
5
+ * - builder-spawner.ts -- builder process spawning, env setup, stream handling
6
+ * - builder-completion.ts -- builder completion handling, execution cycle orchestration
7
+ * - execution-target.ts -- BuilderExecutionTarget (TriggerExecutionTarget impl)
8
+ * - work-unit-scheduler.ts -- DAG-aware work unit readiness, dependency maps
9
+ *
10
+ * This file preserves the original import path for consumers (index.ts, tests).
11
+ */
12
+ export { findReadyWorkUnits } from './work-unit-scheduler.js';
13
+ export type { StrategyDependencyMap, StrategyStatusMap } from './work-unit-scheduler.js';
14
+ export { spawnBuilder, transitionWorkUnitStatus, DEFAULT_MAX_ITERATIONS, LOG_PREFIX, lastGateOutputByWorkUnit } from './builder-spawner.js';
15
+ export { handleBuilderCompletion, runExecutionCycle } from './builder-completion.js';
16
+ export { BuilderExecutionTarget, getBuilderTarget } from './execution-target.js';
17
+ //# sourceMappingURL=execution.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"execution.d.ts","sourceRoot":"","sources":["../src/execution.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAGH,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAC9D,YAAY,EAAE,qBAAqB,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAGzF,OAAO,EAAE,YAAY,EAAE,wBAAwB,EAAE,sBAAsB,EAAE,UAAU,EAAE,wBAAwB,EAAE,MAAM,sBAAsB,CAAC;AAG5I,OAAO,EAAE,uBAAuB,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAGrF,OAAO,EAAE,sBAAsB,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC"}