@ai-dossier/sched 0.57.1 → 0.57.3
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 +16 -10
- package/dist/batch-dispatch.d.ts +1 -1
- package/dist/batch-dispatch.d.ts.map +1 -1
- package/dist/batch-dispatch.js +66 -6
- package/dist/batch-dispatch.js.map +1 -1
- package/dist/recovery.d.ts.map +1 -1
- package/dist/recovery.js +9 -2
- package/dist/recovery.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -536,8 +536,10 @@ validating → attributing → fixing (ONE bounded attempt) → validating
|
|
|
536
536
|
suite report unreadable, after the fallback retry when one applied
|
|
537
537
|
→ blocked → validating (nothing requeued/reverted; #562)
|
|
538
538
|
awaiting-merge (CONFLICTING | auto-merge-blocked)
|
|
539
|
-
|
|
540
|
-
|
|
539
|
+
→ rebasing → re-validating → shipping
|
|
540
|
+
→ (2nd occurrence) dissolving into two half-batches
|
|
541
|
+
#840: with VALIDATED members, keep them landed;
|
|
542
|
+
#867: the PR watch automatically enters this rail
|
|
541
543
|
```
|
|
542
544
|
|
|
543
545
|
1. **Attribution (AC1)** — `attributeByOverlap` maps each failing test to a member by
|
|
@@ -602,10 +604,14 @@ awaiting-merge (CONFLICTING | auto-merge-blocked)
|
|
|
602
604
|
batch branch is simply left behind unmerged, since sched deletes nothing. Every dissolve
|
|
603
605
|
decision — all three strategies — journals its policy inputs (`N=`, `evictions=`,
|
|
604
606
|
`threshold=`), so it is explainable without re-deriving the formula.
|
|
605
|
-
5. **PR conflict (AC4)** —
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
607
|
+
5. **PR conflict (AC4)** — the PR watch routes a CONFLICTING or auto-merge-blocked batch
|
|
608
|
+
into `handlePrConflict`, which rebases the integration branch, re-runs the suite, and
|
|
609
|
+
force-pushes the rewritten branch with a lease before resuming the existing PR watch. A second occurrence,
|
|
610
|
+
a conflicting rebase, a failed fetch, an unusable branch, a checkout that is not on the
|
|
611
|
+
batch branch, or a red suite after a clean rebase dissolves into two half-batches when no
|
|
612
|
+
member is validated. With validated members, #840 keeps their landed work: a clean rebase
|
|
613
|
+
and red suite re-gates the retained batch; every other give-up case blocks it as
|
|
614
|
+
`dissolve-refused:<reason>`.
|
|
609
615
|
6. **Milestones (AC5)** — every eviction and dissolve posts a `batch-validate` /
|
|
610
616
|
`batch-ship` milestone to the batch ANCHOR issue via `ai-dossier runstate post`, with
|
|
611
617
|
the reason, the evicted/requeued/preserved members and the attribution method (a
|
|
@@ -1029,9 +1035,9 @@ Dissolve never throws validated work away:
|
|
|
1029
1035
|
`batch-regate`, `executing_member` pinned to the end — the shape of `sched resume
|
|
1030
1036
|
--batch`); anything else blocks `dissolve-refused:<reason>` (milestone `batch-ship`,
|
|
1031
1037
|
`validated=`; the recorded PR can be resolved by hand, or closed before `sched resume
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1038
|
+
--batch`). With no validated member it still dissolves into halves. Since #867,
|
|
1039
|
+
`reconcilePrWatch` routes a CONFLICTING or auto-merge-blocked batch PR into this recovery
|
|
1040
|
+
path automatically.
|
|
1035
1041
|
|
|
1036
1042
|
#### Member branches live until the batch ends; a requeue resumes on them (#840)
|
|
1037
1043
|
|
|
@@ -1271,7 +1277,7 @@ import {
|
|
|
1271
1277
|
dissolveBatch, // full | halved | partial (#563); preserves everything green
|
|
1272
1278
|
blockBatch, // #562: unreadable suite report → blocked; no requeue, no revert
|
|
1273
1279
|
type BlockOptions, // { reason, milestonePhase? } for blockBatch
|
|
1274
|
-
handlePrConflict, //
|
|
1280
|
+
handlePrConflict, // reship | dissolve; #840: regate | block over validated work
|
|
1275
1281
|
createExecMilestonePoster, // batch milestones via `ai-dossier runstate post`
|
|
1276
1282
|
expandEvictionGroups, // members that must revert together (§E.4 eviction groups)
|
|
1277
1283
|
requeueMember, // the one requeue path (abandon, aggregate eviction, dissolve, sched requeue)
|
package/dist/batch-dispatch.d.ts
CHANGED
|
@@ -71,8 +71,8 @@ import { type BatchSuiteContext, type SuiteResult } from './recovery';
|
|
|
71
71
|
import { tailMembersRefusal } from './state';
|
|
72
72
|
import { type FsExists } from './teardown';
|
|
73
73
|
import type { BatchEntry, CapabilityGateResult, MemberDispatchMode, MemberExitKind, SchedConfig, SchedState } from './types';
|
|
74
|
-
export { tailMembersRefusal };
|
|
75
74
|
export type { CapOutcome } from './types';
|
|
75
|
+
export { tailMembersRefusal };
|
|
76
76
|
/** Everything batch dispatch needs from the outside world. */
|
|
77
77
|
export interface BatchDispatchDeps {
|
|
78
78
|
store: SchedStore;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"batch-dispatch.d.ts","sourceRoot":"","sources":["../src/batch-dispatch.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8DG;AAUH,OAAO,EAIL,KAAK,YAAY,EAGjB,KAAK,gBAAgB,EAGtB,MAAM,gBAAgB,CAAC;AAUxB,OAAO,EAcL,KAAK,gBAAgB,EAGrB,KAAK,SAAS,EAEf,MAAM,YAAY,CAAC;AAEpB,OAAO,EAGL,KAAK,WAAW,EAcjB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,KAAK,OAAO,EAAa,MAAM,WAAW,CAAC;AACpD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAC5C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAExC,OAAO,EACL,KAAK,iBAAiB,
|
|
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
|
@@ -3198,7 +3198,7 @@ function advanceBatchDedupStreak(priorReason, priorSince, priorTicks, reason, no
|
|
|
3198
3198
|
function clearPrWatchFailed(deps, batch, now) {
|
|
3199
3199
|
clearBatchDedupMarker(deps, batch, batch.pr_watch_failed_reason, state_1.CLEARED_PR_WATCH_FIELDS, now);
|
|
3200
3200
|
}
|
|
3201
|
-
function reconcilePrWatch(deps, now, result) {
|
|
3201
|
+
function reconcilePrWatch(deps, config, now, result) {
|
|
3202
3202
|
const state = deps.store.load();
|
|
3203
3203
|
for (const batch of state.batches) {
|
|
3204
3204
|
if (batch.status !== 'awaiting-merge') {
|
|
@@ -3278,9 +3278,65 @@ function reconcilePrWatch(deps, now, result) {
|
|
|
3278
3278
|
}, now, false),
|
|
3279
3279
|
result: undefined,
|
|
3280
3280
|
}));
|
|
3281
|
-
//
|
|
3282
|
-
//
|
|
3283
|
-
//
|
|
3281
|
+
// An awaiting-merge record without its integration checkout is an
|
|
3282
|
+
// incomplete/corrupt batch, not safe to rebase. Keep its durable watch
|
|
3283
|
+
// evidence for an operator rather than running recovery in repoDir.
|
|
3284
|
+
if (batch.branch === null || batch.worktree === null)
|
|
3285
|
+
continue;
|
|
3286
|
+
// Recovery runs git and the aggregate suite outside the store lock. Apply
|
|
3287
|
+
// its result to fresh state below so concurrent scheduler updates survive.
|
|
3288
|
+
const recovered = (0, recovery_1.handlePrConflict)(state, batch.id, recoveryDeps(deps, config, batch, now), {
|
|
3289
|
+
reason,
|
|
3290
|
+
});
|
|
3291
|
+
if (recovered.action === 'reship') {
|
|
3292
|
+
// Rebasing rewrites the integration branch. Pin the lease to origin's
|
|
3293
|
+
// current tip so a concurrent push cannot be overwritten.
|
|
3294
|
+
const remote = deps.exec('git', ['ls-remote', 'origin', `refs/heads/${batch.branch ?? ''}`], batch.worktree ?? deps.repoDir);
|
|
3295
|
+
const remoteTip = remote?.trim().split(/\s+/)[0] ?? '';
|
|
3296
|
+
const pushed = batch.branch !== null &&
|
|
3297
|
+
(remoteTip === '' || groundtruth_1.GIT_OID_RE.test(remoteTip)) &&
|
|
3298
|
+
deps.exec('git', [
|
|
3299
|
+
'push',
|
|
3300
|
+
`--force-with-lease=refs/heads/${batch.branch}:${remoteTip}`,
|
|
3301
|
+
'origin',
|
|
3302
|
+
'--',
|
|
3303
|
+
batch.branch,
|
|
3304
|
+
], batch.worktree ?? deps.repoDir) !== null;
|
|
3305
|
+
if (!pushed) {
|
|
3306
|
+
const blocked = (0, recovery_1.blockBatch)(recovered.state, batch.id, { reason: 'rebase-force-push-failed', milestonePhase: 'batch-ship' }, recoveryDeps(deps, config, batch, now));
|
|
3307
|
+
deps.store.withLock((s) => ({
|
|
3308
|
+
state: applyBatchAndIssues(s, blocked.state, batch.id, [], batch.members),
|
|
3309
|
+
result: undefined,
|
|
3310
|
+
}));
|
|
3311
|
+
stopAndReleaseBlocked(deps, batch.id, now);
|
|
3312
|
+
result.failed.push(unit(batch.id));
|
|
3313
|
+
continue;
|
|
3314
|
+
}
|
|
3315
|
+
// A force-push updates the recorded PR's head. Re-dispatching the tail
|
|
3316
|
+
// would try to ship a second PR, so resume watching this same PR.
|
|
3317
|
+
const reshipped = (0, state_1.transitionBatch)(recovered.state, batch.id, 'awaiting-merge', { pr }, now);
|
|
3318
|
+
deps.store.withLock((s) => ({
|
|
3319
|
+
state: applyBatchAndIssues(s, reshipped, batch.id, [], batch.members),
|
|
3320
|
+
result: undefined,
|
|
3321
|
+
}));
|
|
3322
|
+
continue;
|
|
3323
|
+
}
|
|
3324
|
+
if (recovered.action === 'dissolved' && recovered.dissolve) {
|
|
3325
|
+
applyDissolveOutcome(deps, batch.id, recovered.dissolve, now, batch.members);
|
|
3326
|
+
result.failed.push(unit(batch.id));
|
|
3327
|
+
continue;
|
|
3328
|
+
}
|
|
3329
|
+
const touched = recovered.dissolve
|
|
3330
|
+
? [...recovered.dissolve.requeued, ...recovered.dissolve.parked]
|
|
3331
|
+
: [];
|
|
3332
|
+
deps.store.withLock((s) => ({
|
|
3333
|
+
state: applyBatchAndIssues(s, recovered.state, batch.id, touched, batch.members),
|
|
3334
|
+
result: undefined,
|
|
3335
|
+
}));
|
|
3336
|
+
if (recovered.action === 'blocked') {
|
|
3337
|
+
stopAndReleaseBlocked(deps, batch.id, now);
|
|
3338
|
+
result.failed.push(unit(batch.id));
|
|
3339
|
+
}
|
|
3284
3340
|
}
|
|
3285
3341
|
else {
|
|
3286
3342
|
// #630: the condition cleared — reset the marker so a future
|
|
@@ -4345,7 +4401,11 @@ function reconcileParallelMemberSlot(deps, config, dispatch, batchId, run, slot,
|
|
|
4345
4401
|
// into that tree with its pid no longer tracked anywhere (so neither a
|
|
4346
4402
|
// dissolve nor `sched stop --batch` could stop it). Its work is done —
|
|
4347
4403
|
// stop it first.
|
|
4348
|
-
|
|
4404
|
+
// The member's tree may be rebased or removed immediately after its slot
|
|
4405
|
+
// is released. Keep this slot draining until the agent is really gone so
|
|
4406
|
+
// the #844 SIGKILL bound remains available to a SIGTERM-ignoring agent.
|
|
4407
|
+
if (stopAgentBeforeDeciding(deps, batchId, run.issue, slot, now))
|
|
4408
|
+
return;
|
|
4349
4409
|
journalEvent(deps, 'external-advance', unit(batchId), {
|
|
4350
4410
|
issue: run.issue,
|
|
4351
4411
|
detail: 'member review done',
|
|
@@ -5018,7 +5078,7 @@ function runBatchTick(deps, config, dispatch) {
|
|
|
5018
5078
|
containFailure(batch.id, err);
|
|
5019
5079
|
}
|
|
5020
5080
|
}
|
|
5021
|
-
reconcilePrWatch(deps, now, result);
|
|
5081
|
+
reconcilePrWatch(deps, config, now, result);
|
|
5022
5082
|
const anchorCtx = anchorTickContext(deps);
|
|
5023
5083
|
reconcileStaleBlockedBatches(deps, now, result, anchorCtx);
|
|
5024
5084
|
reconcileAnchorClosure(deps, now, anchorCtx);
|