@bluewombat/conductor 0.8.0 → 0.10.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/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAClF,OAAO,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAWjE,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAClF,OAAO,EAAE,WAAW,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC"}
@@ -0,0 +1,114 @@
1
+ import type { AuthorityPort, ImplementResult, ImplementTrace, TransformerPort } from "../transformers/port.js";
2
+ import type { ProjectRunResult } from "./results.js";
3
+ /**
4
+ * Getting assembled work from where it was made to where it lands.
5
+ *
6
+ * A Ticket does it to the Feature's line and a Feature does it to the Project's
7
+ * final one; the steps are the same and only what they are given differs. This
8
+ * module is the steps. It reads nothing from the ledger and writes nothing to
9
+ * it: whoever uses it says where the work is (`DeliveryUnit`), how a refusal is
10
+ * kept (`DeliveryStore`), and what the checks are (the Transformers).
11
+ *
12
+ * The steps, in order, each a pass that may end the pass early:
13
+ *
14
+ * 1. a fix, when something refused the last round and said why;
15
+ * 2. the align: the line brought into the work, and a conflict sent to the fix;
16
+ * 3. the work's own checks again, when the align or a fix changed the code
17
+ * (a Ticket has them; a Feature's are part of its review);
18
+ * 4. a local review, when the Project has one;
19
+ * — then the work is offered, which is the user's business (it is published in
20
+ * different ways) — and later:
21
+ * 5. the judgement of what was published;
22
+ * 6. whether the line moved on meanwhile, and a realign if so;
23
+ * 7. the fold.
24
+ */
25
+ /** The work to deliver, and where everything about it is. */
26
+ export type DeliveryUnit = {
27
+ /** The Ticket's or the Feature's key; every Transformer id derives from it. */
28
+ key: string;
29
+ intention: string;
30
+ title?: string | undefined;
31
+ /** What it is called in what is said about it. */
32
+ noun: "ticket" | "feature";
33
+ /** Where the work is: the Transformers produce, align and check here. */
34
+ workspace: string;
35
+ /** Where the Gates read the published work: its branch is checked out here. */
36
+ judgeWorkspace: string;
37
+ /** The line it is offered to; empty when the Project names none. */
38
+ target: string;
39
+ /** The directory holding that line, merged into the work at the align. */
40
+ line: string;
41
+ };
42
+ /** What the delivery needs to know of the unit's state, read fresh at each step. */
43
+ export type DeliveryRead = {
44
+ /** What refused the last round, when something did. The fresher of a parked refusal and a Submission's. */
45
+ sentBack?: {
46
+ report: string;
47
+ refusedBy?: string | undefined;
48
+ } | undefined;
49
+ /** Corrective rounds spent: refusals, parked refusals and realigns together. */
50
+ spent: number;
51
+ /** The Submission the work is offered under, once there is one. */
52
+ submission?: {
53
+ reference: string;
54
+ } | undefined;
55
+ };
56
+ /**
57
+ * How the unit keeps what the delivery decides. Each write answers `undefined`
58
+ * when it was done, or the result that ends the pass when it was refused.
59
+ */
60
+ export type DeliveryStore = {
61
+ read(): Promise<DeliveryRead | undefined>;
62
+ /** Stop for a person. */
63
+ freeze(input: {
64
+ kind: "assembly" | "submitted";
65
+ report?: string;
66
+ }): Promise<ProjectRunResult>;
67
+ /** A check refused the work before it was published: keep why, for the fix. */
68
+ park(why: {
69
+ report: string;
70
+ refusedBy?: string | undefined;
71
+ }): Promise<ProjectRunResult | undefined>;
72
+ /** Whatever sent the work back is repaired and checked. */
73
+ unpark(): Promise<ProjectRunResult | undefined>;
74
+ /** The Authority's judgement refused the Submission: keep why, and go back to the fix. */
75
+ refuse(why: {
76
+ report: string;
77
+ refusedBy?: string | undefined;
78
+ }): Promise<ProjectRunResult | undefined>;
79
+ /** The line moved on under the Submission: go back to be aligned. */
80
+ realign(): Promise<ProjectRunResult | undefined>;
81
+ };
82
+ export type DeliveryOptions = {
83
+ transformers: TransformerPort;
84
+ /** Absent: the work is not offered outside, and `settle` has nothing to ask. */
85
+ authority?: AuthorityPort | undefined;
86
+ durationMs: number;
87
+ maxRefusals: number;
88
+ /** Whether the unit's own checks run again after the align (the Ticket's `builder.gates`). */
89
+ recheck: boolean;
90
+ /** Whether a local review follows. For a Feature it is also where its checks run. */
91
+ validate: boolean;
92
+ /** Whether anything can repair a refusal. Without it a refusal is for a person. */
93
+ fixDeclared: boolean;
94
+ /** One job at a time over the directories the line lives in. */
95
+ onLine<T>(job: () => Promise<T>): Promise<T>;
96
+ /** The directory of the line brought up to date with it; false when it could not be. */
97
+ refreshLine(target: string): Promise<boolean>;
98
+ isPaused(): boolean;
99
+ };
100
+ export type Delivery = {
101
+ /** Steps 1 to 4. `ready` means the work may be offered. */
102
+ prepare(unit: DeliveryUnit, store: DeliveryStore): Promise<"ready" | ProjectRunResult>;
103
+ /** The Gates' judgement of the published work; nothing is produced. */
104
+ judge(unit: DeliveryUnit): Promise<ImplementResult>;
105
+ /** Steps 5 to 7. `folded` is the one outcome that is not a pass of its own. */
106
+ settle(unit: DeliveryUnit, store: DeliveryStore): Promise<{
107
+ folded: true;
108
+ reference?: string | undefined;
109
+ } | ProjectRunResult>;
110
+ };
111
+ /** What the last Attempt ended on, for whoever reads the escalation. */
112
+ export declare function reasonOfTraces(traces: ImplementTrace[]): string | undefined;
113
+ export declare function openDelivery(options: DeliveryOptions): Delivery;
114
+ //# sourceMappingURL=delivery.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"delivery.d.ts","sourceRoot":"","sources":["../../src/run/delivery.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,278 @@
1
+ import { foldMessageOf } from "./subject.js";
2
+ /** What the last Attempt ended on, for whoever reads the escalation. */
3
+ export function reasonOfTraces(traces) {
4
+ const last = traces.at(-1);
5
+ const report = last?.report?.trim();
6
+ if (report === undefined || report.length === 0) {
7
+ return undefined;
8
+ }
9
+ return last?.refusedBy === undefined ? report : `${last.refusedBy}: ${report}`;
10
+ }
11
+ export function openDelivery(options) {
12
+ const { transformers, authority, durationMs, maxRefusals } = options;
13
+ const refused = (code) => ({ outcome: "refused", code });
14
+ /**
15
+ * Something broke or refused the work before it was published: hand it to the
16
+ * fix with the reason. A human is asked only when nothing can fix it (no fix
17
+ * declared, a blocking refusal) or the budget is spent.
18
+ */
19
+ async function sendBack(unit, store, read, why) {
20
+ const canRepair = options.fixDeclared && why.blocking !== true && read.spent + 1 < maxRefusals;
21
+ if (!canRepair) {
22
+ return await store.freeze({
23
+ kind: "assembly",
24
+ report: why.refusedBy === undefined ? why.report : `${why.refusedBy}: ${why.report}`,
25
+ });
26
+ }
27
+ const failure = await store.park(why);
28
+ if (failure !== undefined) {
29
+ return failure;
30
+ }
31
+ // Repair is on its way: do not offer, or judge, work that is already known to
32
+ // need it. The next pass produces the fix, then aligns and checks again.
33
+ return { outcome: "paused", key: unit.key };
34
+ }
35
+ /**
36
+ * The line moved on under a Submission, or refused the fold: go back to be
37
+ * aligned with it, judged and published again. Nothing was wrong with the
38
+ * work, so there is no report to repair; the round still counts.
39
+ */
40
+ async function realign(unit, store, read, why) {
41
+ if (read.spent + 1 >= maxRefusals) {
42
+ return await store.freeze({
43
+ kind: "submitted",
44
+ report: `${why} This ${unit.noun} has used all its corrective rounds, so it stops here for a person.`,
45
+ });
46
+ }
47
+ const failure = await store.realign();
48
+ if (failure !== undefined) {
49
+ return failure;
50
+ }
51
+ return { outcome: "paused", key: unit.key };
52
+ }
53
+ async function judge(unit) {
54
+ return await transformers.implement({
55
+ id: `${unit.key}:judgement`,
56
+ context: unit.key,
57
+ stage: unit.noun,
58
+ produce: false,
59
+ intention: unit.intention,
60
+ workspace: unit.judgeWorkspace,
61
+ });
62
+ }
63
+ async function prepare(unit, store) {
64
+ const read = await store.read();
65
+ if (read === undefined) {
66
+ return { outcome: "refused", code: "not-found" };
67
+ }
68
+ const line = unit.target.length > 0 ? unit.target : "the work line";
69
+ const sentBack = read.sentBack;
70
+ if (sentBack !== undefined) {
71
+ // Something refused the last round and said why. That report is the only
72
+ // reason this stage has to produce: the unit is already validated.
73
+ //
74
+ // Before the Integration below, and that order is the whole point. What a
75
+ // producer leaves is loose in the workspace; the Integration is the only
76
+ // thing that takes it up. Producing after it means the repair waits for
77
+ // the next round to be taken up at all, and what goes out meanwhile is the
78
+ // state that was already refused — the same refusal comes back, and the
79
+ // budget empties on the delay.
80
+ const remade = await transformers.implement({
81
+ id: `${unit.key}:fix`,
82
+ context: unit.key,
83
+ stage: unit.noun,
84
+ produce: true,
85
+ intention: unit.intention,
86
+ workspace: unit.workspace,
87
+ report: sentBack.report,
88
+ ...(sentBack.refusedBy === undefined ? {} : { reportFrom: sentBack.refusedBy }),
89
+ });
90
+ if (remade.outcome === "interrupted") {
91
+ return refused("interrupted");
92
+ }
93
+ if (remade.outcome === "invalid-invocation") {
94
+ return refused("transformer-invalid");
95
+ }
96
+ if (remade.outcome === "escalated") {
97
+ // The assembled work, not the unit: naming the unit here sends a reader
98
+ // to look at work that did not fail.
99
+ const why = reasonOfTraces(remade.traces);
100
+ return await store.freeze({
101
+ kind: "assembly",
102
+ ...(why === undefined ? {} : { report: why }),
103
+ });
104
+ }
105
+ }
106
+ // The line is brought current first: aligning with a copy that is behind
107
+ // would leave a Submission as far behind as it was, and send it round again.
108
+ const aligned = await options.onLine(async () => {
109
+ if (!(await options.refreshLine(unit.target))) {
110
+ return undefined;
111
+ }
112
+ return await transformers.integrate({
113
+ id: `${unit.key}:align`,
114
+ context: unit.key,
115
+ parent: unit.workspace,
116
+ child: unit.line,
117
+ durationMs,
118
+ // What is loose in the workspace here is the work the Builder made, or a
119
+ // repair of it.
120
+ subject: sentBack === undefined
121
+ ? foldMessageOf(unit.title ?? unit.intention)
122
+ : "Repair after it was refused",
123
+ mergeSubject: `Merge ${line} into the ${unit.noun}`,
124
+ });
125
+ });
126
+ if (aligned === undefined) {
127
+ return refused("line-refresh-failed");
128
+ }
129
+ if (aligned.outcome === "interrupted") {
130
+ return refused("interrupted");
131
+ }
132
+ if (aligned.outcome === "conflict") {
133
+ // Not a place to stop: the fix is told what happened and does the merge by hand.
134
+ return await sendBack(unit, store, read, {
135
+ report: `Merging the line "${line}" into this ${unit.noun} ` +
136
+ `conflicts: the ${unit.noun} and the line changed the same places. Look at what the line ` +
137
+ `changed since this ${unit.noun} started, and adapt the ${unit.noun}'s changes so they sit on top ` +
138
+ "of it. Keep what the line changed.",
139
+ refusedBy: "align",
140
+ });
141
+ }
142
+ if (aligned.outcome !== "integrated") {
143
+ return refused("transformer-invalid");
144
+ }
145
+ if (options.isPaused()) {
146
+ return { outcome: "paused", key: unit.key };
147
+ }
148
+ // The unit's own checks again, on what is there now. Skipped only when the
149
+ // code is the one they already passed: nothing was repaired this round and
150
+ // the line brought nothing in. `changed` absent means the fold could not
151
+ // say, which counts as changed.
152
+ const unchanged = !options.recheck || (sentBack === undefined && aligned.changed === false);
153
+ const rechecked = unchanged
154
+ ? { outcome: "validated", traces: [] }
155
+ : await transformers.implement({
156
+ id: `${unit.key}:recheck`,
157
+ context: unit.key,
158
+ stage: unit.noun,
159
+ produce: false,
160
+ recheck: true,
161
+ intention: unit.intention,
162
+ workspace: unit.workspace,
163
+ });
164
+ if (rechecked.outcome === "interrupted") {
165
+ return refused("interrupted");
166
+ }
167
+ if (rechecked.outcome === "invalid-invocation") {
168
+ return refused("transformer-invalid");
169
+ }
170
+ if (rechecked.outcome === "escalated") {
171
+ const last = rechecked.traces.at(-1);
172
+ return await sendBack(unit, store, read, {
173
+ report: last?.report ??
174
+ `The checks failed after the ${unit.noun} was aligned with the line, with no reason given.`,
175
+ ...(last?.refusedBy === undefined ? {} : { refusedBy: last.refusedBy }),
176
+ blocking: last?.ended === "fail-blocking",
177
+ });
178
+ }
179
+ // Whatever sent the work back is repaired and checked: it no longer asks for a fix.
180
+ const settled = await store.unpark();
181
+ if (settled !== undefined) {
182
+ return settled;
183
+ }
184
+ if (options.validate) {
185
+ const validated = await transformers.implement({
186
+ id: `${unit.key}:validate`,
187
+ context: unit.key,
188
+ stage: unit.noun,
189
+ validate: true,
190
+ intention: unit.intention,
191
+ workspace: unit.workspace,
192
+ });
193
+ if (validated.outcome === "interrupted") {
194
+ return refused("interrupted");
195
+ }
196
+ if (validated.outcome === "invalid-invocation") {
197
+ return refused("transformer-invalid");
198
+ }
199
+ if (validated.outcome === "escalated") {
200
+ const last = validated.traces.at(-1);
201
+ return await sendBack(unit, store, read, {
202
+ report: last?.report ?? `The assembled ${unit.noun} was refused, with no reason given.`,
203
+ ...(last?.refusedBy === undefined ? {} : { refusedBy: last.refusedBy }),
204
+ blocking: last?.ended === "fail-blocking",
205
+ });
206
+ }
207
+ const cleared = await store.unpark();
208
+ if (cleared !== undefined) {
209
+ return cleared;
210
+ }
211
+ }
212
+ return "ready";
213
+ }
214
+ async function settle(unit, store) {
215
+ const read = await store.read();
216
+ if (read === undefined) {
217
+ return { outcome: "refused", code: "not-found" };
218
+ }
219
+ const submission = read.submission;
220
+ if (authority === undefined || submission === undefined) {
221
+ return refused("transformer-invalid");
222
+ }
223
+ const judged = await judge(unit);
224
+ if (judged.outcome === "interrupted") {
225
+ return refused("interrupted");
226
+ }
227
+ if (judged.outcome === "invalid-invocation") {
228
+ return refused("transformer-invalid");
229
+ }
230
+ if (judged.outcome === "escalated") {
231
+ const last = judged.traces.at(-1);
232
+ const report = last?.report ?? "The Submission was refused, with no reason given.";
233
+ // A blocking refusal is not something another round repairs, and neither
234
+ // is one more refusal than the budget allows.
235
+ if (last?.ended === "fail-blocking" || read.spent + 1 >= maxRefusals) {
236
+ // The refusal that stopped it is never recorded as one — this is the
237
+ // only place it can be kept for the person who reads the escalation.
238
+ return await store.freeze({
239
+ kind: "submitted",
240
+ report: last?.refusedBy === undefined ? report : `${last.refusedBy}: ${report}`,
241
+ });
242
+ }
243
+ const failure = await store.refuse({ report, refusedBy: last?.refusedBy });
244
+ if (failure !== undefined) {
245
+ return failure;
246
+ }
247
+ // Back to where the work is made. The next pass produces with that report
248
+ // in hand and publishes to the same place.
249
+ return { outcome: "paused", key: unit.key };
250
+ }
251
+ // The Gates judged the work as it was published. If the line has moved on
252
+ // since — a person pushed to it, or later a ticket folded into it — a fold
253
+ // would produce something nobody judged. Go back to be aligned with the
254
+ // line again, then judged again, instead of folding.
255
+ const moved = await authority.behind?.({ reference: submission.reference });
256
+ if (moved?.outcome === "unavailable") {
257
+ return { outcome: "paused", key: unit.key };
258
+ }
259
+ if (moved?.outcome === "behind") {
260
+ // Back to where the work is aligned. The next pass brings the work line copy
261
+ // up to date, merges it into the work, checks it, judges it and publishes
262
+ // to the same place.
263
+ return await realign(unit, store, read, "The line moved on while this Submission waited to be folded, so what was judged is not what a fold would produce.");
264
+ }
265
+ const folded = await authority.fold({ reference: submission.reference });
266
+ if (folded.outcome === "unavailable") {
267
+ return { outcome: "paused", key: unit.key };
268
+ }
269
+ if (folded.outcome === "conflict") {
270
+ // The Authority will not fold it as it stands: go back and be aligned with the
271
+ // line again. If the alignment conflicts, the fix is told.
272
+ return await realign(unit, store, read, `The Authority refused the fold: ${folded.reason}`);
273
+ }
274
+ return { folded: true, reference: folded.reference };
275
+ }
276
+ return { prepare, judge, settle };
277
+ }
278
+ //# sourceMappingURL=delivery.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"delivery.js","sourceRoot":"","sources":["../../src/run/delivery.ts"],"names":[],"mappings":"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"}
@@ -1,7 +1,9 @@
1
1
  import type { CommandResult, WorkLedger } from "@bluewombat/work-ledger";
2
2
  import type { AuthorityPort, TransformerPort } from "../transformers/port.js";
3
- export type ConductorRefusalCode = "stable-missing" | "root-invalid" | "persist-failed" | "interrupted" | "isolate-failed" | "warm-failed" | "align-conflict" | "transformer-invalid" | "unavailable" | "not-found" | "point-of-no-return" | "project-busy" | "illegal-transition";
4
- /** Prepare a Feature workspace after Isolation — install deps, and so on. */
3
+ import type { ProjectRunResult } from "./results.js";
4
+ export type { ConductorRefusalCode, ProjectRunResult } from "./results.js";
5
+ export { foldMessageOf, subjectOf } from "./subject.js";
6
+ /** Prepare a Ticket workspace after Isolation — install deps, and so on. */
5
7
  export type WarmOutcome = "warmed" | "failed" | "interrupted" | "invalid-invocation";
6
8
  export type WarmPort = {
7
9
  prepare(input: {
@@ -11,20 +13,18 @@ export type WarmPort = {
11
13
  outcome: WarmOutcome;
12
14
  }>;
13
15
  };
14
- export type ProjectRunResult = {
15
- outcome: "idle";
16
- } | {
17
- outcome: "done";
18
- key: string;
19
- } | {
20
- outcome: "escalated";
21
- key: string;
22
- } | {
23
- outcome: "paused";
24
- key?: string;
25
- } | {
26
- outcome: "refused";
27
- code: ConductorRefusalCode;
16
+ /**
17
+ * Bring the shared copy of the work line up to what the Authority holds, for
18
+ * the line `target` names. Conductor asks right before it reads the copy, so a
19
+ * ticket always starts from, and aligns with, the line as it is now.
20
+ */
21
+ export type LinePort = {
22
+ refresh(target: string): Promise<{
23
+ ok: true;
24
+ } | {
25
+ ok: false;
26
+ detail?: string;
27
+ }>;
28
28
  };
29
29
  export type OpenConductorOptions = {
30
30
  ledger: WorkLedger;
@@ -33,40 +33,59 @@ export type OpenConductorOptions = {
33
33
  workspaceRoot: string;
34
34
  transformerDurationMs?: number;
35
35
  /**
36
- * The outside judge of a Submission. Absent: an assembled feature is folded
36
+ * How many Tickets of a Project may be active at once. Default 1.
37
+ *
38
+ * Above 1 the Project needs an Authority: a Ticket folded straight into the
39
+ * work line would move it under the others with nobody to send them back.
40
+ */
41
+ maxParallel?: number;
42
+ /**
43
+ * Keeps the shared copy of the work line current. Absent: it is whatever its
44
+ * owner left, as before.
45
+ */
46
+ line?: LinePort;
47
+ /**
48
+ * The outside judge of a Submission. Absent: an assembled ticket is folded
37
49
  * into the work line directly, with nobody else asked.
38
50
  */
39
51
  authority?: AuthorityPort;
40
- /** The work line a Submission is offered to. Required with an Authority. */
52
+ /** The work line a Submission is offered to, unless the Ticket names its own `line`. Required with an Authority. */
41
53
  workLineTarget?: string;
42
54
  /** How many times the Authority may send the work back before it escalates. */
43
55
  maxRefusals?: number;
44
56
  /**
45
- * Whether a local judge decides if the assembled feature meets the
57
+ * Whether a local judge decides if the assembled ticket meets the
46
58
  * intention, before any Submission exists — or, without an Authority,
47
- * before the final fold. Absent or `false`: `assembly.validate` is not
59
+ * before the final fold. Absent or `false`: `validate` is not
48
60
  * declared, and `integrating` goes straight to offer (or the local judge on
49
- * `produce: false`), as before.
61
+ * `produce: false`).
50
62
  */
51
- assemblyValidate?: boolean;
63
+ validate?: boolean;
52
64
  /**
53
- * Whether `assembly.fix` is declared. A validate refusal with nothing to
65
+ * Whether the tests of a Task are written before its code. Then a pass of its
66
+ * own runs in the Ticket's workspace first, and what it wrote is committed as a
67
+ * checkpoint, so the producer's work is what comes after it. Absent or `false`:
68
+ * the producer makes the code and the tests together, as before.
69
+ */
70
+ tests?: boolean;
71
+ /**
72
+ * Whether a fix is declared. A validate refusal with nothing to
54
73
  * repair it escalates on the spot rather than spending the budget on a round
55
74
  * that can only repeat the same refusal.
56
75
  */
57
- assemblyFixDeclared?: boolean;
76
+ fixDeclared?: boolean;
58
77
  /**
59
78
  * Told at the moments a pass changes what an outsider would want to know:
60
- * the plan is in, a Subtask is integrated, the work is submitted. Awaited,
79
+ * the work is submitted. Awaited,
61
80
  * so what the caller says lands before the next step; what it throws is
62
81
  * its own problem and does not stop the run.
63
82
  */
64
83
  observe?: (moment: ConductorMoment) => Promise<void> | void;
65
84
  /**
66
- * Prepare the Feature workspace once it exists, before any Subtask is
67
- * isolated from it. Absent: Subtasks inherit whatever Isolation left —
68
- * often a cold tree with no dependencies. Bounded by `durationMs`; retried
69
- * on the next `runProject` until it returns `warmed`.
85
+ * Prepare the workspace once it exists, before the Builder runs in it.
86
+ * Absent: the Builder gets whatever Isolation left — often a cold tree with
87
+ * no dependencies. Bounded by `durationMs`; retried on the next `runProject`
88
+ * until it returns `warmed`.
70
89
  */
71
90
  warm?: WarmPort & {
72
91
  durationMs: number;
@@ -74,15 +93,6 @@ export type OpenConductorOptions = {
74
93
  };
75
94
  /** One thing that happened inside a pass, for whoever is watching from outside. */
76
95
  export type ConductorMoment = {
77
- kind: "planned";
78
- key: string;
79
- } | {
80
- kind: "subtask-integrated";
81
- key: string;
82
- subtaskId: string;
83
- integrated: number;
84
- total: number;
85
- } | {
86
96
  kind: "submitted";
87
97
  key: string;
88
98
  reference: string;
@@ -92,23 +102,25 @@ export type Conductor = {
92
102
  pause(): void;
93
103
  resume(): void;
94
104
  runProject(project: string): Promise<ProjectRunResult>;
105
+ /**
106
+ * Take the next Ticket of the Project that may start, within its parallel
107
+ * limit. Nothing is run. Absent when none may: the Project is full, or
108
+ * nothing is ready or unblocked.
109
+ */
110
+ claimNext(project: string): Promise<{
111
+ key: string;
112
+ } | undefined>;
113
+ /**
114
+ * Drive one Ticket the Project already holds, as far as it goes. Unlike
115
+ * `runProject` it neither claims nor reconciles, so several can run at once.
116
+ */
117
+ runTicket(key: string): Promise<ProjectRunResult>;
95
118
  cancel(key: string): Promise<CommandResult>;
96
119
  /**
97
- * Drop a held Subtask (or planning) without waiting for the bail clock.
98
- * Destroys the declared Subtask directory when one was recorded.
120
+ * Drop a held unit without waiting for the bail clock.
121
+ * Destroys the declared directory when one was recorded.
99
122
  */
100
123
  release(key: string): Promise<CommandResult>;
101
124
  };
102
- /**
103
- * A fold's subject out of prose. Text written the way a commit is — a headline,
104
- * a blank line, the rest — gives its headline. Otherwise the first sentence,
105
- * cut at a word when even that runs past what one line of history shows. A
106
- * subject is not markdown, so the backticks prose uses for names come off; and
107
- * it ends on a word, not on an ellipsis — the whole text follows in the body
108
- * for whoever wants it.
109
- */
110
- export declare function subjectOf(text: string): string;
111
- /** Subject line, then the whole text when the subject did not carry it all. */
112
- export declare function foldMessageOf(text: string): string;
113
125
  export declare function openConductor(options: OpenConductorOptions): Conductor;
114
126
  //# sourceMappingURL=open-conductor.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"open-conductor.d.ts","sourceRoot":"","sources":["../../src/run/open-conductor.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"open-conductor.d.ts","sourceRoot":"","sources":["../../src/run/open-conductor.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,aAAa,EAGb,UAAU,EACX,MAAM,yBAAyB,CAAC;AACjC,OAAO,KAAK,EAAE,aAAa,EAAkB,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAS9F,OAAO,KAAK,EAAwB,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAG3E,YAAY,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAC3E,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAKxD,4EAA4E;AAC5E,MAAM,MAAM,WAAW,GAAG,QAAQ,GAAG,QAAQ,GAAG,aAAa,GAAG,oBAAoB,CAAC;AAErF,MAAM,MAAM,QAAQ,GAAG;IACrB,OAAO,CAAC,KAAK,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,WAAW,CAAA;KAAE,CAAC,CAAC;CAC9F,CAAC;AAEF;;;;GAIG;AACH,MAAM,MAAM,QAAQ,GAAG;IACrB,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,EAAE,EAAE,IAAI,CAAA;KAAE,GAAG;QAAE,EAAE,EAAE,KAAK,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACjF,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG;IACjC,MAAM,EAAE,UAAU,CAAC;IACnB,YAAY,EAAE,eAAe,CAAC;IAC9B,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,MAAM,CAAC;IACtB,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B;;;;;OAKG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;OAGG;IACH,IAAI,CAAC,EAAE,QAAQ,CAAC;IAChB;;;OAGG;IACH,SAAS,CAAC,EAAE,aAAa,CAAC;IAC1B,oHAAoH;IACpH,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,+EAA+E;IAC/E,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;;;OAMG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;;;;OAKG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB;;;;OAIG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB;;;;;OAKG;IACH,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,eAAe,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IAC5D;;;;;OAKG;IACH,IAAI,CAAC,EAAE,QAAQ,GAAG;QAAE,UAAU,EAAE,MAAM,CAAA;KAAE,CAAC;CAC1C,CAAC;AAEF,mFAAmF;AACnF,MAAM,MAAM,eAAe,GAAG;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CAAC;AAEpF,MAAM,MAAM,SAAS,GAAG;IACtB,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1C,KAAK,IAAI,IAAI,CAAC;IACd,MAAM,IAAI,IAAI,CAAC;IACf,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAC;IACvD;;;;OAIG;IACH,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,GAAG,EAAE,MAAM,CAAA;KAAE,GAAG,SAAS,CAAC,CAAC;IACjE;;;OAGG;IACH,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAC;IAClD,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC;IAC5C;;;OAGG;IACH,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC;CAC9C,CAAC;AAyEF,wBAAgB,aAAa,CAAC,OAAO,EAAE,oBAAoB,GAAG,SAAS,CAoyBtE"}