@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,348 @@
1
+ /**
2
+ * Factory instance completion report generation.
3
+ *
4
+ * After the final completion gate passes, this module generates a structured
5
+ * keep/stop/change retrospective. The AI produces the retrospective analysis;
6
+ * execution metrics are computed from instance state and injected separately.
7
+ *
8
+ * Pattern: same one-shot Claude Code --print invocation used by planning,
9
+ * strategy design, and completion gate modules.
10
+ */
11
+ import { spawnAsync } from './process-runner.js';
12
+ import { z } from 'zod';
13
+ import { buildPlanningEnv, extractWorkPlanJson } from './planning.js';
14
+ import { getCycleEvaluations } from './queries/cycle-evaluations.js';
15
+ import { getGateResultsByInstance } from './queries/gate-results.js';
16
+ import { getInstanceWorkUnits } from './queries/work-units.js';
17
+ import { configForFactoryProduct, findFactoryProduct } from './product-config.js';
18
+ // ============================================================================
19
+ // Constants
20
+ // ============================================================================
21
+ /** Timeout for the completion report Claude Code session (5 minutes, matching planning). */
22
+ const REPORT_TIMEOUT_MS = 300_000;
23
+ const LOG_PREFIX = '[completion-report]';
24
+ // ============================================================================
25
+ // Zod schemas (AI output validation)
26
+ // ============================================================================
27
+ const DimensionScoreSchema = z.object({
28
+ dimension: z.string().min(1),
29
+ score: z.enum(['high', 'medium', 'low']),
30
+ notes: z.string().min(1),
31
+ });
32
+ const SpecQualityAssessmentSchema = z.object({
33
+ overallScore: z.enum(['high', 'medium', 'low']),
34
+ dimensionScores: z.array(DimensionScoreSchema),
35
+ gaps: z.array(z.string()),
36
+ });
37
+ const StrategyScoreSchema = z.object({
38
+ strategyName: z.string().min(1),
39
+ score: z.enum(['high', 'medium', 'low']),
40
+ notes: z.string().min(1),
41
+ });
42
+ const StrategyDesignAssessmentSchema = z.object({
43
+ overallScore: z.enum(['high', 'medium', 'low']),
44
+ strategyScores: z.array(StrategyScoreSchema),
45
+ improvements: z.array(z.string()),
46
+ });
47
+ /**
48
+ * Schema for the AI-generated portion of the report.
49
+ * executionMetrics are NOT validated here -- they're computed separately.
50
+ */
51
+ const AiReportOutputSchema = z.object({
52
+ keep: z.array(z.string().min(1)).min(1),
53
+ stop: z.array(z.string().min(1)).min(1),
54
+ change: z.array(z.string().min(1)).min(1),
55
+ specQualityAssessment: SpecQualityAssessmentSchema,
56
+ strategyDesignAssessment: StrategyDesignAssessmentSchema,
57
+ });
58
+ // ============================================================================
59
+ // Prompt builder
60
+ // ============================================================================
61
+ /**
62
+ * Build the prompt for the completion report AI.
63
+ *
64
+ * Includes full factory run context: original spec, cycle evaluations,
65
+ * gate results, work unit outcomes, and strategy outcomes.
66
+ */
67
+ export function buildCompletionReportPrompt(specification, cycleEvaluations, workUnits, gateResults, strategies) {
68
+ const parts = [
69
+ 'You are a factory retrospective analyst. Your job is to produce a structured',
70
+ 'keep/stop/change report from a completed factory run. Your output must be',
71
+ 'grounded in the actual execution data -- no generic platitudes.',
72
+ '',
73
+ '## Original Specification',
74
+ specification,
75
+ ];
76
+ // Strategy summary
77
+ if (strategies && strategies.length > 0) {
78
+ parts.push('', '## Strategy Design');
79
+ const sorted = [...strategies].sort((a, b) => a.priorityRank - b.priorityRank);
80
+ for (const s of sorted) {
81
+ const status = s.executionStatus ?? 'unknown';
82
+ parts.push(`- **${s.name}** (priority ${s.priorityRank}, status: ${status})`);
83
+ if (s.description)
84
+ parts.push(` ${s.description}`);
85
+ if (s.dependsOn.length > 0) {
86
+ const depNames = s.dependsOn
87
+ .map((depId) => sorted.find((x) => x.id === depId)?.name ?? depId)
88
+ .join(', ');
89
+ parts.push(` Depends on: ${depNames}`);
90
+ }
91
+ }
92
+ }
93
+ // Work unit outcomes
94
+ parts.push('', '## Work Unit Outcomes');
95
+ for (const wu of workUnits) {
96
+ parts.push(`- **${wu.title}** [${wu.status}] (${wu.iterationCount} iteration(s))`);
97
+ if (wu.description) {
98
+ // Truncate long descriptions to keep the prompt manageable
99
+ const desc = wu.description.length > 200
100
+ ? wu.description.slice(0, 200) + '...'
101
+ : wu.description;
102
+ parts.push(` ${desc}`);
103
+ }
104
+ }
105
+ // Gate results summary
106
+ const totalGates = gateResults.length;
107
+ const passedGates = gateResults.filter((g) => g.passed).length;
108
+ const failedGates = totalGates - passedGates;
109
+ parts.push('', '## Gate Results Summary');
110
+ parts.push(`Total: ${totalGates}, Passed: ${passedGates}, Failed: ${failedGates}`);
111
+ if (failedGates > 0) {
112
+ parts.push('', 'Failed gates:');
113
+ for (const g of gateResults.filter((r) => !r.passed)) {
114
+ const output = g.output
115
+ ? g.output.length > 150 ? g.output.slice(0, 150) + '...' : g.output
116
+ : 'no output';
117
+ parts.push(`- ${g.gateType} (iteration ${g.iteration}): ${output}`);
118
+ }
119
+ }
120
+ // Cycle evaluations
121
+ if (cycleEvaluations.length > 0) {
122
+ parts.push('', '## Cycle Evaluations');
123
+ for (const ce of cycleEvaluations) {
124
+ parts.push(`- **Cycle ${ce.cycleNumber}**: ${ce.passed ? 'PASSED' : 'FAILED'} (confidence: ${ce.confidence})`);
125
+ parts.push(` ${ce.summary}`);
126
+ if (ce.gaps.length > 0) {
127
+ for (const gap of ce.gaps) {
128
+ parts.push(` - Gap [${gap.severity}]: ${gap.area} -- ${gap.description}`);
129
+ }
130
+ }
131
+ }
132
+ }
133
+ // Instructions
134
+ parts.push('', '## Instructions', '', 'Produce a retrospective report with these sections:', '', '### keep (what worked well)', 'Reference SPECIFIC spec dimensions, template questions, or strategy decisions that produced useful factory output.', 'Bad: "the spec was clear"', 'Good: "the data_model dimension produced well-scoped work units with 100% first-pass gate success"', '', '### stop (what caused friction)', 'Identify SPECIFIC friction with evidence from the execution data.', 'Bad: "some areas were ambiguous"', 'Good: "the error_handling_boundary dimension was under-specified and caused 3 re-planning cycles because the AI could not determine expected error behavior"', '', '### change (concrete recommendations for next time)', 'Must be CONCRETE and actionable.', 'Bad: "improve the spec"', 'Good: "next time, require the behavioral_contracts dimension to reach ready before launch -- 60% of gate failures traced to unspecified behavioral contracts"', '', '### specQualityAssessment', '- overallScore: how well the spec served the factory (high/medium/low)', '- dimensionScores: score each dimension mentioned in the spec', '- gaps: spec areas that were insufficient', '', '### strategyDesignAssessment', '- overallScore: how well the strategy decomposition worked (high/medium/low)', '- strategyScores: score each strategy by name', '- improvements: how to decompose better next time');
135
+ if (!strategies || strategies.length === 0) {
136
+ parts.push('', 'NOTE: This instance did not use strategy-based decomposition.', 'For strategyDesignAssessment, provide a single entry evaluating the flat work unit plan.');
137
+ }
138
+ parts.push('', '## Output Format', 'Return ONLY a JSON object (no markdown fencing, no commentary):', '```', '{', ' "keep": ["specific item 1", "specific item 2"],', ' "stop": ["specific friction 1"],', ' "change": ["concrete recommendation 1"],', ' "specQualityAssessment": {', ' "overallScore": "high" | "medium" | "low",', ' "dimensionScores": [{ "dimension": "name", "score": "high" | "medium" | "low", "notes": "..." }],', ' "gaps": ["gap description"]', ' },', ' "strategyDesignAssessment": {', ' "overallScore": "high" | "medium" | "low",', ' "strategyScores": [{ "strategyName": "name", "score": "high" | "medium" | "low", "notes": "..." }],', ' "improvements": ["improvement description"]', ' }', '}', '```', '', 'Rules:', '- Each of keep, stop, change must have at least 1 item', '- Every item must reference specific execution data, not generic observations', '- Return ONLY the JSON object, nothing else');
139
+ return parts.join('\n');
140
+ }
141
+ // ============================================================================
142
+ // Execution metrics computation
143
+ // ============================================================================
144
+ /**
145
+ * Compute execution metrics from instance state and fetched data.
146
+ * These are factual numbers, not AI-generated.
147
+ */
148
+ export function computeExecutionMetrics(state, workUnits, gateResults, cycleEvaluations) {
149
+ const completedWorkUnits = workUnits.filter((wu) => wu.status === 'completed').length;
150
+ const failedWorkUnits = workUnits.filter((wu) => wu.status === 'failed').length;
151
+ const totalGates = gateResults.length;
152
+ const passedGates = gateResults.filter((g) => g.passed).length;
153
+ const gatePassRate = totalGates > 0 ? passedGates / totalGates : 1;
154
+ const wallClockSeconds = state.startedAt
155
+ ? Math.round((Date.now() - state.startedAt.getTime()) / 1000)
156
+ : 0;
157
+ return {
158
+ totalCycles: cycleEvaluations.length,
159
+ totalWorkUnits: workUnits.length,
160
+ completedWorkUnits,
161
+ failedWorkUnits,
162
+ gatePassRate: Math.round(gatePassRate * 100) / 100,
163
+ totalTokensUsed: state.tokensUsed,
164
+ wallClockSeconds,
165
+ };
166
+ }
167
+ // ============================================================================
168
+ // Main generation function
169
+ // ============================================================================
170
+ /**
171
+ * Generate a structured completion report for a factory instance.
172
+ *
173
+ * Spawns Claude Code in --print mode to produce the retrospective,
174
+ * then merges in computed execution metrics.
175
+ *
176
+ * Returns null on failure -- report generation should never block
177
+ * instance completion.
178
+ */
179
+ export async function generateCompletionReport(state, config, governor) {
180
+ if (!state.specification) {
181
+ console.warn(`${LOG_PREFIX} No specification on instance ${state.instanceId} -- skipping report`);
182
+ return null;
183
+ }
184
+ // Gather context data
185
+ let workUnits;
186
+ let cycleEvaluations;
187
+ let allGateResults;
188
+ let strategies;
189
+ try {
190
+ workUnits = await getInstanceWorkUnits(state.instanceId);
191
+ cycleEvaluations = await getCycleEvaluations(state.instanceId);
192
+ // Fetch gate results for the instance
193
+ allGateResults = await getGateResultsByInstance(state.instanceId);
194
+ // Fetch strategies if available
195
+ const hasStrategies = workUnits.some((wu) => wu.strategyId !== null);
196
+ if (hasStrategies) {
197
+ try {
198
+ const { getStrategiesByFactoryInstance } = await import('./strategy-design.js');
199
+ strategies = await getStrategiesByFactoryInstance(state.instanceId);
200
+ }
201
+ catch (stratErr) {
202
+ // Non-fatal: proceed without strategy context, but set empty array
203
+ // so the prompt doesn't falsely claim "no strategies used"
204
+ strategies = [];
205
+ console.warn(`${LOG_PREFIX} Failed to fetch strategies (non-fatal): ${stratErr instanceof Error ? stratErr.message : String(stratErr)}`);
206
+ }
207
+ }
208
+ }
209
+ catch (err) {
210
+ console.warn(`${LOG_PREFIX} Failed to gather context for report: ${err instanceof Error ? err.message : String(err)}`);
211
+ return null;
212
+ }
213
+ // Compute execution metrics (factual, not AI-generated)
214
+ const executionMetrics = computeExecutionMetrics(state, workUnits, allGateResults, cycleEvaluations);
215
+ // Build prompt
216
+ const prompt = buildCompletionReportPrompt(state.specification, cycleEvaluations, workUnits, allGateResults, strategies);
217
+ // Spawn Claude Code for the AI analysis
218
+ // Use product-scoped repoPath as fallback cwd (correct product repo)
219
+ const productEntry = findFactoryProduct(config, state.productId);
220
+ const productConfig = productEntry ? configForFactoryProduct(config, productEntry) : config;
221
+ const fallbackCwd = productConfig.repoPath;
222
+ let rawOutput;
223
+ if (governor)
224
+ await governor.acquireSlot('factory');
225
+ try {
226
+ const args = ['--print', '--output-format', 'json', '--verbose'];
227
+ const env = buildPlanningEnv(config);
228
+ console.log(`${LOG_PREFIX} Spawning Claude Code for completion report...`);
229
+ rawOutput = await spawnAsync(config.claudeCodePath, args, {
230
+ input: prompt,
231
+ encoding: 'utf-8',
232
+ timeout: REPORT_TIMEOUT_MS,
233
+ cwd: state.worktreePath ?? fallbackCwd,
234
+ env,
235
+ });
236
+ }
237
+ catch (err) {
238
+ const execErr = err;
239
+ if (execErr.killed || execErr.signal === 'SIGTERM') {
240
+ console.warn(`${LOG_PREFIX} Report generation timed out after ${REPORT_TIMEOUT_MS / 1000}s`);
241
+ }
242
+ else {
243
+ console.warn(`${LOG_PREFIX} Report generation failed: ${execErr.message ?? 'unknown error'}`);
244
+ }
245
+ return null;
246
+ }
247
+ finally {
248
+ if (governor)
249
+ governor.releaseSlot('factory');
250
+ }
251
+ if (!rawOutput || rawOutput.trim().length === 0) {
252
+ console.warn(`${LOG_PREFIX} Report generation returned empty output`);
253
+ return null;
254
+ }
255
+ // Extract and validate JSON
256
+ const aiReport = parseAndValidateReport(rawOutput);
257
+ if (!aiReport) {
258
+ // Retry once on validation failure
259
+ console.log(`${LOG_PREFIX} Retrying report generation...`);
260
+ const retryPrompt = buildRetryPrompt(prompt);
261
+ if (governor)
262
+ await governor.acquireSlot('factory');
263
+ try {
264
+ const args = ['--print', '--output-format', 'json', '--verbose'];
265
+ const env = buildPlanningEnv(config);
266
+ const retryOutput = await spawnAsync(config.claudeCodePath, args, {
267
+ input: retryPrompt,
268
+ encoding: 'utf-8',
269
+ timeout: REPORT_TIMEOUT_MS,
270
+ cwd: state.worktreePath ?? fallbackCwd,
271
+ env,
272
+ });
273
+ const retryResult = parseAndValidateReport(retryOutput);
274
+ if (!retryResult) {
275
+ console.warn(`${LOG_PREFIX} Report validation failed on retry -- giving up`);
276
+ return null;
277
+ }
278
+ return { ...retryResult, executionMetrics };
279
+ }
280
+ catch (retryErr) {
281
+ console.warn(`${LOG_PREFIX} Report retry execution failed: ${retryErr instanceof Error ? retryErr.message : String(retryErr)}`);
282
+ return null;
283
+ }
284
+ finally {
285
+ if (governor)
286
+ governor.releaseSlot('factory');
287
+ }
288
+ }
289
+ return { ...aiReport, executionMetrics };
290
+ }
291
+ // ============================================================================
292
+ // Helpers
293
+ // ============================================================================
294
+ /**
295
+ * Parse Claude Code output, extract JSON, and validate against schema.
296
+ * Returns the validated AI report or null on failure.
297
+ */
298
+ function parseAndValidateReport(rawOutput) {
299
+ let jsonStr;
300
+ try {
301
+ jsonStr = extractWorkPlanJson(rawOutput);
302
+ }
303
+ catch (err) {
304
+ console.warn(`${LOG_PREFIX} Failed to extract JSON: ${err instanceof Error ? err.message : String(err)}`);
305
+ return null;
306
+ }
307
+ let parsedJson;
308
+ try {
309
+ parsedJson = JSON.parse(jsonStr);
310
+ }
311
+ catch (err) {
312
+ console.warn(`${LOG_PREFIX} Output is not valid JSON: ${err instanceof Error ? err.message : String(err)}`);
313
+ return null;
314
+ }
315
+ // Normalize: AI sometimes returns a bare array instead of an object.
316
+ if (Array.isArray(parsedJson)) {
317
+ if (parsedJson.length === 1 && typeof parsedJson[0] === 'object' && parsedJson[0] !== null && !Array.isArray(parsedJson[0])) {
318
+ parsedJson = parsedJson[0];
319
+ }
320
+ }
321
+ const validation = AiReportOutputSchema.safeParse(parsedJson);
322
+ if (!validation.success) {
323
+ const issues = validation.error.issues
324
+ .map((i) => `${i.path.join('.')}: ${i.message}`)
325
+ .join('; ');
326
+ console.warn(`${LOG_PREFIX} Validation failed: ${issues}`);
327
+ return null;
328
+ }
329
+ return validation.data;
330
+ }
331
+ /**
332
+ * Build a retry prompt that includes the original prompt plus instruction
333
+ * to return valid JSON this time.
334
+ */
335
+ function buildRetryPrompt(originalPrompt) {
336
+ return [
337
+ originalPrompt,
338
+ '',
339
+ '## IMPORTANT: Previous attempt failed validation',
340
+ 'Your previous response could not be parsed. Please ensure:',
341
+ '- Return ONLY a valid JSON object',
342
+ '- No markdown code fences',
343
+ '- No text before or after the JSON',
344
+ '- All arrays (keep, stop, change) have at least 1 item',
345
+ '- All score fields use exactly "high", "medium", or "low"',
346
+ ].join('\n');
347
+ }
348
+ //# sourceMappingURL=completion-report.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"completion-report.js","sourceRoot":"","sources":["../src/completion-report.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Factory instance completion detection and handling.
3
+ *
4
+ * Checks whether all work units in a factory instance have reached the
5
+ * 'completed' status, and if so, transitions the instance to 'completed'
6
+ * with a summary message.
7
+ *
8
+ * Also provides a WIP commit helper for pause/shutdown scenarios to
9
+ * preserve uncommitted work before the orchestrator stops.
10
+ */
11
+ import type { FactoryConfig } from './types.js';
12
+ export interface CompletionResult {
13
+ /** Whether all work units are completed and the instance was finalized. */
14
+ isComplete: boolean;
15
+ /** Number of work units in 'completed' status. */
16
+ completedCount: number;
17
+ /** Total number of work units for this instance. */
18
+ totalCount: number;
19
+ /** Summary message recorded on the instance (only set when isComplete is true). */
20
+ completionMessage: string | null;
21
+ }
22
+ export interface ShutdownWipResult {
23
+ /** Instance ID that was WIP-committed. */
24
+ instanceId: string;
25
+ /** Commit SHA if a WIP commit was created, null if no changes or commit failed. */
26
+ commitSha: string | null;
27
+ /** Number of active sessions that were marked as cancelled. */
28
+ sessionsCancelled: number;
29
+ }
30
+ /**
31
+ * Check whether all work units for a factory instance are completed.
32
+ *
33
+ * If every work unit has status 'completed', this function:
34
+ * 1. Sets the instance status to 'completed'.
35
+ * 2. Records a completion_message summarizing the work.
36
+ * 3. Sets completed_at to the current timestamp.
37
+ *
38
+ * Work stays on its branch -- no merge, no PR creation.
39
+ *
40
+ * @param instanceId - The factory instance to check.
41
+ * @param config - Factory configuration (used for logging context).
42
+ * @returns A CompletionResult describing the outcome.
43
+ */
44
+ export declare function detectCompletion(instanceId: string, config: FactoryConfig): Promise<CompletionResult>;
45
+ /**
46
+ * Perform a WIP safety commit for an active factory instance.
47
+ *
48
+ * Used during pause or graceful shutdown to preserve any uncommitted
49
+ * changes in the instance's worktree. Also marks active sessions as
50
+ * cancelled so they are not treated as running after restart.
51
+ *
52
+ * @param instanceId - The factory instance ID.
53
+ * @param worktreePath - Absolute path to the instance's worktree.
54
+ * @param label - Human-readable label for the WIP commit message.
55
+ * @returns A ShutdownWipResult with commit info and session counts.
56
+ */
57
+ export declare function commitWipOnShutdown(instanceId: string, worktreePath: string, label: string): Promise<ShutdownWipResult>;
58
+ //# sourceMappingURL=completion.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"completion.d.ts","sourceRoot":"","sources":["../src/completion.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAmB,MAAM,YAAY,CAAC;AAWjE,MAAM,WAAW,gBAAgB;IAC/B,2EAA2E;IAC3E,UAAU,EAAE,OAAO,CAAC;IACpB,kDAAkD;IAClD,cAAc,EAAE,MAAM,CAAC;IACvB,oDAAoD;IACpD,UAAU,EAAE,MAAM,CAAC;IACnB,mFAAmF;IACnF,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;CAClC;AAED,MAAM,WAAW,iBAAiB;IAChC,0CAA0C;IAC1C,UAAU,EAAE,MAAM,CAAC;IACnB,mFAAmF;IACnF,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,+DAA+D;IAC/D,iBAAiB,EAAE,MAAM,CAAC;CAC3B;AAMD;;;;;;;;;;;;;GAaG;AACH,wBAAsB,gBAAgB,CACpC,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,aAAa,GACpB,OAAO,CAAC,gBAAgB,CAAC,CAuE3B;AAqID;;;;;;;;;;;GAWG;AACH,wBAAsB,mBAAmB,CACvC,UAAU,EAAE,MAAM,EAClB,YAAY,EAAE,MAAM,EACpB,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,iBAAiB,CAAC,CAiD5B"}