@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,33 @@
1
+ /**
2
+ * Operational watchdogs for execution unit health monitoring.
3
+ *
4
+ * Three watchdogs run during each checkBuilding() poll cycle:
5
+ * 1. Assignment timeout -- units stuck in 'assigned' state too long
6
+ * 2. Work unit dispatch timeout -- dispatched work units not completing
7
+ * 3. Signal silence -- running units with no stdout activity
8
+ *
9
+ * Each watchdog creates an escalation when its threshold is breached.
10
+ * Timeout values come from the blueprint (nullable), falling back to
11
+ * compile-time defaults.
12
+ */
13
+ import type { FactoryInstanceState } from './types.js';
14
+ import { createFactoryEscalation } from './queries/escalations.js';
15
+ import { updateExecutionUnit } from './queries/execution-units.js';
16
+ /** 5 minutes -- how long a unit can stay in 'assigned' before escalation. */
17
+ export declare const DEFAULT_ASSIGNMENT_TIMEOUT_MS: number;
18
+ /** 30 minutes -- how long a dispatched work unit can run before escalation. */
19
+ export declare const DEFAULT_WORK_UNIT_TIMEOUT_MS: number;
20
+ /** 10 minutes -- how long without stdout before escalation. */
21
+ export declare const DEFAULT_SIGNAL_SILENCE_TIMEOUT_MS: number;
22
+ export interface WatchdogResult {
23
+ assignmentTimeouts: number;
24
+ dispatchTimeouts: number;
25
+ signalSilenceAlerts: number;
26
+ }
27
+ /** Injectable dependencies for testing. */
28
+ export interface WatchdogDeps {
29
+ createEscalation: typeof createFactoryEscalation;
30
+ updateUnit: typeof updateExecutionUnit;
31
+ }
32
+ export declare function runWatchdogs(state: FactoryInstanceState, now?: Date, deps?: WatchdogDeps): Promise<WatchdogResult>;
33
+ //# sourceMappingURL=watchdogs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"watchdogs.d.ts","sourceRoot":"","sources":["../src/watchdogs.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EACV,oBAAoB,EAErB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,uBAAuB,EAAE,MAAM,0BAA0B,CAAC;AACnE,OAAO,EAAE,mBAAmB,EAAE,MAAM,8BAA8B,CAAC;AAQnE,6EAA6E;AAC7E,eAAO,MAAM,6BAA6B,QAAgB,CAAC;AAE3D,+EAA+E;AAC/E,eAAO,MAAM,4BAA4B,QAAiB,CAAC;AAE3D,+DAA+D;AAC/D,eAAO,MAAM,iCAAiC,QAAiB,CAAC;AAMhE,MAAM,WAAW,cAAc;IAC7B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,gBAAgB,EAAE,MAAM,CAAC;IACzB,mBAAmB,EAAE,MAAM,CAAC;CAC7B;AAED,2CAA2C;AAC3C,MAAM,WAAW,YAAY;IAC3B,gBAAgB,EAAE,OAAO,uBAAuB,CAAC;IACjD,UAAU,EAAE,OAAO,mBAAmB,CAAC;CACxC;AAiBD,wBAAsB,YAAY,CAChC,KAAK,EAAE,oBAAoB,EAC3B,GAAG,GAAE,IAAiB,EACtB,IAAI,GAAE,YAA0B,GAC/B,OAAO,CAAC,cAAc,CAAC,CAczB"}
@@ -0,0 +1,170 @@
1
+ /**
2
+ * Operational watchdogs for execution unit health monitoring.
3
+ *
4
+ * Three watchdogs run during each checkBuilding() poll cycle:
5
+ * 1. Assignment timeout -- units stuck in 'assigned' state too long
6
+ * 2. Work unit dispatch timeout -- dispatched work units not completing
7
+ * 3. Signal silence -- running units with no stdout activity
8
+ *
9
+ * Each watchdog creates an escalation when its threshold is breached.
10
+ * Timeout values come from the blueprint (nullable), falling back to
11
+ * compile-time defaults.
12
+ */
13
+ import { createFactoryEscalation } from './queries/escalations.js';
14
+ import { updateExecutionUnit } from './queries/execution-units.js';
15
+ const LOG_PREFIX = '[watchdog]';
16
+ // ============================================================================
17
+ // Default timeouts (used when blueprint columns are NULL)
18
+ // ============================================================================
19
+ /** 5 minutes -- how long a unit can stay in 'assigned' before escalation. */
20
+ export const DEFAULT_ASSIGNMENT_TIMEOUT_MS = 5 * 60 * 1000;
21
+ /** 30 minutes -- how long a dispatched work unit can run before escalation. */
22
+ export const DEFAULT_WORK_UNIT_TIMEOUT_MS = 30 * 60 * 1000;
23
+ /** 10 minutes -- how long without stdout before escalation. */
24
+ export const DEFAULT_SIGNAL_SILENCE_TIMEOUT_MS = 10 * 60 * 1000;
25
+ // ============================================================================
26
+ // Watchdog runner
27
+ // ============================================================================
28
+ /**
29
+ * Run all watchdog checks for a factory instance.
30
+ *
31
+ * Called from checkBuilding() on each poll cycle. Returns counts of
32
+ * how many escalations were created.
33
+ */
34
+ const defaultDeps = {
35
+ createEscalation: createFactoryEscalation,
36
+ updateUnit: updateExecutionUnit,
37
+ };
38
+ export async function runWatchdogs(state, now = new Date(), deps = defaultDeps) {
39
+ const result = {
40
+ assignmentTimeouts: 0,
41
+ dispatchTimeouts: 0,
42
+ signalSilenceAlerts: 0,
43
+ };
44
+ const bp = state.blueprint;
45
+ result.assignmentTimeouts = await checkAssignmentTimeouts(state, bp, now, deps);
46
+ result.dispatchTimeouts = await checkDispatchTimeouts(state, bp, now, deps);
47
+ result.signalSilenceAlerts = await checkSignalSilence(state, bp, now, deps);
48
+ return result;
49
+ }
50
+ // ============================================================================
51
+ // Individual watchdogs
52
+ // ============================================================================
53
+ /**
54
+ * Check for execution units stuck in 'assigned' state beyond the timeout.
55
+ *
56
+ * When a unit is assigned by the scheduler but never transitions to 'running'
57
+ * (e.g., session spawn failed silently), this watchdog catches it, creates an
58
+ * escalation, and resets the unit to 'idle' so the scheduler can retry.
59
+ */
60
+ async function checkAssignmentTimeouts(state, blueprint, now, deps) {
61
+ const timeoutMs = blueprint.unitAssignmentTimeoutMs ?? DEFAULT_ASSIGNMENT_TIMEOUT_MS;
62
+ let count = 0;
63
+ for (const unit of state.executionUnits.values()) {
64
+ if (unit.status !== 'assigned' || !unit.assignedAt)
65
+ continue;
66
+ const elapsed = now.getTime() - unit.assignedAt.getTime();
67
+ if (elapsed < timeoutMs)
68
+ continue;
69
+ console.warn(`${LOG_PREFIX} Unit ${unit.slotIndex} stuck in assigned state for ${Math.round(elapsed / 1000)}s ` +
70
+ `(timeout: ${timeoutMs}ms) -- resetting to idle`);
71
+ try {
72
+ await deps.createEscalation(state.instanceId, 'assignment_timeout', `Execution unit slot ${unit.slotIndex} (${unit.unitId}) was assigned to strategy ` +
73
+ `${unit.assignedStrategyId ?? 'unknown'} for ${Math.round(elapsed / 1000)}s without ` +
74
+ `transitioning to running. Reset to idle.`);
75
+ }
76
+ catch (err) {
77
+ console.error(`${LOG_PREFIX} Failed to create escalation for unit ${unit.unitId}: ` +
78
+ `${err instanceof Error ? err.message : String(err)}`);
79
+ }
80
+ // Reset unit to idle in DB and in-memory
81
+ try {
82
+ await deps.updateUnit(unit.unitId, {
83
+ status: 'idle',
84
+ assignedStrategyId: null,
85
+ assignedAt: null,
86
+ claudeSessionId: null,
87
+ });
88
+ }
89
+ catch (err) {
90
+ console.error(`${LOG_PREFIX} Failed to reset unit ${unit.unitId}: ` +
91
+ `${err instanceof Error ? err.message : String(err)}`);
92
+ }
93
+ unit.status = 'idle';
94
+ unit.assignedStrategyId = null;
95
+ unit.assignedAt = null;
96
+ unit.claudeSessionId = null;
97
+ count++;
98
+ }
99
+ return count;
100
+ }
101
+ /**
102
+ * Check for dispatched work units that have not completed within the timeout.
103
+ *
104
+ * Unlike assignment timeout, this does NOT auto-reset the work unit. It
105
+ * creates an escalation and lets the escalation handler decide how to proceed.
106
+ */
107
+ async function checkDispatchTimeouts(state, blueprint, now, deps) {
108
+ const timeoutMs = blueprint.workUnitTimeoutMs ?? DEFAULT_WORK_UNIT_TIMEOUT_MS;
109
+ let count = 0;
110
+ for (const unit of state.executionUnits.values()) {
111
+ if (unit.status !== 'running' || !unit.dispatchedAt)
112
+ continue;
113
+ const elapsed = now.getTime() - unit.dispatchedAt.getTime();
114
+ if (elapsed < timeoutMs)
115
+ continue;
116
+ console.warn(`${LOG_PREFIX} Unit ${unit.slotIndex} dispatched work unit running for ${Math.round(elapsed / 1000)}s ` +
117
+ `(timeout: ${timeoutMs}ms) -- creating escalation`);
118
+ try {
119
+ await deps.createEscalation(state.instanceId, 'work_unit_timeout', `Execution unit slot ${unit.slotIndex} (${unit.unitId}) has been executing dispatched ` +
120
+ `work for ${Math.round(elapsed / 1000)}s (strategy: ${unit.assignedStrategyId ?? 'unknown'}). ` +
121
+ `Timeout threshold: ${timeoutMs}ms.`);
122
+ }
123
+ catch (err) {
124
+ console.error(`${LOG_PREFIX} Failed to create escalation for dispatch timeout on unit ${unit.unitId}: ` +
125
+ `${err instanceof Error ? err.message : String(err)}`);
126
+ }
127
+ // Clear dispatchedAt and pending set so we don't re-escalate next cycle
128
+ unit.dispatchedAt = null;
129
+ unit.dispatchedWorkUnitIds.clear();
130
+ count++;
131
+ }
132
+ return count;
133
+ }
134
+ /**
135
+ * Check for running units with no stdout activity beyond the threshold.
136
+ *
137
+ * Catches sessions that are alive but stuck (infinite loops, API hangs).
138
+ * Creates an escalation but does not terminate the session.
139
+ */
140
+ async function checkSignalSilence(state, blueprint, now, deps) {
141
+ const timeoutMs = blueprint.signalSilenceTimeoutMs ?? DEFAULT_SIGNAL_SILENCE_TIMEOUT_MS;
142
+ let count = 0;
143
+ for (const unit of state.executionUnits.values()) {
144
+ if (unit.status !== 'running' || !unit.pid)
145
+ continue;
146
+ // Use lastActivityAt if available, fall back to startedAt
147
+ const lastActivity = unit.lastActivityAt ?? unit.startedAt;
148
+ if (!lastActivity)
149
+ continue;
150
+ const elapsed = now.getTime() - lastActivity.getTime();
151
+ if (elapsed < timeoutMs)
152
+ continue;
153
+ console.warn(`${LOG_PREFIX} Unit ${unit.slotIndex} has no stdout activity for ${Math.round(elapsed / 1000)}s ` +
154
+ `(timeout: ${timeoutMs}ms) -- creating escalation`);
155
+ try {
156
+ await deps.createEscalation(state.instanceId, 'signal_silence', `Execution unit slot ${unit.slotIndex} (${unit.unitId}, pid ${unit.pid}) has produced ` +
157
+ `no stdout activity for ${Math.round(elapsed / 1000)}s (strategy: ` +
158
+ `${unit.assignedStrategyId ?? 'unknown'}). Session may be stuck.`);
159
+ }
160
+ catch (err) {
161
+ console.error(`${LOG_PREFIX} Failed to create escalation for signal silence on unit ${unit.unitId}: ` +
162
+ `${err instanceof Error ? err.message : String(err)}`);
163
+ }
164
+ // Update lastActivityAt to now so we don't re-escalate next cycle
165
+ unit.lastActivityAt = now;
166
+ count++;
167
+ }
168
+ return count;
169
+ }
170
+ //# sourceMappingURL=watchdogs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"watchdogs.js","sourceRoot":"","sources":["../src/watchdogs.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,34 @@
1
+ /**
2
+ * DAG scheduling and dependency resolution for factory work units.
3
+ *
4
+ * Pure functions that determine which work units are ready to execute
5
+ * based on intra-plan dependencies and cross-strategy blocking.
6
+ *
7
+ * Extracted from execution.ts for focused module boundaries.
8
+ */
9
+ import type { FactoryWorkUnit } from './types.js';
10
+ /**
11
+ * Map from strategyId to the list of strategy IDs it depends on.
12
+ * Used to enforce cross-strategy dependency blocking at the work unit level.
13
+ */
14
+ export type StrategyDependencyMap = Map<string, string[]>;
15
+ /**
16
+ * Map of strategy ID -> execution status. When provided to findReadyWorkUnits,
17
+ * cross-strategy blocking uses the strategy's execution status (which reflects
18
+ * gate results) instead of checking individual work unit statuses.
19
+ */
20
+ export type StrategyStatusMap = Map<string, string>;
21
+ /**
22
+ * Find work units that are ready to be executed.
23
+ *
24
+ * A work unit is "ready" when:
25
+ * - Its status is 'pending' or 'ready', AND
26
+ * - Every ID in its `blockedBy` array corresponds to a work unit
27
+ * whose status is 'completed', AND
28
+ * - If the work unit has a strategyId and strategyDependencies are provided,
29
+ * ALL work units in all dependency strategies must be 'completed'.
30
+ *
31
+ * This is a pure function -- it operates only on the provided arrays.
32
+ */
33
+ export declare function findReadyWorkUnits(workUnits: FactoryWorkUnit[], strategyDependencies?: StrategyDependencyMap, strategyStatuses?: StrategyStatusMap): FactoryWorkUnit[];
34
+ //# sourceMappingURL=work-unit-scheduler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"work-unit-scheduler.d.ts","sourceRoot":"","sources":["../src/work-unit-scheduler.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EACV,eAAe,EAEhB,MAAM,YAAY,CAAC;AAMpB;;;GAGG;AACH,MAAM,MAAM,qBAAqB,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;AAE1D;;;;GAIG;AACH,MAAM,MAAM,iBAAiB,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAMpD;;;;;;;;;;;GAWG;AACH,wBAAgB,kBAAkB,CAChC,SAAS,EAAE,eAAe,EAAE,EAC5B,oBAAoB,CAAC,EAAE,qBAAqB,EAC5C,gBAAgB,CAAC,EAAE,iBAAiB,GACnC,eAAe,EAAE,CAoEnB"}
@@ -0,0 +1,91 @@
1
+ /**
2
+ * DAG scheduling and dependency resolution for factory work units.
3
+ *
4
+ * Pure functions that determine which work units are ready to execute
5
+ * based on intra-plan dependencies and cross-strategy blocking.
6
+ *
7
+ * Extracted from execution.ts for focused module boundaries.
8
+ */
9
+ // ============================================================================
10
+ // Ready work unit finder
11
+ // ============================================================================
12
+ /**
13
+ * Find work units that are ready to be executed.
14
+ *
15
+ * A work unit is "ready" when:
16
+ * - Its status is 'pending' or 'ready', AND
17
+ * - Every ID in its `blockedBy` array corresponds to a work unit
18
+ * whose status is 'completed', AND
19
+ * - If the work unit has a strategyId and strategyDependencies are provided,
20
+ * ALL work units in all dependency strategies must be 'completed'.
21
+ *
22
+ * This is a pure function -- it operates only on the provided arrays.
23
+ */
24
+ export function findReadyWorkUnits(workUnits, strategyDependencies, strategyStatuses) {
25
+ // Build a lookup of work unit status by ID for O(1) dependency checks.
26
+ const statusById = new Map();
27
+ for (const unit of workUnits) {
28
+ statusById.set(unit.id, unit.status);
29
+ }
30
+ // Build a lookup of strategy completeness: strategyId -> all completed?
31
+ // When strategyStatuses is provided, use the strategy's execution status
32
+ // (which reflects gate results). Otherwise, fall back to checking if all
33
+ // work units in the strategy have status 'completed'.
34
+ let strategyComplete = null;
35
+ if (strategyDependencies && strategyDependencies.size > 0) {
36
+ strategyComplete = new Map();
37
+ if (strategyStatuses) {
38
+ // Use strategy execution status -- downstream only unblocks after gates pass
39
+ for (const [sid] of strategyDependencies) {
40
+ strategyComplete.set(sid, strategyStatuses.get(sid) === 'completed');
41
+ }
42
+ }
43
+ else {
44
+ // Fallback: check work unit statuses directly
45
+ const unitsByStrategy = new Map();
46
+ for (const unit of workUnits) {
47
+ if (unit.strategyId) {
48
+ const list = unitsByStrategy.get(unit.strategyId);
49
+ if (list) {
50
+ list.push(unit);
51
+ }
52
+ else {
53
+ unitsByStrategy.set(unit.strategyId, [unit]);
54
+ }
55
+ }
56
+ }
57
+ for (const [sid, units] of unitsByStrategy) {
58
+ strategyComplete.set(sid, units.every((u) => u.status === 'completed'));
59
+ }
60
+ }
61
+ }
62
+ return workUnits.filter((unit) => {
63
+ // Only consider units that are waiting to be picked up
64
+ if (unit.status !== 'pending' && unit.status !== 'ready') {
65
+ return false;
66
+ }
67
+ // All intra-plan dependencies must be completed.
68
+ // If a blockedBy ID doesn't exist in the work units list (phantom planning
69
+ // ID that was never mapped to a real UUID), treat it as satisfied -- blocking
70
+ // on a non-existent unit would stall the factory permanently.
71
+ const intraReady = unit.blockedBy.every((depId) => {
72
+ const depStatus = statusById.get(depId);
73
+ if (depStatus === undefined)
74
+ return true; // phantom dep -- skip
75
+ return depStatus === 'completed';
76
+ });
77
+ if (!intraReady)
78
+ return false;
79
+ // Cross-strategy dependency check
80
+ if (unit.strategyId && strategyDependencies && strategyComplete) {
81
+ const depStrategies = strategyDependencies.get(unit.strategyId);
82
+ if (depStrategies && depStrategies.length > 0) {
83
+ const allDepsComplete = depStrategies.every((depSid) => strategyComplete.get(depSid) === true);
84
+ if (!allDepsComplete)
85
+ return false;
86
+ }
87
+ }
88
+ return true;
89
+ });
90
+ }
91
+ //# sourceMappingURL=work-unit-scheduler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"work-unit-scheduler.js","sourceRoot":"","sources":["../src/work-unit-scheduler.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,90 @@
1
+ /**
2
+ * Workflow transition orchestrator for the factory engine.
3
+ *
4
+ * Provides a high-level API for transitioning factory entities through
5
+ * workflow-governed state changes. Each transition:
6
+ * 1. Resolves the entity's workflow (cached per instance)
7
+ * 2. Finds the transition from current stage to target stage
8
+ * 3. Fetches and evaluates guards
9
+ * 4. Executes triggers
10
+ * 5. Updates the entity's current_workflow_stage_id
11
+ * 6. Records audit trail
12
+ *
13
+ * Falls back gracefully when no workflow is assigned (direct status update).
14
+ */
15
+ import type { ResolvedFactoryWorkflow, WorkflowTransition, TransitionGuardResult, EvaluationContext, TriggerExecutionTarget, FactoryTemplateContext } from './types.js';
16
+ /**
17
+ * Resolve and cache a factory workflow by entity type.
18
+ * Returns null if no workflow exists for this entity type.
19
+ * Cached entries expire after CACHE_TTL_MS (5 minutes).
20
+ */
21
+ export declare function getOrResolveWorkflow(entityType: string): Promise<ResolvedFactoryWorkflow | null>;
22
+ /**
23
+ * Clear the workflow cache (for testing or hot-reload).
24
+ */
25
+ export declare function clearWorkflowCache(): void;
26
+ /**
27
+ * Find the transition between two stages by name within a workflow.
28
+ * Returns null if no such transition exists.
29
+ */
30
+ export declare function findTransition(workflow: ResolvedFactoryWorkflow, fromStageName: string, toStageName: string): WorkflowTransition | null;
31
+ /**
32
+ * Get the stage name for a given stage ID.
33
+ */
34
+ export declare function getStageName(workflow: ResolvedFactoryWorkflow, stageId: string): string | null;
35
+ /**
36
+ * Evaluate all guards at a workflow transition.
37
+ * Fetches guards from the DB, evaluates conditions, collects triggers.
38
+ */
39
+ export declare function evaluateTransitionGuards(organizationId: string, entityType: string, entityId: string, transition: WorkflowTransition, ctx: EvaluationContext): Promise<TransitionGuardResult>;
40
+ /**
41
+ * Execute triggers from a guard evaluation result.
42
+ * Factory-specific: handles inject_prompt, manage_context, set_field, notify.
43
+ * Skips spawn_agent, create_issue, block_transition (daemon-only).
44
+ */
45
+ export declare function executeFactoryTriggers(triggersToExecute: TransitionGuardResult['triggers_to_execute'], target: TriggerExecutionTarget | null, factoryCtx?: FactoryTemplateContext | null): Promise<void>;
46
+ export interface TransitionResult {
47
+ /** Whether the transition was allowed (guards passed). */
48
+ allowed: boolean;
49
+ /** The new workflow stage ID (null if no workflow or blocked). */
50
+ newStageId: string | null;
51
+ /** The new stage name. */
52
+ newStageName: string | null;
53
+ /** Guard evaluation result (null if no guards). */
54
+ guardResult: TransitionGuardResult | null;
55
+ /** Whether a workflow was found. */
56
+ hasWorkflow: boolean;
57
+ /** Whether the transition was rejected due to a stale stage (concurrent modification). */
58
+ stale?: boolean;
59
+ }
60
+ /**
61
+ * Attempt a workflow-governed transition for a factory entity.
62
+ *
63
+ * This is the main entry point for the factory engine. It:
64
+ * 1. Optionally checks expectedStageId for optimistic locking (concurrent transition protection)
65
+ * 2. Finds the transition in the resolved workflow
66
+ * 3. Evaluates guards
67
+ * 4. Executes triggers (if guards pass)
68
+ * 5. Returns whether the transition is allowed and the new stage ID
69
+ *
70
+ * The caller is responsible for:
71
+ * - Updating the entity's status and current_workflow_stage_id in the DB
72
+ * using WHERE current_workflow_stage_id = expectedStageId for optimistic locking
73
+ * - Updating in-memory state
74
+ * - Retrying on stale result (re-read entity state and re-attempt)
75
+ *
76
+ * @param workflow Resolved workflow (from instance state cache)
77
+ * @param currentStageName Current stage name (e.g. 'pending', 'building')
78
+ * @param targetStageName Target stage name (e.g. 'planning', 'completed')
79
+ * @param organizationId Organization ID for audit trail
80
+ * @param entityType Entity type for audit trail (e.g. 'factory_instance')
81
+ * @param entityId Entity UUID for audit trail
82
+ * @param ctx Evaluation context with factory state data
83
+ * @param target Optional trigger execution target for active sessions
84
+ * @param factoryCtx Optional factory template context for prompt interpolation
85
+ * @param expectedStageId Optional expected current stage ID for optimistic locking.
86
+ * When provided, the transition is rejected with stale=true if the entity's
87
+ * current stage doesn't match, preventing race conditions from concurrent transitions.
88
+ */
89
+ export declare function attemptTransition(workflow: ResolvedFactoryWorkflow | null, currentStageName: string, targetStageName: string, organizationId: string, entityType: string, entityId: string, ctx: EvaluationContext, target?: TriggerExecutionTarget | null, factoryCtx?: FactoryTemplateContext | null, expectedStageId?: string | null): Promise<TransitionResult>;
90
+ //# sourceMappingURL=workflow-transition.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workflow-transition.d.ts","sourceRoot":"","sources":["../src/workflow-transition.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EACV,uBAAuB,EACvB,kBAAkB,EAGlB,qBAAqB,EAErB,iBAAiB,EACjB,sBAAsB,EACtB,sBAAsB,EAEvB,MAAM,YAAY,CAAC;AAuBpB;;;;GAIG;AACH,wBAAsB,oBAAoB,CACxC,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,uBAAuB,GAAG,IAAI,CAAC,CAezC;AAED;;GAEG;AACH,wBAAgB,kBAAkB,IAAI,IAAI,CAEzC;AAMD;;;GAGG;AACH,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,uBAAuB,EACjC,aAAa,EAAE,MAAM,EACrB,WAAW,EAAE,MAAM,GAClB,kBAAkB,GAAG,IAAI,CAS3B;AAED;;GAEG;AACH,wBAAgB,YAAY,CAC1B,QAAQ,EAAE,uBAAuB,EACjC,OAAO,EAAE,MAAM,GACd,MAAM,GAAG,IAAI,CAEf;AAMD;;;GAGG;AACH,wBAAsB,wBAAwB,CAC5C,cAAc,EAAE,MAAM,EACtB,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,kBAAkB,EAC9B,GAAG,EAAE,iBAAiB,GACrB,OAAO,CAAC,qBAAqB,CAAC,CA4FhC;AAMD;;;;GAIG;AACH,wBAAsB,sBAAsB,CAC1C,iBAAiB,EAAE,qBAAqB,CAAC,qBAAqB,CAAC,EAC/D,MAAM,EAAE,sBAAsB,GAAG,IAAI,EACrC,UAAU,CAAC,EAAE,sBAAsB,GAAG,IAAI,GACzC,OAAO,CAAC,IAAI,CAAC,CA4Ef;AAMD,MAAM,WAAW,gBAAgB;IAC/B,0DAA0D;IAC1D,OAAO,EAAE,OAAO,CAAC;IACjB,kEAAkE;IAClE,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,0BAA0B;IAC1B,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,mDAAmD;IACnD,WAAW,EAAE,qBAAqB,GAAG,IAAI,CAAC;IAC1C,oCAAoC;IACpC,WAAW,EAAE,OAAO,CAAC;IACrB,0FAA0F;IAC1F,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAsB,iBAAiB,CACrC,QAAQ,EAAE,uBAAuB,GAAG,IAAI,EACxC,gBAAgB,EAAE,MAAM,EACxB,eAAe,EAAE,MAAM,EACvB,cAAc,EAAE,MAAM,EACtB,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,EAChB,GAAG,EAAE,iBAAiB,EACtB,MAAM,CAAC,EAAE,sBAAsB,GAAG,IAAI,EACtC,UAAU,CAAC,EAAE,sBAAsB,GAAG,IAAI,EAC1C,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,GAC9B,OAAO,CAAC,gBAAgB,CAAC,CAiF3B"}