@telora/daemon 0.20.32 → 0.20.53
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/build-info.json +2 -2
- package/dist/agent-state.d.ts +4 -6
- package/dist/agent-state.d.ts.map +1 -1
- package/dist/agent-state.js +4 -10
- package/dist/agent-state.js.map +1 -1
- package/dist/branch-status.d.ts +25 -3
- package/dist/branch-status.d.ts.map +1 -1
- package/dist/branch-status.js +130 -59
- package/dist/branch-status.js.map +1 -1
- package/dist/completion/completion-decision.d.ts +29 -3
- package/dist/completion/completion-decision.d.ts.map +1 -1
- package/dist/completion/completion-decision.js +15 -3
- package/dist/completion/completion-decision.js.map +1 -1
- package/dist/completion/event-entry-phases.d.ts +57 -0
- package/dist/completion/event-entry-phases.d.ts.map +1 -0
- package/dist/completion/event-entry-phases.js +205 -0
- package/dist/completion/event-entry-phases.js.map +1 -0
- package/dist/completion/event-phases.d.ts +14 -42
- package/dist/completion/event-phases.d.ts.map +1 -1
- package/dist/completion/event-phases.js +63 -190
- package/dist/completion/event-phases.js.map +1 -1
- package/dist/completion/event.d.ts +11 -1
- package/dist/completion/event.d.ts.map +1 -1
- package/dist/completion/event.js +5 -2
- package/dist/completion/event.js.map +1 -1
- package/dist/completion/index.d.ts +0 -3
- package/dist/completion/index.d.ts.map +1 -1
- package/dist/completion/index.js +0 -3
- package/dist/completion/index.js.map +1 -1
- package/dist/completion/review-exit-phase.d.ts +2 -1
- package/dist/completion/review-exit-phase.d.ts.map +1 -1
- package/dist/completion/review-exit-phase.js +41 -1
- package/dist/completion/review-exit-phase.js.map +1 -1
- package/dist/completion/status-advance-phase.d.ts +2 -0
- package/dist/completion/status-advance-phase.d.ts.map +1 -1
- package/dist/completion/status-advance-phase.js +14 -28
- package/dist/completion/status-advance-phase.js.map +1 -1
- package/dist/completion/team-completion.js +1 -1
- package/dist/completion/team-completion.js.map +1 -1
- package/dist/completion/terminated-work-reconcile.d.ts.map +1 -1
- package/dist/completion/terminated-work-reconcile.js +10 -0
- package/dist/completion/terminated-work-reconcile.js.map +1 -1
- package/dist/constants.d.ts +0 -8
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +0 -8
- package/dist/constants.js.map +1 -1
- package/dist/delivery-close-actions.d.ts +39 -0
- package/dist/delivery-close-actions.d.ts.map +1 -0
- package/dist/delivery-close-actions.js +53 -0
- package/dist/delivery-close-actions.js.map +1 -0
- package/dist/delivery-lifecycle.d.ts +11 -0
- package/dist/delivery-lifecycle.d.ts.map +1 -1
- package/dist/delivery-lifecycle.js +13 -14
- package/dist/delivery-lifecycle.js.map +1 -1
- package/dist/delivery-reconciler.d.ts +18 -4
- package/dist/delivery-reconciler.d.ts.map +1 -1
- package/dist/delivery-reconciler.js +18 -4
- package/dist/delivery-reconciler.js.map +1 -1
- package/dist/directive-executor.d.ts +1 -1
- package/dist/directive-executor.js +1 -1
- package/dist/discovery-fetch.d.ts +76 -0
- package/dist/discovery-fetch.d.ts.map +1 -0
- package/dist/discovery-fetch.js +206 -0
- package/dist/discovery-fetch.js.map +1 -0
- package/dist/discovery-poll.d.ts +1 -51
- package/dist/discovery-poll.d.ts.map +1 -1
- package/dist/discovery-poll.js +10 -192
- package/dist/discovery-poll.js.map +1 -1
- package/dist/drain-teardown.d.ts +11 -6
- package/dist/drain-teardown.d.ts.map +1 -1
- package/dist/drain-teardown.js +3 -2
- package/dist/drain-teardown.js.map +1 -1
- package/dist/focus-branch-ahead.d.ts +42 -0
- package/dist/focus-branch-ahead.d.ts.map +1 -0
- package/dist/focus-branch-ahead.js +45 -0
- package/dist/focus-branch-ahead.js.map +1 -0
- package/dist/focus-engine.d.ts.map +1 -1
- package/dist/focus-engine.js +21 -43
- package/dist/focus-engine.js.map +1 -1
- package/dist/focus-executor.js +2 -2
- package/dist/focus-executor.js.map +1 -1
- package/dist/focus-lifecycle.d.ts.map +1 -1
- package/dist/focus-lifecycle.js +32 -3
- package/dist/focus-lifecycle.js.map +1 -1
- package/dist/focus-loop.d.ts +34 -12
- package/dist/focus-loop.d.ts.map +1 -1
- package/dist/focus-loop.js +78 -15
- package/dist/focus-loop.js.map +1 -1
- package/dist/focus-merge.d.ts.map +1 -1
- package/dist/focus-merge.js +6 -1
- package/dist/focus-merge.js.map +1 -1
- package/dist/focus-phase.d.ts +18 -3
- package/dist/focus-phase.d.ts.map +1 -1
- package/dist/focus-phase.js +85 -31
- package/dist/focus-phase.js.map +1 -1
- package/dist/focus-prompt-builder.d.ts.map +1 -1
- package/dist/focus-prompt-builder.js +8 -0
- package/dist/focus-prompt-builder.js.map +1 -1
- package/dist/focus-provisioning.d.ts.map +1 -1
- package/dist/focus-provisioning.js +4 -0
- package/dist/focus-provisioning.js.map +1 -1
- package/dist/focus-stage-lifecycle/planning-release.d.ts +35 -17
- package/dist/focus-stage-lifecycle/planning-release.d.ts.map +1 -1
- package/dist/focus-stage-lifecycle/planning-release.js +53 -22
- package/dist/focus-stage-lifecycle/planning-release.js.map +1 -1
- package/dist/focus-worktree-state.d.ts +17 -6
- package/dist/focus-worktree-state.d.ts.map +1 -1
- package/dist/focus-worktree-state.js +21 -11
- package/dist/focus-worktree-state.js.map +1 -1
- package/dist/guard-engine.d.ts +1 -2
- package/dist/guard-engine.d.ts.map +1 -1
- package/dist/guard-engine.js +1 -2
- package/dist/guard-engine.js.map +1 -1
- package/dist/health-events.d.ts +10 -0
- package/dist/health-events.d.ts.map +1 -0
- package/dist/health-events.js +10 -0
- package/dist/health-events.js.map +1 -0
- package/dist/heartbeat.d.ts.map +1 -1
- package/dist/heartbeat.js +98 -21
- package/dist/heartbeat.js.map +1 -1
- package/dist/host-control/catalog.d.ts.map +1 -1
- package/dist/host-control/catalog.js +4 -1
- package/dist/host-control/catalog.js.map +1 -1
- package/dist/host-control/client.d.ts +3 -4
- package/dist/host-control/client.d.ts.map +1 -1
- package/dist/host-control/client.js +4 -5
- package/dist/host-control/client.js.map +1 -1
- package/dist/listener-auto-advance.d.ts +2 -1
- package/dist/listener-auto-advance.d.ts.map +1 -1
- package/dist/listener-auto-advance.js +36 -40
- package/dist/listener-auto-advance.js.map +1 -1
- package/dist/listener.d.ts +2 -7
- package/dist/listener.d.ts.map +1 -1
- package/dist/listener.js +11 -9
- package/dist/listener.js.map +1 -1
- package/dist/operator-hold.d.ts +66 -0
- package/dist/operator-hold.d.ts.map +1 -0
- package/dist/operator-hold.js +99 -0
- package/dist/operator-hold.js.map +1 -0
- package/dist/poll-trigger.d.ts +28 -0
- package/dist/poll-trigger.d.ts.map +1 -0
- package/dist/poll-trigger.js +31 -0
- package/dist/poll-trigger.js.map +1 -0
- package/dist/prompt-listing.js +6 -0
- package/dist/prompt-listing.js.map +1 -1
- package/dist/prompt-sections/execution-sections.d.ts.map +1 -1
- package/dist/prompt-sections/execution-sections.js +24 -0
- package/dist/prompt-sections/execution-sections.js.map +1 -1
- package/dist/queries/context-lock-queries.d.ts.map +1 -1
- package/dist/queries/context-lock-queries.js +4 -1
- package/dist/queries/context-lock-queries.js.map +1 -1
- package/dist/queries/deliveries.d.ts +17 -0
- package/dist/queries/deliveries.d.ts.map +1 -1
- package/dist/queries/deliveries.js.map +1 -1
- package/dist/queries/issues.d.ts +98 -0
- package/dist/queries/issues.d.ts.map +1 -1
- package/dist/queries/issues.js +135 -0
- package/dist/queries/issues.js.map +1 -1
- package/dist/queries/schemas.d.ts +3 -3
- package/dist/spawn/worktree-session.d.ts.map +1 -1
- package/dist/spawn/worktree-session.js +2 -0
- package/dist/spawn/worktree-session.js.map +1 -1
- package/dist/spawner/index.d.ts +7 -9
- package/dist/spawner/index.d.ts.map +1 -1
- package/dist/spawner/index.js +13 -11
- package/dist/spawner/index.js.map +1 -1
- package/dist/spawner/lifecycle.d.ts +1 -18
- package/dist/spawner/lifecycle.d.ts.map +1 -1
- package/dist/spawner/lifecycle.js +1 -54
- package/dist/spawner/lifecycle.js.map +1 -1
- package/dist/spawner/liveness.d.ts +5 -14
- package/dist/spawner/liveness.d.ts.map +1 -1
- package/dist/spawner/liveness.js +5 -67
- package/dist/spawner/liveness.js.map +1 -1
- package/dist/spawner/state.d.ts +8 -20
- package/dist/spawner/state.d.ts.map +1 -1
- package/dist/spawner/state.js +8 -34
- package/dist/spawner/state.js.map +1 -1
- package/dist/types/focus.d.ts +9 -0
- package/dist/types/focus.d.ts.map +1 -1
- package/dist/types/session.d.ts +0 -44
- package/dist/types/session.d.ts.map +1 -1
- package/dist/unified-shell.d.ts.map +1 -1
- package/dist/unified-shell.js +8 -0
- package/dist/unified-shell.js.map +1 -1
- package/package.json +1 -2
- package/dist/completion/agent-completion.d.ts +0 -48
- package/dist/completion/agent-completion.d.ts.map +0 -1
- package/dist/completion/agent-completion.js +0 -205
- package/dist/completion/agent-completion.js.map +0 -1
- package/dist/delivery-guards.d.ts +0 -41
- package/dist/delivery-guards.d.ts.map +0 -1
- package/dist/delivery-guards.js +0 -200
- package/dist/delivery-guards.js.map +0 -1
- package/dist/spawner/spawn-team.d.ts +0 -20
- package/dist/spawner/spawn-team.d.ts.map +0 -1
- package/dist/spawner/spawn-team.js +0 -19
- package/dist/spawner/spawn-team.js.map +0 -1
- package/dist/spawner/timeout.d.ts +0 -32
- package/dist/spawner/timeout.d.ts.map +0 -1
- package/dist/spawner/timeout.js +0 -126
- package/dist/spawner/timeout.js.map +0 -1
package/dist/delivery-guards.js
DELETED
|
@@ -1,200 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Guard evaluation for delivery stage transitions.
|
|
3
|
-
*
|
|
4
|
-
* Core guard evaluation logic, failure mode resolution, fail-closed
|
|
5
|
-
* handling, and audit trail recording.
|
|
6
|
-
*/
|
|
7
|
-
import { updateDeliveryStatus, createEscalation, createTransitionEvaluation } from './supabase.js';
|
|
8
|
-
import { evaluateGuardsAtTransition, executeTriggers, GuardEvaluationError } from './guard-engine.js';
|
|
9
|
-
import { withRetry, ESCALATION_REASONS, ESCALATION_DISPOSITIONS } from '@telora/daemon-core';
|
|
10
|
-
import { createLogger } from './log.js';
|
|
11
|
-
const log = createLogger({ module: 'guard' });
|
|
12
|
-
// ── Guard evaluation (unified workflow system) ──────────────────────
|
|
13
|
-
/**
|
|
14
|
-
* Evaluate guards at a stage transition for a delivery.
|
|
15
|
-
*
|
|
16
|
-
* This is the core guard evaluation logic extracted from completion-handler.ts.
|
|
17
|
-
* Can be called by:
|
|
18
|
-
* - The per-delivery completion handler (legacy)
|
|
19
|
-
* - The focus team lead (after detecting delivery issue completion)
|
|
20
|
-
*/
|
|
21
|
-
export async function evaluateGuardsForDeliveryTransition(params) {
|
|
22
|
-
const { deliveryId, organizationId, workflowTransition, exitCode, policyFailureMode, deliveryName, sessionId, } = params;
|
|
23
|
-
const baseOutcome = {
|
|
24
|
-
blocked: false,
|
|
25
|
-
shouldMerge: false,
|
|
26
|
-
shouldTriggerRepoll: false,
|
|
27
|
-
sessionStatus: 'completed',
|
|
28
|
-
exitReason: '',
|
|
29
|
-
};
|
|
30
|
-
if (!workflowTransition) {
|
|
31
|
-
return baseOutcome;
|
|
32
|
-
}
|
|
33
|
-
try {
|
|
34
|
-
const guardResult = await evaluateGuardsAtTransition(deliveryId, organizationId, workflowTransition.id, exitCode);
|
|
35
|
-
// Log warnings (soft enforcement failures)
|
|
36
|
-
for (const warning of guardResult.warnings) {
|
|
37
|
-
log.warn(`[guard] Soft warning on "${deliveryName}": ` +
|
|
38
|
-
`guard "${warning.guard_name}" conditions not met`);
|
|
39
|
-
}
|
|
40
|
-
if (!guardResult.should_proceed) {
|
|
41
|
-
// Hard guard blocked the transition
|
|
42
|
-
log.info(`[guard] Transition blocked for "${deliveryName}": ` +
|
|
43
|
-
`${guardResult.blocks.length} hard guard(s) failed`);
|
|
44
|
-
// Execute blocking triggers
|
|
45
|
-
const triggerResult = await executeTriggers(deliveryId, organizationId, workflowTransition.id, guardResult.triggers_to_execute);
|
|
46
|
-
let exitReason = `Guard blocked: ${guardResult.blocks.map(b => b.guard_name).join(', ')}.`;
|
|
47
|
-
if (triggerResult.spawnedSessionIds.length > 0) {
|
|
48
|
-
exitReason += ` Spawned ${triggerResult.spawnedSessionIds.length} guard agent(s).`;
|
|
49
|
-
}
|
|
50
|
-
return {
|
|
51
|
-
blocked: true,
|
|
52
|
-
shouldMerge: false,
|
|
53
|
-
shouldTriggerRepoll: false,
|
|
54
|
-
sessionStatus: 'completed',
|
|
55
|
-
exitReason,
|
|
56
|
-
};
|
|
57
|
-
}
|
|
58
|
-
// All guards passed or only soft warnings -- execute pass/enter triggers
|
|
59
|
-
if (guardResult.triggers_to_execute.length > 0) {
|
|
60
|
-
await executeTriggers(deliveryId, organizationId, workflowTransition.id, guardResult.triggers_to_execute);
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
catch (err) {
|
|
64
|
-
const guardError = err instanceof GuardEvaluationError ? err : null;
|
|
65
|
-
const effectiveMode = resolveGuardFailureMode(policyFailureMode, guardError);
|
|
66
|
-
// Record evaluation error in audit trail
|
|
67
|
-
await recordGuardEvaluationError(err, guardError, deliveryId, organizationId, workflowTransition.id, effectiveMode);
|
|
68
|
-
if (effectiveMode === 'fail-closed') {
|
|
69
|
-
return await handleGuardFailClosed({
|
|
70
|
-
err: err,
|
|
71
|
-
guardError,
|
|
72
|
-
deliveryId,
|
|
73
|
-
deliveryName,
|
|
74
|
-
organizationId,
|
|
75
|
-
sessionId,
|
|
76
|
-
transitionId: workflowTransition.id,
|
|
77
|
-
});
|
|
78
|
-
}
|
|
79
|
-
// Fail-open: log and proceed
|
|
80
|
-
log.error(`[guard] GUARD EVALUATION FAILED for "${deliveryName}": ` +
|
|
81
|
-
`${err.message}. Proceeding without guard checks (fail-open).`);
|
|
82
|
-
return {
|
|
83
|
-
...baseOutcome,
|
|
84
|
-
exitReason: `Warning: guard evaluation skipped due to error.`,
|
|
85
|
-
};
|
|
86
|
-
}
|
|
87
|
-
return baseOutcome;
|
|
88
|
-
}
|
|
89
|
-
// ── Guard failure helpers ───────────────────────────────────────────
|
|
90
|
-
/**
|
|
91
|
-
* Resolve the effective failure mode for a guard evaluation error.
|
|
92
|
-
*/
|
|
93
|
-
export function resolveGuardFailureMode(daemonMode, guardError) {
|
|
94
|
-
if (guardError?.hasHardEnforcementGuards) {
|
|
95
|
-
return 'fail-closed';
|
|
96
|
-
}
|
|
97
|
-
if (guardError?.fetchedGuards !== null && guardError?.fetchedGuards !== undefined) {
|
|
98
|
-
return 'fail-open';
|
|
99
|
-
}
|
|
100
|
-
return daemonMode;
|
|
101
|
-
}
|
|
102
|
-
/**
|
|
103
|
-
* Handle fail-closed for guard evaluation errors.
|
|
104
|
-
*/
|
|
105
|
-
export async function handleGuardFailClosed(params) {
|
|
106
|
-
const { err, guardError, deliveryId, deliveryName, organizationId, sessionId, transitionId } = params;
|
|
107
|
-
const guardNames = guardError?.guardNames ?? [];
|
|
108
|
-
const guardInfo = guardNames.length > 0
|
|
109
|
-
? ` Guards: ${guardNames.join(', ')}.`
|
|
110
|
-
: '';
|
|
111
|
-
log.error(`[guard] GUARD EVALUATION FAILED for "${deliveryName}": ` +
|
|
112
|
-
`${err.message}. Transition blocked per fail-closed configuration.${guardInfo}`);
|
|
113
|
-
const exitReason = `Guard evaluation failed, transition blocked per fail-closed configuration.${guardInfo}`;
|
|
114
|
-
try {
|
|
115
|
-
await updateDeliveryStatus(deliveryId, 'paused');
|
|
116
|
-
}
|
|
117
|
-
catch (statusErr) {
|
|
118
|
-
log.error(`Failed to pause delivery "${deliveryName}":`, statusErr.message);
|
|
119
|
-
}
|
|
120
|
-
try {
|
|
121
|
-
await withRetry(() => createEscalation({
|
|
122
|
-
organizationId,
|
|
123
|
-
sessionId: sessionId ?? '',
|
|
124
|
-
issueId: null,
|
|
125
|
-
reasonType: ESCALATION_REASONS.ERROR_ENCOUNTERED,
|
|
126
|
-
// Operator triage: investigate the fail-closed guard error.
|
|
127
|
-
disposition: ESCALATION_DISPOSITIONS.NEEDS_OPERATOR,
|
|
128
|
-
anchor: { deliveryId },
|
|
129
|
-
description: `Guard evaluation failed (fail-closed). Transition blocked.\n\n` +
|
|
130
|
-
`**Delivery:** ${deliveryName}\n` +
|
|
131
|
-
`**Transition:** ${transitionId}\n` +
|
|
132
|
-
`**Error:** ${err.message}\n` +
|
|
133
|
-
(guardNames.length > 0 ? `**Affected guards:** ${guardNames.join(', ')}\n` : '') +
|
|
134
|
-
`\nThe delivery has been paused. Review the error and re-queue when resolved.`,
|
|
135
|
-
whatWasTried: `Guard evaluation at stage transition failed after retries. ` +
|
|
136
|
-
`Fail-closed mode is active${guardError?.hasHardEnforcementGuards ? ' (hard enforcement guards detected)' : ''}.`,
|
|
137
|
-
helpNeeded: `Investigate the guard evaluation failure, resolve the underlying issue, then re-queue the delivery.`,
|
|
138
|
-
}), { maxAttempts: 3, label: 'escalation-guard-fail-closed' });
|
|
139
|
-
log.info(`Created escalation for guard evaluation failure (fail-closed)`);
|
|
140
|
-
}
|
|
141
|
-
catch (escErr) {
|
|
142
|
-
log.error(`CRITICAL: Failed to create escalation for guard fail-closed after retries: ${escErr.message}. ` +
|
|
143
|
-
`Delivery: "${deliveryName}"`);
|
|
144
|
-
}
|
|
145
|
-
return {
|
|
146
|
-
blocked: true,
|
|
147
|
-
shouldMerge: false,
|
|
148
|
-
shouldTriggerRepoll: false,
|
|
149
|
-
sessionStatus: 'completed',
|
|
150
|
-
exitReason,
|
|
151
|
-
};
|
|
152
|
-
}
|
|
153
|
-
/**
|
|
154
|
-
* Record guard evaluation errors in the audit trail (best-effort).
|
|
155
|
-
*/
|
|
156
|
-
export async function recordGuardEvaluationError(err, guardError, deliveryId, organizationId, transitionId, effectiveMode) {
|
|
157
|
-
const errorDetails = {
|
|
158
|
-
error: err.message,
|
|
159
|
-
failure_mode: effectiveMode,
|
|
160
|
-
};
|
|
161
|
-
if (guardError?.fetchedGuards && guardError.fetchedGuards.length > 0) {
|
|
162
|
-
for (const guard of guardError.fetchedGuards) {
|
|
163
|
-
try {
|
|
164
|
-
await createTransitionEvaluation({
|
|
165
|
-
organization_id: organizationId,
|
|
166
|
-
entity_type: 'delivery',
|
|
167
|
-
entity_id: deliveryId,
|
|
168
|
-
transition_id: transitionId,
|
|
169
|
-
guard_id: guard.id,
|
|
170
|
-
result: 'error',
|
|
171
|
-
blocked: effectiveMode === 'fail-closed',
|
|
172
|
-
enforcement_level: guard.enforcement,
|
|
173
|
-
evaluation_details: errorDetails,
|
|
174
|
-
});
|
|
175
|
-
}
|
|
176
|
-
catch (auditErr) {
|
|
177
|
-
log.warn(`[guard] Failed to record evaluation error for "${guard.name}":`, auditErr.message);
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
else {
|
|
182
|
-
try {
|
|
183
|
-
await createTransitionEvaluation({
|
|
184
|
-
organization_id: organizationId,
|
|
185
|
-
entity_type: 'delivery',
|
|
186
|
-
entity_id: deliveryId,
|
|
187
|
-
transition_id: transitionId,
|
|
188
|
-
guard_id: null,
|
|
189
|
-
result: 'error',
|
|
190
|
-
blocked: effectiveMode === 'fail-closed',
|
|
191
|
-
enforcement_level: null,
|
|
192
|
-
evaluation_details: errorDetails,
|
|
193
|
-
});
|
|
194
|
-
}
|
|
195
|
-
catch (auditErr) {
|
|
196
|
-
log.warn(`Failed to record evaluation error in audit trail:`, auditErr.message);
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
//# sourceMappingURL=delivery-guards.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"delivery-guards.js","sourceRoot":"","sources":["../src/delivery-guards.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* DEPRECATED SHIM -- the real spawn implementation lives in focus-executor.ts.
|
|
3
|
-
*
|
|
4
|
-
* This file held a 612-line decomposed near-duplicate of focus-executor's
|
|
5
|
-
* spawnFocusTeam. The two copies had to be kept in sync by hand, and the
|
|
6
|
-
* duplicate (reachable only via the dead session-lifecycle retry loop)
|
|
7
|
-
* silently drifted: it resolved its resume-failure respawn and its resource
|
|
8
|
-
* governor from module-local bindings nothing initialized. The Daemon
|
|
9
|
-
* Orchestration Decomposition focus (injection #12) unified the paths: ONE
|
|
10
|
-
* spawn implementation -- focus-executor.spawnFocusTeam -- serves all callers
|
|
11
|
-
* (the listener poll loop, directive spawn mode via the pending-directive
|
|
12
|
-
* queue, and the resume-failure retry injected into
|
|
13
|
-
* spawner/helpers.handleTeamProcessClose).
|
|
14
|
-
*
|
|
15
|
-
* Kept as a re-export shim so the spawner barrel (index.ts) and any direct
|
|
16
|
-
* importers keep resolving the SAME live symbols. Do not add logic here.
|
|
17
|
-
*/
|
|
18
|
-
export { spawnFocusTeam, generateFocusBranchName, buildAgentArgs, initGovernor, getGovernor, type SpawnFocusTeamParams, } from '../focus-executor.js';
|
|
19
|
-
export type { LogStreams } from '../types.js';
|
|
20
|
-
//# sourceMappingURL=spawn-team.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"spawn-team.d.ts","sourceRoot":"","sources":["../../src/spawner/spawn-team.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EACL,cAAc,EACd,uBAAuB,EACvB,cAAc,EACd,YAAY,EACZ,WAAW,EACX,KAAK,oBAAoB,GAC1B,MAAM,sBAAsB,CAAC;AAC9B,YAAY,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC"}
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* DEPRECATED SHIM -- the real spawn implementation lives in focus-executor.ts.
|
|
3
|
-
*
|
|
4
|
-
* This file held a 612-line decomposed near-duplicate of focus-executor's
|
|
5
|
-
* spawnFocusTeam. The two copies had to be kept in sync by hand, and the
|
|
6
|
-
* duplicate (reachable only via the dead session-lifecycle retry loop)
|
|
7
|
-
* silently drifted: it resolved its resume-failure respawn and its resource
|
|
8
|
-
* governor from module-local bindings nothing initialized. The Daemon
|
|
9
|
-
* Orchestration Decomposition focus (injection #12) unified the paths: ONE
|
|
10
|
-
* spawn implementation -- focus-executor.spawnFocusTeam -- serves all callers
|
|
11
|
-
* (the listener poll loop, directive spawn mode via the pending-directive
|
|
12
|
-
* queue, and the resume-failure retry injected into
|
|
13
|
-
* spawner/helpers.handleTeamProcessClose).
|
|
14
|
-
*
|
|
15
|
-
* Kept as a re-export shim so the spawner barrel (index.ts) and any direct
|
|
16
|
-
* importers keep resolving the SAME live symbols. Do not add logic here.
|
|
17
|
-
*/
|
|
18
|
-
export { spawnFocusTeam, generateFocusBranchName, buildAgentArgs, initGovernor, getGovernor, } from '../focus-executor.js';
|
|
19
|
-
//# sourceMappingURL=spawn-team.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"spawn-team.js","sourceRoot":"","sources":["../../src/spawner/spawn-team.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EACL,cAAc,EACd,uBAAuB,EACvB,cAAc,EACd,YAAY,EACZ,WAAW,GAEZ,MAAM,sBAAsB,CAAC"}
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Timeout enforcement and graceful shutdown for agent sessions.
|
|
3
|
-
*
|
|
4
|
-
* Handles per-agent timeout warnings, escalating shutdown sequences
|
|
5
|
-
* (stdin close -> SIGTERM -> SIGKILL), and graceful completion shutdown.
|
|
6
|
-
*/
|
|
7
|
-
import type { Writable } from 'node:stream';
|
|
8
|
-
import type { DaemonConfig, RunningAgent } from '../types.js';
|
|
9
|
-
/**
|
|
10
|
-
* Safely send a signal to a process, ignoring errors if the process has already exited.
|
|
11
|
-
*/
|
|
12
|
-
export declare function safeSendSignal(pid: number, signal: NodeJS.Signals): void;
|
|
13
|
-
/**
|
|
14
|
-
* Safely close a writable stdin stream, ignoring errors if already closed.
|
|
15
|
-
*/
|
|
16
|
-
export declare function safeCloseStdin(stdin: Writable): void;
|
|
17
|
-
/**
|
|
18
|
-
* Set up per-agent timeout enforcement with warning at 80% and escalating shutdown.
|
|
19
|
-
*
|
|
20
|
-
* Returns a `timedOut` accessor function (closure over mutable state).
|
|
21
|
-
*/
|
|
22
|
-
export declare function setupTimeoutEnforcement(config: DaemonConfig, runningAgent: RunningAgent, deliveryName: string, sessionId: string, runningAgents: Map<string, RunningAgent>): {
|
|
23
|
-
getTimedOut: () => boolean;
|
|
24
|
-
};
|
|
25
|
-
/**
|
|
26
|
-
* Initiate graceful shutdown for an agent session.
|
|
27
|
-
*
|
|
28
|
-
* Sends a wrap-up message via stdin, waits for the process to exit,
|
|
29
|
-
* and escalates to SIGTERM/SIGKILL if needed.
|
|
30
|
-
*/
|
|
31
|
-
export declare function initiateGracefulShutdown(agent: RunningAgent, deliveryName: string, runningAgents: Map<string, RunningAgent>): void;
|
|
32
|
-
//# sourceMappingURL=timeout.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"timeout.d.ts","sourceRoot":"","sources":["../../src/spawner/timeout.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAO9D;;GAEG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,OAAO,GAAG,IAAI,CAMxE;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,QAAQ,GAAG,IAAI,CAMpD;AAED;;;;GAIG;AACH,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,YAAY,EACpB,YAAY,EAAE,YAAY,EAC1B,YAAY,EAAE,MAAM,EACpB,SAAS,EAAE,MAAM,EACjB,aAAa,EAAE,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC,GACvC;IAAE,WAAW,EAAE,MAAM,OAAO,CAAA;CAAE,CAuChC;AA8BD;;;;;GAKG;AACH,wBAAgB,wBAAwB,CACtC,KAAK,EAAE,YAAY,EACnB,YAAY,EAAE,MAAM,EACpB,aAAa,EAAE,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC,GACvC,IAAI,CAuCN"}
|
package/dist/spawner/timeout.js
DELETED
|
@@ -1,126 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Timeout enforcement and graceful shutdown for agent sessions.
|
|
3
|
-
*
|
|
4
|
-
* Handles per-agent timeout warnings, escalating shutdown sequences
|
|
5
|
-
* (stdin close -> SIGTERM -> SIGKILL), and graceful completion shutdown.
|
|
6
|
-
*/
|
|
7
|
-
import { sendMessage } from '@telora/daemon-core';
|
|
8
|
-
import { createLogger } from '../log.js';
|
|
9
|
-
const log = createLogger({ module: 'timeout' });
|
|
10
|
-
/**
|
|
11
|
-
* Safely send a signal to a process, ignoring errors if the process has already exited.
|
|
12
|
-
*/
|
|
13
|
-
export function safeSendSignal(pid, signal) {
|
|
14
|
-
try {
|
|
15
|
-
process.kill(pid, signal);
|
|
16
|
-
}
|
|
17
|
-
catch (e) {
|
|
18
|
-
log.debug(`[spawner] safeSendSignal(${pid}, ${signal}) failed (process may have exited):`, e.message);
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
/**
|
|
22
|
-
* Safely close a writable stdin stream, ignoring errors if already closed.
|
|
23
|
-
*/
|
|
24
|
-
export function safeCloseStdin(stdin) {
|
|
25
|
-
try {
|
|
26
|
-
stdin.end();
|
|
27
|
-
}
|
|
28
|
-
catch (e) {
|
|
29
|
-
log.debug('[spawner] safeCloseStdin failed (stdin may already be closed):', e.message);
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
/**
|
|
33
|
-
* Set up per-agent timeout enforcement with warning at 80% and escalating shutdown.
|
|
34
|
-
*
|
|
35
|
-
* Returns a `timedOut` accessor function (closure over mutable state).
|
|
36
|
-
*/
|
|
37
|
-
export function setupTimeoutEnforcement(config, runningAgent, deliveryName, sessionId, runningAgents) {
|
|
38
|
-
let timedOut = false;
|
|
39
|
-
const timeoutMs = config.sessionTimeoutMs;
|
|
40
|
-
if (timeoutMs <= 0) {
|
|
41
|
-
return { getTimedOut: () => timedOut };
|
|
42
|
-
}
|
|
43
|
-
// Warning at 80% of timeout -- send warning via stdin
|
|
44
|
-
const warningMs = Math.floor(timeoutMs * 0.8);
|
|
45
|
-
runningAgent.warningTimer = setTimeout(() => {
|
|
46
|
-
const remaining = Math.ceil((timeoutMs - warningMs) / 60000);
|
|
47
|
-
log.warn(`[timeout] Agent for "${deliveryName}" at 80% of timeout limit. ` +
|
|
48
|
-
`Sending warning via stdin. ~${remaining} min remaining.`);
|
|
49
|
-
sendMessage(runningAgent.stdin, `WARNING: You have approximately ${remaining} minutes remaining before the session ` +
|
|
50
|
-
`is terminated. Please wrap up your current work, commit changes, and prepare to exit.`);
|
|
51
|
-
}, warningMs);
|
|
52
|
-
// Hard timeout -- escalating shutdown: message -> close stdin -> SIGTERM -> SIGKILL
|
|
53
|
-
runningAgent.timeoutTimer = setTimeout(() => {
|
|
54
|
-
timedOut = true;
|
|
55
|
-
log.error(`[timeout] Agent for "${deliveryName}" exceeded ${timeoutMs / 60000} min timeout. ` +
|
|
56
|
-
`Sending shutdown message...`);
|
|
57
|
-
runningAgent.streamState = 'shutting_down';
|
|
58
|
-
sendMessage(runningAgent.stdin, `TIMEOUT: Session time limit reached. Stop all work immediately, commit any changes, and exit now.`);
|
|
59
|
-
scheduleTimeoutEscalation(runningAgent, deliveryName, sessionId, runningAgents);
|
|
60
|
-
}, timeoutMs);
|
|
61
|
-
return { getTimedOut: () => timedOut };
|
|
62
|
-
}
|
|
63
|
-
/**
|
|
64
|
-
* Schedule escalating shutdown steps after the initial timeout message:
|
|
65
|
-
* stdin close -> SIGTERM -> SIGKILL
|
|
66
|
-
*/
|
|
67
|
-
function scheduleTimeoutEscalation(agent, deliveryName, sessionId, runningAgents) {
|
|
68
|
-
// Close stdin after a short grace period to signal EOF
|
|
69
|
-
setTimeout(() => safeCloseStdin(agent.stdin), 10000);
|
|
70
|
-
// SIGTERM after stdin close grace period
|
|
71
|
-
setTimeout(() => {
|
|
72
|
-
if (!runningAgents.has(sessionId))
|
|
73
|
-
return;
|
|
74
|
-
log.error(`Agent for "${deliveryName}" did not exit after stdin close. Sending SIGTERM...`);
|
|
75
|
-
safeSendSignal(agent.pid, 'SIGTERM');
|
|
76
|
-
}, 20000);
|
|
77
|
-
// SIGKILL as absolute last resort
|
|
78
|
-
setTimeout(() => {
|
|
79
|
-
if (!runningAgents.has(sessionId))
|
|
80
|
-
return;
|
|
81
|
-
log.error(`Agent for "${deliveryName}" still running. Sending SIGKILL...`);
|
|
82
|
-
safeSendSignal(agent.pid, 'SIGKILL');
|
|
83
|
-
}, 30000);
|
|
84
|
-
}
|
|
85
|
-
/**
|
|
86
|
-
* Initiate graceful shutdown for an agent session.
|
|
87
|
-
*
|
|
88
|
-
* Sends a wrap-up message via stdin, waits for the process to exit,
|
|
89
|
-
* and escalates to SIGTERM/SIGKILL if needed.
|
|
90
|
-
*/
|
|
91
|
-
export function initiateGracefulShutdown(agent, deliveryName, runningAgents) {
|
|
92
|
-
const GRACE_PERIOD_MS = 60000; // 60s for agent to wrap up
|
|
93
|
-
const ESCALATION_STEP_MS = 10000; // 10s between escalation steps
|
|
94
|
-
// Send wrap-up message
|
|
95
|
-
sendMessage(agent.stdin, 'All work is complete. Please commit any remaining changes, clean up, and exit.');
|
|
96
|
-
// Flat escalation chain using absolute offsets from now
|
|
97
|
-
// Step 1: Close stdin after grace period
|
|
98
|
-
const graceTimer = setTimeout(() => {
|
|
99
|
-
if (!runningAgents.has(agent.sessionId))
|
|
100
|
-
return;
|
|
101
|
-
log.warn(`[shutdown] Agent for "${deliveryName}" did not exit within grace period. Closing stdin...`);
|
|
102
|
-
safeCloseStdin(agent.stdin);
|
|
103
|
-
}, GRACE_PERIOD_MS);
|
|
104
|
-
// Step 2: SIGTERM after grace period + one escalation step
|
|
105
|
-
setTimeout(() => {
|
|
106
|
-
if (!runningAgents.has(agent.sessionId))
|
|
107
|
-
return;
|
|
108
|
-
log.warn(`[shutdown] Agent for "${deliveryName}" did not exit after stdin close. Sending SIGTERM...`);
|
|
109
|
-
safeSendSignal(agent.pid, 'SIGTERM');
|
|
110
|
-
}, GRACE_PERIOD_MS + ESCALATION_STEP_MS);
|
|
111
|
-
// Step 3: SIGKILL after grace period + two escalation steps
|
|
112
|
-
setTimeout(() => {
|
|
113
|
-
if (!runningAgents.has(agent.sessionId))
|
|
114
|
-
return;
|
|
115
|
-
log.error(`[shutdown] Agent for "${deliveryName}" still running. Sending SIGKILL...`);
|
|
116
|
-
safeSendSignal(agent.pid, 'SIGKILL');
|
|
117
|
-
}, GRACE_PERIOD_MS + ESCALATION_STEP_MS * 2);
|
|
118
|
-
// Clean up timer if process exits before grace period
|
|
119
|
-
const checkExit = setInterval(() => {
|
|
120
|
-
if (!runningAgents.has(agent.sessionId)) {
|
|
121
|
-
clearTimeout(graceTimer);
|
|
122
|
-
clearInterval(checkExit);
|
|
123
|
-
}
|
|
124
|
-
}, 1000);
|
|
125
|
-
}
|
|
126
|
-
//# sourceMappingURL=timeout.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"timeout.js","sourceRoot":"","sources":["../../src/spawner/timeout.ts"],"names":[],"mappings":"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"}
|