@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.
- package/dist/audit.d.ts +69 -0
- package/dist/audit.d.ts.map +1 -0
- package/dist/audit.js +376 -0
- package/dist/audit.js.map +1 -0
- package/dist/builder-completion.d.ts +35 -0
- package/dist/builder-completion.d.ts.map +1 -0
- package/dist/builder-completion.js +375 -0
- package/dist/builder-completion.js.map +1 -0
- package/dist/builder-spawner.d.ts +40 -0
- package/dist/builder-spawner.d.ts.map +1 -0
- package/dist/builder-spawner.js +493 -0
- package/dist/builder-spawner.js.map +1 -0
- package/dist/completion-gate.d.ts +52 -0
- package/dist/completion-gate.d.ts.map +1 -0
- package/dist/completion-gate.js +336 -0
- package/dist/completion-gate.js.map +1 -0
- package/dist/completion-report.d.ts +36 -0
- package/dist/completion-report.d.ts.map +1 -0
- package/dist/completion-report.js +348 -0
- package/dist/completion-report.js.map +1 -0
- package/dist/completion.d.ts +58 -0
- package/dist/completion.d.ts.map +1 -0
- package/dist/completion.js +287 -0
- package/dist/completion.js.map +1 -0
- package/dist/config.d.ts +16 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +57 -0
- package/dist/config.js.map +1 -0
- package/dist/context-manager.d.ts +152 -0
- package/dist/context-manager.d.ts.map +1 -0
- package/dist/context-manager.js +421 -0
- package/dist/context-manager.js.map +1 -0
- package/dist/crash-detection.d.ts +70 -0
- package/dist/crash-detection.d.ts.map +1 -0
- package/dist/crash-detection.js +123 -0
- package/dist/crash-detection.js.map +1 -0
- package/dist/crash-recovery.d.ts +83 -0
- package/dist/crash-recovery.d.ts.map +1 -0
- package/dist/crash-recovery.js +522 -0
- package/dist/crash-recovery.js.map +1 -0
- package/dist/crash-resolution.d.ts +34 -0
- package/dist/crash-resolution.d.ts.map +1 -0
- package/dist/crash-resolution.js +382 -0
- package/dist/crash-resolution.js.map +1 -0
- package/dist/escalation.d.ts +150 -0
- package/dist/escalation.d.ts.map +1 -0
- package/dist/escalation.js +352 -0
- package/dist/escalation.js.map +1 -0
- package/dist/execution-target.d.ts +31 -0
- package/dist/execution-target.d.ts.map +1 -0
- package/dist/execution-target.js +71 -0
- package/dist/execution-target.js.map +1 -0
- package/dist/execution-unit-init.d.ts +28 -0
- package/dist/execution-unit-init.d.ts.map +1 -0
- package/dist/execution-unit-init.js +115 -0
- package/dist/execution-unit-init.js.map +1 -0
- package/dist/execution.d.ts +17 -0
- package/dist/execution.d.ts.map +1 -0
- package/dist/execution.js +20 -0
- package/dist/execution.js.map +1 -0
- package/dist/factory-engine.d.ts +100 -0
- package/dist/factory-engine.d.ts.map +1 -0
- package/dist/factory-engine.js +243 -0
- package/dist/factory-engine.js.map +1 -0
- package/dist/gap-detection.d.ts +43 -0
- package/dist/gap-detection.d.ts.map +1 -0
- package/dist/gap-detection.js +149 -0
- package/dist/gap-detection.js.map +1 -0
- package/dist/gate-context.d.ts +23 -0
- package/dist/gate-context.d.ts.map +1 -0
- package/dist/gate-context.js +63 -0
- package/dist/gate-context.js.map +1 -0
- package/dist/gate-engine.d.ts +55 -0
- package/dist/gate-engine.d.ts.map +1 -0
- package/dist/gate-engine.js +191 -0
- package/dist/gate-engine.js.map +1 -0
- package/dist/gates/adversarial.d.ts +59 -0
- package/dist/gates/adversarial.d.ts.map +1 -0
- package/dist/gates/adversarial.js +426 -0
- package/dist/gates/adversarial.js.map +1 -0
- package/dist/gates/adversary-spawner.d.ts +35 -0
- package/dist/gates/adversary-spawner.d.ts.map +1 -0
- package/dist/gates/adversary-spawner.js +286 -0
- package/dist/gates/adversary-spawner.js.map +1 -0
- package/dist/gates/adversary-test-dir.d.ts +41 -0
- package/dist/gates/adversary-test-dir.d.ts.map +1 -0
- package/dist/gates/adversary-test-dir.js +150 -0
- package/dist/gates/adversary-test-dir.js.map +1 -0
- package/dist/gates/behavioral-parser.d.ts +32 -0
- package/dist/gates/behavioral-parser.d.ts.map +1 -0
- package/dist/gates/behavioral-parser.js +190 -0
- package/dist/gates/behavioral-parser.js.map +1 -0
- package/dist/gates/behavioral-runner.d.ts +36 -0
- package/dist/gates/behavioral-runner.d.ts.map +1 -0
- package/dist/gates/behavioral-runner.js +306 -0
- package/dist/gates/behavioral-runner.js.map +1 -0
- package/dist/gates/behavioral.d.ts +37 -0
- package/dist/gates/behavioral.d.ts.map +1 -0
- package/dist/gates/behavioral.js +485 -0
- package/dist/gates/behavioral.js.map +1 -0
- package/dist/gates/deterministic.d.ts +24 -0
- package/dist/gates/deterministic.d.ts.map +1 -0
- package/dist/gates/deterministic.js +186 -0
- package/dist/gates/deterministic.js.map +1 -0
- package/dist/git-factory.d.ts +59 -0
- package/dist/git-factory.d.ts.map +1 -0
- package/dist/git-factory.js +102 -0
- package/dist/git-factory.js.map +1 -0
- package/dist/guard-evaluation.d.ts +48 -0
- package/dist/guard-evaluation.d.ts.map +1 -0
- package/dist/guard-evaluation.js +416 -0
- package/dist/guard-evaluation.js.map +1 -0
- package/dist/index.d.ts +30 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +39 -0
- package/dist/index.js.map +1 -0
- package/dist/instance-completion.d.ts +34 -0
- package/dist/instance-completion.d.ts.map +1 -0
- package/dist/instance-completion.js +366 -0
- package/dist/instance-completion.js.map +1 -0
- package/dist/instance-lifecycle.d.ts +15 -0
- package/dist/instance-lifecycle.d.ts.map +1 -0
- package/dist/instance-lifecycle.js +18 -0
- package/dist/instance-lifecycle.js.map +1 -0
- package/dist/instance-phase-dispatch.d.ts +75 -0
- package/dist/instance-phase-dispatch.d.ts.map +1 -0
- package/dist/instance-phase-dispatch.js +674 -0
- package/dist/instance-phase-dispatch.js.map +1 -0
- package/dist/instance-poll-loop.d.ts +43 -0
- package/dist/instance-poll-loop.d.ts.map +1 -0
- package/dist/instance-poll-loop.js +360 -0
- package/dist/instance-poll-loop.js.map +1 -0
- package/dist/instance-state-machine.d.ts +52 -0
- package/dist/instance-state-machine.d.ts.map +1 -0
- package/dist/instance-state-machine.js +235 -0
- package/dist/instance-state-machine.js.map +1 -0
- package/dist/log-manager.d.ts +28 -0
- package/dist/log-manager.d.ts.map +1 -0
- package/dist/log-manager.js +71 -0
- package/dist/log-manager.js.map +1 -0
- package/dist/pipeline-evaluator.d.ts +61 -0
- package/dist/pipeline-evaluator.d.ts.map +1 -0
- package/dist/pipeline-evaluator.js +107 -0
- package/dist/pipeline-evaluator.js.map +1 -0
- package/dist/pipeline-metrics.d.ts +52 -0
- package/dist/pipeline-metrics.d.ts.map +1 -0
- package/dist/pipeline-metrics.js +40 -0
- package/dist/pipeline-metrics.js.map +1 -0
- package/dist/pipeline-traversal.d.ts +43 -0
- package/dist/pipeline-traversal.d.ts.map +1 -0
- package/dist/pipeline-traversal.js +68 -0
- package/dist/pipeline-traversal.js.map +1 -0
- package/dist/plan-parser.d.ts +76 -0
- package/dist/plan-parser.d.ts.map +1 -0
- package/dist/plan-parser.js +223 -0
- package/dist/plan-parser.js.map +1 -0
- package/dist/planning-phase.d.ts +52 -0
- package/dist/planning-phase.d.ts.map +1 -0
- package/dist/planning-phase.js +444 -0
- package/dist/planning-phase.js.map +1 -0
- package/dist/planning-prompt.d.ts +64 -0
- package/dist/planning-prompt.d.ts.map +1 -0
- package/dist/planning-prompt.js +251 -0
- package/dist/planning-prompt.js.map +1 -0
- package/dist/planning.d.ts +16 -0
- package/dist/planning.d.ts.map +1 -0
- package/dist/planning.js +17 -0
- package/dist/planning.js.map +1 -0
- package/dist/process-runner.d.ts +41 -0
- package/dist/process-runner.d.ts.map +1 -0
- package/dist/process-runner.js +81 -0
- package/dist/process-runner.js.map +1 -0
- package/dist/product-config.d.ts +34 -0
- package/dist/product-config.d.ts.map +1 -0
- package/dist/product-config.js +43 -0
- package/dist/product-config.js.map +1 -0
- package/dist/queries/cycle-evaluations.d.ts +23 -0
- package/dist/queries/cycle-evaluations.d.ts.map +1 -0
- package/dist/queries/cycle-evaluations.js +37 -0
- package/dist/queries/cycle-evaluations.js.map +1 -0
- package/dist/queries/escalations.d.ts +30 -0
- package/dist/queries/escalations.d.ts.map +1 -0
- package/dist/queries/escalations.js +42 -0
- package/dist/queries/escalations.js.map +1 -0
- package/dist/queries/execution-units.d.ts +76 -0
- package/dist/queries/execution-units.d.ts.map +1 -0
- package/dist/queries/execution-units.js +109 -0
- package/dist/queries/execution-units.js.map +1 -0
- package/dist/queries/gate-results.d.ts +32 -0
- package/dist/queries/gate-results.d.ts.map +1 -0
- package/dist/queries/gate-results.js +44 -0
- package/dist/queries/gate-results.js.map +1 -0
- package/dist/queries/instances.d.ts +51 -0
- package/dist/queries/instances.d.ts.map +1 -0
- package/dist/queries/instances.js +77 -0
- package/dist/queries/instances.js.map +1 -0
- package/dist/queries/sessions.d.ts +50 -0
- package/dist/queries/sessions.d.ts.map +1 -0
- package/dist/queries/sessions.js +81 -0
- package/dist/queries/sessions.js.map +1 -0
- package/dist/queries/shared.d.ts +38 -0
- package/dist/queries/shared.d.ts.map +1 -0
- package/dist/queries/shared.js +119 -0
- package/dist/queries/shared.js.map +1 -0
- package/dist/queries/specs.d.ts +12 -0
- package/dist/queries/specs.d.ts.map +1 -0
- package/dist/queries/specs.js +21 -0
- package/dist/queries/specs.js.map +1 -0
- package/dist/queries/strategies.d.ts +14 -0
- package/dist/queries/strategies.d.ts.map +1 -0
- package/dist/queries/strategies.js +18 -0
- package/dist/queries/strategies.js.map +1 -0
- package/dist/queries/work-units.d.ts +42 -0
- package/dist/queries/work-units.d.ts.map +1 -0
- package/dist/queries/work-units.js +57 -0
- package/dist/queries/work-units.js.map +1 -0
- package/dist/queries/workflows.d.ts +29 -0
- package/dist/queries/workflows.d.ts.map +1 -0
- package/dist/queries/workflows.js +103 -0
- package/dist/queries/workflows.js.map +1 -0
- package/dist/remediation-units.d.ts +40 -0
- package/dist/remediation-units.d.ts.map +1 -0
- package/dist/remediation-units.js +263 -0
- package/dist/remediation-units.js.map +1 -0
- package/dist/replanning.d.ts +72 -0
- package/dist/replanning.d.ts.map +1 -0
- package/dist/replanning.js +403 -0
- package/dist/replanning.js.map +1 -0
- package/dist/resource-limits.d.ts +62 -0
- package/dist/resource-limits.d.ts.map +1 -0
- package/dist/resource-limits.js +322 -0
- package/dist/resource-limits.js.map +1 -0
- package/dist/scheduler.d.ts +98 -0
- package/dist/scheduler.d.ts.map +1 -0
- package/dist/scheduler.js +203 -0
- package/dist/scheduler.js.map +1 -0
- package/dist/session-adapter.d.ts +89 -0
- package/dist/session-adapter.d.ts.map +1 -0
- package/dist/session-adapter.js +108 -0
- package/dist/session-adapter.js.map +1 -0
- package/dist/sop-generator.d.ts +29 -0
- package/dist/sop-generator.d.ts.map +1 -0
- package/dist/sop-generator.js +235 -0
- package/dist/sop-generator.js.map +1 -0
- package/dist/spec-profiles.d.ts +41 -0
- package/dist/spec-profiles.d.ts.map +1 -0
- package/dist/spec-profiles.js +131 -0
- package/dist/spec-profiles.js.map +1 -0
- package/dist/strategy-design-graph.d.ts +23 -0
- package/dist/strategy-design-graph.d.ts.map +1 -0
- package/dist/strategy-design-graph.js +205 -0
- package/dist/strategy-design-graph.js.map +1 -0
- package/dist/strategy-design-prompt.d.ts +28 -0
- package/dist/strategy-design-prompt.d.ts.map +1 -0
- package/dist/strategy-design-prompt.js +108 -0
- package/dist/strategy-design-prompt.js.map +1 -0
- package/dist/strategy-design-schema.d.ts +767 -0
- package/dist/strategy-design-schema.d.ts.map +1 -0
- package/dist/strategy-design-schema.js +126 -0
- package/dist/strategy-design-schema.js.map +1 -0
- package/dist/strategy-design.d.ts +69 -0
- package/dist/strategy-design.d.ts.map +1 -0
- package/dist/strategy-design.js +411 -0
- package/dist/strategy-design.js.map +1 -0
- package/dist/strategy-gating.d.ts +31 -0
- package/dist/strategy-gating.d.ts.map +1 -0
- package/dist/strategy-gating.js +276 -0
- package/dist/strategy-gating.js.map +1 -0
- package/dist/team-prompt-builder.d.ts +47 -0
- package/dist/team-prompt-builder.d.ts.map +1 -0
- package/dist/team-prompt-builder.js +362 -0
- package/dist/team-prompt-builder.js.map +1 -0
- package/dist/trace-engine.d.ts +40 -0
- package/dist/trace-engine.d.ts.map +1 -0
- package/dist/trace-engine.js +344 -0
- package/dist/trace-engine.js.map +1 -0
- package/dist/types.d.ts +612 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +9 -0
- package/dist/types.js.map +1 -0
- package/dist/unit-session-lifecycle.d.ts +78 -0
- package/dist/unit-session-lifecycle.d.ts.map +1 -0
- package/dist/unit-session-lifecycle.js +141 -0
- package/dist/unit-session-lifecycle.js.map +1 -0
- package/dist/unit-session.d.ts +30 -0
- package/dist/unit-session.d.ts.map +1 -0
- package/dist/unit-session.js +370 -0
- package/dist/unit-session.js.map +1 -0
- package/dist/watchdogs.d.ts +33 -0
- package/dist/watchdogs.d.ts.map +1 -0
- package/dist/watchdogs.js +170 -0
- package/dist/watchdogs.js.map +1 -0
- package/dist/work-unit-scheduler.d.ts +34 -0
- package/dist/work-unit-scheduler.d.ts.map +1 -0
- package/dist/work-unit-scheduler.js +91 -0
- package/dist/work-unit-scheduler.js.map +1 -0
- package/dist/workflow-transition.d.ts +90 -0
- package/dist/workflow-transition.d.ts.map +1 -0
- package/dist/workflow-transition.js +340 -0
- package/dist/workflow-transition.js.map +1 -0
- 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"}
|