@ai-dossier/sched 0.63.0 → 0.65.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 +15 -2
- package/dist/batch-dispatch.d.ts.map +1 -1
- package/dist/batch-dispatch.js +60 -1
- package/dist/batch-dispatch.js.map +1 -1
- package/dist/dispatch.d.ts +18 -11
- package/dist/dispatch.d.ts.map +1 -1
- package/dist/dispatch.js +28 -19
- package/dist/dispatch.js.map +1 -1
- package/dist/engine.d.ts.map +1 -1
- package/dist/engine.js +23 -3
- package/dist/engine.js.map +1 -1
- package/dist/groundtruth.d.ts +24 -0
- package/dist/groundtruth.d.ts.map +1 -1
- package/dist/groundtruth.js +101 -2
- package/dist/groundtruth.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -3
- package/dist/index.js.map +1 -1
- package/dist/merge-mechanism.d.ts +90 -0
- package/dist/merge-mechanism.d.ts.map +1 -0
- package/dist/merge-mechanism.js +169 -0
- package/dist/merge-mechanism.js.map +1 -0
- package/dist/types.d.ts +15 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1814,8 +1814,21 @@ re-screened at all — but neither is closed by it.
|
|
|
1814
1814
|
|
|
1815
1815
|
## The PR watcher + tail work (#468)
|
|
1816
1816
|
|
|
1817
|
-
Dispatched runs park their PR on `auto-merge` (detached ship mode —
|
|
1818
|
-
|
|
1817
|
+
Dispatched runs park their PR on `auto-merge` (detached ship mode) and exit — **only where
|
|
1818
|
+
a merge mechanism is confirmed** (#887). sched's watch only WAITS for a merge; it never merges,
|
|
1819
|
+
so the default prompts render `{ship_clause}` from `GroundTruth.mergeMechanism()` (`gh api
|
|
1820
|
+
repos/<r>` `allow_auto_merge` + allowed methods, and a scan of the remote default branch's
|
|
1821
|
+
`.github/workflows` for a label watcher, both read through the GitHub API so a stale local
|
|
1822
|
+
`origin/*` ref can never hide a newly added watcher — #921; cached 10 min). A confirmed mechanism still parks only
|
|
1823
|
+
after `gh pr view --json autoMergeRequest` reads back non-null (the label is not proof); with no
|
|
1824
|
+
confirmed mechanism — or an unknown one — the run ships **attached** (waits for checks, merges
|
|
1825
|
+
with an allowed method) and blocks `no-merge-mechanism` if it cannot. A batch tail needs a
|
|
1826
|
+
confirmed *watcher* (native auto-merge alone never confirms a detached batch ship). An
|
|
1827
|
+
`awaiting-merge` milestone carrying `ship_mode=attached` is not a park. Backstop for custom
|
|
1828
|
+
prompts: a parked, OPEN PR with no auto-merge request and no watcher (positively read absent —
|
|
1829
|
+
unknown never counts) that persists past 10 minutes fails `no-merge-mechanism`; the batch PR
|
|
1830
|
+
watch has the same backstop (#921): the batch blocks `no-merge-mechanism`, and the onset marker
|
|
1831
|
+
(`BatchEntry.no_merge_mechanism_since`) resets when a request lands. The engine owns everything after the park:
|
|
1819
1832
|
|
|
1820
1833
|
1. **Park detection (AC1)** — an agent exit whose latest milestone is the ship
|
|
1821
1834
|
phase's `awaiting-merge` (with `pr=`) is a VERIFIED park, not an unverified
|
|
@@ -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,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;
|
|
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
|
@@ -116,6 +116,7 @@ const dispatch_health_1 = require("./dispatch-health");
|
|
|
116
116
|
const dossier_root_1 = require("./dossier-root");
|
|
117
117
|
const groundtruth_1 = require("./groundtruth");
|
|
118
118
|
const journal_1 = require("./journal");
|
|
119
|
+
const merge_mechanism_1 = require("./merge-mechanism");
|
|
119
120
|
const readiness_1 = require("./readiness");
|
|
120
121
|
const recovery_1 = require("./recovery");
|
|
121
122
|
const run_log_1 = require("./run-log");
|
|
@@ -1510,6 +1511,8 @@ function spawnTailAgent(deps, config, dispatch, batchId, now, result) {
|
|
|
1510
1511
|
// before a slot is claimed — `blockBatchForOperator` posts a milestone, an
|
|
1511
1512
|
// exec that must not run under the store lock).
|
|
1512
1513
|
const before = deps.store.load();
|
|
1514
|
+
// #887: read outside the store lock (a cache miss runs `gh api`).
|
|
1515
|
+
const mechanism = deps.groundTruth.mergeMechanism?.();
|
|
1513
1516
|
const pending = (0, state_1.findBatch)(before, batchId);
|
|
1514
1517
|
if (pending) {
|
|
1515
1518
|
const refusal = tailDispatchRefusal(before, pending);
|
|
@@ -1540,7 +1543,9 @@ function spawnTailAgent(deps, config, dispatch, batchId, now, result) {
|
|
|
1540
1543
|
}
|
|
1541
1544
|
const spawnSpec = (0, dispatch_1.resolveTierSpawn)(dispatch, 'strong', batch.anchor);
|
|
1542
1545
|
const cmd = spawnSpec.cmd;
|
|
1543
|
-
const prompt = (0, dispatch_1.buildBatchTailPrompt)(dispatch.batchTailPrompt, batchId, batch.anchor, landed, batch.worktree
|
|
1546
|
+
const prompt = (0, dispatch_1.buildBatchTailPrompt)(dispatch.batchTailPrompt, batchId, batch.anchor, landed, batch.worktree,
|
|
1547
|
+
// #887: the repo's detected merge mechanism decides detached vs attached ship.
|
|
1548
|
+
mechanism);
|
|
1544
1549
|
const logFile = (0, dispatch_1.batchTailLogPath)(deps.store.runsDir, batchId);
|
|
1545
1550
|
// #629: fences `handleDeadDispatchApiError`'s classification to this
|
|
1546
1551
|
// dispatch's slice — see `spawnMember`'s identical comment.
|
|
@@ -3324,6 +3329,16 @@ function advanceBatchDedupStreak(priorReason, priorSince, priorTicks, reason, no
|
|
|
3324
3329
|
*/
|
|
3325
3330
|
function clearPrWatchFailed(deps, batch, now) {
|
|
3326
3331
|
clearBatchDedupMarker(deps, batch, batch.pr_watch_failed_reason, state_1.CLEARED_PR_WATCH_FIELDS, now);
|
|
3332
|
+
clearNoMergeMechanism(deps, batch, now);
|
|
3333
|
+
}
|
|
3334
|
+
/** Drop the #921 `no-merge-mechanism` onset marker (a no-op, no write, when none is recorded). */
|
|
3335
|
+
function clearNoMergeMechanism(deps, batch, now) {
|
|
3336
|
+
if (batch.no_merge_mechanism_since == null)
|
|
3337
|
+
return;
|
|
3338
|
+
deps.store.withLock((s) => ({
|
|
3339
|
+
state: (0, state_1.patchBatch)(s, batch.id, { no_merge_mechanism_since: null }, now, false),
|
|
3340
|
+
result: undefined,
|
|
3341
|
+
}));
|
|
3327
3342
|
}
|
|
3328
3343
|
function reconcilePrWatch(deps, config, now, result) {
|
|
3329
3344
|
const state = deps.store.load();
|
|
@@ -3405,6 +3420,9 @@ function reconcilePrWatch(deps, config, now, result) {
|
|
|
3405
3420
|
}, now, false),
|
|
3406
3421
|
result: undefined,
|
|
3407
3422
|
}));
|
|
3423
|
+
// A conflicting/blocked PR is a different condition: end any no-merge-mechanism onset so a
|
|
3424
|
+
// re-ship starts a fresh grace window.
|
|
3425
|
+
clearNoMergeMechanism(deps, batch, now);
|
|
3408
3426
|
// An awaiting-merge record without its integration checkout is an
|
|
3409
3427
|
// incomplete/corrupt batch, not safe to rebase. Keep its durable watch
|
|
3410
3428
|
// evidence for an operator rather than running recovery in repoDir.
|
|
@@ -3465,6 +3483,47 @@ function reconcilePrWatch(deps, config, now, result) {
|
|
|
3465
3483
|
result.failed.push(unit(batch.id));
|
|
3466
3484
|
}
|
|
3467
3485
|
}
|
|
3486
|
+
else if (truth.state === 'OPEN' &&
|
|
3487
|
+
truth.autoMergeRequested === false &&
|
|
3488
|
+
(0, merge_mechanism_1.parkedWithoutMerger)(truth, deps.groundTruth.mergeMechanism?.())) {
|
|
3489
|
+
// #921: the issue-unit backstop (#887) for a batch PR — parked OPEN with no auto-merge
|
|
3490
|
+
// request and a POSITIVELY absent watcher. sched's watch only waits, so once this has
|
|
3491
|
+
// persisted past the grace window the batch blocks loudly instead of waiting forever.
|
|
3492
|
+
// `mergeMechanism()` is cached and, like `prState`, read outside the store lock.
|
|
3493
|
+
clearBatchDedupMarker(deps, batch, batch.pr_watch_failed_reason, state_1.CLEARED_PR_WATCH_FIELDS, now);
|
|
3494
|
+
const step = (0, merge_mechanism_1.advanceNoMergeMechanism)(batch.no_merge_mechanism_since, pr, now);
|
|
3495
|
+
if (step.arm !== null) {
|
|
3496
|
+
deps.store.withLock((s) => ({
|
|
3497
|
+
state: (0, state_1.patchBatch)(s, batch.id, { no_merge_mechanism_since: step.arm }, now, false),
|
|
3498
|
+
result: undefined,
|
|
3499
|
+
}));
|
|
3500
|
+
}
|
|
3501
|
+
else if (step.due) {
|
|
3502
|
+
// Re-check on a fresh load: the batch may have merged, blocked or been abandoned since
|
|
3503
|
+
// the poll above, and blockBatch throws on a terminal batch — never abort the tick.
|
|
3504
|
+
const fresh = deps.store.load();
|
|
3505
|
+
if ((0, state_1.findBatch)(fresh, batch.id)?.status !== 'awaiting-merge')
|
|
3506
|
+
continue;
|
|
3507
|
+
let blocked;
|
|
3508
|
+
try {
|
|
3509
|
+
blocked = (0, recovery_1.blockBatch)(fresh, batch.id, { reason: merge_mechanism_1.NO_MERGE_MECHANISM_REASON, milestonePhase: 'batch-ship' }, recoveryDeps(deps, config, batch, now));
|
|
3510
|
+
}
|
|
3511
|
+
catch {
|
|
3512
|
+
continue;
|
|
3513
|
+
}
|
|
3514
|
+
journalEvent(deps, 'pr-watch-failed', unit(batch.id), {
|
|
3515
|
+
reason: merge_mechanism_1.NO_MERGE_MECHANISM_REASON,
|
|
3516
|
+
pr,
|
|
3517
|
+
at: now.toISOString(),
|
|
3518
|
+
});
|
|
3519
|
+
deps.store.withLock((s) => ({
|
|
3520
|
+
state: applyBatchAndIssues(s, blocked.state, batch.id, [], batch.members),
|
|
3521
|
+
result: undefined,
|
|
3522
|
+
}));
|
|
3523
|
+
stopAndReleaseBlocked(deps, batch.id, now);
|
|
3524
|
+
result.failed.push(unit(batch.id));
|
|
3525
|
+
}
|
|
3526
|
+
}
|
|
3468
3527
|
else {
|
|
3469
3528
|
// #630: the condition cleared — reset the marker so a future
|
|
3470
3529
|
// re-occurrence (even the SAME reason) journals its own fresh entry.
|