@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,493 @@
1
+ /**
2
+ * Builder process lifecycle management -- spawning Claude Code sessions.
3
+ *
4
+ * Spawns a Claude Code builder session per work unit, sets up stream
5
+ * handling, signal detection, heartbeat monitoring, and wires up the
6
+ * completion handler on process exit.
7
+ *
8
+ * Extracted from execution.ts for focused module boundaries.
9
+ */
10
+ import { spawn } from 'node:child_process';
11
+ import { join } from 'node:path';
12
+ import { mkdirSync, existsSync } from 'node:fs';
13
+ import { buildStreamJsonArgs, stripClaudeCodeEnvVars, createLogStream, sendMessage, StreamJsonParser, ActivityTracker, formatEventForLog, buildOtelEnv, } from '@telora/daemon-core';
14
+ import { updateWorkUnitStatus, updateWorkUnitWorkflowStage } from './queries/work-units.js';
15
+ import { createFactorySession, updateFactorySession, getResumableSession } from './queries/sessions.js';
16
+ import { TokenSniffingTransform } from './queries/shared.js';
17
+ import { getOrResolveWorkflow, attemptTransition } from './workflow-transition.js';
18
+ import { needsContextReset, buildFreshContextPrompt, DEFAULT_CONTEXT_RESET_AFTER_ITERATIONS, } from './context-manager.js';
19
+ import { getBuilderTarget } from './execution-target.js';
20
+ import { handleBuilderCompletion } from './builder-completion.js';
21
+ // ============================================================================
22
+ // Constants
23
+ // ============================================================================
24
+ /** Default max iterations when the blueprint doesn't specify one. */
25
+ export const DEFAULT_MAX_ITERATIONS = 3;
26
+ /** Log prefix for all execution-phase messages. */
27
+ export const LOG_PREFIX = '[execution]';
28
+ /**
29
+ * In-memory cache of the last gate failure output per work unit.
30
+ * Used to provide gate feedback when re-spawning a builder with fresh context.
31
+ * Entries are cleaned up when a work unit completes or fails permanently.
32
+ */
33
+ export const lastGateOutputByWorkUnit = new Map();
34
+ /**
35
+ * Build a clean environment for a builder child process.
36
+ *
37
+ * Uses stripClaudeCodeEnvVars from daemon-core to remove inherited
38
+ * CLAUDECODE, CLAUDE_CODE_*, and CLAUDECODE_* env vars that would cause
39
+ * the child to detect a parent session and hang. Injects TELORA_TRACKER_ID
40
+ * for API auth and OTEL telemetry env vars when telemetry is enabled.
41
+ */
42
+ function buildBuilderEnv(config, otelIds) {
43
+ const env = stripClaudeCodeEnvVars(process.env);
44
+ // Inject tracker ID for API auth in the builder process
45
+ env.TELORA_TRACKER_ID = config.trackerId;
46
+ // Inject OTEL telemetry env vars when enabled
47
+ if (otelIds) {
48
+ const otelEnv = buildOtelEnv({
49
+ enabled: config.telemetry.enabled,
50
+ port: config.telemetry.port,
51
+ resourceAttributes: {
52
+ 'telora.org_id': config.organizationId,
53
+ 'telora.instance_id': otelIds.instanceId,
54
+ 'telora.work_unit_id': otelIds.workUnitId,
55
+ 'telora.session_id': otelIds.sessionId,
56
+ 'telora.spec_id': otelIds.specId ?? undefined,
57
+ },
58
+ });
59
+ Object.assign(env, otelEnv);
60
+ }
61
+ return env;
62
+ }
63
+ // ============================================================================
64
+ // Process spawning helpers
65
+ // ============================================================================
66
+ /**
67
+ * Spawn a child process with the given arguments.
68
+ * Extracted for testability.
69
+ */
70
+ function spawnProcess(command, args, cwd, env) {
71
+ return spawn(command, args, {
72
+ cwd,
73
+ env,
74
+ stdio: ['pipe', 'pipe', 'pipe'],
75
+ });
76
+ }
77
+ // ============================================================================
78
+ // Workflow-governed work unit transitions
79
+ // ============================================================================
80
+ /**
81
+ * Transition a work unit through the workflow state machine.
82
+ *
83
+ * Attempts a workflow-governed transition, falling back to direct status
84
+ * update if no workflow exists. On success, persists both the status and
85
+ * the new workflow stage ID.
86
+ */
87
+ export async function transitionWorkUnitStatus(workUnitId, currentStatus, targetStatus, state, extraFields) {
88
+ const workflow = await getOrResolveWorkflow('factory_work_unit');
89
+ const ctx = {
90
+ deliveryId: '',
91
+ openIssueCount: 0,
92
+ totalIssueCount: 0,
93
+ issuesByStatus: {},
94
+ issuesByPriority: {},
95
+ lastExitCode: 0,
96
+ sessionCount: state.activeBuilderSessions.size,
97
+ tokensUsed: state.tokensUsed,
98
+ tokenBudget: state.blueprint.maxTokenBudget,
99
+ };
100
+ // Resolve the active builder as a trigger execution target (if running)
101
+ const target = getBuilderTarget(state, workUnitId);
102
+ const transResult = await attemptTransition(workflow, currentStatus, targetStatus, state.productId, 'factory_work_unit', workUnitId, ctx, target);
103
+ if (!transResult.allowed) {
104
+ console.log(`${LOG_PREFIX} Work unit ${workUnitId} transition ${currentStatus} -> ${targetStatus} ` +
105
+ `blocked by workflow guards`);
106
+ return false;
107
+ }
108
+ // Persist status + workflow stage
109
+ if (transResult.newStageId) {
110
+ await updateWorkUnitWorkflowStage(workUnitId, transResult.newStageId, targetStatus);
111
+ }
112
+ await updateWorkUnitStatus(workUnitId, targetStatus, extraFields);
113
+ return true;
114
+ }
115
+ // ============================================================================
116
+ // Prompt builders
117
+ // ============================================================================
118
+ /**
119
+ * Build the prompt text for a builder working on a specific work unit.
120
+ */
121
+ function buildWorkUnitPrompt(workUnit, state) {
122
+ const lines = [];
123
+ lines.push(`You are a builder agent working on a factory work unit.`);
124
+ lines.push(``);
125
+ lines.push(`## Work Unit`);
126
+ lines.push(`**Title:** ${workUnit.title}`);
127
+ if (workUnit.description) {
128
+ lines.push(`**Description:** ${workUnit.description}`);
129
+ }
130
+ lines.push(`**Iteration:** ${workUnit.iterationCount + 1}`);
131
+ lines.push(``);
132
+ if (state.specification) {
133
+ lines.push(`## Instance Specification`);
134
+ lines.push(state.specification);
135
+ lines.push(``);
136
+ }
137
+ if (state.blueprint.operationalNotes) {
138
+ lines.push(`## Operational Notes`);
139
+ lines.push(state.blueprint.operationalNotes);
140
+ lines.push(``);
141
+ }
142
+ lines.push(`## Instructions`);
143
+ lines.push(`1. Implement the work described above.`);
144
+ lines.push(`2. Follow the project's coding standards (see CLAUDE.md if present).`);
145
+ lines.push(`3. Ensure the code compiles and passes tests.`);
146
+ lines.push(`4. Commit your changes when done.`);
147
+ if (workUnit.iterationCount > 0) {
148
+ lines.push(``);
149
+ lines.push(`## Retry Context`);
150
+ lines.push(`This is iteration ${workUnit.iterationCount + 1}. ` +
151
+ `Previous attempts did not pass the quality gates. ` +
152
+ `Review the gate output below and fix the issues.`);
153
+ const cachedGateOutput = lastGateOutputByWorkUnit.get(workUnit.id);
154
+ if (cachedGateOutput) {
155
+ lines.push(``);
156
+ lines.push(`## Gate Failure Output`);
157
+ lines.push('```');
158
+ lines.push(cachedGateOutput);
159
+ lines.push('```');
160
+ }
161
+ }
162
+ return lines.join('\n');
163
+ }
164
+ /**
165
+ * Build the prompt for a work unit, choosing between standard and fresh
166
+ * context based on the iteration count and context reset threshold.
167
+ *
168
+ * When the work unit has iterated at or beyond the threshold, a fresh
169
+ * context prompt is built using buildFreshContextPrompt from the context
170
+ * manager. This avoids accumulating stale conversation history across
171
+ * many retries.
172
+ *
173
+ * @param workUnit The work unit to build the prompt for.
174
+ * @param state The parent factory instance state.
175
+ * @param contextResetThreshold Number of iterations before triggering a context reset.
176
+ * @returns The prompt string to send to the builder.
177
+ */
178
+ function buildWorkUnitPromptWithContext(workUnit, state, contextResetThreshold) {
179
+ if (needsContextReset(workUnit.iterationCount, contextResetThreshold)) {
180
+ // Retrieve cached gate output from the last failed iteration
181
+ const cachedGateOutput = lastGateOutputByWorkUnit.get(workUnit.id) ?? null;
182
+ console.log(`${LOG_PREFIX} Work unit "${workUnit.title}" (iteration ${workUnit.iterationCount}) ` +
183
+ `exceeds context reset threshold (${contextResetThreshold}) -- using fresh context prompt`);
184
+ return buildFreshContextPrompt(workUnit, state, cachedGateOutput);
185
+ }
186
+ // Standard prompt for early iterations
187
+ return buildWorkUnitPrompt(workUnit, state);
188
+ }
189
+ /**
190
+ * Build the prompt sent when resuming a previous builder session.
191
+ *
192
+ * The resumed session already has full context from its previous run.
193
+ * Instead of re-explaining the task, we direct it to validate existing
194
+ * work and either signal completion or continue building.
195
+ */
196
+ function buildResumeValidationPrompt(workUnit) {
197
+ const lines = [];
198
+ lines.push(`Your previous session for this work unit was interrupted.`);
199
+ lines.push(``);
200
+ lines.push(`## Work Unit: ${workUnit.title}`);
201
+ lines.push(``);
202
+ lines.push(`## Instructions`);
203
+ lines.push(`1. Check the current state of the worktree \u2014 review your commits, file changes, and test results.`);
204
+ lines.push(`2. If the work is already complete and committed, you are done. Exit normally.`);
205
+ lines.push(`3. If the work is partially complete, continue from where you left off.`);
206
+ lines.push(`4. If no meaningful progress was made, start the implementation.`);
207
+ lines.push(``);
208
+ lines.push(`Do NOT re-do work that is already committed and correct.`);
209
+ return lines.join('\n');
210
+ }
211
+ /**
212
+ * Build the prompt sent when resuming a session after a gate failure.
213
+ *
214
+ * The resumed session already knows what it built. It just needs the
215
+ * gate output so it can fix the specific issue.
216
+ */
217
+ function buildGateFeedbackPrompt(workUnit, gateOutput) {
218
+ const lines = [];
219
+ lines.push(`Your previous work on this unit did not pass the quality gates.`);
220
+ lines.push(``);
221
+ lines.push(`## Work Unit: ${workUnit.title}`);
222
+ lines.push(``);
223
+ lines.push(`## Gate Failure Output`);
224
+ lines.push('```');
225
+ lines.push(gateOutput);
226
+ lines.push('```');
227
+ lines.push(``);
228
+ lines.push(`## Instructions`);
229
+ lines.push(`Fix the issues reported above, then commit your changes.`);
230
+ return lines.join('\n');
231
+ }
232
+ // ============================================================================
233
+ // Builder spawning
234
+ // ============================================================================
235
+ /**
236
+ * Spawn a Claude Code builder session for a single work unit.
237
+ *
238
+ * Creates a factory_sessions record, launches the `claude` CLI in
239
+ * stream-json mode, and registers the builder in the instance's
240
+ * `activeBuilderSessions` map.
241
+ *
242
+ * @returns The in-memory BuilderState for the spawned session.
243
+ */
244
+ export async function spawnBuilder(workUnit, state, config, governor) {
245
+ const worktreePath = state.worktreePath;
246
+ if (!worktreePath) {
247
+ throw new Error(`${LOG_PREFIX} Instance ${state.instanceId} has no worktreePath -- ` +
248
+ `cannot spawn builder for work unit ${workUnit.id}`);
249
+ }
250
+ // Ensure log directory exists
251
+ if (!existsSync(config.logDir)) {
252
+ mkdirSync(config.logDir, { recursive: true });
253
+ }
254
+ // Log file paths
255
+ const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
256
+ const logBaseName = `factory-${state.instanceId.slice(0, 8)}-wu-${workUnit.id.slice(0, 8)}-${timestamp}`;
257
+ const stdoutPath = join(config.logDir, `${logBaseName}.stdout.log`);
258
+ const stderrPath = join(config.logDir, `${logBaseName}.stderr.log`);
259
+ // Create session record in DB
260
+ const session = await createFactorySession({
261
+ instanceId: state.instanceId,
262
+ sessionType: 'builder',
263
+ workUnitId: workUnit.id,
264
+ stdoutPath,
265
+ stderrPath,
266
+ });
267
+ // Mark the work unit as in-progress via workflow transition
268
+ await transitionWorkUnitStatus(workUnit.id, workUnit.status, 'in_progress', state, {
269
+ builderSessionId: session.id,
270
+ });
271
+ // Check for a resumable session from a previous pause/resume cycle.
272
+ let resumeClaudeSessionId = null;
273
+ try {
274
+ const previousSession = await getResumableSession(workUnit.id);
275
+ if (previousSession?.claudeSessionId) {
276
+ resumeClaudeSessionId = previousSession.claudeSessionId;
277
+ console.log(`${LOG_PREFIX} Found resumable Claude session ${resumeClaudeSessionId} ` +
278
+ `for work unit "${workUnit.title}"`);
279
+ }
280
+ }
281
+ catch (err) {
282
+ console.warn(`${LOG_PREFIX} Failed to look up resumable session for work unit ${workUnit.id}:`, err.message);
283
+ }
284
+ // Build Claude Code arguments using shared base args from daemon-core
285
+ const args = [];
286
+ // --resume must come before --input-format stream-json
287
+ if (resumeClaudeSessionId) {
288
+ args.push('--resume', resumeClaudeSessionId);
289
+ }
290
+ args.push(...buildStreamJsonArgs({ mcpConfigPath: config.mcpConfigPath }));
291
+ // Acquire a slot from the resource governor (if provided)
292
+ let slotAcquired = false;
293
+ if (governor) {
294
+ await governor.acquireSlot('factory');
295
+ slotAcquired = true;
296
+ }
297
+ // Spawn the builder process with factory-specific OTEL resource attributes
298
+ const env = buildBuilderEnv(config, {
299
+ instanceId: state.instanceId,
300
+ workUnitId: workUnit.id,
301
+ sessionId: session.id,
302
+ specId: state.specId,
303
+ });
304
+ const proc = spawnProcess(config.claudeCodePath, args, worktreePath, env);
305
+ const pid = proc.pid;
306
+ if (pid === undefined) {
307
+ // Process failed to spawn -- release governor slot and clean up
308
+ if (slotAcquired)
309
+ governor.releaseSlot('factory');
310
+ await updateFactorySession(session.id, {
311
+ status: 'failed',
312
+ endedAt: new Date().toISOString(),
313
+ });
314
+ await updateWorkUnitStatus(workUnit.id, 'pending');
315
+ throw new Error(`${LOG_PREFIX} Failed to spawn builder process for work unit ${workUnit.id} -- pid is undefined`);
316
+ }
317
+ // Update session with PID and running status
318
+ await updateFactorySession(session.id, {
319
+ status: 'running',
320
+ pid,
321
+ startedAt: new Date().toISOString(),
322
+ });
323
+ // Build the prompt for this work unit.
324
+ // Build prompt based on session state:
325
+ // - Resumed session + gate feedback: send gate failure output (session knows what it built)
326
+ // - Resumed session + no gate feedback: validate-and-continue directive
327
+ // - Fresh session: full work unit prompt (with gate feedback if retrying)
328
+ let prompt;
329
+ const cachedGateOutput = lastGateOutputByWorkUnit.get(workUnit.id) ?? null;
330
+ if (resumeClaudeSessionId && cachedGateOutput) {
331
+ prompt = buildGateFeedbackPrompt(workUnit, cachedGateOutput);
332
+ }
333
+ else if (resumeClaudeSessionId) {
334
+ prompt = buildResumeValidationPrompt(workUnit);
335
+ }
336
+ else {
337
+ const contextResetThreshold = DEFAULT_CONTEXT_RESET_AFTER_ITERATIONS;
338
+ prompt = buildWorkUnitPromptWithContext(workUnit, state, contextResetThreshold);
339
+ }
340
+ // Send prompt via stdin as stream-json message (using shared sendMessage from daemon-core)
341
+ if (proc.stdin) {
342
+ sendMessage(proc.stdin, prompt);
343
+ }
344
+ else {
345
+ console.error(`${LOG_PREFIX} Cannot send prompt -- process stdin is not available`);
346
+ }
347
+ // Set up logging, stream parsing, and activity tracking
348
+ const logging = setupBuilderLogging(proc, config, session.id, logBaseName, stdoutPath, stderrPath);
349
+ // Build in-memory state
350
+ const builder = {
351
+ sessionId: session.id,
352
+ workUnitId: workUnit.id,
353
+ pid,
354
+ worktreePath,
355
+ startedAt: new Date(),
356
+ iterationCount: workUnit.iterationCount,
357
+ tokenUsage: null,
358
+ stdin: proc.stdin ?? null,
359
+ claudeSessionId: null,
360
+ };
361
+ // Capture Claude session ID for --resume support
362
+ logging.streamParser.on('init', (event) => {
363
+ builder.claudeSessionId = event.session_id;
364
+ updateFactorySession(session.id, {
365
+ claudeSessionId: event.session_id,
366
+ }).catch((err) => {
367
+ console.warn(`${LOG_PREFIX} Failed to persist Claude session ID for session ${session.id}:`, err.message);
368
+ });
369
+ });
370
+ // Register in the instance's active builders map
371
+ state.activeBuilderSessions.set(workUnit.id, builder);
372
+ console.log(`${LOG_PREFIX} Spawned builder for work unit "${workUnit.title}" ` +
373
+ `(session: ${session.id}, pid: ${pid}, iteration: ${workUnit.iterationCount})`);
374
+ // Wire up process lifecycle handlers
375
+ attachBuilderProcessHandlers({
376
+ proc, builder, state, config, workUnit, session,
377
+ governor: governor ?? null, slotAcquired,
378
+ resumeClaudeSessionId, spawnedAt: Date.now(),
379
+ logging,
380
+ });
381
+ return builder;
382
+ }
383
+ /**
384
+ * Set up all logging, stream parsing, and activity tracking for a builder process.
385
+ */
386
+ function setupBuilderLogging(proc, config, sessionId, logBaseName, stdoutPath, stderrPath) {
387
+ const stderrStream = createLogStream(stderrPath);
388
+ proc.stderr?.pipe(stderrStream);
389
+ const jsonlPath = join(config.logDir, `${logBaseName}.stream.jsonl`);
390
+ const jsonlStream = createLogStream(jsonlPath);
391
+ const stdoutLogStream = createLogStream(stdoutPath);
392
+ // Token-sniffing transform extracts usage from result events
393
+ const tokenParser = new TokenSniffingTransform();
394
+ proc.stdout?.pipe(tokenParser).pipe(jsonlStream);
395
+ const streamParser = new StreamJsonParser();
396
+ if (proc.stdout)
397
+ streamParser.attach(proc.stdout);
398
+ // Close stdin on result so --stream-json mode can exit
399
+ streamParser.on('result', () => {
400
+ if (proc.stdin && !proc.stdin.destroyed)
401
+ proc.stdin.end();
402
+ });
403
+ // Human-readable log
404
+ streamParser.on('event', (event) => {
405
+ const line = formatEventForLog(event);
406
+ if (line)
407
+ stdoutLogStream.write(line + '\n');
408
+ });
409
+ // Activity tracking with factory-specific flush callback
410
+ const activityTracker = new ActivityTracker(sessionId, async (snapshot) => {
411
+ await updateFactorySession(sessionId, {
412
+ activitySummary: snapshot,
413
+ });
414
+ });
415
+ activityTracker.attach(streamParser);
416
+ activityTracker.onNarration((text) => {
417
+ updateFactorySession(sessionId, {
418
+ lastNarration: text,
419
+ lastNarrationAt: new Date().toISOString(),
420
+ }).catch((err) => {
421
+ console.warn(`${LOG_PREFIX} Failed to update narration for session ${sessionId}:`, err.message);
422
+ });
423
+ });
424
+ return { stdoutLogStream, stderrStream, jsonlStream, tokenParser, streamParser, activityTracker };
425
+ }
426
+ // ============================================================================
427
+ // Builder process lifecycle handlers
428
+ // ============================================================================
429
+ /**
430
+ * Attach close and error handlers to a builder child process.
431
+ */
432
+ function attachBuilderProcessHandlers(params) {
433
+ const { proc, builder, state, config, workUnit, session, governor, slotAcquired, resumeClaudeSessionId, spawnedAt, logging, } = params;
434
+ const { stdoutLogStream, stderrStream, jsonlStream, tokenParser, activityTracker } = logging;
435
+ proc.on('close', (code) => {
436
+ if (slotAcquired)
437
+ governor.releaseSlot('factory');
438
+ builder.stdin = null;
439
+ // Detect --resume failure: quick exit means session file is missing/corrupted
440
+ const RESUME_FAILURE_THRESHOLD_MS = 15_000;
441
+ const elapsedMs = Date.now() - spawnedAt;
442
+ if (resumeClaudeSessionId && code !== 0 && code !== null && elapsedMs < RESUME_FAILURE_THRESHOLD_MS) {
443
+ console.warn(`${LOG_PREFIX} Resume failed for work unit "${workUnit.title}" ` +
444
+ `(exited in ${elapsedMs}ms), retrying without resume`);
445
+ stdoutLogStream.end();
446
+ stderrStream.end();
447
+ jsonlStream.end();
448
+ state.activeBuilderSessions.delete(workUnit.id);
449
+ updateFactorySession(session.id, {
450
+ status: 'failed',
451
+ endedAt: new Date().toISOString(),
452
+ exitReason: `Resume failed (code ${code}), retrying without resume`,
453
+ }).catch((err) => {
454
+ console.error(`${LOG_PREFIX} Failed to mark session ${session.id} as failed after resume failure:`, err.message);
455
+ });
456
+ updateWorkUnitStatus(workUnit.id, 'ready').catch((err) => {
457
+ console.error(`${LOG_PREFIX} Failed to reset work unit ${workUnit.id} after resume failure:`, err.message);
458
+ });
459
+ return;
460
+ }
461
+ builder.tokenUsage = tokenParser.usage;
462
+ activityTracker.finalFlush().catch((err) => {
463
+ console.warn(`${LOG_PREFIX} activityTracker.finalFlush failed:`, err.message);
464
+ }).finally(() => {
465
+ handleBuilderCompletion(builder, code ?? 1, state, config, governor).catch((error) => {
466
+ console.error(`${LOG_PREFIX} Error handling builder completion for work unit ${workUnit.id}:`, error.message);
467
+ });
468
+ });
469
+ stdoutLogStream.end();
470
+ stderrStream.end();
471
+ jsonlStream.end();
472
+ });
473
+ proc.on('error', (error) => {
474
+ if (slotAcquired)
475
+ governor.releaseSlot('factory');
476
+ builder.stdin = null;
477
+ console.error(`${LOG_PREFIX} Builder process error for work unit "${workUnit.title}":`, error.message);
478
+ state.activeBuilderSessions.delete(workUnit.id);
479
+ updateFactorySession(session.id, {
480
+ status: 'failed',
481
+ endedAt: new Date().toISOString(),
482
+ }).catch((err) => {
483
+ console.error(`${LOG_PREFIX} Failed to update session ${session.id} on error:`, err.message);
484
+ });
485
+ updateWorkUnitStatus(workUnit.id, 'pending').catch((err) => {
486
+ console.error(`${LOG_PREFIX} Failed to revert work unit ${workUnit.id} status:`, err.message);
487
+ });
488
+ stdoutLogStream.end();
489
+ stderrStream.end();
490
+ jsonlStream.end();
491
+ });
492
+ }
493
+ //# sourceMappingURL=builder-spawner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"builder-spawner.js","sourceRoot":"","sources":["../src/builder-spawner.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Instance-level completion gate.
3
+ *
4
+ * Runs after ALL work units are completed but BEFORE the instance transitions
5
+ * to 'completed'. An AI reviewer evaluates the full specification against
6
+ * the entire codebase diff and determines whether everything is actually done.
7
+ *
8
+ * On failure, gaps are converted to remediation work units and the instance
9
+ * goes back to 'building'.
10
+ */
11
+ import type { ResourceGovernor } from '@telora/daemon-core';
12
+ import type { CompletionGateResult, FactoryBlueprint, FactoryConfig, FactoryInstanceState, FactoryWorkUnit } from './types.js';
13
+ import type { PersistedStrategy } from './strategy-design.js';
14
+ /**
15
+ * Generate the full diff between the factory branch and main.
16
+ *
17
+ * Includes a stat summary header followed by the full diff.
18
+ * Truncates to MAX_DIFF_CHARS to avoid blowing up the review prompt.
19
+ */
20
+ export declare function generateInstanceDiff(worktreePath: string, branchName: string): string;
21
+ export { formatGateContext } from './gate-context.js';
22
+ /**
23
+ * Build the prompt for the completion gate AI reviewer.
24
+ */
25
+ export declare function buildCompletionReviewPrompt(specification: string, blueprint: FactoryBlueprint, workUnits: FactoryWorkUnit[], diffText: string, strategies?: PersistedStrategy[], gateContext?: string): string;
26
+ /**
27
+ * Run the instance-level completion gate.
28
+ *
29
+ * Spawns Claude Code in --print mode to review the full diff against
30
+ * the specification. Returns a validated CompletionGateResult or null
31
+ * on any failure.
32
+ *
33
+ * @param state The factory instance state (needs worktreePath, branchName, specification, blueprint)
34
+ * @param config Factory configuration
35
+ * @param workUnits All work units for the instance (for context)
36
+ * @returns Validated CompletionGateResult or null on failure
37
+ */
38
+ export declare function runCompletionGate(state: FactoryInstanceState, config: FactoryConfig, workUnits: FactoryWorkUnit[], governor?: ResourceGovernor | null): Promise<CompletionGateResult | null>;
39
+ /**
40
+ * Convert critical completion gate gaps into remediation work units.
41
+ *
42
+ * Only critical-severity gaps produce new work units. Important gaps are
43
+ * logged but not auto-remediated. If generating remediation units would
44
+ * exceed the blueprint's maxWorkUnits limit, no units are created and
45
+ * the function returns an empty array (caller should escalate).
46
+ *
47
+ * @param state The factory instance state
48
+ * @param gateResult The completion gate result with gaps
49
+ * @returns Array of created work units (empty if none needed or limit exceeded)
50
+ */
51
+ export declare function generateRemediationWorkUnits(state: FactoryInstanceState, gateResult: CompletionGateResult): Promise<FactoryWorkUnit[]>;
52
+ //# sourceMappingURL=completion-gate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"completion-gate.d.ts","sourceRoot":"","sources":["../src/completion-gate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAIH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAO5D,OAAO,KAAK,EACV,oBAAoB,EACpB,gBAAgB,EAChB,aAAa,EACb,oBAAoB,EACpB,eAAe,EAChB,MAAM,YAAY,CAAC;AACpB,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAuC9D;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAClC,YAAY,EAAE,MAAM,EACpB,UAAU,EAAE,MAAM,GACjB,MAAM,CA6BR;AAED,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAMtD;;GAEG;AACH,wBAAgB,2BAA2B,CACzC,aAAa,EAAE,MAAM,EACrB,SAAS,EAAE,gBAAgB,EAC3B,SAAS,EAAE,eAAe,EAAE,EAC5B,QAAQ,EAAE,MAAM,EAChB,UAAU,CAAC,EAAE,iBAAiB,EAAE,EAChC,WAAW,CAAC,EAAE,MAAM,GACnB,MAAM,CAmHR;AAMD;;;;;;;;;;;GAWG;AACH,wBAAsB,iBAAiB,CACrC,KAAK,EAAE,oBAAoB,EAC3B,MAAM,EAAE,aAAa,EACrB,SAAS,EAAE,eAAe,EAAE,EAC5B,QAAQ,CAAC,EAAE,gBAAgB,GAAG,IAAI,GACjC,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAAC,CAoJtC;AAMD;;;;;;;;;;;GAWG;AACH,wBAAsB,4BAA4B,CAChD,KAAK,EAAE,oBAAoB,EAC3B,UAAU,EAAE,oBAAoB,GAC/B,OAAO,CAAC,eAAe,EAAE,CAAC,CA+D5B"}