@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/README.md +3 -3
- package/SPECS.md +179 -163
- package/dist/index.d.ts +5 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/run/delivery.d.ts +114 -0
- package/dist/run/delivery.d.ts.map +1 -0
- package/dist/run/delivery.js +278 -0
- package/dist/run/delivery.js.map +1 -0
- package/dist/run/open-conductor.d.ts +63 -51
- package/dist/run/open-conductor.d.ts.map +1 -1
- package/dist/run/open-conductor.js +378 -470
- package/dist/run/open-conductor.js.map +1 -1
- package/dist/run/paths.d.ts +1 -2
- package/dist/run/paths.d.ts.map +1 -1
- package/dist/run/paths.js +2 -5
- package/dist/run/paths.js.map +1 -1
- package/dist/run/results.d.ts +17 -0
- package/dist/run/results.d.ts.map +1 -0
- package/dist/run/results.js +2 -0
- package/dist/run/results.js.map +1 -0
- package/dist/run/subject.d.ts +12 -0
- package/dist/run/subject.d.ts.map +1 -0
- package/dist/run/subject.js +33 -0
- package/dist/run/subject.js.map +1 -0
- package/dist/transformers/port.d.ts +58 -46
- package/dist/transformers/port.d.ts.map +1 -1
- package/package.json +3 -3
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"
|
|
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":"AAOA,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AA4G7C,wEAAwE;AACxE,MAAM,UAAU,cAAc,CAAC,MAAwB;IACrD,MAAM,IAAI,GAAG,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IAC3B,MAAM,MAAM,GAAG,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;IACpC,IAAI,MAAM,KAAK,SAAS,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAChD,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,OAAO,IAAI,EAAE,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,SAAS,KAAK,MAAM,EAAE,CAAC;AACjF,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,OAAwB;IACnD,MAAM,EAAE,YAAY,EAAE,SAAS,EAAE,UAAU,EAAE,WAAW,EAAE,GAAG,OAAO,CAAC;IAErE,MAAM,OAAO,GAAG,CAAC,IAAmE,EAAE,EAAE,CACtF,CAAC,EAAE,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,CAA4B,CAAC;IAE5D;;;;OAIG;IACH,KAAK,UAAU,QAAQ,CACrB,IAAkB,EAClB,KAAoB,EACpB,IAAkB,EAClB,GAA2E;QAE3E,MAAM,SAAS,GAAG,OAAO,CAAC,WAAW,IAAI,GAAG,CAAC,QAAQ,KAAK,IAAI,IAAI,IAAI,CAAC,KAAK,GAAG,CAAC,GAAG,WAAW,CAAC;QAC/F,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,OAAO,MAAM,KAAK,CAAC,MAAM,CAAC;gBACxB,IAAI,EAAE,UAAU;gBAChB,MAAM,EAAE,GAAG,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,SAAS,KAAK,GAAG,CAAC,MAAM,EAAE;aACrF,CAAC,CAAC;QACL,CAAC;QACD,MAAM,OAAO,GAAG,MAAM,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACtC,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;YAC1B,OAAO,OAAO,CAAC;QACjB,CAAC;QACD,8EAA8E;QAC9E,yEAAyE;QACzE,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC;IAC9C,CAAC;IAED;;;;OAIG;IACH,KAAK,UAAU,OAAO,CACpB,IAAkB,EAClB,KAAoB,EACpB,IAAkB,EAClB,GAAW;QAEX,IAAI,IAAI,CAAC,KAAK,GAAG,CAAC,IAAI,WAAW,EAAE,CAAC;YAClC,OAAO,MAAM,KAAK,CAAC,MAAM,CAAC;gBACxB,IAAI,EAAE,WAAW;gBACjB,MAAM,EAAE,GAAG,GAAG,SAAS,IAAI,CAAC,IAAI,qEAAqE;aACtG,CAAC,CAAC;QACL,CAAC;QACD,MAAM,OAAO,GAAG,MAAM,KAAK,CAAC,OAAO,EAAE,CAAC;QACtC,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;YAC1B,OAAO,OAAO,CAAC;QACjB,CAAC;QACD,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC;IAC9C,CAAC;IAED,KAAK,UAAU,KAAK,CAAC,IAAkB;QACrC,OAAO,MAAM,YAAY,CAAC,SAAS,CAAC;YAClC,EAAE,EAAE,GAAG,IAAI,CAAC,GAAG,YAAY;YAC3B,OAAO,EAAE,IAAI,CAAC,GAAG;YACjB,KAAK,EAAE,IAAI,CAAC,IAAI;YAChB,OAAO,EAAE,KAAK;YACd,SAAS,EAAE,IAAI,CAAC,SAAS;YACzB,SAAS,EAAE,IAAI,CAAC,cAAc;SAC/B,CAAC,CAAC;IACL,CAAC;IAED,KAAK,UAAU,OAAO,CACpB,IAAkB,EAClB,KAAoB;QAEpB,MAAM,IAAI,GAAG,MAAM,KAAK,CAAC,IAAI,EAAE,CAAC;QAChC,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;YACvB,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC;QACnD,CAAC;QACD,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,eAAe,CAAC;QACpE,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC;QAC/B,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;YAC3B,yEAAyE;YACzE,mEAAmE;YACnE,EAAE;YACF,0EAA0E;YAC1E,yEAAyE;YACzE,wEAAwE;YACxE,2EAA2E;YAC3E,wEAAwE;YACxE,+BAA+B;YAC/B,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,SAAS,CAAC;gBAC1C,EAAE,EAAE,GAAG,IAAI,CAAC,GAAG,MAAM;gBACrB,OAAO,EAAE,IAAI,CAAC,GAAG;gBACjB,KAAK,EAAE,IAAI,CAAC,IAAI;gBAChB,OAAO,EAAE,IAAI;gBACb,SAAS,EAAE,IAAI,CAAC,SAAS;gBACzB,SAAS,EAAE,IAAI,CAAC,SAAS;gBACzB,MAAM,EAAE,QAAQ,CAAC,MAAM;gBACvB,GAAG,CAAC,QAAQ,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,QAAQ,CAAC,SAAS,EAAE,CAAC;aAChF,CAAC,CAAC;YACH,IAAI,MAAM,CAAC,OAAO,KAAK,aAAa,EAAE,CAAC;gBACrC,OAAO,OAAO,CAAC,aAAa,CAAC,CAAC;YAChC,CAAC;YACD,IAAI,MAAM,CAAC,OAAO,KAAK,oBAAoB,EAAE,CAAC;gBAC5C,OAAO,OAAO,CAAC,qBAAqB,CAAC,CAAC;YACxC,CAAC;YACD,IAAI,MAAM,CAAC,OAAO,KAAK,WAAW,EAAE,CAAC;gBACnC,wEAAwE;gBACxE,qCAAqC;gBACrC,MAAM,GAAG,GAAG,cAAc,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;gBAC1C,OAAO,MAAM,KAAK,CAAC,MAAM,CAAC;oBACxB,IAAI,EAAE,UAAU;oBAChB,GAAG,CAAC,GAAG,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC;iBAC9C,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QACD,yEAAyE;QACzE,6EAA6E;QAC7E,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,MAAM,CAAC,KAAK,IAAI,EAAE;YAC9C,IAAI,CAAC,CAAC,MAAM,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC;gBAC9C,OAAO,SAAS,CAAC;YACnB,CAAC;YACD,OAAO,MAAM,YAAY,CAAC,SAAS,CAAC;gBAClC,EAAE,EAAE,GAAG,IAAI,CAAC,GAAG,QAAQ;gBACvB,OAAO,EAAE,IAAI,CAAC,GAAG;gBACjB,MAAM,EAAE,IAAI,CAAC,SAAS;gBACtB,KAAK,EAAE,IAAI,CAAC,IAAI;gBAChB,UAAU;gBACV,yEAAyE;gBACzE,gBAAgB;gBAChB,OAAO,EACL,QAAQ,KAAK,SAAS;oBACpB,CAAC,CAAC,aAAa,CAAC,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,SAAS,CAAC;oBAC7C,CAAC,CAAC,6BAA6B;gBACnC,YAAY,EAAE,SAAS,IAAI,aAAa,IAAI,CAAC,IAAI,EAAE;aACpD,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QACH,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;YAC1B,OAAO,OAAO,CAAC,qBAAqB,CAAC,CAAC;QACxC,CAAC;QACD,IAAI,OAAO,CAAC,OAAO,KAAK,aAAa,EAAE,CAAC;YACtC,OAAO,OAAO,CAAC,aAAa,CAAC,CAAC;QAChC,CAAC;QACD,IAAI,OAAO,CAAC,OAAO,KAAK,UAAU,EAAE,CAAC;YACnC,iFAAiF;YACjF,OAAO,MAAM,QAAQ,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE;gBACvC,MAAM,EACJ,qBAAqB,IAAI,eAAe,IAAI,CAAC,IAAI,GAAG;oBACpD,kBAAkB,IAAI,CAAC,IAAI,+DAA+D;oBAC1F,sBAAsB,IAAI,CAAC,IAAI,2BAA2B,IAAI,CAAC,IAAI,gCAAgC;oBACnG,oCAAoC;gBACtC,SAAS,EAAE,OAAO;aACnB,CAAC,CAAC;QACL,CAAC;QACD,IAAI,OAAO,CAAC,OAAO,KAAK,YAAY,EAAE,CAAC;YACrC,OAAO,OAAO,CAAC,qBAAqB,CAAC,CAAC;QACxC,CAAC;QACD,IAAI,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC;YACvB,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC;QAC9C,CAAC;QACD,2EAA2E;QAC3E,2EAA2E;QAC3E,yEAAyE;QACzE,gCAAgC;QAChC,MAAM,SAAS,GAAG,CAAC,OAAO,CAAC,OAAO,IAAI,CAAC,QAAQ,KAAK,SAAS,IAAI,OAAO,CAAC,OAAO,KAAK,KAAK,CAAC,CAAC;QAC5F,MAAM,SAAS,GAAG,SAAS;YACzB,CAAC,CAAE,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,EAAE,EAA6B;YAClE,CAAC,CAAC,MAAM,YAAY,CAAC,SAAS,CAAC;gBAC3B,EAAE,EAAE,GAAG,IAAI,CAAC,GAAG,UAAU;gBACzB,OAAO,EAAE,IAAI,CAAC,GAAG;gBACjB,KAAK,EAAE,IAAI,CAAC,IAAI;gBAChB,OAAO,EAAE,KAAK;gBACd,OAAO,EAAE,IAAI;gBACb,SAAS,EAAE,IAAI,CAAC,SAAS;gBACzB,SAAS,EAAE,IAAI,CAAC,SAAS;aAC1B,CAAC,CAAC;QACP,IAAI,SAAS,CAAC,OAAO,KAAK,aAAa,EAAE,CAAC;YACxC,OAAO,OAAO,CAAC,aAAa,CAAC,CAAC;QAChC,CAAC;QACD,IAAI,SAAS,CAAC,OAAO,KAAK,oBAAoB,EAAE,CAAC;YAC/C,OAAO,OAAO,CAAC,qBAAqB,CAAC,CAAC;QACxC,CAAC;QACD,IAAI,SAAS,CAAC,OAAO,KAAK,WAAW,EAAE,CAAC;YACtC,MAAM,IAAI,GAAG,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;YACrC,OAAO,MAAM,QAAQ,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE;gBACvC,MAAM,EACJ,IAAI,EAAE,MAAM;oBACZ,+BAA+B,IAAI,CAAC,IAAI,mDAAmD;gBAC7F,GAAG,CAAC,IAAI,EAAE,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,CAAC;gBACvE,QAAQ,EAAE,IAAI,EAAE,KAAK,KAAK,eAAe;aAC1C,CAAC,CAAC;QACL,CAAC;QACD,oFAAoF;QACpF,MAAM,OAAO,GAAG,MAAM,KAAK,CAAC,MAAM,EAAE,CAAC;QACrC,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;YAC1B,OAAO,OAAO,CAAC;QACjB,CAAC;QACD,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;YACrB,MAAM,SAAS,GAAG,MAAM,YAAY,CAAC,SAAS,CAAC;gBAC7C,EAAE,EAAE,GAAG,IAAI,CAAC,GAAG,WAAW;gBAC1B,OAAO,EAAE,IAAI,CAAC,GAAG;gBACjB,KAAK,EAAE,IAAI,CAAC,IAAI;gBAChB,QAAQ,EAAE,IAAI;gBACd,SAAS,EAAE,IAAI,CAAC,SAAS;gBACzB,SAAS,EAAE,IAAI,CAAC,SAAS;aAC1B,CAAC,CAAC;YACH,IAAI,SAAS,CAAC,OAAO,KAAK,aAAa,EAAE,CAAC;gBACxC,OAAO,OAAO,CAAC,aAAa,CAAC,CAAC;YAChC,CAAC;YACD,IAAI,SAAS,CAAC,OAAO,KAAK,oBAAoB,EAAE,CAAC;gBAC/C,OAAO,OAAO,CAAC,qBAAqB,CAAC,CAAC;YACxC,CAAC;YACD,IAAI,SAAS,CAAC,OAAO,KAAK,WAAW,EAAE,CAAC;gBACtC,MAAM,IAAI,GAAG,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;gBACrC,OAAO,MAAM,QAAQ,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE;oBACvC,MAAM,EAAE,IAAI,EAAE,MAAM,IAAI,iBAAiB,IAAI,CAAC,IAAI,qCAAqC;oBACvF,GAAG,CAAC,IAAI,EAAE,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,CAAC;oBACvE,QAAQ,EAAE,IAAI,EAAE,KAAK,KAAK,eAAe;iBAC1C,CAAC,CAAC;YACL,CAAC;YACD,MAAM,OAAO,GAAG,MAAM,KAAK,CAAC,MAAM,EAAE,CAAC;YACrC,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;gBAC1B,OAAO,OAAO,CAAC;YACjB,CAAC;QACH,CAAC;QACD,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,KAAK,UAAU,MAAM,CACnB,IAAkB,EAClB,KAAoB;QAEpB,MAAM,IAAI,GAAG,MAAM,KAAK,CAAC,IAAI,EAAE,CAAC;QAChC,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;YACvB,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC;QACnD,CAAC;QACD,MAAM,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC;QACnC,IAAI,SAAS,KAAK,SAAS,IAAI,UAAU,KAAK,SAAS,EAAE,CAAC;YACxD,OAAO,OAAO,CAAC,qBAAqB,CAAC,CAAC;QACxC,CAAC;QACD,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,IAAI,CAAC,CAAC;QACjC,IAAI,MAAM,CAAC,OAAO,KAAK,aAAa,EAAE,CAAC;YACrC,OAAO,OAAO,CAAC,aAAa,CAAC,CAAC;QAChC,CAAC;QACD,IAAI,MAAM,CAAC,OAAO,KAAK,oBAAoB,EAAE,CAAC;YAC5C,OAAO,OAAO,CAAC,qBAAqB,CAAC,CAAC;QACxC,CAAC;QAED,IAAI,MAAM,CAAC,OAAO,KAAK,WAAW,EAAE,CAAC;YACnC,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;YAClC,MAAM,MAAM,GAAG,IAAI,EAAE,MAAM,IAAI,mDAAmD,CAAC;YACnF,yEAAyE;YACzE,8CAA8C;YAC9C,IAAI,IAAI,EAAE,KAAK,KAAK,eAAe,IAAI,IAAI,CAAC,KAAK,GAAG,CAAC,IAAI,WAAW,EAAE,CAAC;gBACrE,qEAAqE;gBACrE,qEAAqE;gBACrE,OAAO,MAAM,KAAK,CAAC,MAAM,CAAC;oBACxB,IAAI,EAAE,WAAW;oBACjB,MAAM,EAAE,IAAI,EAAE,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,SAAS,KAAK,MAAM,EAAE;iBAChF,CAAC,CAAC;YACL,CAAC;YACD,MAAM,OAAO,GAAG,MAAM,KAAK,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC,CAAC;YAC3E,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;gBAC1B,OAAO,OAAO,CAAC;YACjB,CAAC;YACD,0EAA0E;YAC1E,2CAA2C;YAC3C,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC;QAC9C,CAAC;QAED,0EAA0E;QAC1E,2EAA2E;QAC3E,wEAAwE;QACxE,qDAAqD;QACrD,MAAM,KAAK,GAAG,MAAM,SAAS,CAAC,MAAM,EAAE,CAAC,EAAE,SAAS,EAAE,UAAU,CAAC,SAAS,EAAE,CAAC,CAAC;QAC5E,IAAI,KAAK,EAAE,OAAO,KAAK,aAAa,EAAE,CAAC;YACrC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC;QAC9C,CAAC;QACD,IAAI,KAAK,EAAE,OAAO,KAAK,QAAQ,EAAE,CAAC;YAChC,6EAA6E;YAC7E,0EAA0E;YAC1E,qBAAqB;YACrB,OAAO,MAAM,OAAO,CAClB,IAAI,EACJ,KAAK,EACL,IAAI,EACJ,mHAAmH,CACpH,CAAC;QACJ,CAAC;QAED,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,UAAU,CAAC,SAAS,EAAE,CAAC,CAAC;QACzE,IAAI,MAAM,CAAC,OAAO,KAAK,aAAa,EAAE,CAAC;YACrC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC;QAC9C,CAAC;QACD,IAAI,MAAM,CAAC,OAAO,KAAK,UAAU,EAAE,CAAC;YAClC,+EAA+E;YAC/E,2DAA2D;YAC3D,OAAO,MAAM,OAAO,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,mCAAmC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;QAC9F,CAAC;QACD,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,CAAC,SAAS,EAAE,CAAC;IACvD,CAAC;IAED,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;AACpC,CAAC"}
|
|
@@ -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
|
-
|
|
4
|
-
|
|
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
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
} | {
|
|
23
|
-
|
|
24
|
-
|
|
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
|
-
*
|
|
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
|
|
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
|
|
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`: `
|
|
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`)
|
|
61
|
+
* `produce: false`).
|
|
50
62
|
*/
|
|
51
|
-
|
|
63
|
+
validate?: boolean;
|
|
52
64
|
/**
|
|
53
|
-
* Whether
|
|
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
|
-
|
|
76
|
+
fixDeclared?: boolean;
|
|
58
77
|
/**
|
|
59
78
|
* Told at the moments a pass changes what an outsider would want to know:
|
|
60
|
-
* the
|
|
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
|
|
67
|
-
*
|
|
68
|
-
*
|
|
69
|
-
*
|
|
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
|
|
98
|
-
* Destroys the declared
|
|
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":"AAGA,OAAO,KAAK,EACV,aAAa,
|
|
1
|
+
{"version":3,"file":"open-conductor.d.ts","sourceRoot":"","sources":["../../src/run/open-conductor.ts"],"names":[],"mappings":"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"}
|