@ai-dossier/sched 0.2.0 → 0.3.0
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/README.md +85 -17
- package/dist/dispatch.d.ts +128 -0
- package/dist/dispatch.d.ts.map +1 -0
- package/dist/dispatch.js +300 -0
- package/dist/dispatch.js.map +1 -0
- package/dist/engine.d.ts +111 -0
- package/dist/engine.d.ts.map +1 -0
- package/dist/engine.js +936 -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 +222 -0
- package/dist/enqueue.js.map +1 -0
- package/dist/groundtruth.d.ts +135 -0
- package/dist/groundtruth.d.ts.map +1 -0
- package/dist/groundtruth.js +259 -0
- package/dist/groundtruth.js.map +1 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +101 -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 +348 -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 +78 -0
- package/dist/scheduler.d.ts.map +1 -0
- package/dist/scheduler.js +191 -0
- package/dist/scheduler.js.map +1 -0
- package/dist/state.d.ts +40 -0
- package/dist/state.d.ts.map +1 -0
- package/dist/state.js +391 -0
- package/dist/state.js.map +1 -0
- package/dist/status.d.ts +44 -0
- package/dist/status.d.ts.map +1 -0
- package/dist/status.js +82 -0
- package/dist/status.js.map +1 -0
- package/dist/teardown.d.ts +57 -0
- package/dist/teardown.d.ts.map +1 -0
- package/dist/teardown.js +242 -0
- package/dist/teardown.js.map +1 -0
- package/dist/types.d.ts +253 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +91 -0
- package/dist/types.js.map +1 -0
- package/package.json +1 -1
package/dist/state.js
ADDED
|
@@ -0,0 +1,391 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Pure state machines for the scheduler core — RFC-0001 §D as explicit typed
|
|
4
|
+
* transitions. Every function here is pure: it takes a state and returns a new
|
|
5
|
+
* state (immutable spreads, like `packages/worktree-pool/src/pool-state.ts`),
|
|
6
|
+
* and every edge NOT in the tables throws `IllegalTransitionError` (AC3).
|
|
7
|
+
*
|
|
8
|
+
* Failure edges: RFC-0001 §D.1 states "any → blocked(dep-failed) |
|
|
9
|
+
* decision-pending | failed(escalation-cap)" — encoded generically for every
|
|
10
|
+
* non-terminal issue status rather than repeated per row.
|
|
11
|
+
*/
|
|
12
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
+
exports.TRANSITIONS = void 0;
|
|
14
|
+
exports.createEmptyState = createEmptyState;
|
|
15
|
+
exports.validateState = validateState;
|
|
16
|
+
exports.transitionIssue = transitionIssue;
|
|
17
|
+
exports.transitionBatch = transitionBatch;
|
|
18
|
+
exports.transitionSlot = transitionSlot;
|
|
19
|
+
exports.findEntry = findEntry;
|
|
20
|
+
exports.findBatch = findBatch;
|
|
21
|
+
const types_1 = require("./types");
|
|
22
|
+
// --- Transition tables ---
|
|
23
|
+
const ISSUE_BASE_TRANSITIONS = {
|
|
24
|
+
queued: ['classified'],
|
|
25
|
+
classified: ['dispatched', 'batched'],
|
|
26
|
+
// #468: dispatched → parked is the detached-ship exit — the agent parked
|
|
27
|
+
// its PR on auto-merge and exited; parked → shipped accepts the MERGE
|
|
28
|
+
// (never the park — RFC-0001 §E.4 "scheduler gates on merge").
|
|
29
|
+
dispatched: ['shipped', 'parked'],
|
|
30
|
+
parked: ['shipped'],
|
|
31
|
+
shipped: ['done'],
|
|
32
|
+
// batched/waiting/validated also carry `evicted`: RFC-0001 §D.2 dissolving
|
|
33
|
+
// requeues members at ANY batch stage, not just mid-member (F.8).
|
|
34
|
+
batched: ['waiting', 'evicted'],
|
|
35
|
+
waiting: ['in-work', 'evicted'],
|
|
36
|
+
'in-work': ['committed', 'evicted'],
|
|
37
|
+
committed: ['validated', 'evicted'],
|
|
38
|
+
validated: ['shipped-in-batch', 'evicted'],
|
|
39
|
+
'shipped-in-batch': ['done'],
|
|
40
|
+
evicted: ['requeued'],
|
|
41
|
+
requeued: ['dispatched'],
|
|
42
|
+
blocked: ['queued', 'waiting', 'evicted'],
|
|
43
|
+
'decision-pending': ['queued'],
|
|
44
|
+
done: [],
|
|
45
|
+
failed: [],
|
|
46
|
+
};
|
|
47
|
+
/** Failure edges RFC-0001 §D.1 attaches to ANY state (blocked / decision-pending / failed). */
|
|
48
|
+
const ISSUE_UNIVERSAL_FAILURE_EDGES = [
|
|
49
|
+
'blocked',
|
|
50
|
+
'decision-pending',
|
|
51
|
+
'failed',
|
|
52
|
+
];
|
|
53
|
+
function allowedIssueTransitions(from) {
|
|
54
|
+
const base = ISSUE_BASE_TRANSITIONS[from];
|
|
55
|
+
if (types_1.TERMINAL_ISSUE_STATUSES.has(from))
|
|
56
|
+
return base; // no failure edges out of terminal states
|
|
57
|
+
return [...base, ...ISSUE_UNIVERSAL_FAILURE_EDGES];
|
|
58
|
+
}
|
|
59
|
+
const BATCH_TRANSITIONS = {
|
|
60
|
+
forming: ['ready', 'dissolving'],
|
|
61
|
+
ready: ['executing', 'dissolving'],
|
|
62
|
+
// executing → executing advances the member pointer (i/N); the ⟲ in RFC-0001 §D.2.
|
|
63
|
+
executing: ['executing', 'validating', 'dissolving'],
|
|
64
|
+
validating: ['attributing', 'reviewing', 'dissolving'],
|
|
65
|
+
attributing: ['fixing', 'evicting'],
|
|
66
|
+
fixing: ['validating', 'dissolving'],
|
|
67
|
+
evicting: ['validating', 'dissolving'],
|
|
68
|
+
reviewing: ['shipping', 'dissolving'],
|
|
69
|
+
shipping: ['awaiting-merge', 'dissolving'],
|
|
70
|
+
'awaiting-merge': ['rebasing', 'merged'],
|
|
71
|
+
rebasing: ['re-validating', 'dissolving'],
|
|
72
|
+
're-validating': ['shipping', 'dissolving'],
|
|
73
|
+
merged: ['deployed'],
|
|
74
|
+
deployed: ['reported'],
|
|
75
|
+
reported: ['done'],
|
|
76
|
+
done: [],
|
|
77
|
+
dissolving: ['dissolved'],
|
|
78
|
+
dissolved: [],
|
|
79
|
+
};
|
|
80
|
+
const SLOT_BASE_TRANSITIONS = {
|
|
81
|
+
idle: ['assigned'],
|
|
82
|
+
// assigned → idle releases a unit that was claimed but never spawned.
|
|
83
|
+
assigned: ['running', 'idle'],
|
|
84
|
+
running: ['exited', 'recovering'],
|
|
85
|
+
exited: ['verifying'],
|
|
86
|
+
// #464: verifying → recovering is the verify-fail rail — an agent that
|
|
87
|
+
// exited WITHOUT a verified completion is redispatched stronger, exactly
|
|
88
|
+
// like a stall (RFC-0001 §D.3's diagram predates AC2's "an agent exiting
|
|
89
|
+
// is never proof of completion"; this edge is its redispatch path).
|
|
90
|
+
verifying: ['complete', 'recovering'],
|
|
91
|
+
complete: ['idle'],
|
|
92
|
+
recovering: ['running', 'failed'],
|
|
93
|
+
failed: ['idle'],
|
|
94
|
+
};
|
|
95
|
+
/**
|
|
96
|
+
* Operator-abort rail (`sched abandon`, RFC-0001 §D.3 extension): any slot
|
|
97
|
+
* holding a unit that has not completed verification may be forced to
|
|
98
|
+
* `failed` → `idle`. `complete` is excluded — verification passed and the
|
|
99
|
+
* slot is already releasing.
|
|
100
|
+
*/
|
|
101
|
+
const SLOT_ABORTABLE_STATUSES = new Set([
|
|
102
|
+
'assigned',
|
|
103
|
+
'running',
|
|
104
|
+
'exited',
|
|
105
|
+
'verifying',
|
|
106
|
+
'recovering',
|
|
107
|
+
]);
|
|
108
|
+
function allowedSlotTransitions(from) {
|
|
109
|
+
const base = SLOT_BASE_TRANSITIONS[from];
|
|
110
|
+
if (SLOT_ABORTABLE_STATUSES.has(from))
|
|
111
|
+
return [...base, 'failed'];
|
|
112
|
+
return base;
|
|
113
|
+
}
|
|
114
|
+
// --- Construction and validation ---
|
|
115
|
+
/** An empty state carries no timestamps — nothing exists yet to stamp. */
|
|
116
|
+
function createEmptyState() {
|
|
117
|
+
return {
|
|
118
|
+
schema_version: types_1.SCHEMA_VERSION,
|
|
119
|
+
paused: false,
|
|
120
|
+
entries: [],
|
|
121
|
+
batches: [],
|
|
122
|
+
slots: [],
|
|
123
|
+
next_slot_id: 1,
|
|
124
|
+
last_pr_poll_at: null,
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
const ISSUE_STATUSES = new Set(Object.keys(ISSUE_BASE_TRANSITIONS));
|
|
128
|
+
const BATCH_STATUSES = new Set(Object.keys(BATCH_TRANSITIONS));
|
|
129
|
+
const SLOT_STATUSES = new Set(Object.keys(SLOT_BASE_TRANSITIONS));
|
|
130
|
+
const CYCLE_MODES = new Set(['full', 'slot']);
|
|
131
|
+
const MODEL_TIERS = new Set(['mechanical', 'mid', 'strong']);
|
|
132
|
+
function isIsoDateString(value) {
|
|
133
|
+
return typeof value === 'string' && !Number.isNaN(Date.parse(value));
|
|
134
|
+
}
|
|
135
|
+
function validateQueueEntry(data, where) {
|
|
136
|
+
if (data === null || typeof data !== 'object' || Array.isArray(data)) {
|
|
137
|
+
throw new Error(`${where(0)}: entry must be an object`);
|
|
138
|
+
}
|
|
139
|
+
const entry = data;
|
|
140
|
+
if (!Number.isInteger(entry.issue) || entry.issue <= 0) {
|
|
141
|
+
throw new Error(`${where(entry.issue)}: issue must be a positive integer`);
|
|
142
|
+
}
|
|
143
|
+
const label = where(entry.issue);
|
|
144
|
+
if (!CYCLE_MODES.has(String(entry.mode))) {
|
|
145
|
+
throw new Error(`${label}: mode must be 'full' or 'slot'`);
|
|
146
|
+
}
|
|
147
|
+
if (entry.mode === 'full' ? entry.batch !== null : typeof entry.batch !== 'string') {
|
|
148
|
+
throw new Error(`${label}: batch must be a string for slot mode, null for full mode`);
|
|
149
|
+
}
|
|
150
|
+
if (!Array.isArray(entry.deps) ||
|
|
151
|
+
entry.deps.some((d) => !Number.isInteger(d) || d <= 0)) {
|
|
152
|
+
throw new Error(`${label}: deps must be an array of positive issue numbers`);
|
|
153
|
+
}
|
|
154
|
+
if (!MODEL_TIERS.has(String(entry.tier))) {
|
|
155
|
+
throw new Error(`${label}: tier must be mechanical | mid | strong`);
|
|
156
|
+
}
|
|
157
|
+
if (!ISSUE_STATUSES.has(String(entry.status))) {
|
|
158
|
+
throw new Error(`${label}: unknown issue status ${String(entry.status)}`);
|
|
159
|
+
}
|
|
160
|
+
if (entry.reason !== null && typeof entry.reason !== 'string') {
|
|
161
|
+
throw new Error(`${label}: reason must be a string or null`);
|
|
162
|
+
}
|
|
163
|
+
if (entry.pr !== null &&
|
|
164
|
+
entry.pr !== undefined &&
|
|
165
|
+
(!Number.isInteger(entry.pr) || entry.pr <= 0)) {
|
|
166
|
+
throw new Error(`${label}: pr must be a positive integer or null`);
|
|
167
|
+
}
|
|
168
|
+
if (entry.cleanup !== null && entry.cleanup !== undefined && typeof entry.cleanup !== 'string') {
|
|
169
|
+
throw new Error(`${label}: cleanup must be a string or null`);
|
|
170
|
+
}
|
|
171
|
+
if (!isIsoDateString(entry.enqueued_at) || !isIsoDateString(entry.updated_at)) {
|
|
172
|
+
throw new Error(`${label}: enqueued_at/updated_at must be ISO date strings`);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Strict validation of persisted state (mirrors pool-state's `validateState`):
|
|
177
|
+
* wrong schema version or malformed shape throws instead of being coerced, so
|
|
178
|
+
* a corrupt file is a loud failure, never a silent queue reset.
|
|
179
|
+
*
|
|
180
|
+
* Legacy schema versions are accepted and migrated: 1.0.0 (pre-#464) slots
|
|
181
|
+
* backfill `branch`/`last_head` to null; 1.1.0 (pre-#468) entries backfill
|
|
182
|
+
* `pr`/`cleanup` and the state backfills `last_pr_poll_at` to null. The state
|
|
183
|
+
* upgrades to the current schema on the next save.
|
|
184
|
+
*/
|
|
185
|
+
function validateState(data) {
|
|
186
|
+
if (!data || typeof data !== 'object') {
|
|
187
|
+
throw new Error('Scheduler state must be an object');
|
|
188
|
+
}
|
|
189
|
+
const obj = data;
|
|
190
|
+
const version = String(obj.schema_version);
|
|
191
|
+
if (version !== types_1.SCHEMA_VERSION && !types_1.LEGACY_SCHEMA_VERSIONS.includes(version)) {
|
|
192
|
+
throw new Error(`Unsupported schema version: ${version} (expected ${types_1.SCHEMA_VERSION})`);
|
|
193
|
+
}
|
|
194
|
+
if (typeof obj.paused !== 'boolean') {
|
|
195
|
+
throw new Error('Scheduler state must have a paused boolean');
|
|
196
|
+
}
|
|
197
|
+
if (!Array.isArray(obj.entries)) {
|
|
198
|
+
throw new Error('Scheduler state must have an entries array');
|
|
199
|
+
}
|
|
200
|
+
obj.entries.forEach((entry, i) => {
|
|
201
|
+
validateQueueEntry(entry, (n) => `entries[${i}] (issue ${n})`);
|
|
202
|
+
});
|
|
203
|
+
const seenIssues = new Set();
|
|
204
|
+
for (const entry of obj.entries) {
|
|
205
|
+
if (seenIssues.has(entry.issue)) {
|
|
206
|
+
throw new Error(`Duplicate queue entry for issue ${entry.issue}`);
|
|
207
|
+
}
|
|
208
|
+
seenIssues.add(entry.issue);
|
|
209
|
+
}
|
|
210
|
+
if (!Array.isArray(obj.batches)) {
|
|
211
|
+
throw new Error('Scheduler state must have a batches array');
|
|
212
|
+
}
|
|
213
|
+
const seenBatches = new Set();
|
|
214
|
+
for (const batch of obj.batches) {
|
|
215
|
+
if (typeof batch.id !== 'string' || batch.id.length === 0) {
|
|
216
|
+
throw new Error('Batch id must be a non-empty string');
|
|
217
|
+
}
|
|
218
|
+
if (seenBatches.has(batch.id)) {
|
|
219
|
+
throw new Error(`Duplicate batch id ${batch.id}`);
|
|
220
|
+
}
|
|
221
|
+
seenBatches.add(batch.id);
|
|
222
|
+
if (!BATCH_STATUSES.has(String(batch.status))) {
|
|
223
|
+
throw new Error(`Batch ${batch.id}: unknown batch status ${String(batch.status)}`);
|
|
224
|
+
}
|
|
225
|
+
if (!Array.isArray(batch.members) ||
|
|
226
|
+
batch.members.some((m) => !Number.isInteger(m) || m <= 0)) {
|
|
227
|
+
throw new Error(`Batch ${batch.id}: members must be positive issue numbers`);
|
|
228
|
+
}
|
|
229
|
+
if (typeof batch.base_branch !== 'string' || batch.base_branch.length === 0) {
|
|
230
|
+
throw new Error(`Batch ${batch.id}: base_branch must be a non-empty string`);
|
|
231
|
+
}
|
|
232
|
+
if (!Number.isInteger(batch.executing_member) || batch.executing_member < 0) {
|
|
233
|
+
throw new Error(`Batch ${batch.id}: executing_member must be a non-negative integer`);
|
|
234
|
+
}
|
|
235
|
+
if (!isIsoDateString(batch.created_at) || !isIsoDateString(batch.updated_at)) {
|
|
236
|
+
throw new Error(`Batch ${batch.id}: created_at/updated_at must be ISO date strings`);
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
for (const entry of obj.entries) {
|
|
240
|
+
if (entry.batch !== null && !seenBatches.has(entry.batch)) {
|
|
241
|
+
throw new Error(`Issue ${entry.issue}: batch ${entry.batch} does not exist`);
|
|
242
|
+
}
|
|
243
|
+
if (entry.batch !== null) {
|
|
244
|
+
const batch = obj.batches.find((b) => b.id === entry.batch);
|
|
245
|
+
if (batch && !batch.members.includes(entry.issue)) {
|
|
246
|
+
throw new Error(`Issue ${entry.issue}: not listed in batch ${entry.batch} members`);
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
if (!Array.isArray(obj.slots)) {
|
|
251
|
+
throw new Error('Scheduler state must have a slots array');
|
|
252
|
+
}
|
|
253
|
+
const seenSlots = new Set();
|
|
254
|
+
for (const slot of obj.slots) {
|
|
255
|
+
if (!Number.isInteger(slot.id) || slot.id <= 0) {
|
|
256
|
+
throw new Error('Slot id must be a positive integer');
|
|
257
|
+
}
|
|
258
|
+
if (seenSlots.has(slot.id)) {
|
|
259
|
+
throw new Error(`Duplicate slot id ${slot.id}`);
|
|
260
|
+
}
|
|
261
|
+
seenSlots.add(slot.id);
|
|
262
|
+
if (!SLOT_STATUSES.has(String(slot.status))) {
|
|
263
|
+
throw new Error(`Slot ${slot.id}: unknown slot status ${String(slot.status)}`);
|
|
264
|
+
}
|
|
265
|
+
if (slot.unit !== null && typeof slot.unit !== 'string') {
|
|
266
|
+
throw new Error(`Slot ${slot.id}: unit must be a string or null`);
|
|
267
|
+
}
|
|
268
|
+
if (slot.pid !== null && !Number.isInteger(slot.pid)) {
|
|
269
|
+
throw new Error(`Slot ${slot.id}: pid must be an integer or null`);
|
|
270
|
+
}
|
|
271
|
+
if (slot.pid_start !== null &&
|
|
272
|
+
slot.pid_start !== undefined &&
|
|
273
|
+
(!Number.isInteger(slot.pid_start) || slot.pid_start < 0)) {
|
|
274
|
+
throw new Error(`Slot ${slot.id}: pid_start must be a non-negative integer or null`);
|
|
275
|
+
}
|
|
276
|
+
if (slot.phase !== null && typeof slot.phase !== 'string') {
|
|
277
|
+
throw new Error(`Slot ${slot.id}: phase must be a string or null`);
|
|
278
|
+
}
|
|
279
|
+
if (slot.last_progress_at !== null && !isIsoDateString(slot.last_progress_at)) {
|
|
280
|
+
throw new Error(`Slot ${slot.id}: last_progress_at must be an ISO string or null`);
|
|
281
|
+
}
|
|
282
|
+
if (slot.branch !== null && slot.branch !== undefined && typeof slot.branch !== 'string') {
|
|
283
|
+
throw new Error(`Slot ${slot.id}: branch must be a string or null`);
|
|
284
|
+
}
|
|
285
|
+
if (slot.last_head !== null &&
|
|
286
|
+
slot.last_head !== undefined &&
|
|
287
|
+
typeof slot.last_head !== 'string') {
|
|
288
|
+
throw new Error(`Slot ${slot.id}: last_head must be a string or null`);
|
|
289
|
+
}
|
|
290
|
+
if (!Number.isInteger(slot.recoveries) || slot.recoveries < 0) {
|
|
291
|
+
throw new Error(`Slot ${slot.id}: recoveries must be a non-negative integer`);
|
|
292
|
+
}
|
|
293
|
+
if (!isIsoDateString(slot.updated_at)) {
|
|
294
|
+
throw new Error(`Slot ${slot.id}: updated_at must be an ISO date string`);
|
|
295
|
+
}
|
|
296
|
+
if (slot.status === 'idle' && slot.unit !== null) {
|
|
297
|
+
throw new Error(`Slot ${slot.id}: idle slot must not hold a unit`);
|
|
298
|
+
}
|
|
299
|
+
if (slot.status !== 'idle' && slot.unit === null) {
|
|
300
|
+
throw new Error(`Slot ${slot.id}: non-idle slot must hold a unit`);
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
if (!Number.isInteger(obj.next_slot_id) || obj.next_slot_id < 1) {
|
|
304
|
+
throw new Error('next_slot_id must be a positive integer');
|
|
305
|
+
}
|
|
306
|
+
if (obj.last_pr_poll_at !== null &&
|
|
307
|
+
obj.last_pr_poll_at !== undefined &&
|
|
308
|
+
!isIsoDateString(obj.last_pr_poll_at)) {
|
|
309
|
+
throw new Error('last_pr_poll_at must be an ISO date string or null');
|
|
310
|
+
}
|
|
311
|
+
// Migration: pre-#464 (1.0.0) slots carry no branch/last_head/pid_start —
|
|
312
|
+
// backfill null so the returned state always has the current shape. Pre-#468
|
|
313
|
+
// (1.1.0) entries carry no pr/cleanup and the state no last_pr_poll_at.
|
|
314
|
+
const slots = obj.slots.map((slot) => ({
|
|
315
|
+
...slot,
|
|
316
|
+
branch: slot.branch ?? null,
|
|
317
|
+
last_head: slot.last_head ?? null,
|
|
318
|
+
pid_start: slot.pid_start ?? null,
|
|
319
|
+
}));
|
|
320
|
+
const entries = obj.entries.map((entry) => ({
|
|
321
|
+
...entry,
|
|
322
|
+
pr: entry.pr ?? null,
|
|
323
|
+
cleanup: entry.cleanup ?? null,
|
|
324
|
+
}));
|
|
325
|
+
return {
|
|
326
|
+
...data,
|
|
327
|
+
schema_version: types_1.SCHEMA_VERSION,
|
|
328
|
+
entries,
|
|
329
|
+
slots,
|
|
330
|
+
last_pr_poll_at: obj.last_pr_poll_at ?? null,
|
|
331
|
+
};
|
|
332
|
+
}
|
|
333
|
+
function transition(kind, allowed, current, to, patch, now) {
|
|
334
|
+
const from = current.status;
|
|
335
|
+
if (!allowed(from).includes(to)) {
|
|
336
|
+
throw new types_1.IllegalTransitionError(kind, from, to);
|
|
337
|
+
}
|
|
338
|
+
return { ...current, ...patch, status: to, updated_at: now.toISOString() };
|
|
339
|
+
}
|
|
340
|
+
// --- Issue transitions ---
|
|
341
|
+
function transitionIssue(state, issue, to, patch = {}, now = new Date()) {
|
|
342
|
+
const idx = state.entries.findIndex((e) => e.issue === issue);
|
|
343
|
+
if (idx === -1) {
|
|
344
|
+
throw new types_1.SchedNotFoundError(`Queue entry not found: ${issue}`);
|
|
345
|
+
}
|
|
346
|
+
const entries = [...state.entries];
|
|
347
|
+
entries[idx] = transition('issue', (from) => allowedIssueTransitions(from), entries[idx], to, patch, now);
|
|
348
|
+
return { ...state, entries };
|
|
349
|
+
}
|
|
350
|
+
// --- Batch transitions ---
|
|
351
|
+
function transitionBatch(state, batchId, to, patch = {}, now = new Date()) {
|
|
352
|
+
const idx = state.batches.findIndex((b) => b.id === batchId);
|
|
353
|
+
if (idx === -1) {
|
|
354
|
+
throw new types_1.SchedNotFoundError(`Batch not found: ${batchId}`);
|
|
355
|
+
}
|
|
356
|
+
const batches = [...state.batches];
|
|
357
|
+
batches[idx] = transition('batch', (from) => BATCH_TRANSITIONS[from], batches[idx], to, patch, now);
|
|
358
|
+
return { ...state, batches };
|
|
359
|
+
}
|
|
360
|
+
// --- Slot transitions ---
|
|
361
|
+
function transitionSlot(state, slotId, to, patch = {}, now = new Date()) {
|
|
362
|
+
const idx = state.slots.findIndex((s) => s.id === slotId);
|
|
363
|
+
if (idx === -1) {
|
|
364
|
+
throw new types_1.SchedNotFoundError(`Slot not found: ${slotId}`);
|
|
365
|
+
}
|
|
366
|
+
const slots = [...state.slots];
|
|
367
|
+
const clearing = to === 'idle'
|
|
368
|
+
? { unit: null, pid: null, pid_start: null, phase: null, branch: null, last_head: null }
|
|
369
|
+
: {};
|
|
370
|
+
const resetting = to === 'idle' ? { recoveries: 0 } : {};
|
|
371
|
+
slots[idx] = transition('slot', (from) => allowedSlotTransitions(from), slots[idx], to, { ...clearing, ...resetting, ...patch }, now);
|
|
372
|
+
return { ...state, slots };
|
|
373
|
+
}
|
|
374
|
+
// --- Lookups ---
|
|
375
|
+
function findEntry(state, issue) {
|
|
376
|
+
return state.entries.find((e) => e.issue === issue);
|
|
377
|
+
}
|
|
378
|
+
function findBatch(state, batchId) {
|
|
379
|
+
return state.batches.find((b) => b.id === batchId);
|
|
380
|
+
}
|
|
381
|
+
/**
|
|
382
|
+
* All transition tables, exposed as public API — future consumers (#464's
|
|
383
|
+
* dispatcher, status previews) render next-state choices from here instead of
|
|
384
|
+
* re-deriving the RFC tables.
|
|
385
|
+
*/
|
|
386
|
+
exports.TRANSITIONS = {
|
|
387
|
+
issue: (from) => allowedIssueTransitions(from),
|
|
388
|
+
batch: (from) => BATCH_TRANSITIONS[from],
|
|
389
|
+
slot: (from) => allowedSlotTransitions(from),
|
|
390
|
+
};
|
|
391
|
+
//# sourceMappingURL=state.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"state.js","sourceRoot":"","sources":["../src/state.ts"],"names":[],"mappings":"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"}
|
package/dist/status.d.ts
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `sched status` report (AC4): queue, slots, batches, parked PRs, and the
|
|
3
|
+
* blocked/failed sets as a machine-readable report. Text rendering lives in
|
|
4
|
+
* the CLI (`cli/src/commands/sched.ts`, on top of the CLI's shared
|
|
5
|
+
* `renderTable`) — the package deliberately has no dependency on CLI
|
|
6
|
+
* utilities.
|
|
7
|
+
*/
|
|
8
|
+
import type { BatchEntry, QueueEntry, SchedConfig, SchedState, SlotEntry } from './types';
|
|
9
|
+
/** An entry that cannot progress, with the human reason. */
|
|
10
|
+
export interface BlockedItem {
|
|
11
|
+
issue: number;
|
|
12
|
+
status: string;
|
|
13
|
+
reason: string;
|
|
14
|
+
}
|
|
15
|
+
/** A parked unit awaiting its PR merge (#468). */
|
|
16
|
+
export interface ParkedItem {
|
|
17
|
+
issue: number;
|
|
18
|
+
pr: number;
|
|
19
|
+
/** When the unit parked (entry `updated_at`). */
|
|
20
|
+
since: string;
|
|
21
|
+
}
|
|
22
|
+
/** Machine-readable status report (`sched status --json`). */
|
|
23
|
+
export interface StatusReport {
|
|
24
|
+
/** Project slug the report was built for (which state bucket this is). */
|
|
25
|
+
project: string;
|
|
26
|
+
paused: boolean;
|
|
27
|
+
max_slots: number;
|
|
28
|
+
live_slots: number;
|
|
29
|
+
queue: QueueEntry[];
|
|
30
|
+
slots: SlotEntry[];
|
|
31
|
+
batches: BatchEntry[];
|
|
32
|
+
/** Parked units being watched by the PR watcher (#468). */
|
|
33
|
+
parked: ParkedItem[];
|
|
34
|
+
/** When the PR watcher last polled (#468) — null before the first poll. */
|
|
35
|
+
last_pr_poll_at: string | null;
|
|
36
|
+
/** How many units are runnable right now. */
|
|
37
|
+
runnable: number;
|
|
38
|
+
/** Which units are runnable (`issue:<n>` / `batch:<id>`), in dispatch order. */
|
|
39
|
+
runnable_units: string[];
|
|
40
|
+
blocked: BlockedItem[];
|
|
41
|
+
failed: QueueEntry[];
|
|
42
|
+
}
|
|
43
|
+
export declare function buildStatusReport(state: SchedState, config: SchedConfig, project: string): StatusReport;
|
|
44
|
+
//# sourceMappingURL=status.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../src/status.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAQH,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,WAAW,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAG1F,4DAA4D;AAC5D,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,kDAAkD;AAClD,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,EAAE,EAAE,MAAM,CAAC;IACX,iDAAiD;IACjD,KAAK,EAAE,MAAM,CAAC;CACf;AAED,8DAA8D;AAC9D,MAAM,WAAW,YAAY;IAC3B,0EAA0E;IAC1E,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,OAAO,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,UAAU,EAAE,CAAC;IACpB,KAAK,EAAE,SAAS,EAAE,CAAC;IACnB,OAAO,EAAE,UAAU,EAAE,CAAC;IACtB,2DAA2D;IAC3D,MAAM,EAAE,UAAU,EAAE,CAAC;IACrB,2EAA2E;IAC3E,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,6CAA6C;IAC7C,QAAQ,EAAE,MAAM,CAAC;IACjB,gFAAgF;IAChF,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,OAAO,EAAE,WAAW,EAAE,CAAC;IACvB,MAAM,EAAE,UAAU,EAAE,CAAC;CACtB;AAED,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,UAAU,EACjB,MAAM,EAAE,WAAW,EACnB,OAAO,EAAE,MAAM,GACd,YAAY,CA8Ed"}
|
package/dist/status.js
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* `sched status` report (AC4): queue, slots, batches, parked PRs, and the
|
|
4
|
+
* blocked/failed sets as a machine-readable report. Text rendering lives in
|
|
5
|
+
* the CLI (`cli/src/commands/sched.ts`, on top of the CLI's shared
|
|
6
|
+
* `renderTable`) — the package deliberately has no dependency on CLI
|
|
7
|
+
* utilities.
|
|
8
|
+
*/
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.buildStatusReport = buildStatusReport;
|
|
11
|
+
const readiness_1 = require("./readiness");
|
|
12
|
+
const types_1 = require("./types");
|
|
13
|
+
function buildStatusReport(state, config, project) {
|
|
14
|
+
const blocked = [];
|
|
15
|
+
const failed = [];
|
|
16
|
+
const describeBlocker = (b) => b.reason === 'not-in-queue'
|
|
17
|
+
? `dependency #${b.dep} is not in the queue`
|
|
18
|
+
: `dependency #${b.dep} not merged (status: ${b.depStatus ?? 'unknown'})`;
|
|
19
|
+
for (const entry of state.entries) {
|
|
20
|
+
if (entry.status === 'failed') {
|
|
21
|
+
failed.push(entry);
|
|
22
|
+
continue;
|
|
23
|
+
}
|
|
24
|
+
if (entry.status === 'blocked' || entry.status === 'decision-pending') {
|
|
25
|
+
blocked.push({
|
|
26
|
+
issue: entry.issue,
|
|
27
|
+
status: entry.status,
|
|
28
|
+
reason: entry.reason ?? entry.status,
|
|
29
|
+
});
|
|
30
|
+
continue;
|
|
31
|
+
}
|
|
32
|
+
if (types_1.TERMINAL_ISSUE_STATUSES.has(entry.status) || types_1.SATISFIED_ISSUE_STATUSES.has(entry.status)) {
|
|
33
|
+
continue;
|
|
34
|
+
}
|
|
35
|
+
if (entry.mode === 'full') {
|
|
36
|
+
if (readiness_1.DISPATCHABLE_ISSUE_STATUSES.has(entry.status)) {
|
|
37
|
+
const blockers = (0, readiness_1.dependencyBlockers)(state, entry);
|
|
38
|
+
if (blockers.length > 0) {
|
|
39
|
+
blocked.push({
|
|
40
|
+
issue: entry.issue,
|
|
41
|
+
status: entry.status,
|
|
42
|
+
reason: blockers.map(describeBlocker).join('; '),
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
continue;
|
|
47
|
+
}
|
|
48
|
+
// Slot mode: the member runs when its batch dispatches. Cross-batch /
|
|
49
|
+
// external dependency blockers come from the batch's edge set.
|
|
50
|
+
const batch = state.batches.find((b) => b.id === entry.batch);
|
|
51
|
+
if (batch && batch.status !== 'forming' && batch.status !== 'dissolved') {
|
|
52
|
+
const mine = (0, readiness_1.batchBlockers)(state, batch).filter((b) => b.issue === entry.issue);
|
|
53
|
+
if (mine.length > 0) {
|
|
54
|
+
blocked.push({
|
|
55
|
+
issue: entry.issue,
|
|
56
|
+
status: entry.status,
|
|
57
|
+
reason: mine.map(describeBlocker).join('; '),
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
const units = state.paused ? [] : (0, readiness_1.runnableUnits)(state);
|
|
63
|
+
const parked = state.entries
|
|
64
|
+
.filter((e) => e.status === 'parked' && e.pr !== null)
|
|
65
|
+
.map((e) => ({ issue: e.issue, pr: e.pr, since: e.updated_at }));
|
|
66
|
+
return {
|
|
67
|
+
project,
|
|
68
|
+
paused: state.paused,
|
|
69
|
+
max_slots: config.max_slots,
|
|
70
|
+
live_slots: state.slots.filter((s) => types_1.LIVE_SLOT_STATUSES.has(s.status)).length,
|
|
71
|
+
queue: state.entries,
|
|
72
|
+
slots: state.slots,
|
|
73
|
+
batches: state.batches,
|
|
74
|
+
parked,
|
|
75
|
+
last_pr_poll_at: state.last_pr_poll_at,
|
|
76
|
+
runnable: units.length,
|
|
77
|
+
runnable_units: units.map((u) => u.kind === 'issue' ? `issue:${u.issue}` : `batch:${u.batch}`),
|
|
78
|
+
blocked,
|
|
79
|
+
failed,
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
//# sourceMappingURL=status.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"status.js","sourceRoot":"","sources":["../src/status.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Script-based teardown for merged units (#468 AC2) — the tail work that the
|
|
3
|
+
* fleet pattern used to re-dispatch a whole full-cycle run for.
|
|
4
|
+
*
|
|
5
|
+
* Two scripts, chosen by the run's `setup` milestone:
|
|
6
|
+
* - pool-claimed worktree → `worktree-pool return --path <wt> --json` — the
|
|
7
|
+
* pool's own self-check (#453: `verification.entry_status`) is the
|
|
8
|
+
* verification; a non-`warm` entry or a failed exit is a failed step.
|
|
9
|
+
* - cold worktree → `git worktree remove --force <wt>` + a path-gone check
|
|
10
|
+
* (verify-first, so a re-run after a crash between subprocess and state
|
|
11
|
+
* write is idempotent).
|
|
12
|
+
*
|
|
13
|
+
* `--force` on the remove is deliberate: the WIP-sync rule pushes everything
|
|
14
|
+
* durable to origin, so untracked leftovers (logs, warmup status) are trash.
|
|
15
|
+
*
|
|
16
|
+
* A failed teardown is DEGRADATION, never unit failure — the PR is already
|
|
17
|
+
* merged. The outcome is recorded as `cleanup=failed-<step>` on the entry and
|
|
18
|
+
* journaled, and the report agent is dispatched regardless so the failure is
|
|
19
|
+
* surfaced in the report.
|
|
20
|
+
*
|
|
21
|
+
* Everything runs through an injectable `ExecFn` (the project.ts pattern) —
|
|
22
|
+
* tests script the subprocesses, no real pool or git is touched.
|
|
23
|
+
*/
|
|
24
|
+
import type { SetupInfo } from './groundtruth';
|
|
25
|
+
import type { ExecFn } from './project';
|
|
26
|
+
import type { CleanupStatus } from './types';
|
|
27
|
+
/** Timeout for teardown subprocesses — pool return shells out through npx and recycles a worktree (git ops), which is slow. */
|
|
28
|
+
export declare const TEARDOWN_TIMEOUT_MS = 120000;
|
|
29
|
+
/** The outcome recorded on the entry's `cleanup` and in the journal. */
|
|
30
|
+
export interface TeardownResult {
|
|
31
|
+
/** `done` or `failed-<step>` — the entry's `cleanup` value verbatim. */
|
|
32
|
+
cleanup: CleanupStatus;
|
|
33
|
+
/** Human-readable detail for the journal (empty when none). */
|
|
34
|
+
detail: string;
|
|
35
|
+
}
|
|
36
|
+
/** Whether a path exists (injectable so tests need no filesystem). */
|
|
37
|
+
export type FsExists = (p: string) => boolean;
|
|
38
|
+
/**
|
|
39
|
+
* Containment check for a worktree path recovered from an issue comment
|
|
40
|
+
* (#468): the path must be absolute and fully resolved (no `..`/`.`/symlink
|
|
41
|
+
* variance), and — for COLD worktrees — live under one of the two worktree
|
|
42
|
+
* roots this project uses: `<repo>/worktrees/` (setup-issue-workflow's
|
|
43
|
+
* inside-repo convention) or `<repo>/../worktrees/` (the AGENTS.md sibling
|
|
44
|
+
* convention). A crafted milestone can otherwise make the scheduler
|
|
45
|
+
* `git worktree remove --force` ANY registered worktree — including a
|
|
46
|
+
* parallel agent's (CWE-22). Pool-claimed worktrees are validated by the
|
|
47
|
+
* pool itself (return only accepts paths in pool state), so containment
|
|
48
|
+
* applies to the cold path only.
|
|
49
|
+
*/
|
|
50
|
+
export declare function isSafeWorktree(repoRoot: string, worktree: string): boolean;
|
|
51
|
+
/**
|
|
52
|
+
* Run the teardown script for one merged unit. `info` comes from the unit's
|
|
53
|
+
* setup milestone (groundtruth.setupInfo); a missing `info` is the caller's
|
|
54
|
+
* `failed-missing-setup-info` case — this function always has one.
|
|
55
|
+
*/
|
|
56
|
+
export declare function runTeardown(exec: ExecFn, repoDir: string, info: SetupInfo, fsExists?: FsExists): TeardownResult;
|
|
57
|
+
//# sourceMappingURL=teardown.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"teardown.d.ts","sourceRoot":"","sources":["../src/teardown.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAIH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AACxC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAE7C,+HAA+H;AAC/H,eAAO,MAAM,mBAAmB,SAAU,CAAC;AAY3C,wEAAwE;AACxE,MAAM,WAAW,cAAc;IAC7B,wEAAwE;IACxE,OAAO,EAAE,aAAa,CAAC;IACvB,+DAA+D;IAC/D,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,sEAAsE;AACtE,MAAM,MAAM,QAAQ,GAAG,CAAC,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC;AAE9C;;;;;;;;;;;GAWG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAM1E;AAsBD;;;;GAIG;AACH,wBAAgB,WAAW,CACzB,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,SAAS,EACf,QAAQ,GAAE,QAMT,GACA,cAAc,CAsBhB"}
|