@ai-dossier/sched 0.70.1-next.732.1 → 0.70.2-next.735.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/README.md +27 -2
- package/dist/batch-dispatch.d.ts +10 -0
- package/dist/batch-dispatch.d.ts.map +1 -1
- package/dist/batch-dispatch.js +32 -7
- package/dist/batch-dispatch.js.map +1 -1
- package/dist/dispatch.d.ts +11 -0
- package/dist/dispatch.d.ts.map +1 -1
- package/dist/dispatch.js +44 -0
- package/dist/dispatch.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +9 -7
- package/dist/index.js.map +1 -1
- package/dist/types.d.ts +1 -1
- package/dist/types.d.ts.map +1 -1
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -202,6 +202,31 @@ where every mechanical supervision decision is code, not remembered prose:
|
|
|
202
202
|
tick; a runnable unit never waits while a slot is idle (pinned by a regression test).
|
|
203
203
|
Refill was always synchronous; what previously had no journal trace was the release
|
|
204
204
|
itself — see `slot-released` below (#525).
|
|
205
|
+
**Auto-upgrade and child supervision (#1244):** `sched start --auto-upgrade`
|
|
206
|
+
(including `--once`) defers installation and process replacement while any
|
|
207
|
+
recorded slot agent is alive, or this engine/its tick worker still owns a child
|
|
208
|
+
awaiting its exit callback. This includes parallel members, tail, fix and report
|
|
209
|
+
agents, even after their slot is released. Upgrades retry at later tick boundaries
|
|
210
|
+
once those agents drain; the old engine never writes after installing the update.
|
|
211
|
+
On Linux a `/proc/<pid>/stat` state of `Z` is dead for reconciliation, not an
|
|
212
|
+
unkillable agent. Owned children are reaped by libuv when their event loop runs;
|
|
213
|
+
detecting `Z` alone does not reap a child adopted from an older engine image.
|
|
214
|
+
If Linux reports inherited zombies after all live agents and known child
|
|
215
|
+
callbacks drain (including after a tick-worker crash), the engine exits with
|
|
216
|
+
code 75 instead of re-executing: the OS reaper collects the children and the
|
|
217
|
+
service/watchdog starts a fresh process on retained state. An unsupervised
|
|
218
|
+
engine must be started again by its operator. A deliberate upgrade deferral
|
|
219
|
+
is journaled as `engine-auto-upgrade-deferred` with recorded slot/PID and child
|
|
220
|
+
information; unchanged deferrals are deduplicated, and drain is recorded once.
|
|
221
|
+
|
|
222
|
+
To recover an existing `agent-unkillable` batch without abandoning its work:
|
|
223
|
+
`ai-dossier sched resume --batch <id> --project <slug>`. It rechecks every
|
|
224
|
+
recorded batch/member agent's PID and start identity under the state lock and
|
|
225
|
+
refuses while any is genuinely alive. Once all are dead (including zombies),
|
|
226
|
+
it resumes the retained executing position. Members, landed commits, worktrees,
|
|
227
|
+
branches and dispatch profile stay intact; the next tick finishes the original
|
|
228
|
+
member decision. This does not toggle the global pause state. Avoid `abandon`
|
|
229
|
+
when the goal is to keep the batch.
|
|
205
230
|
6. **Journal (AC6)** — every event (assigned, spawned, exit-detected, external-advance,
|
|
206
231
|
progress, stalled, redispatched, fence-written, fence-failed, unit-failed,
|
|
207
232
|
dependents-blocked, slot-released, suspect-dispatch, dispatch-unhealthy, dispatch-failure,
|
|
@@ -403,8 +428,8 @@ ai-dossier sched service uninstall
|
|
|
403
428
|
node / entry-point / repo paths that are missing, relative, or under a temp or `worktrees/`
|
|
404
429
|
directory, and warns that an nvm node path must be re-pinned (re-run `install`) after a node
|
|
405
430
|
upgrade. It runs `sched start --auto-upgrade` (opt out with `--no-auto-upgrade`); after a
|
|
406
|
-
|
|
407
|
-
|
|
431
|
+
completed tick and after all recorded agents and owned children drain, a stale engine
|
|
432
|
+
installs the latest CLI and re-execs the same command before another state write. The
|
|
408
433
|
new version migrates state on load; older engines reject newer schemas. If the Node runtime
|
|
409
434
|
cannot replace the process directly, exit code 75 asks systemd/the watchdog to restart the
|
|
410
435
|
updated entry point.
|
package/dist/batch-dispatch.d.ts
CHANGED
|
@@ -165,6 +165,16 @@ export interface MemberFailure {
|
|
|
165
165
|
*/
|
|
166
166
|
kind?: MemberExitKind;
|
|
167
167
|
}
|
|
168
|
+
/** #1244: this block originates only in executing's member stop ladder.
|
|
169
|
+
* Keep slots and member runs so normal reconciliation finishes that exact
|
|
170
|
+
* decision, rather than redispatching members or discarding landed work.
|
|
171
|
+
* Liveness and transition share the state lock with dispatch/stop.
|
|
172
|
+
*/
|
|
173
|
+
export declare function resumeUnkillableBatch(store: SchedStore, spawnDeps: Pick<SpawnDeps, 'isAlive'>, batchId: string, now?: Date): {
|
|
174
|
+
batch: string;
|
|
175
|
+
outcome: 'resumed';
|
|
176
|
+
from: 'agent-unkillable';
|
|
177
|
+
};
|
|
168
178
|
/**
|
|
169
179
|
* The current member's own branch: `batch/<id>-m<n>-<issue>` (#677) — member
|
|
170
180
|
* index and issue both in the name, and deterministic from persisted state,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"batch-dispatch.d.ts","sourceRoot":"","sources":["../src/batch-dispatch.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8DG;AAWH,OAAO,EAIL,KAAK,YAAY,EAGjB,KAAK,gBAAgB,EAGtB,MAAM,gBAAgB,CAAC;AAUxB,OAAO,EAeL,KAAK,gBAAgB,EAGrB,KAAK,SAAS,EAEf,MAAM,YAAY,CAAC;AAGpB,OAAO,EAGL,KAAK,WAAW,EAcjB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,KAAK,OAAO,EAAa,MAAM,WAAW,CAAC;AAMpD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAW5C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAExC,OAAO,EACL,KAAK,iBAAiB,EActB,KAAK,WAAW,EACjB,MAAM,YAAY,CAAC;AAGpB,OAAO,EA2BL,kBAAkB,EAKnB,MAAM,SAAS,CAAC;AACjB,OAAO,EACL,KAAK,QAAQ,EAMd,MAAM,YAAY,CAAC;AACpB,OAAO,KAAK,EAGV,UAAU,EAEV,oBAAoB,EAKpB,kBAAkB,EAClB,cAAc,EAId,WAAW,EACX,UAAU,EAEX,MAAM,SAAS,CAAC;AAajB,YAAY,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAI1C,OAAO,EAAE,kBAAkB,EAAE,CAAC;AAE9B,8DAA8D;AAC9D,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,UAAU,CAAC;IAClB,OAAO,EAAE,OAAO,CAAC;IACjB,WAAW,EAAE,WAAW,CAAC;IACzB,SAAS,EAAE,SAAS,CAAC;IACrB,GAAG,EAAE,MAAM,IAAI,CAAC;IAChB,uFAAuF;IACvF,OAAO,EAAE,MAAM,CAAC;IAChB,0FAA0F;IAC1F,IAAI,EAAE,MAAM,CAAC;IACb;;;;;;OAMG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;;;OAKG;IACH,QAAQ,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,iBAAiB,KAAK,WAAW,CAAC;IACrE;;;;;;;;;;;;;;;;;;;OAmBG;IACH,aAAa,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,KAAK,oBAAoB,CAAC;IACjF,QAAQ,CAAC,EAAE,QAAQ,CAAC;IACpB;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;;;;OAMG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,8FAA8F;AAC9F,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,uFAAuF;IACvF,qBAAqB,EAAE,MAAM,EAAE,CAAC;IAChC,8FAA8F;IAC9F,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED;;;;;;GAMG;AACH,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC;;;;OAIG;IACH,IAAI,CAAC,EAAE,cAAc,CAAC;CACvB;
|
|
1
|
+
{"version":3,"file":"batch-dispatch.d.ts","sourceRoot":"","sources":["../src/batch-dispatch.ts"],"names":[],"mappings":"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"}
|
package/dist/batch-dispatch.js
CHANGED
|
@@ -97,6 +97,7 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
97
97
|
})();
|
|
98
98
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
99
99
|
exports.MAX_LAND_PUSH_RETRIES = exports.MAX_BATCH_AGENT_RESPAWNS = exports.tailMembersRefusal = void 0;
|
|
100
|
+
exports.resumeUnkillableBatch = resumeUnkillableBatch;
|
|
100
101
|
exports.memberBranchFor = memberBranchFor;
|
|
101
102
|
exports.evictMemberAndContinue = evictMemberAndContinue;
|
|
102
103
|
exports.resumeBlockedGate = resumeBlockedGate;
|
|
@@ -264,6 +265,27 @@ function headTreeOf(deps, worktree) {
|
|
|
264
265
|
function agentAlive(deps, slot) {
|
|
265
266
|
return slot.pid !== null && deps.spawnDeps.isAlive(slot.pid, slot.pid_start ?? undefined);
|
|
266
267
|
}
|
|
268
|
+
/** #1244: this block originates only in executing's member stop ladder.
|
|
269
|
+
* Keep slots and member runs so normal reconciliation finishes that exact
|
|
270
|
+
* decision, rather than redispatching members or discarding landed work.
|
|
271
|
+
* Liveness and transition share the state lock with dispatch/stop.
|
|
272
|
+
*/
|
|
273
|
+
function resumeUnkillableBatch(store, spawnDeps, batchId, now = new Date()) {
|
|
274
|
+
return store.withLock((state) => {
|
|
275
|
+
const batch = (0, state_1.findBatch)(state, batchId);
|
|
276
|
+
if (batch?.status !== 'blocked' || batch.blocked_reason !== 'agent-unkillable') {
|
|
277
|
+
throw new types_1.SchedNotFoundError(`Batch ${batchId} is not blocked on agent-unkillable`);
|
|
278
|
+
}
|
|
279
|
+
const live = (0, state_1.slotsForBatch)(state, batchId).filter((slot) => slot.pid !== null && spawnDeps.isAlive(slot.pid, slot.pid_start ?? undefined));
|
|
280
|
+
if (live.length > 0) {
|
|
281
|
+
throw new types_1.SchedNotFoundError(`Batch ${batchId} still has live agent(s) in slot(s) ${live.map((s) => s.id).join(',')} — wait for them to exit before resuming`);
|
|
282
|
+
}
|
|
283
|
+
return {
|
|
284
|
+
state: (0, state_1.transitionBatch)(state, batchId, 'executing', { blocked_reason: null }, now),
|
|
285
|
+
result: { batch: batchId, outcome: 'resumed', from: 'agent-unkillable' },
|
|
286
|
+
};
|
|
287
|
+
});
|
|
288
|
+
}
|
|
267
289
|
/**
|
|
268
290
|
* Stop the slot's agent if it is still alive (pid-start-safe: a reused pid is
|
|
269
291
|
* never signalled). SIGTERM only — no wait, no escalation. A decision that
|
|
@@ -2708,8 +2730,8 @@ function currentDispatchStamp(stamp, spawnedAt, now) {
|
|
|
2708
2730
|
}
|
|
2709
2731
|
/**
|
|
2710
2732
|
* Stop the slot's agent before a decision that must not run alongside it
|
|
2711
|
-
* (#844). Returns
|
|
2712
|
-
*
|
|
2733
|
+
* (#844). Returns waiting while alive, gone once dead (or without a pid),
|
|
2734
|
+
* and unkillable once SIGKILL's bound expires and the batch blocks.
|
|
2713
2735
|
*
|
|
2714
2736
|
* The first sight sends SIGTERM, stamps `kill_sent_at` and journals
|
|
2715
2737
|
* `member-stop-requested` once; each later tick
|
|
@@ -2718,7 +2740,7 @@ function currentDispatchStamp(stamp, spawnedAt, now) {
|
|
|
2718
2740
|
* `kill-escalated` once (`kill_escalated_at`). Pre-#844 this path re-sent
|
|
2719
2741
|
* SIGTERM forever, so an agent ignoring it held its member indefinitely.
|
|
2720
2742
|
*/
|
|
2721
|
-
function stopAgentBeforeDeciding(deps, config, batchId, memberIssue, slot, now, result) {
|
|
2743
|
+
function stopAgentBeforeDeciding(deps, config, batchId, memberIssue, slot, now, result, reason) {
|
|
2722
2744
|
if (!agentAlive(deps, slot))
|
|
2723
2745
|
return 'gone';
|
|
2724
2746
|
const pid = slot.pid;
|
|
@@ -2745,8 +2767,10 @@ function stopAgentBeforeDeciding(deps, config, batchId, memberIssue, slot, now,
|
|
|
2745
2767
|
slot: slot.id,
|
|
2746
2768
|
detail: `agent remained alive ${dispatch_1.KILL_ESCALATION_MS / 1000}s after SIGKILL — blocking for operator`,
|
|
2747
2769
|
});
|
|
2748
|
-
blockBatchForOperator(deps, config, batchId, { reason: 'agent-unkillable' }, now, result);
|
|
2749
2770
|
}
|
|
2771
|
+
// A crash after the stamp but before the block must finish the block on
|
|
2772
|
+
// the next tick; the stamp deduplicates telemetry, not the transition.
|
|
2773
|
+
blockBatchForOperator(deps, config, batchId, { reason: 'agent-unkillable' }, now, result);
|
|
2750
2774
|
return 'unkillable';
|
|
2751
2775
|
}
|
|
2752
2776
|
const firstEscalation = escalate && currentDispatchStamp(slot.kill_escalated_at, slot.spawned_at, now) === null;
|
|
@@ -2768,6 +2792,7 @@ function stopAgentBeforeDeciding(deps, config, batchId, memberIssue, slot, now,
|
|
|
2768
2792
|
}
|
|
2769
2793
|
if (sentAt === null) {
|
|
2770
2794
|
journalEvent(deps, 'member-stop-requested', unit(batchId), {
|
|
2795
|
+
reason,
|
|
2771
2796
|
issue: memberIssue,
|
|
2772
2797
|
pid,
|
|
2773
2798
|
slot: slot.id,
|
|
@@ -2803,7 +2828,7 @@ function repromptWrongProcedure(deps, config, batchId, memberIssue, milestoneAt,
|
|
|
2803
2828
|
// dying full-cycle run could still push, post, or open a PR. Signal it and
|
|
2804
2829
|
// decide on a later tick, once it is gone — and so the re-prompt's
|
|
2805
2830
|
// `reprompted_at` fence postdates everything it could still post.
|
|
2806
|
-
if (stopAgentBeforeDeciding(deps, config, batchId, memberIssue, slot, now, result) !== 'gone')
|
|
2831
|
+
if (stopAgentBeforeDeciding(deps, config, batchId, memberIssue, slot, now, result, 'wrong-procedure') !== 'gone')
|
|
2807
2832
|
return 'waiting';
|
|
2808
2833
|
const outcome = deps.store.withLock((s) => {
|
|
2809
2834
|
const b = (0, state_1.findBatch)(s, batchId);
|
|
@@ -2860,7 +2885,7 @@ function wrongProcedureFailure(lastTool, shippedPr = null) {
|
|
|
2860
2885
|
function decideWrongProcedure(deps, config, batchId, memberIssue, milestone, slot, release, lastTool, now, result) {
|
|
2861
2886
|
const shipped = (0, groundtruth_1.wrongProcedureShippedPr)(milestone);
|
|
2862
2887
|
if (shipped !== null) {
|
|
2863
|
-
if (stopAgentBeforeDeciding(deps, config, batchId, memberIssue, slot, now, result) !== 'gone')
|
|
2888
|
+
if (stopAgentBeforeDeciding(deps, config, batchId, memberIssue, slot, now, result, 'wrong-procedure') !== 'gone')
|
|
2864
2889
|
return 'waiting';
|
|
2865
2890
|
// #844: the caller's eviction releases the slot in its own write.
|
|
2866
2891
|
return wrongProcedureFailure(lastTool(), shipped);
|
|
@@ -4759,7 +4784,7 @@ function reconcileParallelMemberSlot(deps, config, dispatch, batchId, run, slot,
|
|
|
4759
4784
|
// The member's tree may be rebased or removed immediately after its slot
|
|
4760
4785
|
// is released. Keep this slot draining until the agent is really gone so
|
|
4761
4786
|
// the #844 SIGKILL bound remains available to a SIGTERM-ignoring agent.
|
|
4762
|
-
if (stopAgentBeforeDeciding(deps, config, batchId, run.issue, slot, now, result) !== 'gone')
|
|
4787
|
+
if (stopAgentBeforeDeciding(deps, config, batchId, run.issue, slot, now, result, 'member-complete') !== 'gone')
|
|
4763
4788
|
return;
|
|
4764
4789
|
journalEvent(deps, 'external-advance', unit(batchId), {
|
|
4765
4790
|
issue: run.issue,
|