@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,421 @@
1
+ /**
2
+ * Factory context management module.
3
+ *
4
+ * Builds message payloads for managing AI builder context during the
5
+ * build-gate execution cycle. Supports three operations:
6
+ *
7
+ * - compact: Instruct a running builder to summarize and compact its context
8
+ * - load_files: Instruct a running builder to read specific files into context
9
+ * - reset: Build a fresh prompt for re-spawning a builder with clean context
10
+ *
11
+ * Key design principle: this module produces PAYLOADS only. It never touches
12
+ * ChildProcess, streams, or any process management. The execution module
13
+ * (execution.ts) is responsible for sending payloads to builder processes.
14
+ */
15
+ // ============================================================================
16
+ // Constants
17
+ // ============================================================================
18
+ /** Log prefix for all context management messages. */
19
+ const LOG_PREFIX = '[context-mgr]';
20
+ /**
21
+ * Default number of iterations before triggering a context reset.
22
+ * Can be overridden by blueprint configuration.
23
+ */
24
+ export const DEFAULT_CONTEXT_RESET_AFTER_ITERATIONS = 3;
25
+ /** Maximum number of recent gate results to include in a reset payload. */
26
+ const MAX_RECENT_GATE_RESULTS = 10;
27
+ // ============================================================================
28
+ // Operation payload builders
29
+ // ============================================================================
30
+ /**
31
+ * Build a compact operation payload.
32
+ *
33
+ * Instructs a running builder to summarize its current context and continue
34
+ * working from the summary, dropping conversation history before the summary.
35
+ *
36
+ * @returns The message string to send to the builder's stdin via stream-json.
37
+ */
38
+ export function buildCompactPayload() {
39
+ return ('[context-management] Compact your context. Summarize the key state of your ' +
40
+ 'current work (what you\'ve done, what\'s left, recent gate feedback) into a ' +
41
+ 'concise summary, then continue working from that summary. Drop conversation ' +
42
+ 'history before this point.');
43
+ }
44
+ /**
45
+ * Build a load_files operation payload.
46
+ *
47
+ * Instructs a running builder to read specific files into its context.
48
+ * The file list is formatted one-per-line for readability.
49
+ *
50
+ * @param files Array of file paths to load.
51
+ * @returns The message string to send to the builder's stdin via stream-json.
52
+ */
53
+ export function buildLoadFilesPayload(files) {
54
+ if (files.length === 0) {
55
+ console.warn(`${LOG_PREFIX} load_files called with empty file list`);
56
+ return '[context-management] No files specified to load.';
57
+ }
58
+ const fileList = files.map((f) => ` - ${f}`).join('\n');
59
+ return ('[context-management] Load the following files into your context by reading them:\n' +
60
+ fileList);
61
+ }
62
+ /**
63
+ * Build a reset payload containing the full context for re-spawning a builder.
64
+ *
65
+ * Used when a work unit has iterated multiple times and needs a fresh context
66
+ * instead of accumulating stale conversation history. Includes:
67
+ * - The work unit spec and description
68
+ * - Instance specification
69
+ * - Operational notes from the blueprint
70
+ * - Summary of previous iteration results (gate feedback)
71
+ *
72
+ * @param workUnit The work unit being reset.
73
+ * @param state The parent factory instance state.
74
+ * @param gateOutput The gate failure output from the most recent iteration (if any).
75
+ * @returns A structured payload object with the fresh prompt.
76
+ */
77
+ export function buildResetPayload(workUnit, state, gateOutput) {
78
+ return {
79
+ freshPrompt: buildFreshContextPrompt(workUnit, state, gateOutput),
80
+ reason: `Context reset after ${workUnit.iterationCount} iteration(s)`,
81
+ };
82
+ }
83
+ /**
84
+ * Build a context payload for a given work unit from the current factory
85
+ * instance state.
86
+ *
87
+ * Extracts the work unit's title, description, strategy scope, interface
88
+ * contracts, recent gate results, relevant files, and operational notes
89
+ * into a self-contained payload that can be used to build a fresh prompt
90
+ * via the ContextManager interface.
91
+ */
92
+ export function buildContextPayload(state, workUnitId) {
93
+ // Find the active builder for this work unit to get iteration context
94
+ const builder = state.activeBuilderSessions.get(workUnitId);
95
+ // Default work unit metadata
96
+ let workUnitTitle = `Work Unit ${workUnitId.slice(0, 8)}`;
97
+ const workUnitDescription = '';
98
+ if (builder) {
99
+ workUnitTitle = `Work Unit (session: ${builder.sessionId.slice(0, 8)}, iteration: ${builder.iterationCount})`;
100
+ }
101
+ // Extract strategy scope from specification
102
+ const strategyScope = state.specification ?? 'No specification available';
103
+ // Build simplified interface contracts from blueprint context
104
+ const produces = [];
105
+ const consumes = [];
106
+ // Extract relevant files from the worktree path
107
+ const relevantFiles = [];
108
+ if (state.worktreePath) {
109
+ relevantFiles.push(state.worktreePath);
110
+ }
111
+ // Include operational notes from the blueprint
112
+ const operationalNotes = state.blueprint.operationalNotes;
113
+ // Build recent gate results (empty array -- actual results are fetched
114
+ // asynchronously by the caller via getGateResults query)
115
+ const recentGateResults = [];
116
+ return {
117
+ workUnitTitle,
118
+ workUnitDescription,
119
+ strategyScope,
120
+ interfaceContracts: { produces, consumes },
121
+ recentGateResults,
122
+ relevantFiles,
123
+ operationalNotes,
124
+ };
125
+ }
126
+ /**
127
+ * Build a context payload with full work unit data.
128
+ *
129
+ * This is the preferred overload when the caller has the work unit metadata
130
+ * and gate results available (which avoids async DB lookups in the pure
131
+ * payload builder).
132
+ */
133
+ export function buildContextPayloadWithData(state, workUnitTitle, workUnitDescription, strategyScope, interfaceContracts, recentGateResults, relevantFiles) {
134
+ return {
135
+ workUnitTitle,
136
+ workUnitDescription,
137
+ strategyScope,
138
+ interfaceContracts,
139
+ recentGateResults: recentGateResults.slice(-MAX_RECENT_GATE_RESULTS),
140
+ relevantFiles,
141
+ operationalNotes: state.blueprint.operationalNotes,
142
+ };
143
+ }
144
+ // ============================================================================
145
+ // Fresh context prompt builder
146
+ // ============================================================================
147
+ /**
148
+ * Build a fresh prompt for a work unit that needs a context reset.
149
+ *
150
+ * This replaces the standard buildWorkUnitPrompt when iterationCount has
151
+ * exceeded the context reset threshold. It provides all necessary context
152
+ * in a single prompt without relying on prior conversation history.
153
+ *
154
+ * @param workUnit The work unit to build the prompt for.
155
+ * @param state The parent factory instance state.
156
+ * @param gateOutput The gate failure output from the most recent iteration (if any).
157
+ * @returns The full prompt string for a fresh builder session.
158
+ */
159
+ export function buildFreshContextPrompt(workUnit, state, gateOutput) {
160
+ const lines = [];
161
+ lines.push('You are a builder agent working on a factory work unit.');
162
+ lines.push('');
163
+ lines.push('## Context Reset');
164
+ lines.push(`This is a FRESH context session. Previous iterations (${workUnit.iterationCount}) ` +
165
+ 'did not pass the quality gates. Your conversation history has been reset to ' +
166
+ 'give you a clean start. All relevant context is included below.');
167
+ lines.push('');
168
+ lines.push('## Work Unit');
169
+ lines.push(`**Title:** ${workUnit.title}`);
170
+ if (workUnit.description) {
171
+ lines.push(`**Description:** ${workUnit.description}`);
172
+ }
173
+ lines.push(`**Iteration:** ${workUnit.iterationCount + 1} (fresh context)`);
174
+ lines.push('');
175
+ if (state.specification) {
176
+ lines.push('## Instance Specification');
177
+ lines.push(state.specification);
178
+ lines.push('');
179
+ }
180
+ if (state.blueprint.operationalNotes) {
181
+ lines.push('## Operational Notes');
182
+ lines.push(state.blueprint.operationalNotes);
183
+ lines.push('');
184
+ }
185
+ lines.push('## Instructions');
186
+ lines.push('1. Implement the work described above.');
187
+ lines.push('2. Follow the project\'s coding standards (see CLAUDE.md if present).');
188
+ lines.push('3. Ensure the code compiles and passes tests.');
189
+ lines.push('4. Commit your changes when done.');
190
+ lines.push('');
191
+ if (gateOutput) {
192
+ lines.push('## Previous Gate Feedback');
193
+ lines.push('The following feedback is from the most recent gate evaluation. ' +
194
+ 'Address these issues in your implementation:');
195
+ lines.push('');
196
+ // Truncate very long gate output to keep the prompt manageable
197
+ const maxGateOutputLength = 8000;
198
+ if (gateOutput.length > maxGateOutputLength) {
199
+ lines.push(gateOutput.slice(0, maxGateOutputLength));
200
+ lines.push('... (gate output truncated)');
201
+ }
202
+ else {
203
+ lines.push(gateOutput);
204
+ }
205
+ lines.push('');
206
+ }
207
+ lines.push('## Important');
208
+ lines.push('This is a retry with fresh context. Review the existing code in the worktree ' +
209
+ 'carefully before making changes -- previous iterations may have made partial progress. ' +
210
+ 'Focus on the gate feedback above to understand what still needs to be fixed.');
211
+ return lines.join('\n');
212
+ }
213
+ /**
214
+ * Build a fresh context prompt from a ContextPayload.
215
+ *
216
+ * Used by the FactoryContextManager class when handling reset operations
217
+ * via the ContextManager interface.
218
+ */
219
+ export function buildFreshContextPromptFromPayload(payload, blueprint, operationalNotes) {
220
+ const sections = [];
221
+ // Role and orientation
222
+ sections.push('# Builder Session Context', '', 'You are a builder in a software factory. Your context has been reset to give you', 'a fresh start. This prompt contains everything you need to continue your work.', '');
223
+ // Work unit scope
224
+ sections.push('## Work Unit', `**Title:** ${payload.workUnitTitle}`);
225
+ if (payload.workUnitDescription) {
226
+ sections.push(`**Description:** ${payload.workUnitDescription}`);
227
+ }
228
+ sections.push('');
229
+ // Strategy context
230
+ sections.push('## Strategy Scope', '', payload.strategyScope, '');
231
+ // Interface contracts
232
+ if (payload.interfaceContracts.produces.length > 0 || payload.interfaceContracts.consumes.length > 0) {
233
+ sections.push('### Interface Contracts', '');
234
+ if (payload.interfaceContracts.produces.length > 0) {
235
+ sections.push('**This strategy produces:**');
236
+ for (const item of payload.interfaceContracts.produces) {
237
+ sections.push(`- **${item.name}**: ${item.description}`);
238
+ }
239
+ sections.push('');
240
+ }
241
+ if (payload.interfaceContracts.consumes.length > 0) {
242
+ sections.push('**This strategy consumes (from dependencies):**');
243
+ for (const item of payload.interfaceContracts.consumes) {
244
+ sections.push(`- **${item.name}**: ${item.description}`);
245
+ }
246
+ sections.push('');
247
+ }
248
+ }
249
+ // Iteration history from gate results
250
+ if (payload.recentGateResults.length > 0) {
251
+ sections.push('## Previous Gate Results', '');
252
+ sections.push('The following gate results are from previous iterations of this work unit.', 'Use them to understand what has been tried and what needs to be fixed.', '');
253
+ for (const result of payload.recentGateResults) {
254
+ const status = result.passed ? 'PASSED' : 'FAILED';
255
+ sections.push(`### [${status}] ${result.checkName}`);
256
+ if (!result.passed && result.output) {
257
+ const output = result.output.length > 3000
258
+ ? '...[truncated]...\n' + result.output.slice(-3000)
259
+ : result.output;
260
+ sections.push('```');
261
+ sections.push(output);
262
+ sections.push('```');
263
+ }
264
+ sections.push('');
265
+ }
266
+ }
267
+ // Files to load
268
+ if (payload.relevantFiles.length > 0) {
269
+ sections.push('## Files to Load', '', 'Start by reading these files to understand the current state of the codebase:', '');
270
+ for (const file of payload.relevantFiles) {
271
+ sections.push(`- \`${file}\``);
272
+ }
273
+ sections.push('');
274
+ }
275
+ // Operational notes
276
+ const notes = operationalNotes ?? payload.operationalNotes ?? blueprint.operationalNotes;
277
+ if (notes) {
278
+ sections.push('## Operational Notes', '', notes, '');
279
+ }
280
+ // Scope boundary
281
+ sections.push('## Scope Boundary', '', 'IMPORTANT: Stay within the scope of your assigned work unit.', 'Do NOT modify code outside of your scope boundary.', 'Do NOT attempt to implement features assigned to other work units or strategies.', 'Focus exclusively on completing the work described above.', '', '## Instructions', '', '1. Read the files listed above to understand the current state.', '2. Implement the work described in your work unit scope.', '3. Follow the project\'s coding standards (see CLAUDE.md if present).', '4. Ensure the code compiles and passes tests.', '5. Commit your changes when done.');
282
+ return sections.join('\n');
283
+ }
284
+ // ============================================================================
285
+ // Context directive executor (payload routing)
286
+ // ============================================================================
287
+ /**
288
+ * Execute a context management directive by building the appropriate payload.
289
+ *
290
+ * This is the entry point called by the trigger execution system
291
+ * (workflow-transition.ts) when a manage_context trigger fires. It routes
292
+ * the directive to the correct payload builder.
293
+ *
294
+ * @param directive The context directive from the workflow trigger.
295
+ * @returns The message payload to send to the builder, or null if no action needed.
296
+ */
297
+ export function executeDirective(directive) {
298
+ switch (directive.type) {
299
+ case 'compact':
300
+ console.log(`${LOG_PREFIX} Building compact payload`);
301
+ return buildCompactPayload();
302
+ case 'load_files':
303
+ if (!directive.files || directive.files.length === 0) {
304
+ console.warn(`${LOG_PREFIX} load_files directive with no files -- skipping`);
305
+ return null;
306
+ }
307
+ console.log(`${LOG_PREFIX} Building load_files payload (${directive.files.length} file(s))`);
308
+ return buildLoadFilesPayload(directive.files);
309
+ case 'reset':
310
+ // Reset requires work unit and state context that the directive doesn't carry.
311
+ // The reset flow is handled separately in the execution module via
312
+ // buildResetPayload() / buildFreshContextPrompt().
313
+ console.log(`${LOG_PREFIX} Reset directive received -- handled by execution module`);
314
+ return null;
315
+ default: {
316
+ // Exhaustive check
317
+ const _exhaustive = directive.type;
318
+ console.warn(`${LOG_PREFIX} Unknown directive type: ${String(_exhaustive)}`);
319
+ return null;
320
+ }
321
+ }
322
+ }
323
+ // ============================================================================
324
+ // Context Manager implementation
325
+ // ============================================================================
326
+ /**
327
+ * Factory context manager implementation.
328
+ *
329
+ * Translates context operations into message payloads. The actual process
330
+ * I/O (sending messages, restarting processes) is handled by the caller
331
+ * (execution.ts).
332
+ */
333
+ export class FactoryContextManager {
334
+ blueprint;
335
+ constructor(blueprint) {
336
+ this.blueprint = blueprint;
337
+ }
338
+ /**
339
+ * Execute a context management operation.
340
+ *
341
+ * Returns a ContextOperationResult containing the message text to send
342
+ * to the builder session. The caller is responsible for actually
343
+ * delivering the message (via stdin for compact/load_files, or by
344
+ * restarting the process for reset).
345
+ */
346
+ async executeOperation(sessionId, operation) {
347
+ switch (operation.type) {
348
+ case 'compact':
349
+ return this.handleCompact(sessionId);
350
+ case 'reset':
351
+ return this.handleReset(sessionId, operation.contextPayload);
352
+ case 'load_files':
353
+ return this.handleLoadFiles(sessionId, operation.files);
354
+ default: {
355
+ const _exhaustive = operation;
356
+ return {
357
+ success: false,
358
+ operation: _exhaustive.type,
359
+ error: `Unknown context operation type`,
360
+ };
361
+ }
362
+ }
363
+ }
364
+ /**
365
+ * Build a context payload from the current factory instance state for
366
+ * a given work unit.
367
+ */
368
+ buildResetPayload(state, workUnitId) {
369
+ return buildContextPayload(state, workUnitId);
370
+ }
371
+ // --------------------------------------------------------------------------
372
+ // Operation handlers
373
+ // --------------------------------------------------------------------------
374
+ handleCompact(sessionId) {
375
+ console.log(`${LOG_PREFIX} Compact operation for session ${sessionId}`);
376
+ return {
377
+ success: true,
378
+ operation: 'compact',
379
+ message: buildCompactPayload(),
380
+ };
381
+ }
382
+ handleReset(sessionId, payload) {
383
+ console.log(`${LOG_PREFIX} Reset operation for session ${sessionId}`);
384
+ const message = buildFreshContextPromptFromPayload(payload, this.blueprint, payload.operationalNotes);
385
+ return {
386
+ success: true,
387
+ operation: 'reset',
388
+ message,
389
+ };
390
+ }
391
+ handleLoadFiles(sessionId, files) {
392
+ if (files.length === 0) {
393
+ return {
394
+ success: false,
395
+ operation: 'load_files',
396
+ error: 'No files specified for load_files operation',
397
+ };
398
+ }
399
+ console.log(`${LOG_PREFIX} Load files operation for session ${sessionId}: ${files.length} file(s)`);
400
+ return {
401
+ success: true,
402
+ operation: 'load_files',
403
+ message: buildLoadFilesPayload(files),
404
+ };
405
+ }
406
+ }
407
+ // ============================================================================
408
+ // Threshold helper
409
+ // ============================================================================
410
+ /**
411
+ * Determine whether a work unit needs a context reset based on its
412
+ * iteration count and the configured threshold.
413
+ *
414
+ * @param iterationCount The current iteration count of the work unit.
415
+ * @param threshold The configured context reset threshold (default: 3).
416
+ * @returns True if the work unit should get a fresh context on next spawn.
417
+ */
418
+ export function needsContextReset(iterationCount, threshold = DEFAULT_CONTEXT_RESET_AFTER_ITERATIONS) {
419
+ return iterationCount > 0 && iterationCount >= threshold;
420
+ }
421
+ //# sourceMappingURL=context-manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context-manager.js","sourceRoot":"","sources":["../src/context-manager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,70 @@
1
+ /**
2
+ * Orphan detection for factory crash recovery.
3
+ *
4
+ * Scans for orphaned worktrees, stale sessions, and incomplete instances
5
+ * that were left behind after an unclean orchestrator shutdown.
6
+ *
7
+ * Provides:
8
+ * - Git worktree list parsing
9
+ * - Factory worktree directory scanning
10
+ * - Types shared between detection and resolution modules
11
+ */
12
+ import type { FactoryConfig } from './types.js';
13
+ export interface OrphanedWorktree {
14
+ /** Absolute path to the worktree directory on disk. */
15
+ worktreePath: string;
16
+ /** Git branch name derived from the worktree entry (if available). */
17
+ branchName: string | null;
18
+ }
19
+ export interface RecoveryAction {
20
+ type: 'worktree_wip_committed' | 'session_reset' | 'instance_paused' | 'escalation_created' | 'execution_unit_reset';
21
+ /** Entity ID (worktree path, session ID, instance ID, or execution unit ID). */
22
+ entityId: string;
23
+ /** Human-readable description of what was done. */
24
+ description: string;
25
+ }
26
+ export interface RecoveryResult {
27
+ /** Number of orphaned worktrees found on disk. */
28
+ orphanedWorktreesFound: number;
29
+ /** Number of WIP commits created for orphaned worktrees. */
30
+ wipCommitsCreated: number;
31
+ /** Number of sessions reset from 'running' to 'failed'. */
32
+ sessionsReset: number;
33
+ /** Number of instances reset from 'building'/'gating' to 'paused'. */
34
+ instancesPaused: number;
35
+ /** Number of escalations created for paused instances. */
36
+ escalationsCreated: number;
37
+ /** Number of execution units reset from 'assigned'/'running' to 'idle'. */
38
+ executionUnitsReset: number;
39
+ /** Detailed log of all recovery actions taken. */
40
+ actions: RecoveryAction[];
41
+ /** Non-fatal errors encountered during recovery. */
42
+ errors: string[];
43
+ }
44
+ interface GitResult {
45
+ success: boolean;
46
+ output: string;
47
+ error: string;
48
+ }
49
+ /**
50
+ * Run a git command synchronously and return a structured result.
51
+ * Never throws -- callers inspect `result.success`.
52
+ */
53
+ export declare function runGit(args: string[], cwd: string): GitResult;
54
+ /**
55
+ * Parse `git worktree list --porcelain` output to build a map of
56
+ * worktree path -> branch name for all registered worktrees.
57
+ */
58
+ export declare function parseWorktreeList(repoPath: string): Map<string, string>;
59
+ /**
60
+ * Scan the factory worktree directory for directories that exist on disk.
61
+ *
62
+ * Returns all subdirectories found in `factoryWorktreeDir`, each with
63
+ * its git branch name (if git tracks it) or null.
64
+ *
65
+ * The caller determines which worktrees are "orphaned" by comparing
66
+ * against the in-memory active instances map (which is empty on fresh start).
67
+ */
68
+ export declare function scanFactoryWorktrees(config: FactoryConfig): OrphanedWorktree[];
69
+ export {};
70
+ //# sourceMappingURL=crash-detection.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"crash-detection.d.ts","sourceRoot":"","sources":["../src/crash-detection.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAKH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAMhD,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;AASD,UAAU,SAAS;IACjB,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;;GAGG;AACH,wBAAgB,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,GAAG,EAAE,MAAM,GAAG,SAAS,CAgC7D;AAMD;;;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,CAyC9E"}
@@ -0,0 +1,123 @@
1
+ /**
2
+ * Orphan detection for factory crash recovery.
3
+ *
4
+ * Scans for orphaned worktrees, stale sessions, and incomplete instances
5
+ * that were left behind after an unclean orchestrator shutdown.
6
+ *
7
+ * Provides:
8
+ * - Git worktree list parsing
9
+ * - Factory worktree directory scanning
10
+ * - Types shared between detection and resolution modules
11
+ */
12
+ import { execFileSync } from 'node:child_process';
13
+ import { existsSync, readdirSync, statSync } from 'node:fs';
14
+ import { join, resolve } from 'node:path';
15
+ // ============================================================================
16
+ // Git helpers (synchronous, same pattern as git-factory.ts)
17
+ // ============================================================================
18
+ /** Default timeout for git CLI operations (30 seconds -- read-only ops are fast). */
19
+ const GIT_TIMEOUT_MS = 30_000;
20
+ /**
21
+ * Run a git command synchronously and return a structured result.
22
+ * Never throws -- callers inspect `result.success`.
23
+ */
24
+ export function runGit(args, cwd) {
25
+ try {
26
+ const output = execFileSync('git', args, {
27
+ cwd,
28
+ encoding: 'utf-8',
29
+ stdio: ['pipe', 'pipe', 'pipe'],
30
+ timeout: GIT_TIMEOUT_MS,
31
+ });
32
+ return { success: true, output: output.trim(), error: '' };
33
+ }
34
+ catch (err) {
35
+ const execErr = err;
36
+ if (execErr.killed || execErr.signal === 'SIGTERM') {
37
+ return {
38
+ success: false,
39
+ output: execErr.stdout?.toString() ?? '',
40
+ error: `Git operation timed out after ${GIT_TIMEOUT_MS}ms: git ${args.join(' ')}`,
41
+ };
42
+ }
43
+ return {
44
+ success: false,
45
+ output: execErr.stdout?.toString() ?? '',
46
+ error: execErr.stderr?.toString() ?? execErr.message ?? 'Unknown git error',
47
+ };
48
+ }
49
+ }
50
+ // ============================================================================
51
+ // Worktree scanning
52
+ // ============================================================================
53
+ /**
54
+ * Parse `git worktree list --porcelain` output to build a map of
55
+ * worktree path -> branch name for all registered worktrees.
56
+ */
57
+ export function parseWorktreeList(repoPath) {
58
+ const result = runGit(['worktree', 'list', '--porcelain'], repoPath);
59
+ const map = new Map();
60
+ if (!result.success)
61
+ return map;
62
+ let currentPath = null;
63
+ for (const line of result.output.split('\n')) {
64
+ if (line.startsWith('worktree ')) {
65
+ currentPath = line.slice('worktree '.length);
66
+ }
67
+ else if (line.startsWith('branch refs/heads/') && currentPath) {
68
+ map.set(currentPath, line.slice('branch refs/heads/'.length));
69
+ currentPath = null;
70
+ }
71
+ else if (line === '') {
72
+ currentPath = null;
73
+ }
74
+ }
75
+ return map;
76
+ }
77
+ /**
78
+ * Scan the factory worktree directory for directories that exist on disk.
79
+ *
80
+ * Returns all subdirectories found in `factoryWorktreeDir`, each with
81
+ * its git branch name (if git tracks it) or null.
82
+ *
83
+ * The caller determines which worktrees are "orphaned" by comparing
84
+ * against the in-memory active instances map (which is empty on fresh start).
85
+ */
86
+ export function scanFactoryWorktrees(config) {
87
+ const { factoryWorktreeDir, repoPath } = config;
88
+ if (!existsSync(factoryWorktreeDir)) {
89
+ console.log(`[crash-recovery] Factory worktree directory does not exist: ${factoryWorktreeDir}`);
90
+ return [];
91
+ }
92
+ // Read subdirectories
93
+ const entries = readdirSync(factoryWorktreeDir);
94
+ const subdirs = entries.filter((entry) => {
95
+ const fullPath = join(factoryWorktreeDir, entry);
96
+ try {
97
+ return statSync(fullPath).isDirectory();
98
+ }
99
+ catch {
100
+ return false;
101
+ }
102
+ });
103
+ if (subdirs.length === 0)
104
+ return [];
105
+ // Parse git worktree list to map paths -> branch names
106
+ const worktreeMap = parseWorktreeList(repoPath);
107
+ const pathToBranch = new Map();
108
+ for (const [wtPath, branch] of worktreeMap) {
109
+ pathToBranch.set(resolve(wtPath), branch);
110
+ }
111
+ // Build orphan list
112
+ const orphans = [];
113
+ for (const subdir of subdirs) {
114
+ const fullPath = resolve(join(factoryWorktreeDir, subdir));
115
+ const branchName = pathToBranch.get(fullPath) ?? null;
116
+ orphans.push({
117
+ worktreePath: fullPath,
118
+ branchName,
119
+ });
120
+ }
121
+ return orphans;
122
+ }
123
+ //# sourceMappingURL=crash-detection.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"crash-detection.js","sourceRoot":"","sources":["../src/crash-detection.ts"],"names":[],"mappings":"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"}