@ai-dossier/sched 0.46.1 → 0.47.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 +33 -11
- package/dist/batch-dispatch.d.ts +17 -2
- package/dist/batch-dispatch.d.ts.map +1 -1
- package/dist/batch-dispatch.js +903 -133
- package/dist/batch-dispatch.js.map +1 -1
- package/dist/engine.d.ts +3 -2
- package/dist/engine.d.ts.map +1 -1
- package/dist/engine.js +3 -2
- package/dist/engine.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -2
- package/dist/index.js.map +1 -1
- package/dist/journal.d.ts +4 -1
- package/dist/journal.d.ts.map +1 -1
- package/dist/journal.js +5 -2
- package/dist/journal.js.map +1 -1
- package/dist/persist.d.ts.map +1 -1
- package/dist/persist.js +10 -1
- package/dist/persist.js.map +1 -1
- package/dist/scheduler.d.ts.map +1 -1
- package/dist/scheduler.js +5 -5
- package/dist/scheduler.js.map +1 -1
- package/dist/state.d.ts +25 -0
- package/dist/state.d.ts.map +1 -1
- package/dist/state.js +155 -12
- package/dist/state.js.map +1 -1
- package/dist/status.d.ts.map +1 -1
- package/dist/status.js +5 -2
- package/dist/status.js.map +1 -1
- package/dist/types.d.ts +89 -4
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +9 -2
- package/dist/types.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -32,7 +32,7 @@ ai-dossier sched status # queue (+pr/cleanup), engine lease, slots, ba
|
|
|
32
32
|
ai-dossier sched pause # prevent every new agent process; live units keep running
|
|
33
33
|
ai-dossier sched resume
|
|
34
34
|
ai-dossier sched stop --issue 42 # terminate one full-cycle agent and record it stopped (no recovery)
|
|
35
|
-
ai-dossier sched stop --batch b1 # terminate
|
|
35
|
+
ai-dossier sched stop --batch b1 # terminate every batch agent (incl. parallel members) and stop unfinished members
|
|
36
36
|
ai-dossier sched abandon --issue 42 --reason "operator abort"
|
|
37
37
|
ai-dossier sched abandon --batch b1 # dissolve; members requeue as full-cycle
|
|
38
38
|
ai-dossier sched stats --issues 4..9 # per-issue tokens/cost from ~/.dossier/runs.jsonl (#524)
|
|
@@ -53,8 +53,8 @@ directory directly, reconstructing costs from the raw dispatch logs rather than
|
|
|
53
53
|
takeovers; it does not terminate agents that are already running. `stop --issue <n>` is the
|
|
54
54
|
single-command stop path: it PID-start-safely terminates that issue's live agent, releases its
|
|
55
55
|
slot, and records a terminal `stopped` outcome that will not recover or escalate. An active
|
|
56
|
-
slot-mode member must instead be stopped through `stop --batch <id>`, which terminates
|
|
57
|
-
|
|
56
|
+
slot-mode member must instead be stopped through `stop --batch <id>`, which terminates every agent
|
|
57
|
+
the batch holds (its own slot plus one per running parallel member, `batch:<id>#<issue>`) and atomically stops the batch and its unfinished members. `abandon` only records failure
|
|
58
58
|
and releases the slot; it intentionally does not terminate its process.
|
|
59
59
|
|
|
60
60
|
Since #507, `enqueue` additionally reads each candidate issue's live GitHub labels (one
|
|
@@ -754,7 +754,7 @@ only when `batchExec`/`runBatchSuite` are both configured on `EngineDeps` — dr
|
|
|
754
754
|
`batch:<id>` unit through:
|
|
755
755
|
|
|
756
756
|
```
|
|
757
|
-
ready → executing(member i/N
|
|
757
|
+
ready → executing(serial: member i/N ⟲ | parallel: members ∥, ordered landing) → validating → reviewing → shipping
|
|
758
758
|
→ awaiting-merge → merged → deployed → reported → done
|
|
759
759
|
failure rails: executing → dissolving (a member self-reports blocked)
|
|
760
760
|
validating → attributing → (fixing | evicting) → validating → dissolving
|
|
@@ -774,7 +774,25 @@ failure rails: executing → dissolving (a member self-reports blocked)
|
|
|
774
774
|
`warm_commands` even in repos that never use the pool for anything else).
|
|
775
775
|
This shared tree is the batch's INTEGRATION branch: members branch off it, and
|
|
776
776
|
the tail work (aggregate suite, review, ship) runs in it (#677).
|
|
777
|
-
- **Members run
|
|
777
|
+
- **Members run in PARALLEL by default (#809)** — each member's `member-cycle` agent holds
|
|
778
|
+
its OWN slot (`batch:<id>#<issue>`, bounded by config `member_parallelism`, default
|
|
779
|
+
`max_slots`, and free capacity), in its own worktree cut off the integration branch, so
|
|
780
|
+
a batch's member phase costs ≈ max(member), not sum(member). Nothing lands until a
|
|
781
|
+
member-order prefix is verified: each verified member is rebased onto the integration
|
|
782
|
+
TIP in its own worktree, its pushed branch refreshed (`--force-with-lease`), then
|
|
783
|
+
`merge --ff-only`-landed — the same linear, `(#<issue>)`-trailed history (and
|
|
784
|
+
`memberRanges` attribution) as serial landing. A member whose diff no longer rebases
|
|
785
|
+
onto the members landed before it is evicted (`landing-conflict`, requeued full-cycle,
|
|
786
|
+
its pushed branch kept) — batch-integrate's eviction verdict; a parent repair agent (#813) for
|
|
787
|
+
that conflict is a follow-up. A gate-inconclusive member still lands and keeps its
|
|
788
|
+
tree; once every member resolves the batch blocks on it exactly as in serial mode
|
|
789
|
+
(`sched resume --batch` works unchanged). The mode is decided ONCE at the
|
|
790
|
+
`ready → executing` claim and persisted (`BatchEntry.member_dispatch`, `member_runs`
|
|
791
|
+
per member; schema 1.23.0): **serial** when `member_parallelism` is 1, the batch has
|
|
792
|
+
an eviction group, or a member `deps` on another member; a batch already past `ready`
|
|
793
|
+
with no recorded mode (claimed by a pre-1.23.0 engine) stays serial across the upgrade.
|
|
794
|
+
Dissolve, `sched stop --batch` and `abandon` stop/release every member slot.
|
|
795
|
+
- **Serial mode: members run `member-cycle` one fresh agent at a time — each in its OWN
|
|
778
796
|
worktree** on its OWN branch `batch/<id>-m<n>-<issue>` (#677, RFC-0001 §J.3), cut off
|
|
779
797
|
the integration branch, warmed, and pushed before the agent spawns; the agent never
|
|
780
798
|
creates either. When the member's incremental gate passes, the scheduler LANDS the
|
|
@@ -801,8 +819,9 @@ failure rails: executing → dissolving (a member self-reports blocked)
|
|
|
801
819
|
gate later to resolve the block once the capability is fixed, and applies the same
|
|
802
820
|
evidence bar on the recheck — a still-unevidenced `task-failed` stays blocked rather
|
|
803
821
|
than evicting on a resume.
|
|
804
|
-
- **The batch's
|
|
805
|
-
agent, the report agent, a bounded fix agent) — never held across a wait
|
|
822
|
+
- **The batch's own slot is claimed FRESH for each live step** (a serial member, the tail
|
|
823
|
+
agent, the report agent, a bounded fix agent) — never held across a wait; parallel
|
|
824
|
+
members hold their own member slots instead. The aggregate
|
|
806
825
|
suite itself runs with NO slot claimed at all (deterministic engine work, not an LLM
|
|
807
826
|
step).
|
|
808
827
|
- **Two failure rails.** A member that never went green evicts directly (nothing to
|
|
@@ -1028,6 +1047,8 @@ import {
|
|
|
1028
1047
|
duplicateEvictionDetail, // the one eviction-duplicate wording, shared by both rails
|
|
1029
1048
|
isPreservedMember, // the single definition of "already green"
|
|
1030
1049
|
createBatch, // the single BatchEntry constructor
|
|
1050
|
+
batchMemberUnit, // #809: a parallel member's slot unit, `batch:<id>#<issue>`
|
|
1051
|
+
slotsForBatch, // #809: every live slot a batch holds (its own + member slots)
|
|
1031
1052
|
type RecoveryDeps, // inject exec/repoDir/journal/milestone-poster/suite-runner/clock
|
|
1032
1053
|
type SuiteRunner, // re-runs the aggregate suite after a revert or rebase
|
|
1033
1054
|
type BatchMilestonePoster, // batch-milestone sink (createExecMilestonePoster is default)
|
|
@@ -1108,7 +1129,8 @@ telemetry" below.
|
|
|
1108
1129
|
│ # pr_poll_interval_ms, dispatch (incl. report_prompt,
|
|
1109
1130
|
│ # phase_stall_timeout_ms, fence_takeover_timeout_ms, tiers — #527,
|
|
1110
1131
|
│ # suite_command — #562, disallowed_tools — #591), auto_upgrade — #537,
|
|
1111
|
-
│ # dissolve_policy — #563
|
|
1132
|
+
│ # dissolve_policy — #563, default_batch_priority — #565,
|
|
1133
|
+
│ # max_full_review_members — #771, member_parallelism — #809
|
|
1112
1134
|
├── events.jsonl # append-only event journal (the operator's flight recorder)
|
|
1113
1135
|
├── runs/ # per-unit agent output logs (issue-<n>.log)
|
|
1114
1136
|
└── .sched-lock/ # cross-process directory mutex (pid; stolen from dead holders)
|
|
@@ -1215,8 +1237,7 @@ after-the-fact recovery, not a missing-data bug.
|
|
|
1215
1237
|
queue data.
|
|
1216
1238
|
- **Schema**: state/config files from #460 (schema 1.0.0), #464 (1.1.0), #468 (1.2.0),
|
|
1217
1239
|
#472 (1.3.0), #500 (1.4.0), #505 (1.5.0), #504 (1.6.0), #523 (1.7.0) and #524 (1.8.0)
|
|
1218
|
-
load and migrate to 1.
|
|
1219
|
-
load and migrate to 1.13.0 automatically (slot `branch`/`last_head`/`pid_start`, slot `role` (inferred from the
|
|
1240
|
+
load and migrate to the current schema (1.23.0) automatically (slot `branch`/`last_head`/`pid_start`, slot `role` (inferred from the
|
|
1220
1241
|
unit's queue entry, with the persisted `phase` as a fallback — #500), entry
|
|
1221
1242
|
`pr`/`cleanup`/`failure_evidence`, batch `anchor`/`branch`/`run_id`/`eviction_groups`/
|
|
1222
1243
|
`evictions`/`fix_attempts`/`rebase_attempts`, state-level `last_pr_poll_at` backfill to
|
|
@@ -1228,7 +1249,8 @@ after-the-fact recovery, not a missing-data bug.
|
|
|
1228
1249
|
`stale_milestone_ignored_for` backfill to `null` — #610, and state-level
|
|
1229
1250
|
`consecutive_dispatch_api_errors`/`dispatch_pause_reset_at` backfill to `0`/`null` —
|
|
1230
1251
|
#629; batch `anchor_closed_at` and `anchor_close_failed_reason`/`_since`/`_ticks`
|
|
1231
|
-
backfill to `null`/`null`/`null`/`0` — #768, schema 1.22.0
|
|
1252
|
+
backfill to `null`/`null`/`null`/`0` — #768, schema 1.22.0; batch `member_dispatch`/`member_runs`
|
|
1253
|
+
backfill to `null`/`[]` — #809, schema 1.23.0 — a null mode past `ready` runs serially).
|
|
1232
1254
|
- **`max_slots`** bounds live units (`assigned | running | recovering`); dependency
|
|
1233
1255
|
edges gate readiness — an issue with an unmerged dependency, and a batch behind an
|
|
1234
1256
|
unmerged batch, are never runnable.
|
package/dist/batch-dispatch.d.ts
CHANGED
|
@@ -11,7 +11,8 @@
|
|
|
11
11
|
* at batch-phase granularity instead of per-issue-phase granularity:
|
|
12
12
|
*
|
|
13
13
|
* ```
|
|
14
|
-
* ready → executing(member i/N
|
|
14
|
+
* ready → executing(serial: member i/N ⟲ | parallel: members ∥ + ordered landing)
|
|
15
|
+
* → validating → reviewing → shipping
|
|
15
16
|
* → awaiting-merge → merged → deployed → reported → done
|
|
16
17
|
* failure rails (RFC F.2/F.8/F.9):
|
|
17
18
|
* executing → dissolving (a member self-reports blocked, RFC F.1)
|
|
@@ -67,7 +68,7 @@ import type { SchedStore } from './persist';
|
|
|
67
68
|
import type { ExecFn } from './project';
|
|
68
69
|
import { type BatchSuiteContext, type SuiteResult } from './recovery';
|
|
69
70
|
import { type FsExists } from './teardown';
|
|
70
|
-
import type { BatchEntry, CapabilityGateResult, SchedConfig } from './types';
|
|
71
|
+
import type { BatchEntry, CapabilityGateResult, MemberDispatchMode, SchedConfig, SchedState } from './types';
|
|
71
72
|
export type { CapOutcome } from './types';
|
|
72
73
|
/** Everything batch dispatch needs from the outside world. */
|
|
73
74
|
export interface BatchDispatchDeps {
|
|
@@ -230,6 +231,20 @@ export declare function resumeBlockedGate(deps: BatchDispatchDeps, config: Sched
|
|
|
230
231
|
blockedBy?: 'inconclusive' | 'unevidenced-failure';
|
|
231
232
|
detail?: string;
|
|
232
233
|
};
|
|
234
|
+
/**
|
|
235
|
+
* How a batch should dispatch its members (#809) — decided once, at the
|
|
236
|
+
* `ready → executing` claim, and persisted on `BatchEntry.member_dispatch`.
|
|
237
|
+
*
|
|
238
|
+
* Serial when the operator set `member_parallelism: 1`, or the batch itself
|
|
239
|
+
* says its members are not independent: an eviction group (members that must
|
|
240
|
+
* revert together — e.g. one built on another's API) or a member whose `deps`
|
|
241
|
+
* names another member (it must see that member's landed work before it is
|
|
242
|
+
* cut). Parallel otherwise — the batch-cycle skill's and prep dossier's
|
|
243
|
+
* design (RFC-0001 §J.3: each member works off the integration branch and
|
|
244
|
+
* sees no one else's changes until the parent lands them).
|
|
245
|
+
*/
|
|
246
|
+
/** @internal exported for tests. */
|
|
247
|
+
export declare function memberDispatchModeFor(state: SchedState, batch: BatchEntry, config: SchedConfig): MemberDispatchMode;
|
|
233
248
|
/**
|
|
234
249
|
* One batch reconcile+refill pass. Called from `engine.ts`'s `tick()` after
|
|
235
250
|
* the issue-level pass — this pass never claims a slot the issue pass already
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"batch-dispatch.d.ts","sourceRoot":"","sources":["../src/batch-dispatch.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"batch-dispatch.d.ts","sourceRoot":"","sources":["../src/batch-dispatch.ts"],"names":[],"mappings":"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"}
|