@ai-dossier/sched 0.2.0 → 0.2.1
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/dispatch.d.ts +103 -0
- package/dist/dispatch.d.ts.map +1 -0
- package/dist/dispatch.js +262 -0
- package/dist/dispatch.js.map +1 -0
- package/dist/engine.d.ts +71 -0
- package/dist/engine.d.ts.map +1 -0
- package/dist/engine.js +590 -0
- package/dist/engine.js.map +1 -0
- package/dist/enqueue.d.ts +38 -0
- package/dist/enqueue.d.ts.map +1 -0
- package/dist/enqueue.js +220 -0
- package/dist/enqueue.js.map +1 -0
- package/dist/groundtruth.d.ts +74 -0
- package/dist/groundtruth.d.ts.map +1 -0
- package/dist/groundtruth.js +114 -0
- package/dist/groundtruth.js.map +1 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +86 -0
- package/dist/index.js.map +1 -0
- package/dist/journal.d.ts +32 -0
- package/dist/journal.d.ts.map +1 -0
- package/dist/journal.js +113 -0
- package/dist/journal.js.map +1 -0
- package/dist/persist.d.ts +54 -0
- package/dist/persist.d.ts.map +1 -0
- package/dist/persist.js +334 -0
- package/dist/persist.js.map +1 -0
- package/dist/project.d.ts +41 -0
- package/dist/project.d.ts.map +1 -0
- package/dist/project.js +124 -0
- package/dist/project.js.map +1 -0
- package/dist/readiness.d.ts +43 -0
- package/dist/readiness.d.ts.map +1 -0
- package/dist/readiness.js +102 -0
- package/dist/readiness.js.map +1 -0
- package/dist/scheduler.d.ts +66 -0
- package/dist/scheduler.d.ts.map +1 -0
- package/dist/scheduler.js +174 -0
- package/dist/scheduler.js.map +1 -0
- package/dist/state.d.ts +39 -0
- package/dist/state.d.ts.map +1 -0
- package/dist/state.js +360 -0
- package/dist/state.js.map +1 -0
- package/dist/status.d.ts +32 -0
- package/dist/status.d.ts.map +1 -0
- package/dist/status.js +76 -0
- package/dist/status.js.map +1 -0
- package/dist/types.d.ts +214 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +87 -0
- package/dist/types.js.map +1 -0
- package/package.json +2 -2
package/dist/engine.js
ADDED
|
@@ -0,0 +1,590 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* The scheduler engine (#464): dispatch, completion verification, and the
|
|
4
|
+
* stall/escalation ladder (RFC-0001 §C.1) — the deterministic organs that
|
|
5
|
+
* replace fleet-cycle's LLM supervision.
|
|
6
|
+
*
|
|
7
|
+
* One `tick()` is a full reconcile+refill cycle:
|
|
8
|
+
*
|
|
9
|
+
* 1. **Poll** ground truth for every live unit OUTSIDE the state lock (gh/git
|
|
10
|
+
* subprocesses are slow; the lock must never wait on a network call).
|
|
11
|
+
* 2. **Apply** under `SchedStore.withLock`:
|
|
12
|
+
* - `assigned` slots (crash between assign and spawn) are spawned/re-attached
|
|
13
|
+
* - `running` slots: dead pid → exit rail; ground truth says complete →
|
|
14
|
+
* external advance (kill the leftover agent, complete); new milestone or
|
|
15
|
+
* pushed commit → progress; no progress for `stall_timeout_ms` →
|
|
16
|
+
* redispatch one tier stronger (cap 2, then failed)
|
|
17
|
+
* - `exited`/`verifying` slots: the agent exited — completion is verified
|
|
18
|
+
* against ground truth, never assumed (AC2); unverified exits ride the
|
|
19
|
+
* same recovery ladder as stalls
|
|
20
|
+
* - `recovering` slots: respawned with the escalated tier (resume rails —
|
|
21
|
+
* the agent re-enters via gate and resumes from the milestone trail)
|
|
22
|
+
* - failures block their TRANSITIVE dependents (AC4)
|
|
23
|
+
* 3. **Refill**: `computeAssignments` fills every freed slot in the SAME tick —
|
|
24
|
+
* a runnable unit never waits while a slot is idle (AC5).
|
|
25
|
+
*
|
|
26
|
+
* Everything that touches the world (processes, GitHub, git) is injected;
|
|
27
|
+
* the state machine is pure. Only `issue:<n>` units are dispatched — batch
|
|
28
|
+
* member sequencing is a follow-up (#464 non-goal).
|
|
29
|
+
*/
|
|
30
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
31
|
+
if (k2 === undefined) k2 = k;
|
|
32
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
33
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
34
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
35
|
+
}
|
|
36
|
+
Object.defineProperty(o, k2, desc);
|
|
37
|
+
}) : (function(o, m, k, k2) {
|
|
38
|
+
if (k2 === undefined) k2 = k;
|
|
39
|
+
o[k2] = m[k];
|
|
40
|
+
}));
|
|
41
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
42
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
43
|
+
}) : function(o, v) {
|
|
44
|
+
o["default"] = v;
|
|
45
|
+
});
|
|
46
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
47
|
+
var ownKeys = function(o) {
|
|
48
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
49
|
+
var ar = [];
|
|
50
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
51
|
+
return ar;
|
|
52
|
+
};
|
|
53
|
+
return ownKeys(o);
|
|
54
|
+
};
|
|
55
|
+
return function (mod) {
|
|
56
|
+
if (mod && mod.__esModule) return mod;
|
|
57
|
+
var result = {};
|
|
58
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
59
|
+
__setModuleDefault(result, mod);
|
|
60
|
+
return result;
|
|
61
|
+
};
|
|
62
|
+
})();
|
|
63
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
64
|
+
exports.tick = tick;
|
|
65
|
+
exports.runLoop = runLoop;
|
|
66
|
+
const path = __importStar(require("node:path"));
|
|
67
|
+
const dispatch_1 = require("./dispatch");
|
|
68
|
+
const groundtruth_1 = require("./groundtruth");
|
|
69
|
+
const journal_1 = require("./journal");
|
|
70
|
+
const scheduler_1 = require("./scheduler");
|
|
71
|
+
const state_1 = require("./state");
|
|
72
|
+
const types_1 = require("./types");
|
|
73
|
+
function emptyResult() {
|
|
74
|
+
return {
|
|
75
|
+
spawned: [],
|
|
76
|
+
externalAdvances: [],
|
|
77
|
+
completed: [],
|
|
78
|
+
redispatched: [],
|
|
79
|
+
failed: [],
|
|
80
|
+
blocked: [],
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
function journal(ctx, event, unit, extra = {}) {
|
|
84
|
+
ctx.deps.journal.append((0, journal_1.unitEvent)(event, unit, extra), ctx.deps.now());
|
|
85
|
+
}
|
|
86
|
+
function slotOf(state, unit) {
|
|
87
|
+
return state.slots.find((s) => s.unit === unit);
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Metadata patch on a slot WITHOUT a status transition (pid/phase/branch/
|
|
91
|
+
* last_head/last_progress are data, not machine states — RFC-0001 §D.3 keeps
|
|
92
|
+
* them alongside the status, and the transition tables stay pure).
|
|
93
|
+
*/
|
|
94
|
+
function patchSlot(state, slotId, patch, now) {
|
|
95
|
+
return {
|
|
96
|
+
...state,
|
|
97
|
+
slots: state.slots.map((s) => s.id === slotId ? { ...s, ...patch, updated_at: now.toISOString() } : s),
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
/** Walk a slot to `idle` one declared edge per iteration; `step` picks the next status. */
|
|
101
|
+
function walkSlotToIdle(state, unit, now, step) {
|
|
102
|
+
let next = state;
|
|
103
|
+
let slot = slotOf(next, unit);
|
|
104
|
+
while (slot && slot.status !== 'idle') {
|
|
105
|
+
next = (0, state_1.transitionSlot)(next, slot.id, step(slot.status), {}, now);
|
|
106
|
+
slot = slotOf(next, unit);
|
|
107
|
+
}
|
|
108
|
+
return next;
|
|
109
|
+
}
|
|
110
|
+
/** Kill the agent holding `unit`'s slot, if it is alive. */
|
|
111
|
+
function killUnitAgent(ctx, state, unit) {
|
|
112
|
+
const slot = slotOf(state, unit);
|
|
113
|
+
if (slot &&
|
|
114
|
+
slot.pid !== null &&
|
|
115
|
+
ctx.deps.spawnDeps.isAlive(slot.pid, slot.pid_start ?? undefined)) {
|
|
116
|
+
ctx.deps.spawnDeps.kill(slot.pid, slot.pid_start ?? undefined);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
// --- Poll (outside the lock) ---
|
|
120
|
+
function pollUnits(deps, state) {
|
|
121
|
+
const out = new Map();
|
|
122
|
+
for (const slot of state.slots) {
|
|
123
|
+
if (slot.unit === null)
|
|
124
|
+
continue;
|
|
125
|
+
if (slot.status !== 'running' && slot.status !== 'verifying' && slot.status !== 'exited') {
|
|
126
|
+
continue;
|
|
127
|
+
}
|
|
128
|
+
const issue = (0, journal_1.issueOfUnit)(slot.unit);
|
|
129
|
+
if (issue === null || out.has(slot.unit))
|
|
130
|
+
continue;
|
|
131
|
+
const milestone = deps.groundTruth.latestMilestone(issue);
|
|
132
|
+
out.set(slot.unit, {
|
|
133
|
+
reachable: milestone !== undefined,
|
|
134
|
+
milestone: milestone ?? null,
|
|
135
|
+
closed: deps.groundTruth.issueClosed(issue),
|
|
136
|
+
head: slot.branch !== null ? deps.groundTruth.branchHead(slot.branch) : null,
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
return out;
|
|
140
|
+
}
|
|
141
|
+
// --- Spawn / fail / complete ---
|
|
142
|
+
/** Spawn (or respawn) the agent for `unit` and move its slot to `running`. */
|
|
143
|
+
function spawnUnit(ctx, state, unit) {
|
|
144
|
+
const issue = (0, journal_1.issueOfUnit)(unit);
|
|
145
|
+
if (issue === null)
|
|
146
|
+
return state;
|
|
147
|
+
const entry = (0, state_1.findEntry)(state, issue);
|
|
148
|
+
const slot = slotOf(state, unit);
|
|
149
|
+
if (!entry ||
|
|
150
|
+
!slot ||
|
|
151
|
+
slot.status === 'idle' ||
|
|
152
|
+
slot.status === 'complete' ||
|
|
153
|
+
slot.status === 'failed') {
|
|
154
|
+
return state;
|
|
155
|
+
}
|
|
156
|
+
const cmd = (0, dispatch_1.buildAgentCommand)(ctx.dispatch.command, entry.tier, issue, ctx.dispatch.tierModels);
|
|
157
|
+
const prompt = (0, dispatch_1.buildPrompt)(ctx.dispatch.prompt, issue);
|
|
158
|
+
const logFile = path.join(ctx.deps.store.runsDir, `${(0, dispatch_1.unitLogName)(unit)}.log`);
|
|
159
|
+
let pid;
|
|
160
|
+
try {
|
|
161
|
+
pid = ctx.deps.spawnDeps.spawn(cmd, prompt, logFile);
|
|
162
|
+
}
|
|
163
|
+
catch (err) {
|
|
164
|
+
// A spawn failure fails the unit through the declared failure rail —
|
|
165
|
+
// visible in `sched status` (Failed: … spawn-error) instead of aborting
|
|
166
|
+
// the whole tick and silently discarding every other unit's reconcile.
|
|
167
|
+
return failUnit(ctx, state, unit, `spawn-error: ${err.message}`);
|
|
168
|
+
}
|
|
169
|
+
const now = ctx.deps.now();
|
|
170
|
+
const patch = {
|
|
171
|
+
pid,
|
|
172
|
+
pid_start: ctx.deps.spawnDeps.processStart(pid),
|
|
173
|
+
phase: 'gate',
|
|
174
|
+
last_progress_at: now.toISOString(),
|
|
175
|
+
};
|
|
176
|
+
const next = slot.status === 'assigned' || slot.status === 'recovering'
|
|
177
|
+
? (0, state_1.transitionSlot)(state, slot.id, 'running', patch, now)
|
|
178
|
+
: patchSlot(state, slot.id, patch, now);
|
|
179
|
+
journal(ctx, 'spawned', unit, {
|
|
180
|
+
pid,
|
|
181
|
+
tier: entry.tier,
|
|
182
|
+
slot: slot.id,
|
|
183
|
+
cmd: cmd.join(' '),
|
|
184
|
+
log: logFile,
|
|
185
|
+
});
|
|
186
|
+
ctx.result.spawned.push(unit);
|
|
187
|
+
return next;
|
|
188
|
+
}
|
|
189
|
+
/** Fail a unit: entry → failed, slot released, transitive dependents blocked (AC4). */
|
|
190
|
+
function failUnit(ctx, state, unit, reason) {
|
|
191
|
+
const issue = (0, journal_1.issueOfUnit)(unit);
|
|
192
|
+
if (issue === null)
|
|
193
|
+
return state;
|
|
194
|
+
const now = ctx.deps.now();
|
|
195
|
+
killUnitAgent(ctx, state, unit);
|
|
196
|
+
let next = releaseSlotViaFailure(ctx, state, unit);
|
|
197
|
+
const entry = (0, state_1.findEntry)(next, issue);
|
|
198
|
+
if (entry && !types_1.TERMINAL_ISSUE_STATUSES.has(entry.status)) {
|
|
199
|
+
next = (0, state_1.transitionIssue)(next, issue, 'failed', { reason }, now);
|
|
200
|
+
journal(ctx, 'unit-failed', unit, { reason });
|
|
201
|
+
ctx.result.failed.push(unit);
|
|
202
|
+
const blocked = blockTransitiveDependents(ctx, next, issue);
|
|
203
|
+
next = blocked.state;
|
|
204
|
+
ctx.result.blocked.push(...blocked.issues);
|
|
205
|
+
}
|
|
206
|
+
return next;
|
|
207
|
+
}
|
|
208
|
+
/** Release a unit's slot to idle through the failure rail (failed → idle). */
|
|
209
|
+
function releaseSlotViaFailure(ctx, state, unit) {
|
|
210
|
+
return walkSlotToIdle(state, unit, ctx.deps.now(), (status) => status === 'complete' || status === 'failed' ? 'idle' : 'failed');
|
|
211
|
+
}
|
|
212
|
+
/** Block every entry that transitively depends on `failedIssue` (AC4). */
|
|
213
|
+
function blockTransitiveDependents(ctx, state, failedIssue) {
|
|
214
|
+
const now = ctx.deps.now();
|
|
215
|
+
const reason = `dep-failed:${failedIssue}`;
|
|
216
|
+
// BFS over reversed dependency edges: who depends on the failed issue,
|
|
217
|
+
// directly or through another to-be-blocked entry?
|
|
218
|
+
const queue = [failedIssue];
|
|
219
|
+
const seen = new Set([failedIssue]);
|
|
220
|
+
const dependents = [];
|
|
221
|
+
while (queue.length > 0) {
|
|
222
|
+
const current = queue.shift();
|
|
223
|
+
for (const entry of state.entries) {
|
|
224
|
+
if (seen.has(entry.issue) || !entry.deps.includes(current))
|
|
225
|
+
continue;
|
|
226
|
+
seen.add(entry.issue);
|
|
227
|
+
queue.push(entry.issue);
|
|
228
|
+
dependents.push(entry.issue);
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
const blockedIssues = [];
|
|
232
|
+
let next = state;
|
|
233
|
+
for (const issue of dependents) {
|
|
234
|
+
const entry = (0, state_1.findEntry)(next, issue);
|
|
235
|
+
if (!entry)
|
|
236
|
+
continue;
|
|
237
|
+
// Terminal/satisfied entries keep their outcome; already-blocked entries
|
|
238
|
+
// keep their (possibly more specific) reason.
|
|
239
|
+
if (types_1.TERMINAL_ISSUE_STATUSES.has(entry.status) ||
|
|
240
|
+
entry.status === 'blocked' ||
|
|
241
|
+
entry.status === 'shipped' ||
|
|
242
|
+
entry.status === 'shipped-in-batch') {
|
|
243
|
+
continue;
|
|
244
|
+
}
|
|
245
|
+
// A dependent mid-run is working toward a doomed merge — release its slot.
|
|
246
|
+
const unit = `issue:${issue}`;
|
|
247
|
+
killUnitAgent(ctx, next, unit);
|
|
248
|
+
next = releaseSlotViaFailure(ctx, next, unit);
|
|
249
|
+
next = (0, state_1.transitionIssue)(next, issue, 'blocked', { reason }, now);
|
|
250
|
+
journal(ctx, 'dependents-blocked', unit, { reason });
|
|
251
|
+
blockedIssues.push(issue);
|
|
252
|
+
}
|
|
253
|
+
return { state: next, issues: blockedIssues };
|
|
254
|
+
}
|
|
255
|
+
/**
|
|
256
|
+
* The recovery decision for a unit that must be redispatched one tier
|
|
257
|
+
* stronger (stall or unverified exit, AC4). At the escalation cap or the
|
|
258
|
+
* strongest tier, the unit fails instead — the designed signal that a human,
|
|
259
|
+
* not a stronger model, is next.
|
|
260
|
+
*/
|
|
261
|
+
function enterRecovery(ctx, state, unit, causeEvent, cause, evidence = {}) {
|
|
262
|
+
const issue = (0, journal_1.issueOfUnit)(unit);
|
|
263
|
+
if (issue === null)
|
|
264
|
+
return state;
|
|
265
|
+
const now = ctx.deps.now();
|
|
266
|
+
const entry = (0, state_1.findEntry)(state, issue);
|
|
267
|
+
const slot = slotOf(state, unit);
|
|
268
|
+
if (!entry || !slot)
|
|
269
|
+
return state;
|
|
270
|
+
killUnitAgent(ctx, state, unit);
|
|
271
|
+
const nextTier = (0, dispatch_1.escalateTier)(entry.tier);
|
|
272
|
+
if (slot.recoveries >= types_1.ESCALATION_CAP || nextTier === null) {
|
|
273
|
+
// Cap reached (2 escalations) or already at the strongest tier — the
|
|
274
|
+
// designed signal that a human, not a stronger model, is next.
|
|
275
|
+
const reason = slot.recoveries >= types_1.ESCALATION_CAP ? 'escalation-cap' : `${cause}-at-strongest-tier`;
|
|
276
|
+
return failUnit(ctx, state, unit, reason);
|
|
277
|
+
}
|
|
278
|
+
let next = (0, state_1.transitionSlot)(state, slot.id, 'recovering', { pid: null, recoveries: slot.recoveries + 1 }, now);
|
|
279
|
+
next = {
|
|
280
|
+
...next,
|
|
281
|
+
entries: next.entries.map((e) => e.issue === issue ? { ...e, tier: nextTier, updated_at: now.toISOString() } : e),
|
|
282
|
+
};
|
|
283
|
+
journal(ctx, causeEvent, unit, {
|
|
284
|
+
detail: cause,
|
|
285
|
+
slot: slot.id,
|
|
286
|
+
...(slot.last_progress_at !== null ? { last_progress_at: slot.last_progress_at } : {}),
|
|
287
|
+
...evidence,
|
|
288
|
+
});
|
|
289
|
+
journal(ctx, 'redispatched', unit, { tier: nextTier, slot: slot.id });
|
|
290
|
+
ctx.result.redispatched.push(unit);
|
|
291
|
+
// Respawn immediately on the recovering rail — recovering → running.
|
|
292
|
+
return spawnUnit(ctx, next, unit);
|
|
293
|
+
}
|
|
294
|
+
/** Complete a unit whose ground truth is verified (AC2). */
|
|
295
|
+
function completeUnit(ctx, state, unit, via) {
|
|
296
|
+
const issue = (0, journal_1.issueOfUnit)(unit);
|
|
297
|
+
if (issue === null)
|
|
298
|
+
return state;
|
|
299
|
+
const now = ctx.deps.now();
|
|
300
|
+
// Walk the slot machine to idle through its declared edges: complete is
|
|
301
|
+
// reachable only via exited → verifying → complete → idle.
|
|
302
|
+
let next = walkSlotToIdle(state, unit, now, (status) => {
|
|
303
|
+
if (status === 'complete' || status === 'failed')
|
|
304
|
+
return 'idle';
|
|
305
|
+
if (status === 'running')
|
|
306
|
+
return 'exited';
|
|
307
|
+
if (status === 'exited')
|
|
308
|
+
return 'verifying';
|
|
309
|
+
if (status === 'verifying')
|
|
310
|
+
return 'complete';
|
|
311
|
+
return 'failed'; // assigned/recovering: nothing verified yet — never wedge
|
|
312
|
+
});
|
|
313
|
+
const entry = (0, state_1.findEntry)(next, issue);
|
|
314
|
+
if (entry && entry.status === 'dispatched') {
|
|
315
|
+
next = (0, state_1.transitionIssue)(next, issue, 'shipped', {}, now);
|
|
316
|
+
next = (0, state_1.transitionIssue)(next, issue, 'done', {}, now);
|
|
317
|
+
}
|
|
318
|
+
else if (entry && entry.status === 'shipped') {
|
|
319
|
+
next = (0, state_1.transitionIssue)(next, issue, 'done', {}, now);
|
|
320
|
+
}
|
|
321
|
+
journal(ctx, via, unit);
|
|
322
|
+
if (via === 'external-advance')
|
|
323
|
+
ctx.result.externalAdvances.push(unit);
|
|
324
|
+
else
|
|
325
|
+
ctx.result.completed.push(unit);
|
|
326
|
+
return next;
|
|
327
|
+
}
|
|
328
|
+
// --- Per-slot reconciliation ---
|
|
329
|
+
/** Apply the polled milestone/branch/head signals; returns whether progress happened. */
|
|
330
|
+
function applyProgressSignals(ctx, state, slot, truth, unit) {
|
|
331
|
+
const now = ctx.deps.now();
|
|
332
|
+
let next = state;
|
|
333
|
+
let progressed = false;
|
|
334
|
+
if (truth.milestone !== null) {
|
|
335
|
+
// Live phase per unit (AC6).
|
|
336
|
+
if (truth.milestone.phase !== slot.phase) {
|
|
337
|
+
next = patchSlot(next, slot.id, { phase: truth.milestone.phase }, now);
|
|
338
|
+
journal(ctx, 'phase-updated', unit, { phase: truth.milestone.phase, slot: slot.id });
|
|
339
|
+
}
|
|
340
|
+
// The setup milestone carries the branch name — capture it once so the
|
|
341
|
+
// pushed-commit stall signal can watch the remote head.
|
|
342
|
+
if (slot.branch === null && typeof truth.milestone.keys.branch === 'string') {
|
|
343
|
+
next = patchSlot(next, slot.id, { branch: truth.milestone.keys.branch }, now);
|
|
344
|
+
}
|
|
345
|
+
if (Date.parse(truth.milestone.at) > Date.parse(slot.last_progress_at ?? '')) {
|
|
346
|
+
progressed = true;
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
if (truth.head !== null && truth.head !== slot.last_head) {
|
|
350
|
+
progressed = true;
|
|
351
|
+
next = patchSlot(next, slot.id, { last_head: truth.head }, now);
|
|
352
|
+
}
|
|
353
|
+
if (progressed) {
|
|
354
|
+
next = patchSlot(next, slot.id, { last_progress_at: now.toISOString() }, now);
|
|
355
|
+
journal(ctx, 'progress', unit, {
|
|
356
|
+
slot: slot.id,
|
|
357
|
+
detail: truth.milestone
|
|
358
|
+
? `milestone ${truth.milestone.phase}/${truth.milestone.status}`
|
|
359
|
+
: 'new pushed commit',
|
|
360
|
+
});
|
|
361
|
+
}
|
|
362
|
+
return { state: next, progressed };
|
|
363
|
+
}
|
|
364
|
+
/** Reconcile one running slot against its polled ground truth. */
|
|
365
|
+
function reconcileRunning(ctx, state, slot, truth, unit) {
|
|
366
|
+
const now = ctx.deps.now();
|
|
367
|
+
// Orphaned pid after a sched restart, or a normally-exited agent: the exit
|
|
368
|
+
// is DETECTED, never trusted as completion (AC2/AC3).
|
|
369
|
+
if (slot.pid !== null && !ctx.deps.spawnDeps.isAlive(slot.pid, slot.pid_start ?? undefined)) {
|
|
370
|
+
journal(ctx, 'exit-detected', unit, { pid: slot.pid, slot: slot.id });
|
|
371
|
+
const exited = (0, state_1.transitionSlot)(state, slot.id, 'exited', {}, now);
|
|
372
|
+
return completeUnitOrRecover(ctx, exited, unit, truth, 'verify-complete');
|
|
373
|
+
}
|
|
374
|
+
// The milestone poll FAILED (gh outage, missing binary) — unreachable is NOT
|
|
375
|
+
// known-absent (decision 2, option A): stall and advance decisions pause for
|
|
376
|
+
// this unit until truth returns. The dead-pid rail above still ran — local
|
|
377
|
+
// truth needs no network.
|
|
378
|
+
if (!truth.reachable) {
|
|
379
|
+
journal(ctx, 'ground-truth-unreachable', unit, {
|
|
380
|
+
slot: slot.id,
|
|
381
|
+
detail: 'stall/advance decisions paused until truth returns',
|
|
382
|
+
});
|
|
383
|
+
return state;
|
|
384
|
+
}
|
|
385
|
+
// Ground truth says the unit is DONE while the agent still holds the slot —
|
|
386
|
+
// externally-advanced state (AC3): reclaim the slot, kill the leftover agent.
|
|
387
|
+
if ((0, groundtruth_1.isVerifiedComplete)(truth.milestone, truth.closed)) {
|
|
388
|
+
journal(ctx, 'external-advance', unit, {
|
|
389
|
+
pid: slot.pid,
|
|
390
|
+
slot: slot.id,
|
|
391
|
+
detail: truth.closed ? 'issue closed' : 'report done',
|
|
392
|
+
});
|
|
393
|
+
killUnitAgent(ctx, state, unit);
|
|
394
|
+
const exited = (0, state_1.transitionSlot)(state, slot.id, 'exited', {}, now);
|
|
395
|
+
return completeUnitOrRecover(ctx, exited, unit, truth, 'external-advance');
|
|
396
|
+
}
|
|
397
|
+
const progress = applyProgressSignals(ctx, state, slot, truth, unit);
|
|
398
|
+
if (progress.progressed)
|
|
399
|
+
return progress.state;
|
|
400
|
+
// No progress: the stall timer (AC4).
|
|
401
|
+
const lastProgress = slot.last_progress_at ? Date.parse(slot.last_progress_at) : 0;
|
|
402
|
+
if (now.getTime() - lastProgress >= ctx.dispatch.stallTimeoutMs) {
|
|
403
|
+
return enterRecovery(ctx, progress.state, unit, 'stalled', 'stall');
|
|
404
|
+
}
|
|
405
|
+
return progress.state;
|
|
406
|
+
}
|
|
407
|
+
/**
|
|
408
|
+
* An exited/verifying slot: verify the claimed state against ground truth
|
|
409
|
+
* (AC2). Verified → complete; unverified → the same recovery ladder as a
|
|
410
|
+
* stall. `via` distinguishes the journal's completion event.
|
|
411
|
+
*/
|
|
412
|
+
function completeUnitOrRecover(ctx, state, unit, truth, via) {
|
|
413
|
+
const now = ctx.deps.now();
|
|
414
|
+
let next = state;
|
|
415
|
+
let slot = slotOf(next, unit);
|
|
416
|
+
if (slot && slot.status === 'exited') {
|
|
417
|
+
next = (0, state_1.transitionSlot)(next, slot.id, 'verifying', {}, now);
|
|
418
|
+
slot = slotOf(next, unit);
|
|
419
|
+
}
|
|
420
|
+
if (!slot || slot.status !== 'verifying')
|
|
421
|
+
return next;
|
|
422
|
+
// The poll failed — unreachable is not "unverified" (decision 2, option A):
|
|
423
|
+
// hold the exit in `verifying` until truth returns, then decide. The agent
|
|
424
|
+
// is already gone; no slot work is lost by waiting.
|
|
425
|
+
if (!truth.reachable) {
|
|
426
|
+
journal(ctx, 'ground-truth-unreachable', unit, {
|
|
427
|
+
slot: slot.id,
|
|
428
|
+
detail: 'exit verification paused until truth returns',
|
|
429
|
+
});
|
|
430
|
+
return next;
|
|
431
|
+
}
|
|
432
|
+
if ((0, groundtruth_1.isVerifiedComplete)(truth.milestone, truth.closed)) {
|
|
433
|
+
return completeUnit(ctx, next, unit, via);
|
|
434
|
+
}
|
|
435
|
+
return enterRecovery(ctx, next, unit, 'verify-incomplete', 'unverified-exit', {
|
|
436
|
+
observed: truth.milestone
|
|
437
|
+
? `milestone ${truth.milestone.phase}/${truth.milestone.status}; closed=${truth.closed}`
|
|
438
|
+
: `no milestone; closed=${truth.closed}`,
|
|
439
|
+
});
|
|
440
|
+
}
|
|
441
|
+
/** Re-attach or spawn a slot left `assigned` by a crash between assign and spawn. */
|
|
442
|
+
function reconcileAssigned(ctx, state, slot, unit) {
|
|
443
|
+
if (slot.pid !== null && ctx.deps.spawnDeps.isAlive(slot.pid)) {
|
|
444
|
+
// Crash after spawn, before the running transition: re-attach by pid.
|
|
445
|
+
journal(ctx, 'orphan-pid', unit, {
|
|
446
|
+
pid: slot.pid,
|
|
447
|
+
slot: slot.id,
|
|
448
|
+
detail: 're-attached after restart',
|
|
449
|
+
});
|
|
450
|
+
return (0, state_1.transitionSlot)(state, slot.id, 'running', {}, ctx.deps.now());
|
|
451
|
+
}
|
|
452
|
+
journal(ctx, 'assigned', unit, { slot: slot.id, detail: 'crash-recovery spawn' });
|
|
453
|
+
return spawnUnit(ctx, state, unit);
|
|
454
|
+
}
|
|
455
|
+
/** Reconcile a `recovering` slot: respawn with the escalated tier. */
|
|
456
|
+
function reconcileRecovering(ctx, state, unit) {
|
|
457
|
+
return spawnUnit(ctx, state, unit);
|
|
458
|
+
}
|
|
459
|
+
// --- Tick phases ---
|
|
460
|
+
/** Phase 1: reconcile every existing slot against its polled ground truth. */
|
|
461
|
+
function reconcileSlots(ctx, state, polled) {
|
|
462
|
+
let next = state;
|
|
463
|
+
for (const slot of state.slots) {
|
|
464
|
+
const unit = slot.unit;
|
|
465
|
+
if (unit === null)
|
|
466
|
+
continue;
|
|
467
|
+
const truth = polled.get(unit) ?? {
|
|
468
|
+
reachable: true,
|
|
469
|
+
milestone: null,
|
|
470
|
+
closed: false,
|
|
471
|
+
head: null,
|
|
472
|
+
};
|
|
473
|
+
switch (slot.status) {
|
|
474
|
+
case 'assigned':
|
|
475
|
+
next = reconcileAssigned(ctx, next, slot, unit);
|
|
476
|
+
break;
|
|
477
|
+
case 'running':
|
|
478
|
+
next = reconcileRunning(ctx, next, slot, truth, unit);
|
|
479
|
+
break;
|
|
480
|
+
case 'exited':
|
|
481
|
+
case 'verifying':
|
|
482
|
+
next = completeUnitOrRecover(ctx, next, unit, truth, 'verify-complete');
|
|
483
|
+
break;
|
|
484
|
+
case 'recovering':
|
|
485
|
+
next = reconcileRecovering(ctx, next, unit);
|
|
486
|
+
break;
|
|
487
|
+
default:
|
|
488
|
+
break;
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
return next;
|
|
492
|
+
}
|
|
493
|
+
/** Phase 2: self-heal orphaned dispatches (crash between the entry and slot transitions). */
|
|
494
|
+
function requeueOrphanedDispatches(ctx, state) {
|
|
495
|
+
const held = new Set(state.slots.map((s) => s.unit).filter((u) => u !== null));
|
|
496
|
+
let next = state;
|
|
497
|
+
for (const entry of state.entries) {
|
|
498
|
+
if (entry.status !== 'dispatched' || held.has(`issue:${entry.issue}`))
|
|
499
|
+
continue;
|
|
500
|
+
const now = ctx.deps.now();
|
|
501
|
+
next = (0, state_1.transitionIssue)(next, entry.issue, 'blocked', { reason: 'orphaned-dispatch' }, now);
|
|
502
|
+
next = (0, state_1.transitionIssue)(next, entry.issue, 'queued', { reason: null }, now);
|
|
503
|
+
journal(ctx, 'requeued', `issue:${entry.issue}`, {
|
|
504
|
+
detail: 'orphaned dispatch requeued after restart',
|
|
505
|
+
});
|
|
506
|
+
}
|
|
507
|
+
return next;
|
|
508
|
+
}
|
|
509
|
+
/** Phase 3: refill — every freed slot is filled in THIS tick (AC5). */
|
|
510
|
+
function dispatchAssignments(ctx, state, config) {
|
|
511
|
+
const now = ctx.deps.now();
|
|
512
|
+
const { state: assigned, assignments } = (0, scheduler_1.computeAssignments)(state, config, now, ['issue']);
|
|
513
|
+
let next = assigned;
|
|
514
|
+
for (const assignment of assignments) {
|
|
515
|
+
if (assignment.kind !== 'issue')
|
|
516
|
+
continue;
|
|
517
|
+
const unit = `issue:${assignment.issue}`;
|
|
518
|
+
journal(ctx, 'assigned', unit, { slot: assignment.slot });
|
|
519
|
+
const entry = (0, state_1.findEntry)(next, assignment.issue);
|
|
520
|
+
if (!entry)
|
|
521
|
+
continue;
|
|
522
|
+
if (entry.status === 'queued') {
|
|
523
|
+
next = (0, state_1.transitionIssue)(next, assignment.issue, 'classified', {}, now);
|
|
524
|
+
}
|
|
525
|
+
next = (0, state_1.transitionIssue)(next, assignment.issue, 'dispatched', {}, now);
|
|
526
|
+
next = spawnUnit(ctx, next, unit);
|
|
527
|
+
}
|
|
528
|
+
return next;
|
|
529
|
+
}
|
|
530
|
+
/**
|
|
531
|
+
* One full reconcile+refill cycle. Ground truth is polled WITHOUT the lock;
|
|
532
|
+
* every state mutation happens under `store.withLock`; refills are computed in
|
|
533
|
+
* the same pass, so a freed slot is reused within this tick (AC5).
|
|
534
|
+
*/
|
|
535
|
+
function tick(deps, config) {
|
|
536
|
+
const dispatch = (0, dispatch_1.resolveDispatch)(config);
|
|
537
|
+
const polled = pollUnits(deps, deps.store.load());
|
|
538
|
+
return deps.store.withLock((state) => {
|
|
539
|
+
const ctx = { deps, dispatch, result: emptyResult() };
|
|
540
|
+
let next = reconcileSlots(ctx, state, polled);
|
|
541
|
+
next = requeueOrphanedDispatches(ctx, next);
|
|
542
|
+
next = dispatchAssignments(ctx, next, config);
|
|
543
|
+
return { state: next, result: ctx.result };
|
|
544
|
+
});
|
|
545
|
+
}
|
|
546
|
+
/**
|
|
547
|
+
* The long-running loop behind `sched start`: tick, sleep, repeat. Returns
|
|
548
|
+
* when `shouldStop()` says so (the CLI wires SIGINT). A failed tick is
|
|
549
|
+
* journaled (`tick-failed`, with the error name — `LockTimeoutError` and
|
|
550
|
+
* `CorruptStateError` demand different operator actions) and reported on
|
|
551
|
+
* stderr, and the loop continues — one bad tick (e.g. a transient gh
|
|
552
|
+
* failure) never stops the scheduler.
|
|
553
|
+
*/
|
|
554
|
+
async function runLoop(deps, config, shouldStop, onTick) {
|
|
555
|
+
const interval = (0, dispatch_1.resolveDispatch)(config).reconcileIntervalMs;
|
|
556
|
+
while (!shouldStop()) {
|
|
557
|
+
try {
|
|
558
|
+
const result = tick(deps, config);
|
|
559
|
+
onTick?.(result);
|
|
560
|
+
}
|
|
561
|
+
catch (err) {
|
|
562
|
+
const detail = `${err.name}: ${err.message}`;
|
|
563
|
+
process.stderr.write(`⚠ sched tick failed: ${detail}\n`);
|
|
564
|
+
deps.journal.append({ event: 'tick-failed', detail }, deps.now());
|
|
565
|
+
}
|
|
566
|
+
if (shouldStop())
|
|
567
|
+
break;
|
|
568
|
+
await sleep(interval, shouldStop);
|
|
569
|
+
}
|
|
570
|
+
}
|
|
571
|
+
function sleep(ms, shouldStop) {
|
|
572
|
+
return new Promise((resolve) => {
|
|
573
|
+
const timer = setTimeout(() => {
|
|
574
|
+
clearInterval(stopCheck);
|
|
575
|
+
resolve();
|
|
576
|
+
}, ms);
|
|
577
|
+
const stopCheck = setInterval(() => {
|
|
578
|
+
if (shouldStop()) {
|
|
579
|
+
clearTimeout(timer);
|
|
580
|
+
clearInterval(stopCheck);
|
|
581
|
+
resolve();
|
|
582
|
+
}
|
|
583
|
+
}, Math.min(dispatch_1.STOP_POLL_MAX_MS, Math.max(dispatch_1.STOP_POLL_MIN_MS, Math.floor(ms / 10))));
|
|
584
|
+
if (typeof timer.unref === 'function')
|
|
585
|
+
timer.unref();
|
|
586
|
+
if (typeof stopCheck.unref === 'function')
|
|
587
|
+
stopCheck.unref();
|
|
588
|
+
});
|
|
589
|
+
}
|
|
590
|
+
//# sourceMappingURL=engine.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"engine.js","sourceRoot":"","sources":["../src/engine.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Enqueue: accept queue entries from CLI flags or a batch-prep manifest
|
|
3
|
+
* (RFC-0001 §C.1 — "queue entries (issue → mode, batch membership, deps, tier)
|
|
4
|
+
* written by batch-prep"). Pure validation + state mutation: rejects duplicate
|
|
5
|
+
* active issues, mode/batch mismatches, self-dependencies, and dependency
|
|
6
|
+
* cycles at enqueue time rather than at assignment time.
|
|
7
|
+
*/
|
|
8
|
+
import type { CycleMode, ModelTier, SchedState } from './types';
|
|
9
|
+
export declare class EnqueueError extends Error {
|
|
10
|
+
constructor(message: string);
|
|
11
|
+
}
|
|
12
|
+
/** One unit of work as provided by flags or a manifest (defaults applied by `enqueueEntries`). */
|
|
13
|
+
export interface EnqueueInput {
|
|
14
|
+
issue: number;
|
|
15
|
+
mode?: CycleMode;
|
|
16
|
+
batch?: string | null;
|
|
17
|
+
deps?: number[];
|
|
18
|
+
tier?: ModelTier;
|
|
19
|
+
base_branch?: string;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Parse a `--from-manifest` payload. Accepts either a bare array of entries or
|
|
23
|
+
* `{ "project": "...", "entries": [...] }` (the batch-prep output shape;
|
|
24
|
+
* `project` is accepted and ignored — the CLI resolves the project itself).
|
|
25
|
+
*/
|
|
26
|
+
export declare function parseManifest(raw: unknown): EnqueueInput[];
|
|
27
|
+
/**
|
|
28
|
+
* Dependency-cycle detection over the combined graph (existing entries +
|
|
29
|
+
* inputs). Deps pointing at issues not in the graph are allowed — they stay
|
|
30
|
+
* permanently unsatisfied and surface in `sched status`'s blocked set.
|
|
31
|
+
*/
|
|
32
|
+
export declare function assertNoDependencyCycle(state: SchedState, inputs: EnqueueInput[]): void;
|
|
33
|
+
/**
|
|
34
|
+
* Append validated entries to the queue (AC1). Returns the new state; throws
|
|
35
|
+
* `EnqueueError` on any rejection — the caller saves nothing when it throws.
|
|
36
|
+
*/
|
|
37
|
+
export declare function enqueueEntries(state: SchedState, inputs: EnqueueInput[], now?: Date): SchedState;
|
|
38
|
+
//# sourceMappingURL=enqueue.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"enqueue.d.ts","sourceRoot":"","sources":["../src/enqueue.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAc,UAAU,EAAE,MAAM,SAAS,CAAC;AAG5E,qBAAa,YAAa,SAAQ,KAAK;gBACzB,OAAO,EAAE,MAAM;CAI5B;AAED,kGAAkG;AAClG,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AASD;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,OAAO,GAAG,YAAY,EAAE,CAiD1D;AAED;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,UAAU,EAAE,MAAM,EAAE,YAAY,EAAE,GAAG,IAAI,CAiCvF;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAC5B,KAAK,EAAE,UAAU,EACjB,MAAM,EAAE,YAAY,EAAE,EACtB,GAAG,GAAE,IAAiB,GACrB,UAAU,CAwGZ"}
|