@ai-dossier/sched 0.2.1 → 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 +26 -1
- package/dist/dispatch.d.ts.map +1 -1
- package/dist/dispatch.js +43 -5
- package/dist/dispatch.js.map +1 -1
- package/dist/engine.d.ts +53 -13
- package/dist/engine.d.ts.map +1 -1
- package/dist/engine.js +421 -75
- package/dist/engine.js.map +1 -1
- package/dist/enqueue.d.ts.map +1 -1
- package/dist/enqueue.js +2 -0
- package/dist/enqueue.js.map +1 -1
- package/dist/groundtruth.d.ts +66 -5
- package/dist/groundtruth.d.ts.map +1 -1
- package/dist/groundtruth.js +150 -5
- package/dist/groundtruth.js.map +1 -1
- package/dist/index.d.ts +6 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +17 -2
- package/dist/index.js.map +1 -1
- package/dist/persist.d.ts.map +1 -1
- package/dist/persist.js +14 -0
- package/dist/persist.js.map +1 -1
- package/dist/scheduler.d.ts +12 -0
- package/dist/scheduler.d.ts.map +1 -1
- package/dist/scheduler.js +47 -30
- package/dist/scheduler.js.map +1 -1
- package/dist/state.d.ts +4 -3
- package/dist/state.d.ts.map +1 -1
- package/dist/state.js +37 -6
- package/dist/state.js.map +1 -1
- package/dist/status.d.ts +16 -4
- package/dist/status.d.ts.map +1 -1
- package/dist/status.js +10 -4
- package/dist/status.js.map +1 -1
- 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 +43 -4
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +9 -5
- package/dist/types.js.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -3,11 +3,14 @@
|
|
|
3
3
|
[](https://www.npmjs.com/package/@ai-dossier/sched)
|
|
4
4
|
|
|
5
5
|
Deterministic scheduler core for dossier batch cycles — queue, worker slots, typed state
|
|
6
|
-
machines, crash-safe persistence,
|
|
7
|
-
processes, verifying their completion against ground truth,
|
|
8
|
-
stall/escalation ladder
|
|
9
|
-
|
|
10
|
-
|
|
6
|
+
machines, crash-safe persistence, the **dispatch engine** (#464: spawning agent
|
|
7
|
+
processes, verifying their completion against ground truth, mechanizing the
|
|
8
|
+
stall/escalation ladder), and since #468 the **PR watcher + tail work** (parked-PR
|
|
9
|
+
watching, script-based teardown, cheap-tier report dispatch — retiring the fleet
|
|
10
|
+
pattern of re-dispatching a full-cycle run for the tail). The scheduler itself **never
|
|
11
|
+
invokes an LLM** — it spawns the agent process the operator configured and reconciles
|
|
12
|
+
the durable record (`ai-dossier runstate` / `gh` / `git`) that the spawned run leaves
|
|
13
|
+
behind.
|
|
11
14
|
|
|
12
15
|
Design: RFC-0001 *Batch Cycles* §B/C.1/D (the RFC lives on branch `docs/batch-cycles-rfc`,
|
|
13
16
|
not yet merged to `main`; the §D state machines are frozen verbatim into the types below).
|
|
@@ -17,14 +20,14 @@ this state machine makes impossible to forget.
|
|
|
17
20
|
|
|
18
21
|
## CLI surface
|
|
19
22
|
|
|
20
|
-
Consumed through the monorepo CLI (`@ai-dossier/cli` ≥ 0.
|
|
23
|
+
Consumed through the monorepo CLI (`@ai-dossier/cli` ≥ 0.19.0):
|
|
21
24
|
|
|
22
25
|
```bash
|
|
23
26
|
ai-dossier sched enqueue --issues 101,105..109 --deps 100 --tier strong # flags
|
|
24
27
|
ai-dossier sched enqueue --from-manifest batch-prep.json # batch-prep output
|
|
25
|
-
ai-dossier sched start # the dispatch engine: spawn, verify, escalate (Ctrl-C stops it)
|
|
28
|
+
ai-dossier sched start # the dispatch engine: spawn, verify, escalate, watch parked PRs (Ctrl-C stops it)
|
|
26
29
|
ai-dossier sched start --once # a single reconcile+refill tick (cron-style)
|
|
27
|
-
ai-dossier sched status # queue
|
|
30
|
+
ai-dossier sched status # queue (+pr/cleanup), parked PRs, slots, batches, blocked/failed
|
|
28
31
|
ai-dossier sched pause # stop NEW assignments; live units keep running
|
|
29
32
|
ai-dossier sched resume
|
|
30
33
|
ai-dossier sched abandon --issue 42 --reason "operator abort"
|
|
@@ -91,13 +94,26 @@ import {
|
|
|
91
94
|
parseManifest, // batch-prep JSON → EnqueueInput[]
|
|
92
95
|
computeAssignments, // pure: fill idle slots with runnable units, bounded by max_slots
|
|
93
96
|
runnableUnits, // pure: which units may run right now (dep-gated)
|
|
94
|
-
tick, // one engine cycle: reconcile + verify + refill + spawn
|
|
97
|
+
tick, // one engine cycle: reconcile + verify + refill + spawn,
|
|
98
|
+
// and since #468: park-watch, teardown, report dispatch
|
|
95
99
|
runLoop, // the sched start loop (tick, sleep, repeat)
|
|
96
|
-
type TickResult, // what one tick did (spawned/
|
|
97
|
-
|
|
100
|
+
type TickResult, // what one tick did (spawned/parked/merge-accepted/report-dispatched/
|
|
101
|
+
// teardown/completed/redispatched/failed/blocked)
|
|
102
|
+
type EngineDeps, // inject everything the engine touches (store/journal/spawn/ground
|
|
103
|
+
// truth/clock/repoDir/teardownExec)
|
|
98
104
|
createSpawnDeps, // real detached-spawn process I/O
|
|
99
|
-
createExecGroundTruth, // runstate/gh/git ground truth via subprocesses (injectable exec)
|
|
100
|
-
|
|
105
|
+
createExecGroundTruth, // runstate/gh/git ground truth via subprocesses (injectable exec);
|
|
106
|
+
// since #468 also gh pr view PR state + setup info from comments
|
|
107
|
+
resolveDispatch, // config → resolved command/prompt/report-prompt/tier-models/timers
|
|
108
|
+
buildReportPrompt, // report-agent prompt ({issue}/{pr}/{cleanup} substituted)
|
|
109
|
+
reportTierFor, // report (re)dispatch tier after N escalations
|
|
110
|
+
isParkedMilestone, // ship-phase awaiting-merge + pr= → the park signal
|
|
111
|
+
prOfMilestone, // a milestone's pr= key as a positive integer
|
|
112
|
+
parsePrViewJson, // gh pr view --json → PR truth (mergedAt/mergeable/blocked label)
|
|
113
|
+
parseSetupInfo, // gh issue view --json comments → teardown inputs
|
|
114
|
+
runTeardown, // #468 script teardown for a merged unit (pool return / worktree remove)
|
|
115
|
+
isSafeWorktree, // worktree-path containment check (CWE-22)
|
|
116
|
+
TEARDOWN_TIMEOUT_MS, // teardown subprocess timeout (120 s)
|
|
101
117
|
Journal, // append-only events.jsonl
|
|
102
118
|
transitionIssue, transitionBatch, transitionSlot, // typed §D transitions
|
|
103
119
|
TRANSITIONS, // the transition tables themselves (for previews)
|
|
@@ -119,7 +135,8 @@ fake agents and stub ground truth; no LLM calls anywhere.
|
|
|
119
135
|
```
|
|
120
136
|
~/.dossier/sched/<project>/
|
|
121
137
|
├── state.json # hot operational truth — atomic tmp+fsync+rename writes;
|
|
122
|
-
├── config.json # durable intent: max_slots, stall_timeout_ms, reconcile_interval_ms,
|
|
138
|
+
├── config.json # durable intent: max_slots, stall_timeout_ms, reconcile_interval_ms,
|
|
139
|
+
│ # pr_poll_interval_ms, dispatch (incl. report_prompt)
|
|
123
140
|
├── events.jsonl # append-only event journal (the operator's flight recorder)
|
|
124
141
|
├── runs/ # per-unit agent output logs (issue-<n>.log)
|
|
125
142
|
└── .sched-lock/ # cross-process directory mutex (pid; stolen from dead holders)
|
|
@@ -133,14 +150,63 @@ fake agents and stub ground truth; no LLM calls anywhere.
|
|
|
133
150
|
- **Corrupt state is loud**: `load()` throws `CorruptStateError` naming the file —
|
|
134
151
|
never a silent queue reset. `state.json` is deletable and rebuildable from GitHub,
|
|
135
152
|
which remains the system of record.
|
|
136
|
-
- **Schema**: state/config files from #460 (schema 1.0.0)
|
|
137
|
-
automatically (slot `branch`/`last_head
|
|
153
|
+
- **Schema**: state/config files from #460 (schema 1.0.0) and #464 (1.1.0) load and
|
|
154
|
+
migrate to 1.2.0 automatically (slot `branch`/`last_head`, entry `pr`/`cleanup`,
|
|
155
|
+
and state-level `last_pr_poll_at` backfill to null).
|
|
138
156
|
- **`max_slots`** bounds live units (`assigned | running | recovering`); dependency
|
|
139
157
|
edges gate readiness — an issue with an unmerged dependency, and a batch behind an
|
|
140
158
|
unmerged batch, are never runnable.
|
|
141
159
|
- **Pause** stops new assignments only; abandon routes through the typed failure rails
|
|
142
160
|
(`evicted → requeued{full}` for batch members — nothing green is discarded).
|
|
143
161
|
|
|
162
|
+
## The PR watcher + tail work (#468)
|
|
163
|
+
|
|
164
|
+
Dispatched runs park their PR on `auto-merge` (detached ship mode — the default
|
|
165
|
+
prompt instructs it) and exit. The engine owns everything after the park:
|
|
166
|
+
|
|
167
|
+
1. **Park detection (AC1)** — an agent exit whose latest milestone is the ship
|
|
168
|
+
phase's `awaiting-merge` (with `pr=`) is a VERIFIED park, not an unverified
|
|
169
|
+
exit: the entry moves to `parked`, the slot is released (a waiting unit
|
|
170
|
+
consumes zero slots), and the watcher takes over.
|
|
171
|
+
2. **PR watching (AC1)** — parked PRs are polled every `pr_poll_interval_ms`
|
|
172
|
+
(default 150 s — "every 2–3 min", persisted `last_pr_poll_at` so a restart
|
|
173
|
+
honors the cadence; checked on each reconcile tick when due, so a
|
|
174
|
+
`reconcile_interval_ms` longer than the interval slows the effective cadence)
|
|
175
|
+
via `gh pr view --json state,mergedAt,mergeable,labels`.
|
|
176
|
+
A merge is accepted only when state is MERGED **and** `mergedAt` is non-null
|
|
177
|
+
**and** the issue is closed — never inferred from an agent exit. An
|
|
178
|
+
unreachable poll pauses the watcher (decision 2, option A).
|
|
179
|
+
3. **Failure states (AC3)** — `CONFLICTING`, closed-unmerged, or the
|
|
180
|
+
`auto-merge-blocked` label fail the unit with the reason and block its
|
|
181
|
+
TRANSITIVE dependents. The engine never merges anything itself.
|
|
182
|
+
4. **Gating on MERGE, not park (AC4)** — `parked` is not a satisfied status:
|
|
183
|
+
dependents stay blocked until the merge lands (`parked → shipped`).
|
|
184
|
+
5. **Teardown as a script (AC2)** — on merge, the run's setup milestone
|
|
185
|
+
(recovered once from the issue's comments — collaborator-authored only, and
|
|
186
|
+
the worktree path must pass a containment check before any destructive
|
|
187
|
+
subprocess) chooses the script: pool-claimed worktrees run
|
|
188
|
+
`worktree-pool return --path <wt> --json` (the pool's own self-check is the
|
|
189
|
+
verification); cold worktrees run
|
|
190
|
+
`git worktree remove --force <wt>` with a path-gone check. Both are
|
|
191
|
+
verify-first idempotent; a failed step records `cleanup=failed-<step>` on
|
|
192
|
+
the entry and in the journal — degradation, never unit failure.
|
|
193
|
+
6. **Report dispatch (AC2)** — once teardown is recorded (when a slot is
|
|
194
|
+
free — a waiting report consumes zero slots), a **mechanical-tier** report
|
|
195
|
+
agent is spawned with the report-phase prompt (`dispatch.report_prompt`;
|
|
196
|
+
`{issue}`/`{pr}`/`{cleanup}` substituted — the cleanup status rides into
|
|
197
|
+
the report). It completes like any agent; a report that stalls climbs the
|
|
198
|
+
same ladder (mechanical → mid → strong, cap 2), and at the cap the unit
|
|
199
|
+
completes (`done`, reason `report-escalation-cap`) with a `report-failed`
|
|
200
|
+
journal event — the work is merged, so dependents are never re-blocked.
|
|
201
|
+
The full-cycle tail-run pattern (re-dispatching a whole run for
|
|
202
|
+
teardown+report) is retired.
|
|
203
|
+
|
|
204
|
+
`sched status` shows parked PRs (zero slots, with the last poll's age), a
|
|
205
|
+
`pr` column and a `cleanup` column on the queue; every watcher decision lands
|
|
206
|
+
in `events.jsonl` (`pr-parked`, `merge-accepted`, `pr-watch-failed`,
|
|
207
|
+
`pr-watch-waiting`, `teardown-done`/`teardown-failed`, `report-dispatched`,
|
|
208
|
+
`report-failed`, `ground-truth-unreachable`).
|
|
209
|
+
|
|
144
210
|
## Development
|
|
145
211
|
|
|
146
212
|
```bash
|
|
@@ -152,4 +218,6 @@ npm test # vitest — state machines, persistence, crash/restart, engine
|
|
|
152
218
|
|
|
153
219
|
No network, no GitHub in unit tests — persistence tests run on temp directories; the
|
|
154
220
|
integration tests spawn fake-agent fixtures against a scratch git repo with stubbed
|
|
155
|
-
ground truth.
|
|
221
|
+
ground truth. The #468 integration tests run the full detached-ship tail
|
|
222
|
+
(park → watch → merge → REAL worktree removal → report) end-to-end, including a
|
|
223
|
+
sched restart mid-watch.
|
package/dist/dispatch.d.ts
CHANGED
|
@@ -22,18 +22,34 @@ export declare const DEFAULT_TIER_MODELS: Readonly<Record<ModelTier, string>>;
|
|
|
22
22
|
export declare const DEFAULT_DISPATCH_COMMAND: readonly string[];
|
|
23
23
|
/** opencode equivalent (the run machinery's second agent, #459). */
|
|
24
24
|
export declare const OPENCODE_DISPATCH_COMMAND: readonly string[];
|
|
25
|
-
/**
|
|
25
|
+
/**
|
|
26
|
+
* Default prompt sent on the child's stdin. Detached ship mode (#468): the
|
|
27
|
+
* agent parks the PR on `auto-merge` and STOPS — the scheduler's PR watcher
|
|
28
|
+
* owns the merge wait and dispatches teardown + report as tail work. The
|
|
29
|
+
* fleet pattern of re-dispatching a full-cycle run for the tail is retired.
|
|
30
|
+
* Operators wanting attached runs (agent drives to the final report itself)
|
|
31
|
+
* override `dispatch.prompt` in config.json.
|
|
32
|
+
*/
|
|
26
33
|
export declare const DEFAULT_PROMPT_TEMPLATE: string;
|
|
34
|
+
/**
|
|
35
|
+
* Default prompt for the report agent dispatched after a merged PR (#468
|
|
36
|
+
* AC2) — a cheap-tier run of the report phase only, never a full cycle.
|
|
37
|
+
*/
|
|
38
|
+
export declare const DEFAULT_REPORT_PROMPT_TEMPLATE: string;
|
|
27
39
|
/** Fully-resolved dispatch settings the engine runs with. */
|
|
28
40
|
export interface ResolvedDispatch {
|
|
29
41
|
/** Command template with `{model}`/`{issue}` placeholders. */
|
|
30
42
|
command: string[];
|
|
31
43
|
/** Prompt template with `{issue}` placeholder. */
|
|
32
44
|
prompt: string;
|
|
45
|
+
/** Report-agent prompt template with `{issue}`/`{pr}`/`{cleanup}` placeholders (#468). */
|
|
46
|
+
reportPrompt: string;
|
|
33
47
|
/** Model per tier; null means "no model flag" (the command's `--model {model}` pair drops). */
|
|
34
48
|
tierModels: Record<ModelTier, string | null>;
|
|
35
49
|
stallTimeoutMs: number;
|
|
36
50
|
reconcileIntervalMs: number;
|
|
51
|
+
/** Parked-PR poll interval (#468 AC1, default 150 s — "every 2–3 min"). */
|
|
52
|
+
prPollIntervalMs: number;
|
|
37
53
|
}
|
|
38
54
|
/** Resolve engine dispatch settings from the (possibly sparse) config. */
|
|
39
55
|
export declare function resolveDispatch(config: SchedConfig): ResolvedDispatch;
|
|
@@ -46,8 +62,17 @@ export declare function resolveDispatch(config: SchedConfig): ResolvedDispatch;
|
|
|
46
62
|
export declare function buildAgentCommand(template: readonly string[], tier: ModelTier, issue: number, tierModels: Readonly<Record<ModelTier, string | null>>): string[];
|
|
47
63
|
/** Build the child's stdin prompt for one dispatch. */
|
|
48
64
|
export declare function buildPrompt(template: string, issue: number): string;
|
|
65
|
+
/** Build the report agent's stdin prompt (#468): `{issue}`/`{pr}`/`{cleanup}` substituted. */
|
|
66
|
+
export declare function buildReportPrompt(template: string, issue: number, pr: number, cleanup: string): string;
|
|
49
67
|
/** One tier stronger on the ladder, or null at the top (RFC-0001 §C.1). */
|
|
50
68
|
export declare function escalateTier(tier: ModelTier): ModelTier | null;
|
|
69
|
+
/**
|
|
70
|
+
* The tier for a report-agent (re)dispatch after `recoveries` escalations
|
|
71
|
+
* (#468): reports start cheap (mechanical) and climb the same ladder —
|
|
72
|
+
* mechanical → mid → strong — with null past the top. The engine's
|
|
73
|
+
* `ESCALATION_CAP` check fails the unit before that null is reached.
|
|
74
|
+
*/
|
|
75
|
+
export declare function reportTierFor(recoveries: number): ModelTier | null;
|
|
51
76
|
export interface SpawnDeps {
|
|
52
77
|
/**
|
|
53
78
|
* Spawn a detached agent process and return its pid. `logFile` receives the
|
package/dist/dispatch.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dispatch.d.ts","sourceRoot":"","sources":["../src/dispatch.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAMH,OAAO,
|
|
1
|
+
{"version":3,"file":"dispatch.d.ts","sourceRoot":"","sources":["../src/dispatch.ts"],"names":[],"mappings":"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"}
|
package/dist/dispatch.js
CHANGED
|
@@ -50,11 +50,13 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
50
50
|
};
|
|
51
51
|
})();
|
|
52
52
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
53
|
-
exports.STOP_POLL_MAX_MS = exports.STOP_POLL_MIN_MS = exports.DEFAULT_PROMPT_TEMPLATE = exports.OPENCODE_DISPATCH_COMMAND = exports.DEFAULT_DISPATCH_COMMAND = exports.DEFAULT_TIER_MODELS = void 0;
|
|
53
|
+
exports.STOP_POLL_MAX_MS = exports.STOP_POLL_MIN_MS = exports.DEFAULT_REPORT_PROMPT_TEMPLATE = exports.DEFAULT_PROMPT_TEMPLATE = exports.OPENCODE_DISPATCH_COMMAND = exports.DEFAULT_DISPATCH_COMMAND = exports.DEFAULT_TIER_MODELS = void 0;
|
|
54
54
|
exports.resolveDispatch = resolveDispatch;
|
|
55
55
|
exports.buildAgentCommand = buildAgentCommand;
|
|
56
56
|
exports.buildPrompt = buildPrompt;
|
|
57
|
+
exports.buildReportPrompt = buildReportPrompt;
|
|
57
58
|
exports.escalateTier = escalateTier;
|
|
59
|
+
exports.reportTierFor = reportTierFor;
|
|
58
60
|
exports.unitLogName = unitLogName;
|
|
59
61
|
exports.procStartTime = procStartTime;
|
|
60
62
|
exports.createSpawnDeps = createSpawnDeps;
|
|
@@ -87,12 +89,30 @@ exports.OPENCODE_DISPATCH_COMMAND = [
|
|
|
87
89
|
'--model',
|
|
88
90
|
'{model}',
|
|
89
91
|
];
|
|
90
|
-
/**
|
|
92
|
+
/**
|
|
93
|
+
* Default prompt sent on the child's stdin. Detached ship mode (#468): the
|
|
94
|
+
* agent parks the PR on `auto-merge` and STOPS — the scheduler's PR watcher
|
|
95
|
+
* owns the merge wait and dispatches teardown + report as tail work. The
|
|
96
|
+
* fleet pattern of re-dispatching a full-cycle run for the tail is retired.
|
|
97
|
+
* Operators wanting attached runs (agent drives to the final report itself)
|
|
98
|
+
* override `dispatch.prompt` in config.json.
|
|
99
|
+
*/
|
|
91
100
|
exports.DEFAULT_PROMPT_TEMPLATE = 'Run the full-cycle-issue workflow for GitHub issue #{issue} in this repository.\n\n' +
|
|
92
101
|
'Begin by fetching the workflow: ai-dossier run imboard-ai/git/full-cycle-issue --pull\n\n' +
|
|
93
|
-
'Then execute it
|
|
94
|
-
'(gate, setup, plan, implement, review
|
|
95
|
-
'
|
|
102
|
+
'Then execute it for issue #{issue} in detached ship mode (ship_mode=detached), following every ' +
|
|
103
|
+
'phase (gate, setup, plan, implement, review) without asking questions, until Phase 5 parks the ' +
|
|
104
|
+
'PR: apply the auto-merge label, post the awaiting-merge milestone, and STOP. Do not wait for ' +
|
|
105
|
+
'the merge, do not run teardown or report — the scheduler watches the PR and dispatches those.';
|
|
106
|
+
/**
|
|
107
|
+
* Default prompt for the report agent dispatched after a merged PR (#468
|
|
108
|
+
* AC2) — a cheap-tier run of the report phase only, never a full cycle.
|
|
109
|
+
*/
|
|
110
|
+
exports.DEFAULT_REPORT_PROMPT_TEMPLATE = 'Run the report phase for GitHub issue #{issue} in this repository.\n\n' +
|
|
111
|
+
'Begin by fetching the workflow: ai-dossier run imboard-ai/git/report-issue --pull\n\n' +
|
|
112
|
+
'The work is DONE: pull request #{pr} is merged (merge commit via `gh pr view {pr}`), the issue ' +
|
|
113
|
+
'is closed, and the worktree is already torn down (cleanup status: {cleanup}). Do not ' +
|
|
114
|
+
're-implement, re-review, or re-ship anything — produce the final report for issue #{issue} and ' +
|
|
115
|
+
'post its runstate milestone.';
|
|
96
116
|
/** Resolve engine dispatch settings from the (possibly sparse) config. */
|
|
97
117
|
function resolveDispatch(config) {
|
|
98
118
|
const dispatch = config.dispatch ?? {};
|
|
@@ -104,9 +124,11 @@ function resolveDispatch(config) {
|
|
|
104
124
|
return {
|
|
105
125
|
command: dispatch.command ?? [...exports.DEFAULT_DISPATCH_COMMAND],
|
|
106
126
|
prompt: dispatch.prompt ?? exports.DEFAULT_PROMPT_TEMPLATE,
|
|
127
|
+
reportPrompt: dispatch.report_prompt ?? exports.DEFAULT_REPORT_PROMPT_TEMPLATE,
|
|
107
128
|
tierModels,
|
|
108
129
|
stallTimeoutMs: config.stall_timeout_ms ?? types_1.DEFAULT_STALL_TIMEOUT_MS,
|
|
109
130
|
reconcileIntervalMs: config.reconcile_interval_ms ?? types_1.DEFAULT_RECONCILE_INTERVAL_MS,
|
|
131
|
+
prPollIntervalMs: config.pr_poll_interval_ms ?? types_1.DEFAULT_PR_POLL_INTERVAL_MS,
|
|
110
132
|
};
|
|
111
133
|
}
|
|
112
134
|
/**
|
|
@@ -137,10 +159,26 @@ function buildAgentCommand(template, tier, issue, tierModels) {
|
|
|
137
159
|
function buildPrompt(template, issue) {
|
|
138
160
|
return template.replaceAll('{issue}', String(issue));
|
|
139
161
|
}
|
|
162
|
+
/** Build the report agent's stdin prompt (#468): `{issue}`/`{pr}`/`{cleanup}` substituted. */
|
|
163
|
+
function buildReportPrompt(template, issue, pr, cleanup) {
|
|
164
|
+
return template
|
|
165
|
+
.replaceAll('{issue}', String(issue))
|
|
166
|
+
.replaceAll('{pr}', String(pr))
|
|
167
|
+
.replaceAll('{cleanup}', cleanup);
|
|
168
|
+
}
|
|
140
169
|
/** One tier stronger on the ladder, or null at the top (RFC-0001 §C.1). */
|
|
141
170
|
function escalateTier(tier) {
|
|
142
171
|
return types_1.TIER_LADDER[tier];
|
|
143
172
|
}
|
|
173
|
+
/**
|
|
174
|
+
* The tier for a report-agent (re)dispatch after `recoveries` escalations
|
|
175
|
+
* (#468): reports start cheap (mechanical) and climb the same ladder —
|
|
176
|
+
* mechanical → mid → strong — with null past the top. The engine's
|
|
177
|
+
* `ESCALATION_CAP` check fails the unit before that null is reached.
|
|
178
|
+
*/
|
|
179
|
+
function reportTierFor(recoveries) {
|
|
180
|
+
return types_1.TIER_ORDER[recoveries] ?? null;
|
|
181
|
+
}
|
|
144
182
|
/** `issue:464` → `issue-464` (filesystem-safe unit ids for log file names). */
|
|
145
183
|
function unitLogName(unit) {
|
|
146
184
|
return (0, project_1.sanitizeSlug)(unit);
|
package/dist/dispatch.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dispatch.js","sourceRoot":"","sources":["../src/dispatch.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;GAgBG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"dispatch.js","sourceRoot":"","sources":["../src/dispatch.ts"],"names":[],"mappings":"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"}
|
package/dist/engine.d.ts
CHANGED
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* The scheduler engine (#464): dispatch, completion verification, and the
|
|
3
3
|
* stall/escalation ladder (RFC-0001 §C.1) — the deterministic organs that
|
|
4
|
-
* replace fleet-cycle's LLM supervision.
|
|
4
|
+
* replace fleet-cycle's LLM supervision. Since #468 it also owns the
|
|
5
|
+
* detached-ship tail: the PR watcher, script-based teardown, and the
|
|
6
|
+
* cheap-tier report dispatch.
|
|
5
7
|
*
|
|
6
8
|
* One `tick()` is a full reconcile+refill cycle:
|
|
7
9
|
*
|
|
8
|
-
* 1. **Poll** ground truth for every live unit
|
|
9
|
-
* subprocesses are slow; the lock must never wait
|
|
10
|
+
* 1. **Poll** ground truth for every live unit and every parked PR OUTSIDE
|
|
11
|
+
* the state lock (gh/git subprocesses are slow; the lock must never wait
|
|
12
|
+
* on a network call). Parked PRs poll on their own cadence
|
|
13
|
+
* (`pr_poll_interval_ms`, persisted `last_pr_poll_at`) — every 2–3 min.
|
|
10
14
|
* 2. **Apply** under `SchedStore.withLock`:
|
|
11
15
|
* - `assigned` slots (crash between assign and spawn) are spawned/re-attached
|
|
12
16
|
* - `running` slots: dead pid → exit rail; ground truth says complete →
|
|
@@ -14,13 +18,25 @@
|
|
|
14
18
|
* pushed commit → progress; no progress for `stall_timeout_ms` →
|
|
15
19
|
* redispatch one tier stronger (cap 2, then failed)
|
|
16
20
|
* - `exited`/`verifying` slots: the agent exited — completion is verified
|
|
17
|
-
* against ground truth, never assumed (AC2);
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
+
* against ground truth, never assumed (AC2); an exit whose milestone is
|
|
22
|
+
* the ship phase's `awaiting-merge` (with `pr=`) is a VERIFIED park:
|
|
23
|
+
* entry → parked, slot released (a parked unit holds no slot — AC5)
|
|
24
|
+
* - `parked` entries: the watcher applies the PR truth — merge accepted
|
|
25
|
+
* only when state MERGED AND mergedAt non-null AND the issue is closed
|
|
26
|
+
* (AC1) → shipped (gating on MERGE, never the park — AC4);
|
|
27
|
+
* CONFLICTING / closed-unmerged / auto-merge-blocked → failed + transitive
|
|
28
|
+
* dependents blocked (AC3)
|
|
21
29
|
* - failures block their TRANSITIVE dependents (AC4)
|
|
22
|
-
*
|
|
23
|
-
*
|
|
30
|
+
* - report agents are dispatched for merged units whose teardown is
|
|
31
|
+
* already recorded (before queue refill — cheap reports don't queue
|
|
32
|
+
* behind long runs)
|
|
33
|
+
* - **Refill** in the SAME lock pass: `computeAssignments` fills every
|
|
34
|
+
* freed slot — a runnable unit never waits while a slot is idle (AC5)
|
|
35
|
+
* 3. **Teardown** (outside the lock — pool/git subprocesses are slow): for
|
|
36
|
+
* every freshly-merged unit, recover the setup milestone's worktree info
|
|
37
|
+
* and run pool return / worktree remove, VERIFIED before claimed
|
|
38
|
+
* (`cleanup=failed-<step>` on mismatch, AC2). Results land in a second
|
|
39
|
+
* short lock pass together with the report dispatch.
|
|
24
40
|
*
|
|
25
41
|
* Everything that touches the world (processes, GitHub, git) is injected;
|
|
26
42
|
* the state machine is pure. Only `issue:<n>` units are dispatched — batch
|
|
@@ -30,6 +46,7 @@ import { type SpawnDeps } from './dispatch';
|
|
|
30
46
|
import { type GroundTruth } from './groundtruth';
|
|
31
47
|
import { type Journal } from './journal';
|
|
32
48
|
import type { SchedStore } from './persist';
|
|
49
|
+
import type { ExecFn } from './project';
|
|
33
50
|
import { type SchedConfig } from './types';
|
|
34
51
|
export interface EngineDeps {
|
|
35
52
|
store: SchedStore;
|
|
@@ -37,6 +54,10 @@ export interface EngineDeps {
|
|
|
37
54
|
groundTruth: GroundTruth;
|
|
38
55
|
spawnDeps: SpawnDeps;
|
|
39
56
|
now: () => Date;
|
|
57
|
+
/** Repo working directory — cwd for teardown subprocesses (#468). */
|
|
58
|
+
repoDir: string;
|
|
59
|
+
/** Exec for teardown scripts (#468); injectable so tests never touch git/npx. */
|
|
60
|
+
teardownExec: ExecFn;
|
|
40
61
|
}
|
|
41
62
|
/** What one tick did — surfaced by `sched start`. */
|
|
42
63
|
export interface TickResult {
|
|
@@ -46,17 +67,36 @@ export interface TickResult {
|
|
|
46
67
|
externalAdvances: string[];
|
|
47
68
|
/** Units verified complete after an observed exit. */
|
|
48
69
|
completed: string[];
|
|
70
|
+
/** Units whose agent exited having parked its PR (#468) — now watcher-owned. */
|
|
71
|
+
parked: string[];
|
|
72
|
+
/** Parked units whose merge was accepted this tick (#468). */
|
|
73
|
+
mergeAccepted: string[];
|
|
74
|
+
/** Report agents dispatched for merged units this tick (#468). */
|
|
75
|
+
reportDispatched: string[];
|
|
76
|
+
/** Merged units whose report could not dispatch — waiting for a free slot (#468). */
|
|
77
|
+
reportWaiting: number;
|
|
78
|
+
/** Units whose teardown was verified this tick (#468). */
|
|
79
|
+
teardownDone: string[];
|
|
80
|
+
/** Units whose teardown failed a step this tick (#468) — degradation, not unit failure. */
|
|
81
|
+
teardownFailed: string[];
|
|
49
82
|
/** Units redispatched one tier stronger (stall or unverified exit). */
|
|
50
83
|
redispatched: string[];
|
|
51
|
-
/**
|
|
84
|
+
/**
|
|
85
|
+
* Units that hit a failure rail. Full-cycle units end `failed`; MERGED
|
|
86
|
+
* units also land here on merged-aware REPORT failures
|
|
87
|
+
* (`report-escalation-cap` / report spawn-error), where the unit actually
|
|
88
|
+
* completes (`done`, reason recorded) — the report failed, not the work.
|
|
89
|
+
*/
|
|
52
90
|
failed: string[];
|
|
53
91
|
/** Issues blocked transitively by a failure. */
|
|
54
92
|
blocked: number[];
|
|
55
93
|
}
|
|
56
94
|
/**
|
|
57
|
-
* One full reconcile+refill cycle. Ground truth is polled WITHOUT the lock
|
|
58
|
-
* every state mutation happens under
|
|
59
|
-
* the same pass, so a freed slot
|
|
95
|
+
* One full reconcile+refill cycle. Ground truth is polled WITHOUT the lock
|
|
96
|
+
* (live units AND parked PRs); every state mutation happens under
|
|
97
|
+
* `store.withLock`; refills are computed in the same pass, so a freed slot
|
|
98
|
+
* is reused within this tick (AC5). Teardown subprocesses run between two
|
|
99
|
+
* short lock passes — a slow `npx`/`git` call never holds the lock.
|
|
60
100
|
*/
|
|
61
101
|
export declare function tick(deps: EngineDeps, config: SchedConfig): TickResult;
|
|
62
102
|
/**
|
package/dist/engine.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../src/engine.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../src/engine.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CG;AAGH,OAAO,EAQL,KAAK,SAAS,EAIf,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,KAAK,WAAW,EAMjB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAe,KAAK,OAAO,EAAa,MAAM,WAAW,CAAC;AACjE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAC5C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAIxC,OAAO,EAKL,KAAK,WAAW,EAKjB,MAAM,SAAS,CAAC;AAEjB,MAAM,WAAW,UAAU;IACzB,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,qEAAqE;IACrE,OAAO,EAAE,MAAM,CAAC;IAChB,iFAAiF;IACjF,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,qDAAqD;AACrD,MAAM,WAAW,UAAU;IACzB,8DAA8D;IAC9D,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,kFAAkF;IAClF,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAC3B,sDAAsD;IACtD,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,gFAAgF;IAChF,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,8DAA8D;IAC9D,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,kEAAkE;IAClE,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAC3B,qFAAqF;IACrF,aAAa,EAAE,MAAM,CAAC;IACtB,0DAA0D;IAC1D,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,2FAA2F;IAC3F,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,uEAAuE;IACvE,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB;;;;;OAKG;IACH,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,gDAAgD;IAChD,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AA06BD;;;;;;GAMG;AACH,wBAAgB,IAAI,CAAC,IAAI,EAAE,UAAU,EAAE,MAAM,EAAE,WAAW,GAAG,UAAU,CAyCtE;AAED;;;;;;;GAOG;AACH,wBAAsB,OAAO,CAC3B,IAAI,EAAE,UAAU,EAChB,MAAM,EAAE,WAAW,EACnB,UAAU,EAAE,MAAM,OAAO,EACzB,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,UAAU,KAAK,IAAI,GACpC,OAAO,CAAC,IAAI,CAAC,CAcf"}
|