@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,83 @@
1
+ /**
2
+ * Factory crash recovery: orphaned worktree detection, stale session cleanup,
3
+ * and stuck instance recovery.
4
+ *
5
+ * When the factory orchestrator crashes (SIGKILL, OOM, power loss), worktrees
6
+ * and DB records persist with no in-memory tracking. On restart, this module:
7
+ *
8
+ * 1. Scans `.telora/factory-worktrees/` for directories not tracked in memory.
9
+ * 2. Resets factory_sessions stuck in 'running' to 'failed'.
10
+ * 3. Resets factory_instances stuck in 'building'/'gating' to 'paused' with
11
+ * an escalation about unclean shutdown.
12
+ * 4. Commits WIP changes in orphaned worktrees to preserve in-flight work.
13
+ *
14
+ * Runs after config init and before the poll loop starts, so the factory
15
+ * starts in a clean, known state.
16
+ *
17
+ * Mirrors the recovery patterns from packages/daemon/src/crash-recovery.ts.
18
+ */
19
+ import type { FactoryConfig } from './types.js';
20
+ export interface OrphanedWorktree {
21
+ /** Absolute path to the worktree directory on disk. */
22
+ worktreePath: string;
23
+ /** Git branch name derived from the worktree entry (if available). */
24
+ branchName: string | null;
25
+ }
26
+ export interface RecoveryAction {
27
+ type: 'worktree_wip_committed' | 'session_reset' | 'instance_paused' | 'escalation_created' | 'execution_unit_reset';
28
+ /** Entity ID (worktree path, session ID, instance ID, or execution unit ID). */
29
+ entityId: string;
30
+ /** Human-readable description of what was done. */
31
+ description: string;
32
+ }
33
+ export interface RecoveryResult {
34
+ /** Number of orphaned worktrees found on disk. */
35
+ orphanedWorktreesFound: number;
36
+ /** Number of WIP commits created for orphaned worktrees. */
37
+ wipCommitsCreated: number;
38
+ /** Number of sessions reset from 'running' to 'failed'. */
39
+ sessionsReset: number;
40
+ /** Number of instances reset from 'building'/'gating' to 'paused'. */
41
+ instancesPaused: number;
42
+ /** Number of escalations created for paused instances. */
43
+ escalationsCreated: number;
44
+ /** Number of execution units reset from 'assigned'/'running' to 'idle'. */
45
+ executionUnitsReset: number;
46
+ /** Detailed log of all recovery actions taken. */
47
+ actions: RecoveryAction[];
48
+ /** Non-fatal errors encountered during recovery. */
49
+ errors: string[];
50
+ }
51
+ /**
52
+ * Parse `git worktree list --porcelain` output to build a map of
53
+ * worktree path -> branch name for all registered worktrees.
54
+ */
55
+ export declare function parseWorktreeList(repoPath: string): Map<string, string>;
56
+ /**
57
+ * Scan the factory worktree directory for directories that exist on disk.
58
+ *
59
+ * Returns all subdirectories found in `factoryWorktreeDir`, each with
60
+ * its git branch name (if git tracks it) or null.
61
+ *
62
+ * The caller determines which worktrees are "orphaned" by comparing
63
+ * against the in-memory active instances map (which is empty on fresh start).
64
+ */
65
+ export declare function scanFactoryWorktrees(config: FactoryConfig): OrphanedWorktree[];
66
+ /**
67
+ * Run full crash recovery on factory orchestrator startup.
68
+ *
69
+ * Should be called after config init and API client setup, but before
70
+ * the poll loop starts. Safe to call multiple times -- idempotent by
71
+ * design. A second run with no crashed state finds nothing to recover.
72
+ *
73
+ * Recovery steps:
74
+ * 1. Scan for orphaned worktrees and WIP-commit uncommitted changes.
75
+ * 2. Reset factory_sessions stuck in 'running' to 'failed'.
76
+ * 3. Reset factory_instances stuck in 'building'/'gating' to 'paused'.
77
+ * 4. Create escalations for paused instances.
78
+ *
79
+ * @param config - Factory configuration.
80
+ * @returns A RecoveryResult summarizing all actions taken.
81
+ */
82
+ export declare function recoverFromCrash(config: FactoryConfig): Promise<RecoveryResult>;
83
+ //# sourceMappingURL=crash-recovery.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"crash-recovery.d.ts","sourceRoot":"","sources":["../src/crash-recovery.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAKH,OAAO,KAAK,EAAE,aAAa,EAAmB,MAAM,YAAY,CAAC;AAYjE,MAAM,WAAW,gBAAgB;IAC/B,uDAAuD;IACvD,YAAY,EAAE,MAAM,CAAC;IACrB,sEAAsE;IACtE,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,wBAAwB,GAAG,eAAe,GAAG,iBAAiB,GAAG,oBAAoB,GAAG,sBAAsB,CAAC;IACrH,gFAAgF;IAChF,QAAQ,EAAE,MAAM,CAAC;IACjB,mDAAmD;IACnD,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,cAAc;IAC7B,kDAAkD;IAClD,sBAAsB,EAAE,MAAM,CAAC;IAC/B,4DAA4D;IAC5D,iBAAiB,EAAE,MAAM,CAAC;IAC1B,2DAA2D;IAC3D,aAAa,EAAE,MAAM,CAAC;IACtB,sEAAsE;IACtE,eAAe,EAAE,MAAM,CAAC;IACxB,0DAA0D;IAC1D,kBAAkB,EAAE,MAAM,CAAC;IAC3B,2EAA2E;IAC3E,mBAAmB,EAAE,MAAM,CAAC;IAC5B,kDAAkD;IAClD,OAAO,EAAE,cAAc,EAAE,CAAC;IAC1B,oDAAoD;IACpD,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAyDD;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAiBvE;AAED;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,aAAa,GAAG,gBAAgB,EAAE,CA6C9E;AAgWD;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,gBAAgB,CAAC,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,cAAc,CAAC,CA0FrF"}
@@ -0,0 +1,522 @@
1
+ /**
2
+ * Factory crash recovery: orphaned worktree detection, stale session cleanup,
3
+ * and stuck instance recovery.
4
+ *
5
+ * When the factory orchestrator crashes (SIGKILL, OOM, power loss), worktrees
6
+ * and DB records persist with no in-memory tracking. On restart, this module:
7
+ *
8
+ * 1. Scans `.telora/factory-worktrees/` for directories not tracked in memory.
9
+ * 2. Resets factory_sessions stuck in 'running' to 'failed'.
10
+ * 3. Resets factory_instances stuck in 'building'/'gating' to 'paused' with
11
+ * an escalation about unclean shutdown.
12
+ * 4. Commits WIP changes in orphaned worktrees to preserve in-flight work.
13
+ *
14
+ * Runs after config init and before the poll loop starts, so the factory
15
+ * starts in a clean, known state.
16
+ *
17
+ * Mirrors the recovery patterns from packages/daemon/src/crash-recovery.ts.
18
+ */
19
+ import { execFileSync } from 'node:child_process';
20
+ import { existsSync, readdirSync, statSync } from 'node:fs';
21
+ import { join, resolve } from 'node:path';
22
+ import { commitWip } from './git-factory.js';
23
+ import { updateInstanceStatus, getActiveInstances } from './queries/instances.js';
24
+ import { updateFactorySession } from './queries/sessions.js';
25
+ import { createFactoryEscalation } from './queries/escalations.js';
26
+ import { getExecutionUnitsByInstance, updateExecutionUnit } from './queries/execution-units.js';
27
+ import { productLabel } from './product-config.js';
28
+ // ============================================================================
29
+ // Git helpers (synchronous, same pattern as git-factory.ts)
30
+ // ============================================================================
31
+ /** Default timeout for git CLI operations (30 seconds -- read-only ops are fast). */
32
+ const GIT_TIMEOUT_MS = 30_000;
33
+ /**
34
+ * Run a git command synchronously and return a structured result.
35
+ * Never throws -- callers inspect `result.success`.
36
+ */
37
+ function runGit(args, cwd) {
38
+ try {
39
+ const output = execFileSync('git', args, {
40
+ cwd,
41
+ encoding: 'utf-8',
42
+ stdio: ['pipe', 'pipe', 'pipe'],
43
+ timeout: GIT_TIMEOUT_MS,
44
+ });
45
+ return { success: true, output: output.trim(), error: '' };
46
+ }
47
+ catch (err) {
48
+ const execErr = err;
49
+ if (execErr.killed || execErr.signal === 'SIGTERM') {
50
+ return {
51
+ success: false,
52
+ output: execErr.stdout?.toString() ?? '',
53
+ error: `Git operation timed out after ${GIT_TIMEOUT_MS}ms: git ${args.join(' ')}`,
54
+ };
55
+ }
56
+ return {
57
+ success: false,
58
+ output: execErr.stdout?.toString() ?? '',
59
+ error: execErr.stderr?.toString() ?? execErr.message ?? 'Unknown git error',
60
+ };
61
+ }
62
+ }
63
+ // ============================================================================
64
+ // Worktree scanning
65
+ // ============================================================================
66
+ /**
67
+ * Parse `git worktree list --porcelain` output to build a map of
68
+ * worktree path -> branch name for all registered worktrees.
69
+ */
70
+ export function parseWorktreeList(repoPath) {
71
+ const result = runGit(['worktree', 'list', '--porcelain'], repoPath);
72
+ const map = new Map();
73
+ if (!result.success)
74
+ return map;
75
+ let currentPath = null;
76
+ for (const line of result.output.split('\n')) {
77
+ if (line.startsWith('worktree ')) {
78
+ currentPath = line.slice('worktree '.length);
79
+ }
80
+ else if (line.startsWith('branch refs/heads/') && currentPath) {
81
+ map.set(currentPath, line.slice('branch refs/heads/'.length));
82
+ currentPath = null;
83
+ }
84
+ else if (line === '') {
85
+ currentPath = null;
86
+ }
87
+ }
88
+ return map;
89
+ }
90
+ /**
91
+ * Scan the factory worktree directory for directories that exist on disk.
92
+ *
93
+ * Returns all subdirectories found in `factoryWorktreeDir`, each with
94
+ * its git branch name (if git tracks it) or null.
95
+ *
96
+ * The caller determines which worktrees are "orphaned" by comparing
97
+ * against the in-memory active instances map (which is empty on fresh start).
98
+ */
99
+ export function scanFactoryWorktrees(config) {
100
+ // Parse git worktree list from all configured product repos
101
+ const pathToBranch = new Map();
102
+ for (const product of config.products) {
103
+ const worktreeMap = parseWorktreeList(product.repoPath);
104
+ for (const [wtPath, branch] of worktreeMap) {
105
+ pathToBranch.set(resolve(wtPath), branch);
106
+ }
107
+ }
108
+ // Scan each product's factory worktree directory
109
+ const orphans = [];
110
+ for (const product of config.products) {
111
+ const factoryDir = resolve(product.repoPath, '.telora', 'factory-worktrees');
112
+ if (!existsSync(factoryDir)) {
113
+ continue;
114
+ }
115
+ const entries = readdirSync(factoryDir);
116
+ const subdirs = entries.filter((entry) => {
117
+ const fullPath = join(factoryDir, entry);
118
+ try {
119
+ return statSync(fullPath).isDirectory();
120
+ }
121
+ catch {
122
+ return false;
123
+ }
124
+ });
125
+ for (const subdir of subdirs) {
126
+ const fullPath = resolve(join(factoryDir, subdir));
127
+ const branchName = pathToBranch.get(fullPath) ?? null;
128
+ orphans.push({
129
+ worktreePath: fullPath,
130
+ branchName,
131
+ });
132
+ }
133
+ }
134
+ if (orphans.length === 0) {
135
+ console.log('[crash-recovery] No orphaned factory worktrees found across any product');
136
+ }
137
+ return orphans;
138
+ }
139
+ // ============================================================================
140
+ // Recovery: orphaned worktrees
141
+ // ============================================================================
142
+ /**
143
+ * WIP-commit any uncommitted changes in orphaned factory worktrees.
144
+ *
145
+ * This preserves in-flight work that was not committed before the crash.
146
+ * The worktrees are left in place -- they will be reused when the instance
147
+ * resumes (after being reset to 'paused').
148
+ */
149
+ function recoverOrphanedWorktrees(orphans) {
150
+ let wipCommitsCreated = 0;
151
+ const actions = [];
152
+ for (const orphan of orphans) {
153
+ const label = orphan.branchName ?? 'unknown-branch';
154
+ try {
155
+ const sha = commitWip(orphan.worktreePath, `crash-recovery: ${label}`);
156
+ if (sha) {
157
+ wipCommitsCreated++;
158
+ actions.push({
159
+ type: 'worktree_wip_committed',
160
+ entityId: orphan.worktreePath,
161
+ description: `WIP commit ${sha.slice(0, 8)} created for orphaned worktree (branch: ${label})`,
162
+ });
163
+ console.log(`[crash-recovery] WIP commit ${sha.slice(0, 8)} for orphaned worktree: ${orphan.worktreePath}`);
164
+ }
165
+ else {
166
+ console.log(`[crash-recovery] Orphaned worktree has no uncommitted changes: ${orphan.worktreePath}`);
167
+ }
168
+ }
169
+ catch (err) {
170
+ console.warn(`[crash-recovery] Failed to WIP-commit orphaned worktree ${orphan.worktreePath}: ` +
171
+ `${err instanceof Error ? err.message : String(err)}`);
172
+ }
173
+ }
174
+ return { wipCommitsCreated, actions };
175
+ }
176
+ // ============================================================================
177
+ // Recovery: stale sessions
178
+ // ============================================================================
179
+ /**
180
+ * Reset factory sessions stuck in 'running' or 'starting' status to 'failed'.
181
+ *
182
+ * After a crash, any sessions that were 'running' are no longer actually
183
+ * running -- their processes died with the orchestrator. We query the API
184
+ * for all instances that might have active sessions and reset them.
185
+ */
186
+ async function recoverStaleSessions(config) {
187
+ const sessionsReset = 0;
188
+ const actions = [];
189
+ const errors = [];
190
+ // We need to find sessions stuck in 'running' status. Since we don't have
191
+ // a direct "get all running sessions" query, we use getActiveSessionsForInstance
192
+ // for each instance that might have stale sessions. We get the instances from
193
+ // the pending query (which returns instances that aren't in terminal states).
194
+ //
195
+ // However, getPendingInstances only returns 'pending' status. For crash
196
+ // recovery we need instances in 'building' and 'gating' states too.
197
+ // Those will be handled via the instance recovery below, which also
198
+ // resets their sessions. But we still want a catch-all for any sessions
199
+ // that might be orphaned.
200
+ //
201
+ // The approach: reset sessions for instances we know about from worktree
202
+ // scanning. The instance recovery step will handle the rest.
203
+ // Note: Session reset for specific instances happens in recoverStuckInstances.
204
+ // This function serves as documentation of the strategy. The actual per-instance
205
+ // session reset is co-located with the instance status reset for atomicity.
206
+ void config; // Config may be used in future for direct session queries
207
+ return { sessionsReset, actions, errors };
208
+ }
209
+ // ============================================================================
210
+ // Recovery: stuck instances
211
+ // ============================================================================
212
+ /**
213
+ * Find and recover factory instances stuck in 'building' or 'gating' status.
214
+ *
215
+ * After an unclean shutdown, these instances had active processing that
216
+ * was interrupted. We:
217
+ * 1. Reset their status to 'paused'.
218
+ * 2. Mark their active sessions as 'failed'.
219
+ * 3. Create an escalation to notify the human operator.
220
+ */
221
+ async function recoverStuckInstances(config) {
222
+ let instancesPaused = 0;
223
+ let sessionsReset = 0;
224
+ let escalationsCreated = 0;
225
+ const actions = [];
226
+ const errors = [];
227
+ // Query non-terminal instances (designing, planning, building, paused) and
228
+ // filter for those stuck in active processing states after the crash.
229
+ // Query instances across all configured products (per-product isolation)
230
+ const instances = [];
231
+ for (const product of config.products) {
232
+ const pLabel = productLabel(product);
233
+ try {
234
+ const productInstances = await getActiveInstances(product.id);
235
+ if (productInstances.length > 0) {
236
+ console.log(`[crash-recovery] [${pLabel}] Found ${productInstances.length} active instance(s)`);
237
+ }
238
+ instances.push(...productInstances);
239
+ }
240
+ catch (err) {
241
+ const msg = `[${pLabel}] Failed to query instances for crash recovery: ${err instanceof Error ? err.message : String(err)}`;
242
+ console.warn(`[crash-recovery] ${msg}`);
243
+ errors.push(msg);
244
+ // continue to next product
245
+ }
246
+ }
247
+ // Filter for instances that are stuck in active processing states
248
+ // Note: 'gating' was removed as an instance-level status -- gates run
249
+ // inline per work unit during the 'building' phase.
250
+ const stuckStatuses = new Set(['building']);
251
+ const stuckInstances = instances.filter((inst) => stuckStatuses.has(inst.status));
252
+ if (stuckInstances.length === 0) {
253
+ console.log('[crash-recovery] No stuck instances found in building status');
254
+ return { instancesPaused, sessionsReset, escalationsCreated, actions, errors };
255
+ }
256
+ console.log(`[crash-recovery] Found ${stuckInstances.length} instance(s) stuck in building/gating status`);
257
+ // Build a reverse map: instance product_id -> product label for per-instance logging
258
+ const productLabelByProductId = new Map();
259
+ for (const product of config.products) {
260
+ productLabelByProductId.set(product.id, productLabel(product));
261
+ }
262
+ for (const instance of stuckInstances) {
263
+ const instLabel = productLabelByProductId.get(instance.productId ?? '') ?? '';
264
+ const instPrefix = instLabel ? `[crash-recovery] [${instLabel}]` : '[crash-recovery]';
265
+ // Step 1: Reset active sessions to 'failed'
266
+ try {
267
+ const { getActiveSessionsForInstance } = await import('./queries/sessions.js');
268
+ const activeSessions = await getActiveSessionsForInstance(instance.id);
269
+ for (const session of activeSessions) {
270
+ try {
271
+ await updateFactorySession(session.id, {
272
+ status: 'failed',
273
+ endedAt: new Date().toISOString(),
274
+ });
275
+ sessionsReset++;
276
+ actions.push({
277
+ type: 'session_reset',
278
+ entityId: session.id,
279
+ description: `Session reset from '${session.status}' to 'failed' (instance ${instance.id}, crash recovery)`,
280
+ });
281
+ }
282
+ catch (err) {
283
+ const msg = `Failed to reset session ${session.id}: ${err instanceof Error ? err.message : String(err)}`;
284
+ console.warn(`${instPrefix} ${msg}`);
285
+ errors.push(msg);
286
+ }
287
+ }
288
+ }
289
+ catch (err) {
290
+ const msg = `Failed to query sessions for instance ${instance.id}: ${err instanceof Error ? err.message : String(err)}`;
291
+ console.warn(`${instPrefix} ${msg}`);
292
+ errors.push(msg);
293
+ }
294
+ // Step 2: Reset instance status to 'paused'
295
+ try {
296
+ await updateInstanceStatus(instance.id, 'paused', {
297
+ escalationReason: 'Unclean shutdown recovery',
298
+ escalationMessage: `Factory orchestrator crashed or was killed while instance was in '${instance.status}' status. ` +
299
+ 'Instance has been paused for manual review. Active sessions have been marked as failed. ' +
300
+ 'Resume or cancel this instance from the control panel.',
301
+ escalatedAt: new Date().toISOString(),
302
+ });
303
+ instancesPaused++;
304
+ actions.push({
305
+ type: 'instance_paused',
306
+ entityId: instance.id,
307
+ description: `Instance reset from '${instance.status}' to 'paused' (crash recovery)`,
308
+ });
309
+ console.log(`${instPrefix} Instance ${instance.id} reset: ${instance.status} -> paused`);
310
+ }
311
+ catch (err) {
312
+ const msg = `Failed to pause instance ${instance.id}: ${err instanceof Error ? err.message : String(err)}`;
313
+ console.error(`${instPrefix} ${msg}`);
314
+ errors.push(msg);
315
+ continue; // Skip escalation if we couldn't even pause the instance
316
+ }
317
+ // Step 3: Create escalation
318
+ try {
319
+ await createFactoryEscalation(instance.id, 'Unclean shutdown: factory orchestrator crashed', `Instance was in '${instance.status}' status when the factory orchestrator shut down unexpectedly. ` +
320
+ `The instance has been paused and its active sessions marked as failed. ` +
321
+ `Please review the instance state and either resume or cancel it.`);
322
+ escalationsCreated++;
323
+ actions.push({
324
+ type: 'escalation_created',
325
+ entityId: instance.id,
326
+ description: `Escalation created for instance paused during crash recovery (was '${instance.status}')`,
327
+ });
328
+ console.log(`${instPrefix} Created escalation for instance ${instance.id}`);
329
+ }
330
+ catch (err) {
331
+ const msg = `Failed to create escalation for instance ${instance.id}: ${err instanceof Error ? err.message : String(err)}`;
332
+ console.warn(`${instPrefix} ${msg}`);
333
+ errors.push(msg);
334
+ }
335
+ }
336
+ return { instancesPaused, sessionsReset, escalationsCreated, actions, errors };
337
+ }
338
+ // ============================================================================
339
+ // Recovery: orphaned execution units
340
+ // ============================================================================
341
+ /**
342
+ * Reset execution units stuck in 'assigned' or 'running' status to 'idle'.
343
+ *
344
+ * After a crash, these units had active sessions that died with the daemon.
345
+ * We query ALL active (non-terminal) instances and reset their orphaned units.
346
+ * This runs BEFORE instance adoption so the scheduler sees clean state.
347
+ */
348
+ async function recoverOrphanedExecutionUnits(config) {
349
+ let executionUnitsReset = 0;
350
+ const actions = [];
351
+ const errors = [];
352
+ // Query instances across all configured products (per-product isolation)
353
+ const instances = [];
354
+ // Build a reverse map: product id -> product label for per-instance logging
355
+ const productLabelById = new Map();
356
+ for (const product of config.products) {
357
+ const pLabel = productLabel(product);
358
+ productLabelById.set(product.id, pLabel);
359
+ try {
360
+ const productInstances = await getActiveInstances(product.id);
361
+ instances.push(...productInstances);
362
+ }
363
+ catch (err) {
364
+ const msg = `[${pLabel}] Failed to query instances for execution unit recovery: ${err instanceof Error ? err.message : String(err)}`;
365
+ console.warn(`[crash-recovery] ${msg}`);
366
+ errors.push(msg);
367
+ // continue to next product
368
+ }
369
+ }
370
+ // Only building instances have execution units
371
+ const buildingInstances = instances.filter((inst) => inst.status === 'building');
372
+ if (buildingInstances.length === 0) {
373
+ console.log('[crash-recovery] No building instances found -- skipping execution unit recovery');
374
+ return { executionUnitsReset, actions, errors };
375
+ }
376
+ for (const instance of buildingInstances) {
377
+ const instLabel = productLabelById.get(instance.productId ?? '') ?? '';
378
+ const instPrefix = instLabel ? `[crash-recovery] [${instLabel}]` : '[crash-recovery]';
379
+ let units;
380
+ try {
381
+ units = await getExecutionUnitsByInstance(instance.id);
382
+ }
383
+ catch (err) {
384
+ const msg = `Failed to query execution units for instance ${instance.id}: ${err instanceof Error ? err.message : String(err)}`;
385
+ console.warn(`${instPrefix} ${msg}`);
386
+ errors.push(msg);
387
+ continue;
388
+ }
389
+ const orphanedUnits = units.filter((u) => u.status === 'assigned' || u.status === 'running');
390
+ for (const unit of orphanedUnits) {
391
+ try {
392
+ await updateExecutionUnit(unit.id, {
393
+ status: 'idle',
394
+ assignedStrategyId: null,
395
+ claudeSessionId: null,
396
+ assignedAt: null,
397
+ });
398
+ executionUnitsReset++;
399
+ actions.push({
400
+ type: 'execution_unit_reset',
401
+ entityId: unit.id,
402
+ description: `Execution unit reset from '${unit.status}' to 'idle' ` +
403
+ `(instance ${instance.id}, slot ${unit.slotIndex}, crash recovery)`,
404
+ });
405
+ console.log(`${instPrefix} Reset execution unit ${unit.id} (slot ${unit.slotIndex}) ` +
406
+ `from '${unit.status}' to 'idle' (instance ${instance.id})`);
407
+ }
408
+ catch (err) {
409
+ const msg = `Failed to reset execution unit ${unit.id}: ${err instanceof Error ? err.message : String(err)}`;
410
+ console.warn(`${instPrefix} ${msg}`);
411
+ errors.push(msg);
412
+ }
413
+ }
414
+ }
415
+ if (executionUnitsReset > 0) {
416
+ console.log(`[crash-recovery] Reset ${executionUnitsReset} orphaned execution unit(s) to idle`);
417
+ }
418
+ else {
419
+ console.log('[crash-recovery] No orphaned execution units found');
420
+ }
421
+ return { executionUnitsReset, actions, errors };
422
+ }
423
+ // ============================================================================
424
+ // Main recovery orchestrator
425
+ // ============================================================================
426
+ /**
427
+ * Run full crash recovery on factory orchestrator startup.
428
+ *
429
+ * Should be called after config init and API client setup, but before
430
+ * the poll loop starts. Safe to call multiple times -- idempotent by
431
+ * design. A second run with no crashed state finds nothing to recover.
432
+ *
433
+ * Recovery steps:
434
+ * 1. Scan for orphaned worktrees and WIP-commit uncommitted changes.
435
+ * 2. Reset factory_sessions stuck in 'running' to 'failed'.
436
+ * 3. Reset factory_instances stuck in 'building'/'gating' to 'paused'.
437
+ * 4. Create escalations for paused instances.
438
+ *
439
+ * @param config - Factory configuration.
440
+ * @returns A RecoveryResult summarizing all actions taken.
441
+ */
442
+ export async function recoverFromCrash(config) {
443
+ console.log('[crash-recovery] Starting factory crash recovery scan...');
444
+ const result = {
445
+ orphanedWorktreesFound: 0,
446
+ wipCommitsCreated: 0,
447
+ sessionsReset: 0,
448
+ instancesPaused: 0,
449
+ escalationsCreated: 0,
450
+ executionUnitsReset: 0,
451
+ actions: [],
452
+ errors: [],
453
+ };
454
+ // Step 1: Scan for orphaned worktrees and WIP-commit uncommitted changes
455
+ try {
456
+ const orphans = scanFactoryWorktrees(config);
457
+ result.orphanedWorktreesFound = orphans.length;
458
+ if (orphans.length > 0) {
459
+ console.log(`[crash-recovery] Found ${orphans.length} worktree(s) across factory-worktrees directories`);
460
+ const worktreeResult = recoverOrphanedWorktrees(orphans);
461
+ result.wipCommitsCreated = worktreeResult.wipCommitsCreated;
462
+ result.actions.push(...worktreeResult.actions);
463
+ }
464
+ }
465
+ catch (err) {
466
+ const msg = `Failed during worktree scan: ${err instanceof Error ? err.message : String(err)}`;
467
+ console.error(`[crash-recovery] ${msg}`);
468
+ result.errors.push(msg);
469
+ }
470
+ // Step 2: Reset stale sessions (catch-all for sessions not tied to instances)
471
+ try {
472
+ const sessionResult = await recoverStaleSessions(config);
473
+ result.sessionsReset += sessionResult.sessionsReset;
474
+ result.actions.push(...sessionResult.actions);
475
+ result.errors.push(...sessionResult.errors);
476
+ }
477
+ catch (err) {
478
+ const msg = `Failed during stale session recovery: ${err instanceof Error ? err.message : String(err)}`;
479
+ console.error(`[crash-recovery] ${msg}`);
480
+ result.errors.push(msg);
481
+ }
482
+ // Step 3: Reset orphaned execution units (assigned/running -> idle)
483
+ // This runs BEFORE instance adoption so the scheduler sees clean state.
484
+ try {
485
+ const euResult = await recoverOrphanedExecutionUnits(config);
486
+ result.executionUnitsReset = euResult.executionUnitsReset;
487
+ result.actions.push(...euResult.actions);
488
+ result.errors.push(...euResult.errors);
489
+ }
490
+ catch (err) {
491
+ const msg = `Failed during execution unit recovery: ${err instanceof Error ? err.message : String(err)}`;
492
+ console.error(`[crash-recovery] ${msg}`);
493
+ result.errors.push(msg);
494
+ }
495
+ // Step 4: Reset stuck instances (building/gating -> paused) and their sessions
496
+ try {
497
+ const instanceResult = await recoverStuckInstances(config);
498
+ result.instancesPaused = instanceResult.instancesPaused;
499
+ result.sessionsReset += instanceResult.sessionsReset;
500
+ result.escalationsCreated = instanceResult.escalationsCreated;
501
+ result.actions.push(...instanceResult.actions);
502
+ result.errors.push(...instanceResult.errors);
503
+ }
504
+ catch (err) {
505
+ const msg = `Failed during stuck instance recovery: ${err instanceof Error ? err.message : String(err)}`;
506
+ console.error(`[crash-recovery] ${msg}`);
507
+ result.errors.push(msg);
508
+ }
509
+ // Summary
510
+ console.log(`[crash-recovery] Factory recovery complete: ` +
511
+ `${result.orphanedWorktreesFound} worktree(s) found, ` +
512
+ `${result.wipCommitsCreated} WIP commit(s), ` +
513
+ `${result.sessionsReset} session(s) reset, ` +
514
+ `${result.executionUnitsReset} execution unit(s) reset, ` +
515
+ `${result.instancesPaused} instance(s) paused, ` +
516
+ `${result.escalationsCreated} escalation(s) created`);
517
+ if (result.errors.length > 0) {
518
+ console.warn(`[crash-recovery] ${result.errors.length} non-fatal error(s) during recovery`);
519
+ }
520
+ return result;
521
+ }
522
+ //# sourceMappingURL=crash-recovery.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"crash-recovery.js","sourceRoot":"","sources":["../src/crash-recovery.ts"],"names":[],"mappings":"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"}